././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.430468 SABnzbd-4.3.2/README.mkd0000644000000000000000000000531314625637243013657 0ustar00runnerstaffRelease Notes - SABnzbd 4.3.2 ========================================================= This is the second bug fix release of SABnzbd 4.3.0. ## Bug fixes and changes since 4.3.1 * Added Special option `disable_archive` for jobs to always be permanently deleted. * Specific AppRise notifications could fail to send. * Update of the article decoder core (`rapidyenc`). * Windows: After some time the interface would no longer load. * Windows: Custom shortcuts would be removed by the installer. * Windows/macOS: Updated Unrar to 7.01 and 7zip to 24.05. ## Key changes since 4.2.0 * **Archive:** * When jobs are removed from the History, they are moved to the Archive. * Keep your History clean and still be able to reliably use Duplicate Detection. * **Apprise Integrated:** * Send notifications using Apprise to almost any notification service. * Supported notifications: https://github.com/caronc/apprise/wiki * Notification Script `SABnzbd-notify.py` is no longer needed. * **Added IPv6-staging option:** * Enable `ipv6_staging` in Config - Specials to get additional IPv6 features: * Add IPv6 hostnames during address selection. * Internet Bandwidth is measured separately for IPv4 and IPv6. * **Other:** * The `text` output format is removed from the API, `json` is the default. * Handling of multiple inputs to several API methods was improved. * File browser dialog is available to select file paths in the Config. * Users will be warned if they configure an Indexer as a Server. * Added `SAB_API_KEY` and `SAB_API_URL` to script environment variables. * Windows/macOS: Updated Python to 3.12.3, Multipar to v1.3.3.2, Unrar to 7.00 and 7zip to 24.03. ## Bug fixes since 4.2.0 * Incorrect warnings of unknown status codes could be thrown. * Watched Folder would not work if Socks5 proxy was active. * Prevent crash on invalid Server Expiration Date. * Windows: Installer could create duplicate shortcuts. ## Upgrade notices * You can directly upgrade from version 3.0.0 and newer. * Upgrading from older versions will require performing a `Queue repair`. * Downgrading from version 4.2.0 or newer to 3.7.2 or older will require performing a `Queue repair` due to changes in the internal data format. ## Known problems and solutions * Read `ISSUES.txt` or https://sabnzbd.org/wiki/introduction/known-issues ## About SABnzbd is an open-source cross-platform binary newsreader. It simplifies the process of downloading from Usenet dramatically, thanks to its web-based user interface and advanced built-in post-processing options that automatically verify, repair, extract and clean up posts downloaded from Usenet. (c) Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4378502 SABnzbd-4.3.2/ISSUES.txt0000644000000000000000000000506214625637243014002 0ustar00runnerstaff******************************************* *** Known issues *** ******************************************* - To prevent unexpectedly large NZBs from eating your download quota you can set the option 'size_limit' on the Config->Special page. Any NZB larger than this size will be set to paused and get a low priority. - When par2 or unrar hang up, never just stop SABnzbd. Instead use your operating system's task manager to stop the par2 or unrar program. Forcing SABnzbd to quit may damage your queues. - Some Usenet servers have intermittent login (or other) problems. For these the server blocking method is not very favourable. There is an INI-only option that will limit blocks to 1 minute. no_penalties = 1 See: https://sabnzbd.org/wiki/configuration/3.4/special - Some third-party utilities try to probe SABnzbd API in such a way that you will often see warnings about unauthenticated access. If you are sure these probes are harmless, you can suppress the warnings by setting the option "api_warnings" to 0. See: https://sabnzbd.org/wiki/configuration/3.4/special - On macOS you may encounter downloaded files with foreign characters. The par2 repair may fail when the files were created on a Windows system. The problem is caused by the PAR2 utility and we cannot fix this now. This does not apply to files inside RAR files. - The "Watched Folder" sometimes fails to delete the NZB files it has processed. This happens when other software still accesses these files. Some third-party utilities supporting SABnzbd are known to do this. We cannot solve this problem, because the Operating System (read Windows) prevents the removal. - When SABnzbd cannot send notification emails, check your virus scanner, firewall or security suite. It may be blocking outgoing email. - When you are using external drives or network shares on macOS or Linux make sure that the drives are mounted. The operating system will simply redirect your files to alternative locations. You may have trouble finding the files when mounting the drive later. On macOS, SABnzbd will not create new folders in /Volumes. The result will be a failed job that can be retried once the volume has been mounted. - If you use a mounted drive as "temporary download folder", it must be present when SABnzbd starts up. If not, SABnzbd will use the default location. You can make SABnzbd wait for a mount of the "temporary download folder" by setting Config->Special->wait_for_dfolder to 1. SABnzbd will appear to hang until the drive is mounted. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.437972 SABnzbd-4.3.2/COPYRIGHT.txt0000644000000000000000000000305114625637243014333 0ustar00runnerstaff (c) Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) The SABnzbd-Team is: Active team: Safihre sanderjo jcfp inpheaux zoggy Sleeping members: ShyPike sw1tch pairofdimes rAf Honorary member (and original author): Gregor Kaufmann The main contributors and moderators of the translations: Danish: Rene (nordjyden6), Scott Dutch: ShyPike, Safihre French: rAf, Fox Ace, Fred, Morback, Jih German: Severin Heiniger, Tim Hartmann, DonPizza, Alex Norwegian: Protx, mjelva, TomP, John Romanian: nicusor Serbian: Ozzii, Krišan Darko Swedish: Malmis, Kim Joahnsson, Patrik-liind, Chris M Spanish: Syquus, Adolfo Jayme Portuguese (Brazil): lrrosa, diegosps Russian: Pavel Maryanov Polish: Tomasz 'Zen' Napierala Chinese: XsLiDian Finnish: Matti Ylönen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See accompanying files GPL2.txt and GPL3.txt. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4380465 SABnzbd-4.3.2/requirements.txt0000644000000000000000000000522514625637243015513 0ustar00runnerstaff# Main requirements # Note that not all sub-dependencies are listed, but only ones we know could cause trouble apprise==1.8.0 sabctools==8.2.0 CT3==3.3.3.post1 cffi==1.16.0 pycparser==2.22 feedparser==6.0.11 configobj==5.0.8 cheroot==10.0.1 six==1.16.0 cherrypy==18.9.0 jaraco.functools==4.0.1 jaraco.collections==5.0.0 jaraco.text==3.8.1 # Newer version introduces irrelevant extra dependencies jaraco.classes==3.4.0 jaraco.context==4.3.0 more-itertools==10.2.0 zc.lockfile==3.0.post1 python-dateutil==2.9.0.post0 tempora==5.5.1 pytz==2024.1 sgmllib3k==1.0.0 portend==3.2.0 chardet==5.2.0 PySocks==1.7.1 puremagic==1.23 guessit==3.8.0 babelfish==0.6.1 rebulk==3.2.0 # Recent cryptography versions require Rust. If you run into issues compiling this # SABnzbd will also work with older pre-Rust versions such as cryptography==3.3.2 cryptography==42.0.7 # We recommend using "orjson" as it is 2x as fast as "ujson". However, it requires # Rust so SABnzbd works just as well with "ujson" or the Python built in "json" module ujson==5.10.0 # Windows system integration pywin32==306; sys_platform == 'win32' windows-toasts==1.1.1; sys_platform == 'win32' and python_version > '3.8' winrt-runtime==2.0.1; sys_platform == 'win32' and python_version > '3.8' winrt-Windows.Data.Xml.Dom==2.0.1; sys_platform == 'win32' and python_version > '3.8' winrt-Windows.Foundation==2.0.1; sys_platform == 'win32' and python_version > '3.8' winrt-Windows.Foundation.Collections==2.0.1; sys_platform == 'win32' and python_version > '3.8' winrt-Windows.UI.Notifications==2.0.1; sys_platform == 'win32' and python_version > '3.8' # macOS system calls pyobjc-core==10.2; sys_platform == 'darwin' pyobjc-framework-Cocoa==10.2; sys_platform == 'darwin' # Linux notifications notify2==0.3.1; sys_platform != 'win32' and sys_platform != 'darwin' # Apprise Requirements requests==2.31.0 requests-oauthlib==2.0.0 PyYAML==6.0.1 markdown==3.6 paho-mqtt==1.6.1 # Pinned, newer versions don't work with AppRise yet # Requests Requirements charset_normalizer==3.3.2 idna==3.7 urllib3==2.2.1 certifi==2024.2.2 oauthlib==3.2.2 PyJWT==2.8.0 blinker==1.8.2 # Optional support for *nix tray icon. # Note that pygobject depends on pycairo, which requires pkg-config and cairo headers. # See https://pycairo.readthedocs.io/en/latest/getting_started.html # Uncomment line below or manually install after installing requirements. # pygobject>=3.10.2; sys_platform != 'win32' and sys_platform != 'darwin' # Optional support for system power management on *nix. # Requires libdbus-1-dev to be installed. # Uncomment line below or manually install after installing requirements. # dbus-python; sys_platform != 'win32' and sys_platform != 'darwin' ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4381485 SABnzbd-4.3.2/INSTALL.txt0000644000000000000000000001137714625637243014103 0ustar00runnerstaff SABnzbd ------------------------------------------------------------------------------- 0) LICENSE ------------------------------------------------------------------------------- (c) Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ------------------------------------------------------------------------------- 1) INSTALL with the Windows installer ------------------------------------------------------------------------------- Just run the downloaded EXE file and the installer will start. It's just a simple standard installer. After installation, find the SABnzbd program in the Start menu and start it. Within a few seconds your web browser will start and show the user interface. Use the "Help" button in the web-interface to be directed to the Help Wiki. ------------------------------------------------------------------------------- 2) INSTALL pre-built Windows binaries ------------------------------------------------------------------------------- Unzip pre-built version to any folder of your liking. Start the SABnzbd.exe program. Within a few seconds your web browser will start and show the user interface. Use the "Help" button in the web-interface to be directed to the Help Wiki. ------------------------------------------------------------------------------- 3) INSTALL pre-built macOS binaries ------------------------------------------------------------------------------- Download the DMG file, mount and drag the SABnzbd icon to Applications. Just like you do with so many apps. ------------------------------------------------------------------------------- 4) INSTALL with only sources ------------------------------------------------------------------------------- Specific guides to install from source are available for Windows and macOS: https://sabnzbd.org/wiki/installation/install-macos https://sabnzbd.org/wiki/installation/install-from-source-windows Only Python 3.8 and above is supported. On Linux systems you need to install: par2 unrar python3-setuptools python3-pip On non-X86 platforms, for which PyPI does not provide all pre-compiled packages, you also need to install these development libraries (exact names might differ per platform): libffi-dev libssl-dev Unpack the ZIP-file containing the SABnzbd sources to any folder of your liking. Inside the SABnzbd source directory, install all required Python packages by running: python3 -m pip install -r requirements.txt If you want non-English languages, you need to compile the translations. Start this from a shell terminal (or command prompt): python3 tools/make_mo.py To start SABnzbd, run this from a shell terminal (or command prompt): python3 -OO SABnzbd.py Within a few seconds your web browser will start and show the user interface. Use the "Help" button in the web-interface to be directed to the Help Wiki. ------------------------------------------------------------------------------- 5) TROUBLESHOOTING ------------------------------------------------------------------------------- Your browser may start up with just an error page. This means that SABnzbd cannot use the default port 8080 to run its web-server on. Try to use another port, you'll need to use the a command window: SABnzbd.exe -s localhost:7777 or python3 SABnzbd.py -s localhost:7777 You may of course try other port numbers too. For troubleshooting on Windows you can use the program SABnzbd-console.exe. This will show a black window where logging information will be shown. This may help you solve problems easier. ------------------------------------------------------------------------------- 6) MORE INFORMATION ------------------------------------------------------------------------------- Visit our wiki: https://sabnzbd.org/wiki/ ------------------------------------------------------------------------------- 7) CREDITS ------------------------------------------------------------------------------- Several parts of SABnzbd were built by other people, illustrating the wonderful world of Free Open Source Software. See the licenses folder of the main program and of the skin folders. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.438239 SABnzbd-4.3.2/GPL3.txt0000644000000000000000000010451314625637243013475 0ustar00runnerstaff GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4383254 SABnzbd-4.3.2/GPL2.txt0000644000000000000000000004310614625637243013474 0ustar00runnerstaff GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.438413 SABnzbd-4.3.2/SABnzbd.py0000755000000000000000000017333714625637243014101 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import sys # Trick to show a better message on older Python # releases that don't support walrus operator if Python_38_is_required_to_run_SABnzbd := sys.hexversion < 0x03080000: print("Sorry, requires Python 3.8 or above") print("You can read more at: https://sabnzbd.org/wiki/installation/install-off-modules") sys.exit(1) import os import logging import logging.handlers import importlib.util import traceback import getopt import signal import socket import platform import subprocess import multiprocessing import ssl import time import re import gc from typing import List, Dict, Any try: import sabctools import Cheetah import feedparser import configobj import cherrypy import cheroot.errors import portend import cryptography import chardet import guessit import puremagic import socks except ImportError as e: print("Not all required Python modules are available, please check requirements.txt") print("Missing module:", e.name) print("You can read more at: https://sabnzbd.org/wiki/installation/install-off-modules") print("If you still experience problems, remove all .pyc files in this folder and subfolders") sys.exit(1) import sabnzbd import sabnzbd.lang import sabnzbd.interface from sabnzbd.constants import ( DEF_TIMEOUT, DEF_LOG_ERRFILE, DEF_MAIN_TMPL, DEF_STD_WEB_DIR, DEF_WORKDIR, DEF_INTERFACES, DEF_LANGUAGE, VALID_NZB_FILES, VALID_ARCHIVES, DEF_INI_FILE, MAX_WARNINGS, RSS_FILE_NAME, DEF_LOG_FILE, DEF_STD_CONFIG, DEF_LOG_CHERRY, CONFIG_BACKUP_HTTPS, ) import sabnzbd.newsunpack from sabnzbd.misc import ( exit_sab, split_host, create_https_certificates, ip_extract, set_serv_parms, get_serv_parms, get_from_url, upload_file_to_sabnzbd, is_localhost, is_lan_addr, ip_in_subnet, helpful_warning, set_https_verification, ) from sabnzbd.filesystem import get_ext, real_path, long_path, globber_full, remove_file from sabnzbd.panic import panic_tmpl, panic_port, panic_host, panic, launch_a_browser import sabnzbd.config as config import sabnzbd.cfg import sabnzbd.notifier as notifier import sabnzbd.zconfig from sabnzbd.getipaddress import local_ipv4 import sabnzbd.utils.ssdp as ssdp try: import win32api import win32serviceutil import win32evtlogutil import win32event import win32service import win32ts import servicemanager from win32com.shell import shell, shellcon from sabnzbd.utils.apireg import get_connection_info, set_connection_info import sabnzbd.sabtray win32api.SetConsoleCtrlHandler(sabnzbd.sig_handler, True) except ImportError: if sabnzbd.WIN32: print("Sorry, requires Python module PyWin32.") sys.exit(1) # Global for this module, signaling loglevel change LOG_FLAG = False def guard_loglevel(): """Callback function for guarding loglevel""" global LOG_FLAG LOG_FLAG = True class GUIHandler(logging.Handler): """Logging handler collects the last warnings/errors/exceptions to be displayed in the web-gui """ def __init__(self, size): """Initializes the handler""" logging.Handler.__init__(self) self._size: int = size self.store: List[Dict[str, Any]] = [] def emit(self, record: logging.LogRecord): """Emit a record by adding it to our private queue""" # If % is part of the msg, this could fail try: parsed_msg = record.msg % record.args except TypeError: parsed_msg = record.msg + str(record.args) warning = { "type": record.levelname, "text": parsed_msg, "time": int(time.time()), "origin": "%s%d" % (record.filename, record.lineno), } # Append traceback, if available if record.exc_info: warning["text"] = "%s\n%s" % (warning["text"], traceback.format_exc()) # Do not notify the same notification within 1 minute from the same source # This prevents endless looping if the notification service itself throws an error/warning # We don't check based on message content, because if it includes a timestamp it's not unique if not any( stored_warning["origin"] == warning["origin"] and stored_warning["time"] + DEF_TIMEOUT > time.time() for stored_warning in self.store ): if record.levelno == logging.WARNING: sabnzbd.notifier.send_notification(T("Warning"), parsed_msg, "warning") else: sabnzbd.notifier.send_notification(T("Error"), parsed_msg, "error") # Loose the oldest record if len(self.store) >= self._size: self.store.pop(0) self.store.append(warning) def clear(self): self.store = [] def count(self): return len(self.store) def content(self): """Return an array with last records""" return self.store def print_help(): print() print(("Usage: %s [-f ] " % sabnzbd.MY_NAME)) print() print("Options marked [*] are stored in the config file") print() print("Options:") print(" -f --config-file Location of config file") print(" -s --server Listen on server:port [*]") print(" -t --templates Template directory [*]") print() print(" -l --logging <-1..2> Set logging level (-1=off, 0=least,2= most) [*]") print(" -w --weblogging Enable cherrypy access logging") print() print(" -b --browser <0..1> Auto browser launch (0= off, 1= on) [*]") if sabnzbd.WIN32: print(" -d --daemon Use when run as a service") else: print(" -d --daemon Fork daemon process") print(" --pid Create a PID file in the given folder (full path)") print(" --pidfile Create a PID file with the given name (full path)") print() print(" -h --help Print this message") print(" -v --version Print version information") print(" -c --clean Remove queue, cache and logs") print(" -p --pause Start in paused mode") print(" --repair Add orphaned jobs from the incomplete folder to the queue") print(" --repair-all Try to reconstruct the queue from the incomplete folder") print(" with full data reconstruction") print(" --https Port to use for HTTPS server") print(" --ipv6_hosting <0|1> Listen on IPv6 address [::1] [*]") print(" --inet_exposure <0..5> Set external internet access [*]") print(" --no-login Start with username and password reset") print(" --log-all Log all article handling (for developers)") print(" --disable-file-log Logging is only written to console") print(" --console Force logging to console") print(" --new Run a new instance of SABnzbd") print() print("NZB (or related) file:") print(" NZB or compressed NZB file, with extension .nzb, .zip, .rar, .7z, .gz, or .bz2") print() def print_version(): print( ( """ %s-%s (C) Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. """ % (sabnzbd.MY_NAME, sabnzbd.__version__) ) ) def daemonize(): """Daemonize the process, based on various StackOverflow answers""" try: pid = os.fork() if pid > 0: sys.exit(0) except OSError: print("fork() failed") sys.exit(1) os.chdir(sabnzbd.DIR_PROG) os.setsid() # Make sure I can read my own files and shut out others prev = os.umask(0) os.umask(prev and int("077", 8)) try: pid = os.fork() if pid > 0: sys.exit(0) except OSError: print("fork() failed") sys.exit(1) # Flush I/O buffers sys.stdout.flush() sys.stderr.flush() # Get log file path and remove the log file if it got too large log_path = os.path.join(sabnzbd.cfg.log_dir.get_path(), DEF_LOG_ERRFILE) if os.path.exists(log_path) and os.path.getsize(log_path) > sabnzbd.cfg.log_size(): remove_file(log_path) # Replace file descriptors for stdin, stdout, and stderr with open("/dev/null", "rb", 0) as f: os.dup2(f.fileno(), sys.stdin.fileno()) with open(log_path, "ab", 0) as f: os.dup2(f.fileno(), sys.stdout.fileno()) with open(log_path, "ab", 0) as f: os.dup2(f.fileno(), sys.stderr.fileno()) def abort_and_show_error(browserhost, cherryport, err=""): """Abort program because of CherryPy troubles""" logging.error(T("Failed to start web-interface") + " : " + str(err)) if not sabnzbd.DAEMON: if "49" in err: panic_host(browserhost, cherryport) else: panic_port(browserhost, cherryport) sabnzbd.halt() exit_sab(2) def identify_web_template(key, defweb, wdir): """Determine a correct web template set, return full template path""" if wdir is None: try: wdir = fix_webname(key()) except: wdir = "" if not wdir: wdir = defweb if key: key.set(wdir) if not wdir: # No default value defined, accept empty path return "" full_dir = real_path(sabnzbd.DIR_INTERFACES, wdir) full_main = real_path(full_dir, DEF_MAIN_TMPL) if not os.path.exists(full_main): helpful_warning(T("Cannot find web template: %s, trying standard template"), full_main) full_dir = real_path(sabnzbd.DIR_INTERFACES, DEF_STD_WEB_DIR) full_main = real_path(full_dir, DEF_MAIN_TMPL) if not os.path.exists(full_main): logging.exception("Cannot find standard template: %s", full_dir) panic_tmpl(full_dir) exit_sab(1) logging.info("Template location for %s is %s", defweb, full_dir) return real_path(full_dir, "templates") def check_template_scheme(color, web_dir): """Check existence of color-scheme""" if color and os.path.exists(os.path.join(web_dir, "static", "stylesheets", "colorschemes", color + ".css")): return color elif color and os.path.exists(os.path.join(web_dir, "static", "stylesheets", "colorschemes", color)): return color else: return "" def fix_webname(name): if name: xname = name.title() else: xname = "" if xname in ("Default",): return "Glitter" elif xname in ("Glitter",): return xname elif xname in ("Wizard",): return name.lower() elif xname in ("Config",): return "Glitter" else: return name def get_user_profile_paths(): """Get the default data locations on Windows""" if sabnzbd.DAEMON: # In daemon mode, do not try to access the user profile # just assume that everything defaults to the program dir sabnzbd.DIR_LCLDATA = sabnzbd.DIR_PROG sabnzbd.DIR_HOME = sabnzbd.DIR_PROG if sabnzbd.WIN32: # Ignore Win32 "logoff" signal # This should work, but it doesn't # Instead the signal_handler will ignore the "logoff" signal # signal.signal(5, signal.SIG_IGN) pass return elif sabnzbd.WIN32: try: path = shell.SHGetFolderPath(0, shellcon.CSIDL_LOCAL_APPDATA, None, 0) sabnzbd.DIR_LCLDATA = os.path.join(path, DEF_WORKDIR) sabnzbd.DIR_HOME = os.environ["USERPROFILE"] except: try: root = os.environ["AppData"] user = os.environ["USERPROFILE"] sabnzbd.DIR_LCLDATA = "%s\\%s" % (root.replace("\\Roaming", "\\Local"), DEF_WORKDIR) sabnzbd.DIR_HOME = user except: pass # Long-path everything sabnzbd.DIR_LCLDATA = long_path(sabnzbd.DIR_LCLDATA) sabnzbd.DIR_HOME = long_path(sabnzbd.DIR_HOME) return elif sabnzbd.MACOS: if home := os.environ.get("HOME"): sabnzbd.DIR_LCLDATA = "%s/Library/Application Support/SABnzbd" % home sabnzbd.DIR_HOME = home return else: # Unix/Linux if home := os.environ.get("HOME"): sabnzbd.DIR_LCLDATA = "%s/.%s" % (home, DEF_WORKDIR) sabnzbd.DIR_HOME = home return # Nothing worked panic("Cannot access the user profile.", "Please start with sabnzbd.ini file in another location") exit_sab(2) def print_modules(): """Log all detected optional or external modules""" if sabnzbd.decoder.SABCTOOLS_ENABLED: # Yes, we have SABCTools, and it's the correct version, so it's enabled logging.info("SABCTools module (v%s)... found!", sabnzbd.decoder.SABCTOOLS_VERSION) logging.info("SABCTools module is using SIMD set: %s", sabnzbd.decoder.SABCTOOLS_SIMD) logging.info("SABCTools module is linked to OpenSSL: %s", sabnzbd.decoder.SABCTOOLS_OPENSSL_LINKED) # Check if we managed to link, warning for now # It won't work on OpenSSL < 1.1.1 anyway, so we skip the check there if not sabnzbd.decoder.SABCTOOLS_OPENSSL_LINKED and ssl.OPENSSL_VERSION_INFO >= (1, 1, 1): logging.warning( "Could not link to OpenSSL library, please report here: " "https://github.com/sabnzbd/sabnzbd/issues/2421" ) else: # Wrong SABCTools version, if it was fully missing it would fail to start due to check at the very top logging.error( T("SABCTools disabled: no correct version found! (Found v%s, expecting v%s)"), sabnzbd.decoder.SABCTOOLS_VERSION, sabnzbd.constants.SABCTOOLS_VERSION_REQUIRED, ) # Do not allow downloading sabnzbd.NO_DOWNLOADING = True logging.info("Cryptography module (v%s)... found!", cryptography.__version__) if sabnzbd.WIN32 and sabnzbd.newsunpack.MULTIPAR_COMMAND: logging.info("MultiPar binary... found (%s)", sabnzbd.newsunpack.MULTIPAR_COMMAND) if sabnzbd.newsunpack.PAR2_COMMAND: logging.info("par2 binary... found (%s)", sabnzbd.newsunpack.PAR2_COMMAND) else: logging.error(T("par2 binary... NOT found!")) # Do not allow downloading sabnzbd.NO_DOWNLOADING = True if sabnzbd.newsunpack.RAR_COMMAND: logging.info("UNRAR binary... found (%s)", sabnzbd.newsunpack.RAR_COMMAND) # Report problematic unrar if sabnzbd.newsunpack.RAR_PROBLEM: have_str = "%.2f" % (float(sabnzbd.newsunpack.RAR_VERSION) / 100) want_str = "%.2f" % (float(sabnzbd.constants.REC_RAR_VERSION) / 100) helpful_warning(T("Your UNRAR version is %s, we recommend version %s or higher.
"), have_str, want_str) elif not (sabnzbd.WIN32 or sabnzbd.MACOS): logging.info("UNRAR binary version %.2f", (float(sabnzbd.newsunpack.RAR_VERSION) / 100)) else: logging.error(T("unrar binary... NOT found")) # Do not allow downloading sabnzbd.NO_DOWNLOADING = True if sabnzbd.newsunpack.SEVENZIP_COMMAND: logging.info("7za binary... found (%s)", sabnzbd.newsunpack.SEVENZIP_COMMAND) if not (sabnzbd.WIN32 or sabnzbd.MACOS): logging.info("7za binary version %s", sabnzbd.newsunpack.SEVENZIP_VERSION) else: logging.warning(T("7za binary... NOT found!")) if not sabnzbd.WIN32: if sabnzbd.newsunpack.NICE_COMMAND: logging.info("nice binary... found (%s)", sabnzbd.newsunpack.NICE_COMMAND) else: logging.info("nice binary... NOT found!") if sabnzbd.newsunpack.IONICE_COMMAND: logging.info("ionice binary... found (%s)", sabnzbd.newsunpack.IONICE_COMMAND) else: logging.info("ionice binary... NOT found!") # Show fatal warning if sabnzbd.NO_DOWNLOADING: logging.error(T("Essential modules are missing, downloading cannot start.")) def all_localhosts(): """Return all unique values of localhost in order of preference""" ips = ["127.0.0.1"] try: # Check whether IPv6 is available and enabled info = socket.getaddrinfo("::1", None) af, socktype, proto, _canonname, _sa = info[0] s = socket.socket(af, socktype, proto) s.close() except socket.error: return ips try: info = socket.getaddrinfo("localhost", None) except socket.error: # localhost does not resolve return ips ips = [] for item in info: item = item[4][0] # Avoid problems on strange Linux settings if not isinstance(item, str): continue # Only return IPv6 when enabled if item not in ips and ("::1" not in item or sabnzbd.cfg.ipv6_hosting()): ips.append(item) return ips def check_resolve(host): """Return True if 'host' resolves""" try: socket.getaddrinfo(host, None) except socket.error: # Does not resolve return False return True def get_webhost(cherryhost, cherryport, https_port): """Determine the webhost address and port, return (host, port, browserhost) """ if cherryhost == "0.0.0.0" and not check_resolve("127.0.0.1"): cherryhost = "" elif cherryhost == "::" and not check_resolve("::1"): cherryhost = "" if cherryhost is None: cherryhost = sabnzbd.cfg.cherryhost() else: sabnzbd.cfg.cherryhost.set(cherryhost) # Get IP address, but discard APIPA/IPV6 # If only APIPA's or IPV6 are found, fall back to localhost ipv4 = ipv6 = False localhost = hostip = "localhost" try: info = socket.getaddrinfo(socket.gethostname(), None) except socket.error: # Hostname does not resolve try: # Valid user defined name? info = socket.getaddrinfo(cherryhost, None) except socket.error: if not is_localhost(cherryhost): cherryhost = "0.0.0.0" try: info = socket.getaddrinfo(localhost, None) except socket.error: info = socket.getaddrinfo("127.0.0.1", None) localhost = "127.0.0.1" for item in info: ip = str(item[4][0]) if ip.startswith("169.254."): pass # Automatic Private IP Addressing (APIPA) elif ":" in ip: ipv6 = True elif "." in ip and not ipv4: ipv4 = True hostip = ip # A blank host will use the local ip address if cherryhost == "": if ipv6 and ipv4: # To protect Firefox users, use numeric IP cherryhost = hostip browserhost = hostip else: cherryhost = socket.gethostname() browserhost = cherryhost # 0.0.0.0 will listen on all ipv4 interfaces (no ipv6 addresses) elif cherryhost == "0.0.0.0": # Just take the gamble for this cherryhost = "0.0.0.0" browserhost = localhost # :: will listen on all ipv6 interfaces (no ipv4 addresses) elif cherryhost in ("::", "[::]"): cherryhost = cherryhost.strip("[").strip("]") # Assume '::1' == 'localhost' browserhost = localhost # IPV6 address elif "[" in cherryhost or ":" in cherryhost: browserhost = cherryhost # IPV6 numeric address elif cherryhost.replace(".", "").isdigit(): # IPV4 numerical browserhost = cherryhost elif cherryhost == localhost: cherryhost = localhost browserhost = localhost else: # If on APIPA, use numerical IP, to help FireFoxers if ipv6 and ipv4: cherryhost = hostip browserhost = cherryhost # Some systems don't like brackets in numerical ipv6 if sabnzbd.MACOS: cherryhost = cherryhost.strip("[]") else: try: socket.getaddrinfo(cherryhost, None) except socket.error: cherryhost = cherryhost.strip("[]") if ipv6 and ipv4 and cherryhost == "" and sabnzbd.WIN32: helpful_warning(T("Please be aware the 0.0.0.0 hostname will need an IPv6 address for external access")) if cherryhost == "localhost" and not sabnzbd.WIN32 and not sabnzbd.MACOS: # On the Ubuntu family, localhost leads to problems for CherryPy ips = ip_extract() if "127.0.0.1" in ips and "::1" in ips: cherryhost = "127.0.0.1" if ips[0] != "127.0.0.1": browserhost = "127.0.0.1" # This is to please Chrome on macOS if cherryhost == "localhost" and sabnzbd.MACOS: cherryhost = "127.0.0.1" browserhost = "localhost" if cherryport is None: cherryport = sabnzbd.cfg.cherryport.get_int() else: sabnzbd.cfg.cherryport.set(str(cherryport)) if https_port is None: https_port = sabnzbd.cfg.https_port.get_int() else: sabnzbd.cfg.https_port.set(str(https_port)) # if the https port was specified, assume they want HTTPS enabling also sabnzbd.cfg.enable_https.set(True) if cherryport == https_port and sabnzbd.cfg.enable_https(): sabnzbd.cfg.enable_https.set(False) # Should have a translated message, but that's not available yet logging.error(T("HTTP and HTTPS ports cannot be the same")) return cherryhost, cherryport, browserhost, https_port def attach_server(host, port, cert=None, key=None, chain=None): """Define and attach server, optionally HTTPS""" if sabnzbd.cfg.ipv6_hosting() or "::1" not in host: http_server = cherrypy._cpserver.Server() http_server.bind_addr = (host, port) if cert and key: http_server.ssl_module = "builtin" http_server.ssl_certificate = cert http_server.ssl_private_key = key http_server.ssl_certificate_chain = chain http_server.subscribe() def is_sabnzbd_running(url): """Return True when there's already a SABnzbd instance running.""" try: url = "%s&mode=version" % url # Do this without certificate verification, few installations will have that prev = set_https_verification(False) ver = get_from_url(url) set_https_verification(prev) return ver and (re.search(r"\d+\.\d+\.", ver) or ver.strip() == sabnzbd.__version__) except: return False def find_free_port(host, currentport): """Return a free port, 0 when nothing is free""" n = 0 while n < 10 and currentport <= 49151: try: portend.free(host, currentport, timeout=0.025) return currentport except: currentport += 5 n += 1 return 0 def check_for_sabnzbd(url, upload_nzbs, allow_browser=True): """Check for a running instance of sabnzbd on this port allow_browser==True|None will launch the browser, False will not. """ if allow_browser is None: allow_browser = True if is_sabnzbd_running(url): # Upload any specified nzb files to the running instance if upload_nzbs: prev = set_https_verification(False) for f in upload_nzbs: upload_file_to_sabnzbd(url, f) set_https_verification(prev) else: # Launch the web browser and quit since sabnzbd is already running # Trim away everything after the final slash in the URL url = url[: url.rfind("/") + 1] launch_a_browser(url, force=allow_browser) exit_sab(0) return True return False def evaluate_inipath(path): """Derive INI file path from a partial path. Full file path: if file does not exist the name must contain a dot but not a leading dot. foldername is enough, the standard name will be appended. """ path = os.path.normpath(os.path.abspath(path)) inipath = os.path.join(path, DEF_INI_FILE) if os.path.isdir(path): return inipath elif os.path.isfile(path) or os.path.isfile(path + ".bak"): return path else: _dirpart, name = os.path.split(path) if name.find(".") < 1: return inipath else: return path def commandline_handler(): """Split win32-service commands are true parameters Returns: service, sab_opts, serv_opts, upload_nzbs """ service = "" sab_opts = [] serv_opts = [os.path.normpath(os.path.abspath(sys.argv[0]))] upload_nzbs = [] try: opts, args = getopt.getopt( sys.argv[1:], "phdvncwl:s:f:t:b:2:", [ "pause", "help", "daemon", "nobrowser", "clean", "logging=", "weblogging", "server=", "templates", "ipv6_hosting=", "inet_exposure=", "browser=", "config-file=", "disable-file-log", "version", "https=", "autorestarted", "repair", "repair-all", "log-all", "no-login", "pid=", "new", "console", "pidfile=", # Below Win32 Service options "password=", "username=", "startup=", "perfmonini=", "perfmondll=", "interactive", "wait=", ], ) except getopt.GetoptError: print_help() exit_sab(2) # Check for Win32 service commands if args and args[0] in ("install", "update", "remove", "start", "stop", "restart", "debug"): service = args[0] serv_opts.extend(args) if not service: # Get and remove any NZB file names for entry in args: if get_ext(entry) in VALID_NZB_FILES + VALID_ARCHIVES: upload_nzbs.append(os.path.abspath(entry)) for opt, arg in opts: if opt in ("password", "username", "startup", "perfmonini", "perfmondll", "interactive", "wait"): # Service option, just collect if service: serv_opts.append(opt) if arg: serv_opts.append(arg) else: if opt == "-f": arg = os.path.normpath(os.path.abspath(arg)) sab_opts.append((opt, arg)) return service, sab_opts, serv_opts, upload_nzbs def get_f_option(opts): """Return value of the -f option""" for opt, arg in opts: if opt == "-f": return arg else: return None def main(): global LOG_FLAG import sabnzbd # Due to ApplePython bug autobrowser = None autorestarted = False sabnzbd.MY_FULLNAME = __file__ sabnzbd.MY_NAME = os.path.basename(sabnzbd.MY_FULLNAME) fork = False pause = False inifile = None cherryhost = None cherryport = None https_port = None cherrypylogging = None clean_up = False logging_level = None console_logging = False no_file_log = False web_dir = None repair = 0 no_login = False sabnzbd.RESTART_ARGS = [sys.argv[0]] pid_path = None pid_file = None new_instance = False ipv6_hosting = None inet_exposure = None _service, sab_opts, _serv_opts, upload_nzbs = commandline_handler() for opt, arg in sab_opts: if opt == "--servicecall": sabnzbd.MY_FULLNAME = arg elif opt in ("-d", "--daemon"): if not sabnzbd.WIN32: fork = True autobrowser = False sabnzbd.DAEMON = True sabnzbd.RESTART_ARGS.append(opt) elif opt in ("-f", "--config-file"): inifile = arg sabnzbd.RESTART_ARGS.append(opt) sabnzbd.RESTART_ARGS.append(arg) elif opt in ("-h", "--help"): print_help() exit_sab(0) elif opt in ("-t", "--templates"): web_dir = arg elif opt in ("-s", "--server"): (cherryhost, cherryport) = split_host(arg) elif opt in ("-n", "--nobrowser"): autobrowser = False elif opt in ("-b", "--browser"): try: autobrowser = bool(int(arg)) except ValueError: autobrowser = True elif opt == "--autorestarted": autorestarted = True elif opt in ("-c", "--clean"): clean_up = True elif opt in ("-w", "--weblogging"): cherrypylogging = True elif opt in ("-l", "--logging"): try: logging_level = int(arg) except: logging_level = -2 if logging_level < -1 or logging_level > 2: print_help() exit_sab(1) elif opt == "--console": console_logging = True sabnzbd.RESTART_ARGS.append(opt) elif opt in ("-v", "--version"): print_version() exit_sab(0) elif opt in ("-p", "--pause"): pause = True elif opt == "--https": https_port = int(arg) sabnzbd.RESTART_ARGS.append(opt) sabnzbd.RESTART_ARGS.append(arg) elif opt == "--repair": repair = 1 pause = True elif opt == "--repair-all": repair = 2 pause = True elif opt == "--log-all": sabnzbd.LOG_ALL = True elif opt == "--disable-file-log": no_file_log = True elif opt == "--no-login": no_login = True elif opt == "--pid": pid_path = arg sabnzbd.RESTART_ARGS.append(opt) sabnzbd.RESTART_ARGS.append(arg) elif opt == "--pidfile": pid_file = arg sabnzbd.RESTART_ARGS.append(opt) sabnzbd.RESTART_ARGS.append(arg) elif opt == "--new": new_instance = True elif opt == "--ipv6_hosting": ipv6_hosting = arg elif opt == "--inet_exposure": inet_exposure = arg sabnzbd.MY_FULLNAME = os.path.normpath(os.path.abspath(sabnzbd.MY_FULLNAME)) sabnzbd.MY_NAME = os.path.basename(sabnzbd.MY_FULLNAME) sabnzbd.DIR_PROG = os.path.dirname(sabnzbd.MY_FULLNAME) sabnzbd.DIR_INTERFACES = real_path(sabnzbd.DIR_PROG, DEF_INTERFACES) sabnzbd.DIR_LANGUAGE = real_path(sabnzbd.DIR_PROG, DEF_LANGUAGE) org_dir = os.getcwd() # Need console logging if requested, for SABnzbd.py and SABnzbd-console.exe console_logging = console_logging or sys.executable.endswith("console.exe") or not hasattr(sys, "frozen") console_logging = console_logging and not sabnzbd.DAEMON LOGLEVELS = (logging.FATAL, logging.WARNING, logging.INFO, logging.DEBUG) # Setup primary logging to prevent default console logging gui_log = GUIHandler(MAX_WARNINGS) gui_log.setLevel(logging.WARNING) format_gui = "%(asctime)s\n%(levelname)s\n%(message)s" gui_log.setFormatter(logging.Formatter(format_gui)) sabnzbd.GUIHANDLER = gui_log # Create logger logger = logging.getLogger("") logger.setLevel(logging.WARNING) logger.addHandler(gui_log) if inifile: # INI file given, simplest case inifile = evaluate_inipath(inifile) else: # No ini file given, need profile data get_user_profile_paths() # Find out where INI file is inifile = os.path.abspath(os.path.join(sabnzbd.DIR_LCLDATA, DEF_INI_FILE)) # Long-path notation on Windows to be sure inifile = long_path(inifile) # If INI file at non-std location, then use INI location as $HOME if sabnzbd.DIR_LCLDATA != os.path.dirname(inifile): sabnzbd.DIR_HOME = os.path.dirname(inifile) # All system data dirs are relative to the place we found the INI file sabnzbd.DIR_LCLDATA = os.path.dirname(inifile) if not os.path.exists(inifile) and not os.path.exists(inifile + ".bak") and not os.path.exists(sabnzbd.DIR_LCLDATA): try: os.makedirs(sabnzbd.DIR_LCLDATA) except IOError: panic('Cannot create folder "%s".' % sabnzbd.DIR_LCLDATA, "Check specified INI file location.") exit_sab(1) sabnzbd.cfg.set_root_folders(sabnzbd.DIR_HOME, sabnzbd.DIR_LCLDATA) res, msg = config.read_config(inifile) if not res: panic(msg, "Specify a correct file or delete this file.") exit_sab(1) # Set root folders for HTTPS server file paths sabnzbd.cfg.set_root_folders2() if ipv6_hosting is not None: sabnzbd.cfg.ipv6_hosting.set(ipv6_hosting) # Determine web host address cherryhost, cherryport, browserhost, https_port = get_webhost(cherryhost, cherryport, https_port) enable_https = sabnzbd.cfg.enable_https() # When this is a daemon, just check and bail out if port in use if sabnzbd.DAEMON: if enable_https and https_port: try: portend.free(cherryhost, https_port, timeout=0.05) except IOError: abort_and_show_error(browserhost, cherryport) except: abort_and_show_error(browserhost, cherryport, "49") try: portend.free(cherryhost, cherryport, timeout=0.05) except IOError: abort_and_show_error(browserhost, cherryport) except: abort_and_show_error(browserhost, cherryport, "49") # Windows instance is reachable through registry url = None if sabnzbd.WIN32 and not new_instance: url = get_connection_info() if url and check_for_sabnzbd(url, upload_nzbs, autobrowser): exit_sab(0) # SSL if enable_https: port = https_port or cherryport try: portend.free(browserhost, port, timeout=0.05) except IOError as error: if str(error) == "Port not bound.": pass else: if not url: url = "https://%s:%s%s/api?" % (browserhost, port, sabnzbd.cfg.url_base()) if new_instance or not check_for_sabnzbd(url, upload_nzbs, autobrowser): # Bail out if we have fixed our ports after first start-up if sabnzbd.cfg.fixed_ports(): abort_and_show_error(browserhost, cherryport) # Find free port to bind newport = find_free_port(browserhost, port) if newport > 0: # Save the new port if https_port: https_port = newport sabnzbd.cfg.https_port.set(newport) else: # In case HTTPS == HTTP port cherryport = newport sabnzbd.cfg.cherryport.set(newport) except: # Something else wrong, probably badly specified host abort_and_show_error(browserhost, cherryport, "49") # NonSSL check if there's no HTTPS or we only use 1 port if not (enable_https and not https_port): try: portend.free(browserhost, cherryport, timeout=0.05) except IOError as error: if str(error) == "Port not bound.": pass else: if not url: url = "http://%s:%s%s/api?" % (browserhost, cherryport, sabnzbd.cfg.url_base()) if new_instance or not check_for_sabnzbd(url, upload_nzbs, autobrowser): # Bail out if we have fixed our ports after first start-up if sabnzbd.cfg.fixed_ports(): abort_and_show_error(browserhost, cherryport) # Find free port to bind port = find_free_port(browserhost, cherryport) if port > 0: sabnzbd.cfg.cherryport.set(port) cherryport = port except: # Something else wrong, probably badly specified host abort_and_show_error(browserhost, cherryport, "49") # We found a port, now we never check again sabnzbd.cfg.fixed_ports.set(True) # Logging-checks logdir = sabnzbd.cfg.log_dir.get_path() if fork and not logdir: print("Error: I refuse to fork without a log directory!") sys.exit(1) if clean_up: for x in globber_full(logdir): if RSS_FILE_NAME not in x: try: os.remove(x) except: pass # Prevent the logger from raising exceptions # primarily to reduce the fallout of Python issue 4749 logging.raiseExceptions = 0 # Log-related constants we always need if logging_level is None: logging_level = sabnzbd.cfg.log_level() else: sabnzbd.cfg.log_level.set(logging_level) sabnzbd.LOGFILE = os.path.join(logdir, DEF_LOG_FILE) logformat = "%(asctime)s::%(levelname)s::[%(module)s:%(lineno)d] %(message)s" logger.setLevel(LOGLEVELS[logging_level + 1]) try: if not no_file_log: rollover_log = logging.handlers.RotatingFileHandler( sabnzbd.LOGFILE, "a+", sabnzbd.cfg.log_size(), sabnzbd.cfg.log_backups() ) rollover_log.setFormatter(logging.Formatter(logformat)) logger.addHandler(rollover_log) except IOError: print("Error:") print("Can't write to logfile") exit_sab(2) # Fork on non-Windows processes if fork and not sabnzbd.WIN32: daemonize() else: if console_logging: console = logging.StreamHandler(stream=sys.stdout) console.setLevel(LOGLEVELS[logging_level + 1]) console.setFormatter(logging.Formatter(logformat)) logger.addHandler(console) if no_file_log: logging.info("Console logging only") # Start SABnzbd logging.info("--------------------------------") logging.info("%s-%s", sabnzbd.MY_NAME, sabnzbd.__version__) # See if we can get version from git when running an unknown revision if sabnzbd.__baseline__ == "unknown": try: sabnzbd.__baseline__ = sabnzbd.misc.run_command( ["git", "rev-parse", "--short", "HEAD"], cwd=sabnzbd.DIR_PROG ).strip() except: pass logging.info("Commit = %s", sabnzbd.__baseline__) logging.info("Full executable path = %s", sabnzbd.MY_FULLNAME) logging.info("Arguments = %s", sabnzbd.CMDLINE) logging.info("Python-version = %s", sys.version) logging.info("Dockerized = %s", sabnzbd.DOCKER) logging.info("CPU architecture = %s", platform.uname().machine) try: logging.info("Platform = %s - %s", os.name, platform.platform()) except: # Can fail on special platforms (like Snapcraft or embedded) pass # Find encoding; relevant for external processing activities logging.info("Preferred encoding = %s", sabnzbd.encoding.CODEPAGE) # On Linux/FreeBSD/Unix "UTF-8" is strongly, strongly advised: if not sabnzbd.WIN32 and not sabnzbd.MACOS and not ("utf-8" in sabnzbd.encoding.CODEPAGE.lower()): helpful_warning( T( "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads." ), sabnzbd.encoding.CODEPAGE, ) # Verify umask, we need at least 700 if not sabnzbd.WIN32 and sabnzbd.ORG_UMASK > int("077", 8): sabnzbd.misc.helpful_warning( T("Current umask (%o) might deny SABnzbd access to the files and folders it creates."), sabnzbd.ORG_UMASK, ) # Log JSON module in case of problems logging.debug("JSON-module = %s %s", sabnzbd.api.json.__name__, sabnzbd.api.json.__version__) # SSL Information logging.info("SSL version = %s", ssl.OPENSSL_VERSION) # Load (extra) certificates if supplied by certifi # This is optional and provided in the binaries if importlib.util.find_spec("certifi") is not None: import certifi try: os.environ["SSL_CERT_FILE"] = certifi.where() logging.info("Certifi version = %s", certifi.__version__) logging.info("Loaded additional certificates from %s", os.environ["SSL_CERT_FILE"]) except: # Sometimes the certificate file is blocked logging.warning(T("Could not load additional certificates from certifi package")) logging.info("Traceback: ", exc_info=True) # List the number of certificates available (can take up to 1.5 seconds) if sabnzbd.cfg.log_level() > 1: logging.debug("Available certificates = %s", repr(ssl.create_default_context().cert_store_stats())) logging.info("Using INI file %s", inifile) # Store auto-browser setting from command line if autobrowser is not None: sabnzbd.cfg.autobrowser.set(autobrowser) sabnzbd.initialize(pause, clean_up, repair=repair) os.chdir(sabnzbd.DIR_PROG) sabnzbd.WEB_DIR = identify_web_template(sabnzbd.cfg.web_dir, DEF_STD_WEB_DIR, fix_webname(web_dir)) sabnzbd.WEB_DIR_CONFIG = identify_web_template(None, DEF_STD_CONFIG, "") sabnzbd.WIZARD_DIR = os.path.join(sabnzbd.DIR_INTERFACES, "wizard") sabnzbd.WEB_COLOR = check_template_scheme(sabnzbd.cfg.web_color(), sabnzbd.WEB_DIR) sabnzbd.cfg.web_color.set(sabnzbd.WEB_COLOR) # Handle the several tray icons if sabnzbd.cfg.tray_icon() and not sabnzbd.DAEMON and not sabnzbd.WIN_SERVICE: if sabnzbd.WIN32: sabnzbd.WINTRAY = sabnzbd.sabtray.SABTrayThread() elif sabnzbd.LINUX_POWER and os.environ.get("DISPLAY"): try: import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk import sabnzbd.sabtraylinux sabnzbd.sabtraylinux.StatusIcon() except: logging.info("python3-gi not found, no SysTray.") # Find external programs sabnzbd.newsunpack.find_programs(sabnzbd.DIR_PROG) print_modules() # HTTPS certificate generation https_cert = sabnzbd.cfg.https_cert.get_path() https_key = sabnzbd.cfg.https_key.get_path() https_chain = sabnzbd.cfg.https_chain.get_path() if not (sabnzbd.cfg.https_chain() and os.path.exists(https_chain)): https_chain = None if enable_https: # If either the HTTPS certificate or key do not exist, make some self-signed ones. if not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key)): create_https_certificates(https_cert, https_key) if not (os.path.exists(https_cert) and os.path.exists(https_key)): logging.warning(T("Disabled HTTPS because of missing CERT and KEY files")) enable_https = False sabnzbd.cfg.enable_https.set(False) # So the cert and key files do exist, now let's check if they are valid: trialcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) try: trialcontext.load_cert_chain(https_cert, https_key) logging.info("HTTPS keys are OK") except: logging.warning(T("Disabled HTTPS because of invalid CERT and KEY files")) logging.info("Traceback: ", exc_info=True) enable_https = False sabnzbd.cfg.enable_https.set(False) # Starting of the webserver # Determine if this system has multiple definitions for 'localhost' hosts = all_localhosts() multilocal = len(hosts) > 1 and cherryhost in ("localhost", "0.0.0.0") # For 0.0.0.0 CherryPy will always pick IPv4, so make sure the secondary localhost is IPv6 if multilocal and cherryhost == "0.0.0.0" and hosts[1] == "127.0.0.1": hosts[1] = "::1" # The Windows binary requires numeric localhost as primary address if cherryhost == "localhost": cherryhost = hosts[0] if enable_https: if https_port: # Extra HTTP port for primary localhost attach_server(cherryhost, cherryport) if multilocal: # Extra HTTP port for secondary localhost attach_server(hosts[1], cherryport) # Extra HTTPS port for secondary localhost attach_server(hosts[1], https_port, https_cert, https_key, https_chain) cherryport = https_port elif multilocal: # Extra HTTPS port for secondary localhost attach_server(hosts[1], cherryport, https_cert, https_key, https_chain) cherrypy.config.update( { "server.ssl_module": "builtin", "server.ssl_certificate": https_cert, "server.ssl_private_key": https_key, "server.ssl_certificate_chain": https_chain, } ) elif multilocal: # Extra HTTP port for secondary localhost attach_server(hosts[1], cherryport) if no_login: sabnzbd.cfg.username.set("") sabnzbd.cfg.password.set("") # Overwrite inet_exposure from command-line for VPS-setups if inet_exposure: sabnzbd.cfg.inet_exposure.set(inet_exposure) mime_gzip = ( "text/*", "application/javascript", "application/x-javascript", "application/json", "application/xml", "application/vnd.ms-fontobject", "application/font*", "image/svg+xml", ) cherrypy.config.update( { "server.environment": "production", "server.socket_host": cherryhost, "server.socket_port": cherryport, "server.shutdown_timeout": 0, "engine.autoreload.on": False, "tools.encode.on": True, "tools.gzip.on": True, "tools.gzip.mime_types": mime_gzip, "request.show_tracebacks": True, "error_page.401": sabnzbd.panic.error_page_401, "error_page.404": sabnzbd.panic.error_page_404, } ) # Catch shutdown errors that can break cherrypy/cheroot # See https://github.com/cherrypy/cheroot/issues/710 try: cheroot.errors.acceptable_sock_shutdown_exceptions += (OSError,) except AttributeError: pass # Do we want CherryPy Logging? Cannot be done via the config cherrypy.log.screen = False cherrypy.log.access_log.propagate = False if cherrypylogging: sabnzbd.WEBLOGFILE = os.path.join(logdir, DEF_LOG_CHERRY) cherrypy.log.access_file = str(sabnzbd.WEBLOGFILE) # Force mimetypes (OS might overwrite them) forced_mime_types = {"css": "text/css", "js": "application/javascript"} static = { "tools.staticdir.on": True, "tools.staticdir.dir": os.path.join(sabnzbd.WEB_DIR, "static"), "tools.staticdir.content_types": forced_mime_types, } staticcfg = { "tools.staticdir.on": True, "tools.staticdir.dir": os.path.join(sabnzbd.WEB_DIR_CONFIG, "staticcfg"), "tools.staticdir.content_types": forced_mime_types, } wizard_static = { "tools.staticdir.on": True, "tools.staticdir.dir": os.path.join(sabnzbd.WIZARD_DIR, "static"), "tools.staticdir.content_types": forced_mime_types, } appconfig = { "/api": { "tools.auth_basic.on": False, "tools.response_headers.on": True, "tools.response_headers.headers": [("Access-Control-Allow-Origin", "*")], }, "/static": static, "/wizard/static": wizard_static, "/favicon.ico": { "tools.staticfile.on": True, "tools.staticfile.filename": os.path.join(sabnzbd.WEB_DIR_CONFIG, "staticcfg", "ico", "favicon.ico"), }, "/staticcfg": staticcfg, } # Make available from both URLs main_page = sabnzbd.interface.MainPage() cherrypy.Application.relative_urls = "server" cherrypy.tree.mount(main_page, "/", config=appconfig) cherrypy.tree.mount(main_page, sabnzbd.cfg.url_base(), config=appconfig) # Set authentication for CherryPy sabnzbd.interface.set_auth(cherrypy.config) logging.info("Starting web-interface on %s:%s", cherryhost, cherryport) sabnzbd.cfg.log_level.callback(guard_loglevel) try: cherrypy.engine.start() except: # Since the webserver is started by cherrypy in a separate thread, we can't really catch any # start-up errors. This try/except only catches very few errors, the rest is only shown in the console. logging.error(T("Failed to start web-interface: "), exc_info=True) abort_and_show_error(browserhost, cherryport) # Create a record of the active cert/key/chain files, for use with config.create_config_backup() if enable_https: for setting in CONFIG_BACKUP_HTTPS.values(): if full_path := getattr(sabnzbd.cfg, setting).get_path(): sabnzbd.CONFIG_BACKUP_HTTPS_OK.append(full_path) # Set URL for browser if enable_https: sabnzbd.BROWSER_URL = "https://%s:%s%s" % (browserhost, cherryport, sabnzbd.cfg.url_base()) else: sabnzbd.BROWSER_URL = "http://%s:%s%s" % (browserhost, cherryport, sabnzbd.cfg.url_base()) if sabnzbd.WIN32: # Write URL for uploads and version check directly to registry set_connection_info(f"{sabnzbd.BROWSER_URL}/api?apikey={sabnzbd.cfg.api_key()}") if pid_path or pid_file: sabnzbd.pid_file(pid_path, pid_file, cherryport) # Stop here in case of fatal errors if sabnzbd.NO_DOWNLOADING: return # Apply proxy, if configured, before main requests are made sabnzbd.misc.set_socks5_proxy() # Start all SABnzbd tasks logging.info("Starting %s-%s", sabnzbd.MY_NAME, sabnzbd.__version__) try: sabnzbd.start() except: logging.exception("Failed to start %s-%s", sabnzbd.MY_NAME, sabnzbd.__version__) sabnzbd.halt() # Upload any nzb/zip/rar/nzb.gz/nzb.bz2 files from file association if upload_nzbs: for upload_nzb in upload_nzbs: sabnzbd.nzbparser.add_nzbfile(upload_nzb) if not autorestarted: launch_a_browser(sabnzbd.BROWSER_URL) notifier.send_notification("SABnzbd", T("SABnzbd %s started") % sabnzbd.__version__, "startup") autorestarted = False # Start SSDP and Bonjour if SABnzbd isn't listening on localhost only if sabnzbd.cfg.enable_broadcast() and not is_localhost(cherryhost): # Try to find a LAN IP address for SSDP/Bonjour if is_lan_addr(cherryhost): # A specific listening address was configured, use that external_host = cherryhost else: # Fall back to the IPv4 address of the LAN interface external_host = local_ipv4() logging.debug("Using %s as host address for Bonjour and SSDP", external_host) # Only broadcast to local network addresses. If local ranges have been defined, further # restrict broadcasts to those specific ranges in order to avoid broadcasting to the "wrong" # private network when the system is connected to multiple such networks (e.g. a corporate # VPN in addition to a standard household LAN). if is_lan_addr(external_host) and ( (not sabnzbd.cfg.local_ranges()) or any(ip_in_subnet(external_host, r) for r in sabnzbd.cfg.local_ranges()) ): # Start Bonjour and SSDP sabnzbd.zconfig.set_bonjour(external_host, cherryport) # Set URL for browser for external hosts ssdp_url = "%s://%s:%s%s" % ( ("https" if enable_https else "http"), external_host, cherryport, sabnzbd.cfg.url_base(), ) ssdp.start_ssdp( external_host, "SABnzbd", ssdp_url, "SABnzbd %s" % sabnzbd.__version__, "SABnzbd Team", "https://sabnzbd.org/", "SABnzbd %s" % sabnzbd.__version__, ssdp_broadcast_interval=sabnzbd.cfg.ssdp_broadcast_interval(), ) # Have to keep this running, otherwise logging will terminate timer = 0 while not sabnzbd.SABSTOP: # Wait to be awoken or every 3 seconds with sabnzbd.SABSTOP_CONDITION: sabnzbd.SABSTOP_CONDITION.wait(3) timer += 1 # Check for loglevel changes if LOG_FLAG: LOG_FLAG = False level = LOGLEVELS[sabnzbd.cfg.log_level() + 1] logger.setLevel(level) if console_logging: console.setLevel(level) # 300 sec polling tasks if not timer % 100: if sabnzbd.LOG_ALL: logging.debug("Triggering Python garbage collection") gc.collect() timer = 0 # 30 sec polling tasks if not timer % 10: # Keep OS awake (if needed) sabnzbd.misc.keep_awake() # Restart scheduler (if needed) sabnzbd.Scheduler.restart(plan_restart=False) # Save config (if needed) config.save_config() # Check the threads if not sabnzbd.check_all_tasks(): autorestarted = True sabnzbd.TRIGGER_RESTART = True # 3 sec polling tasks # Check for auto-restart request # Or special restart cases like Mac and WindowsService if sabnzbd.TRIGGER_RESTART: logging.info("Performing triggered restart") sabnzbd.shutdown_program() # Add arguments and make sure we are in the right directory if sabnzbd.Downloader.paused: sabnzbd.RESTART_ARGS.append("-p") if autorestarted: sabnzbd.RESTART_ARGS.append("--autorestarted") sys.argv = sabnzbd.RESTART_ARGS os.chdir(org_dir) # Restore backup if sabnzbd.RESTORE_DATA: config.restore_config_backup(sabnzbd.RESTORE_DATA) # Binaries require special restart if hasattr(sys, "frozen"): if sabnzbd.MACOS: # On macOS restart of app instead of embedded python my_args = " ".join(sys.argv[1:]) cmd = 'kill -9 %s && open "%s" --args %s' % (os.getpid(), sys.executable, my_args) logging.info("Launching: %s", cmd) os.system(cmd) elif sabnzbd.WIN_SERVICE: # Use external service handler to do the restart # Wait 5 seconds to clean up subprocess.Popen("timeout 5 & sc start SABnzbd", shell=True) elif sabnzbd.WIN32: # Just a simple restart of the exe os.execv(sys.executable, ['"%s"' % arg for arg in sys.argv]) else: # CherryPy has special logic to include interpreter options such as "-OO" cherrypy.engine._do_execv() # Send our final goodbyes! notifier.send_notification("SABnzbd", T("SABnzbd shutdown finished"), "startup") logging.info("Leaving SABnzbd") sabnzbd.pid_file() try: sys.stderr.flush() sys.stdout.flush() except AttributeError: # Not supported on Windows binaries pass if hasattr(sys, "frozen") and sabnzbd.MACOS: try: AppHelper.stopEventLoop() except: # Failing AppHelper library! os._exit(0) elif sabnzbd.WIN_SERVICE: # Do nothing, let service handle it pass else: os._exit(0) ############################################################################## # Windows Service Support ############################################################################## if sabnzbd.WIN32: class SABnzbd(win32serviceutil.ServiceFramework): """Win32 Service Handler""" _svc_name_ = "SABnzbd" _svc_display_name_ = "SABnzbd Binary Newsreader" _svc_deps_ = ["EventLog", "Tcpip"] _svc_description_ = ( "Automated downloading from Usenet. " 'Set to "automatic" to start the service at system startup. ' "You may need to login with a real user account when you need " "access to network shares." ) # Only SABnzbd-console.exe can print to the console, so the service is installed # from there. But we run SABnzbd.exe so nothing is logged. Logging can cause the # Windows Service to stop because the output buffers are full. if hasattr(sys, "frozen"): _exe_name_ = "SABnzbd.exe" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) sabnzbd.WIN_SERVICE = self def SvcDoRun(self): msg = "SABnzbd-service %s" % sabnzbd.__version__ self.Logger(servicemanager.PYS_SERVICE_STARTED, msg + " has started") sys.argv = get_serv_parms(self._svc_name_) main() self.Logger(servicemanager.PYS_SERVICE_STOPPED, msg + " has stopped") def SvcStop(self): sabnzbd.shutdown_program() self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def Logger(self, state, msg): win32evtlogutil.ReportEvent( self._svc_display_name_, state, 0, servicemanager.EVENTLOG_INFORMATION_TYPE, (self._svc_name_, msg) ) def ErrLogger(self, msg, text): win32evtlogutil.ReportEvent( self._svc_display_name_, servicemanager.PYS_SERVICE_STOPPED, 0, servicemanager.EVENTLOG_ERROR_TYPE, (self._svc_name_, msg), text, ) SERVICE_MSG = """ You may need to set additional Service parameters! Verify the settings in Windows Services (services.msc). https://sabnzbd.org/wiki/advanced/sabnzbd-as-a-windows-service """ def handle_windows_service(): """Handle everything for Windows Service Returns True when any service commands were detected or when we have started as a service. """ # Detect if running as Windows Service # Adapted from https://stackoverflow.com/a/55248281/5235502 # Only works when run from the exe-files if hasattr(sys, "frozen") and win32ts.ProcessIdToSessionId(win32api.GetCurrentProcessId()) == 0: servicemanager.Initialize() servicemanager.PrepareToHostSingle(SABnzbd) servicemanager.StartServiceCtrlDispatcher() return True # Handle installation and other options service, sab_opts, serv_opts, _upload_nzbs = commandline_handler() if service: if service in ("install", "update"): # In this case check for required parameters path = get_f_option(sab_opts) if not path: print(("The -f parameter is required.\n" "Use: -f %s" % service)) return True # First run the service installed, because this will # set the service key in the Registry win32serviceutil.HandleCommandLine(SABnzbd, argv=serv_opts) # Add our own parameter to the Registry if set_serv_parms(SABnzbd._svc_name_, sab_opts): print(SERVICE_MSG) else: print("ERROR: Cannot set required registry info.") else: # Pass the other commands directly win32serviceutil.HandleCommandLine(SABnzbd) return bool(service) ############################################################################## # Platform specific startup code ############################################################################## if __name__ == "__main__": # Require for freezing multiprocessing.freeze_support() # We can only register these in the main thread signal.signal(signal.SIGINT, sabnzbd.sig_handler) signal.signal(signal.SIGTERM, sabnzbd.sig_handler) if sabnzbd.WIN32: if not handle_windows_service(): main() elif sabnzbd.MACOS and sabnzbd.FOUNDATION: # macOS binary runner from threading import Thread from PyObjCTools import AppHelper from AppKit import NSApplication from sabnzbd.osxmenu import SABnzbdDelegate # Need to run the main application in separate thread because the eventLoop # has to be in the main thread. The eventLoop is required for the menu. # This code is made with trial-and-error, please feel free to improve! class startApp(Thread): def run(self): main() AppHelper.stopEventLoop() sabApp = startApp() sabApp.start() # Initialize the menu shared_app = NSApplication.sharedApplication() sabnzbd.MACOSTRAY = SABnzbdDelegate.alloc().init() shared_app.setDelegate_(sabnzbd.MACOSTRAY) # Build the menu sabnzbd.MACOSTRAY.awakeFromNib() # Run the main eventloop AppHelper.runEventLoop() else: main() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4384885 SABnzbd-4.3.2/README.txt0000644000000000000000000000531314625637243013723 0ustar00runnerstaffRelease Notes - SABnzbd 4.3.2 ========================================================= This is the second bug fix release of SABnzbd 4.3.0. ## Bug fixes and changes since 4.3.1 * Added Special option `disable_archive` for jobs to always be permanently deleted. * Specific AppRise notifications could fail to send. * Update of the article decoder core (`rapidyenc`). * Windows: After some time the interface would no longer load. * Windows: Custom shortcuts would be removed by the installer. * Windows/macOS: Updated Unrar to 7.01 and 7zip to 24.05. ## Key changes since 4.2.0 * **Archive:** * When jobs are removed from the History, they are moved to the Archive. * Keep your History clean and still be able to reliably use Duplicate Detection. * **Apprise Integrated:** * Send notifications using Apprise to almost any notification service. * Supported notifications: https://github.com/caronc/apprise/wiki * Notification Script `SABnzbd-notify.py` is no longer needed. * **Added IPv6-staging option:** * Enable `ipv6_staging` in Config - Specials to get additional IPv6 features: * Add IPv6 hostnames during address selection. * Internet Bandwidth is measured separately for IPv4 and IPv6. * **Other:** * The `text` output format is removed from the API, `json` is the default. * Handling of multiple inputs to several API methods was improved. * File browser dialog is available to select file paths in the Config. * Users will be warned if they configure an Indexer as a Server. * Added `SAB_API_KEY` and `SAB_API_URL` to script environment variables. * Windows/macOS: Updated Python to 3.12.3, Multipar to v1.3.3.2, Unrar to 7.00 and 7zip to 24.03. ## Bug fixes since 4.2.0 * Incorrect warnings of unknown status codes could be thrown. * Watched Folder would not work if Socks5 proxy was active. * Prevent crash on invalid Server Expiration Date. * Windows: Installer could create duplicate shortcuts. ## Upgrade notices * You can directly upgrade from version 3.0.0 and newer. * Upgrading from older versions will require performing a `Queue repair`. * Downgrading from version 4.2.0 or newer to 3.7.2 or older will require performing a `Queue repair` due to changes in the internal data format. ## Known problems and solutions * Read `ISSUES.txt` or https://sabnzbd.org/wiki/introduction/known-issues ## About SABnzbd is an open-source cross-platform binary newsreader. It simplifies the process of downloading from Usenet dramatically, thanks to its web-based user interface and advanced built-in post-processing options that automatically verify, repair, extract and clean up posts downloaded from Usenet. (c) Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.438637 SABnzbd-4.3.2/LICENSE.txt0000644000000000000000000000142314625637243014046 0ustar00runnerstaff(c) Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See accompanying files GPL2.txt and GPL3.txt.././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4387243 SABnzbd-4.3.2/tools/make_mo.py0000755000000000000000000002511214625637243015351 0ustar00runnerstaff#!/usr/bin/python3 -OO # -*- coding: utf-8 -*- # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ make_mo - Compile PO files to MO files """ import glob import os import re import sys import gettext import subprocess PO_DIR = "po/main" POE_DIR = "po/email" PON_DIR = "po/nsis" MO_DIR = "locale" EMAIL_DIR = "email" MO_LOCALE = "/LC_MESSAGES" DOMAIN = "SABnzbd" DOMAIN_E = "SABemail" DOMAIN_N = "SABnsis" LANG_MARKER = "language.txt" NSIS = "NSIS_Installer.nsi" LanguageTable = { "aa": ("Afar", "Afaraf"), "af": ("Afrikaans", "Afrikaans"), "ak": ("Akan", "Akan"), "sq": ("Albanian", "Shqip"), "an": ("Aragonese", "Aragonés"), "ae": ("Avestan", "Avesta"), "ay": ("Aymara", "Aymararu"), "bm": ("Bambara", "Bamanankan"), "eu": ("Basque", "Euskara"), "bi": ("Bislama", "Bislama"), "bs": ("Bosnian", "Bosanskijezik"), "br": ("Breton", "Brezhoneg"), "ca": ("Catalan", "Català"), "ch": ("Chamorro", "Chamoru"), "kw": ("Cornish", "Kernewek"), "co": ("Corsican", "Corsu"), "hr": ("Croatian", "Hrvatski"), "cs": ("Czech", "Cesky, ceština"), "da": ("Danish", "Dansk"), "nl": ("Dutch", "Nederlands"), "en": ("English", "English"), "eo": ("Esperanto", "Esperanto"), "et": ("Estonian", "Eesti"), "fo": ("Faroese", "Føroyskt"), "fj": ("Fijian", "Vosa Vakaviti"), "fi": ("Finnish", "Suomi"), "fr": ("French", "Français"), "gl": ("Galician", "Galego"), "de": ("German", "Deutsch"), "he": ("Hebrew", "עִבְרִית‎"), "hz": ("Herero", "Otjiherero"), "ho": ("Hiri Motu", "Hiri Motu"), "hu": ("Hungarian", "Magyar"), "id": ("Indonesian", "Bahasa Indonesia"), "ga": ("Irish", "Gaeilge"), "io": ("Ido", "Ido"), "is": ("Icelandic", "Íslenska"), "it": ("Italian", "Italiano"), "jv": ("Javanese", "BasaJawa"), "rw": ("Kinyarwanda", "Ikinyarwanda"), "kg": ("Kongo", "KiKongo"), "kj": ("Kwanyama", "Kuanyama"), "la": ("Latin", "Lingua latina"), "lb": ("Luxembourgish", "Lëtzebuergesch"), "lg": ("Luganda", "Luganda"), "li": ("Limburgish", "Limburgs"), "ln": ("Lingala", "Lingála"), "lt": ("Lithuanian", "Lietuviukalba"), "lv": ("Latvian", "Latviešuvaloda"), "gv": ("Manx", "Gaelg"), "mg": ("Malagasy", "Malagasy fiteny"), "mt": ("Maltese", "Malti"), "nb": ("Norwegian", "Norsk"), # Bokmål "nn": ("Norwegian", "Norsk"), # Nynorsk "no": ("Norwegian", "Norsk"), "oc": ("Occitan", "Occitan"), "om": ("Oromo", "Afaan Oromoo"), "pl": ("Polish", "Polski"), "pt": ("Portuguese", "Português"), "pt_BR": ("PortugueseBR", "Português, Brasil"), # NSIS uses "PortugueseBR" "rm": ("Romansh", "Rumantsch grischun"), "rn": ("Kirundi", "kiRundi"), "ro": ("Romanian", "Româna"), "sc": ("Sardinian", "Sardu"), "se": ("Northern Sami", "Davvisámegiella"), "sm": ("Samoan", "Gagana fa'a Samoa"), "gd": ("Gaelic", "Gàidhlig"), "ru": ("Russian", "русский язык"), "sr": ("Serbian", "српски"), "sn": ("Shona", "Chi Shona"), "sk": ("Slovak", "Slovencina"), "sl": ("Slovene", "Slovenšcina"), "st": ("Southern Sotho", "Sesotho"), "es": ("Spanish", "Español, castellano"), # NSIS cannot handle "Spanish Castilian" "su": ("Sundanese", "Basa Sunda"), "sw": ("Swahili", "Kiswahili"), "ss": ("Swati", "SiSwati"), "sv": ("Swedish", "Svenska"), "tn": ("Tswana", "Setswana"), "to": ("Tonga (Tonga Islands)", "faka Tonga"), "tr": ("Turkish", "Türkçe"), "ts": ("Tsonga", "Xitsonga"), "tw": ("Twi", "Twi"), "ty": ("Tahitian", "Reo Tahiti"), "wa": ("Walloon", "Walon"), "cy": ("Welsh", "Cymraeg"), "wo": ("Wolof", "Wollof"), "fy": ("Western Frisian", "Frysk"), "xh": ("Xhosa", "isi Xhosa"), "yo": ("Yoruba", "Yorùbá"), "zu": ("Zulu", "isi Zulu"), "zh_CN": ("SimpChinese", "简体中文"), } # Filter for retrieving readable language from PO file RE_LANG = re.compile(r'"Language-Description:\s([^"]+)\\n') def run(cmd): """Run system command, returns exit-code and stdout""" try: txt = subprocess.check_output(cmd, universal_newlines=True) ret = 0 except subprocess.CalledProcessError as e: txt = e.output ret = e.returncode return ret, txt def process_po_folder(domain, folder, extra=""): """Process each PO file in folder""" result = True for fname in glob.glob(os.path.join(folder, "*.po")): basename = os.path.split(fname)[1] name = os.path.splitext(basename)[0] mo_path = os.path.normpath("%s/%s%s" % (MO_DIR, name, MO_LOCALE)) mo_name = "%s.mo" % domain if not os.path.exists(mo_path): os.makedirs(mo_path) # Create the MO file mo_file = os.path.join(mo_path, mo_name) print(("Compile %s" % mo_file)) if extra: cmd = TOOL + [extra, "-o", mo_file, fname] else: cmd = TOOL + ["-o", mo_file, fname] ret, output = run(cmd) if ret != 0: print(("\nMissing %s. Please install this package first." % TOOL)) exit(1) if "WARNING:" in output: print(output) result = False return result def remove_mo_files(): """Remove MO files in locale""" for root, dirs, files in os.walk(MO_DIR, topdown=False): for f in files: if not f.startswith(DOMAIN): os.remove(os.path.join(root, f)) def translate_tmpl(prefix, lng): """Translate template 'prefix' into language 'lng'""" # Open the original file with open(EMAIL_DIR + "/%s-en.tmpl" % prefix, "r", encoding="utf-8") as src: data = src.read() # Run through translator data = _(data) # Save the translation with open("email/%s-%s.tmpl" % (prefix, lng), "w", encoding="utf-8") as fp: if not -1 < data.find("UTF-8") < 30: fp.write("#encoding UTF-8\n") fp.write(data) def make_templates(): """Create email templates""" if not os.path.exists("email"): os.makedirs("email") for path in glob.glob(os.path.join(MO_DIR, "*")): lng = os.path.split(path)[1] if lng != "en" and os.path.exists(os.path.join(POE_DIR, lng + ".po")): print(("Create email template for %s" % lng)) trans = gettext.translation(DOMAIN_E, MO_DIR, [lng], fallback=False) trans.install(names=["lgettext"]) translate_tmpl("email", lng) translate_tmpl("rss", lng) translate_tmpl("badfetch", lng) mo_path = os.path.normpath("%s/%s%s/%s.mo" % (MO_DIR, path, MO_LOCALE, DOMAIN_E)) if os.path.exists(mo_path): os.remove(mo_path) def patch_nsis(): """Patch translation into the NSIS script""" RE_NSIS = re.compile(r'^(\s*LangString\s+)(\w+)(\s+\$\{LANG_)(\w+)\}\s+(".*)', re.I) languages = [os.path.split(path)[1] for path in glob.glob(os.path.join(MO_DIR, "*"))] with open(NSIS, "r") as src: new = [] for line in src: if m := RE_NSIS.search(line): leader = m.group(1) item = m.group(2) rest = m.group(3) langname = m.group(4).upper() text = m.group(5).strip('"\n') if langname == "ENGLISH": # Write back old content new.append(line) # Replace silly $\ construction with just a \ text = text.replace('$\\"', '"').replace("$\\", "\\") for lcode in languages: lng = LanguageTable.get(lcode) if lng and lcode != "en": lng = lng[0].upper() if item == "MsgLangCode": # The language code will be stored in the registry text_trans = lcode else: trans = gettext.translation(DOMAIN_N, MO_DIR, [lcode], fallback=False) trans.install(names=["lgettext"]) text_trans = _(text) text_trans = text_trans.replace("\r", "").replace("\n", "\\r\\n") text_trans = text_trans.replace("\\", "$\\").replace('"', '$\\"') line = '%s%s%s%s} "%s"\n' % (leader, item, rest, lng, text_trans) new.append(line) elif lng is None: print("Warning: unsupported language %s (%s)! Add it to the table." % (langname, lcode)) else: new.append(line) # Force writing of unicode to process Chinese and Hebrew with open(NSIS + ".tmp", "w", encoding="utf-8") as dst: # Add UTF-8 BOM manually, so NSIS picks the translations up correctly dst.write("\ufeff") for line in new: dst.write(line) # ---------------------------------------------------------------------------- # Determine location of MsgFmt tool path, py = os.path.split(sys.argv[0]) tl = os.path.abspath(os.path.normpath(os.path.join(path, "msgfmt.py"))) if os.path.exists(tl): if os.name == "nt": TOOL = [sys.executable, tl] else: TOOL = [tl] result = True if len(sys.argv) > 1 and sys.argv[1] == "nsis": print("NSIS MO file") result = result and process_po_folder(DOMAIN_N, PON_DIR) print("Patch NSIS script") patch_nsis() else: print("Email MO files") result = result and process_po_folder(DOMAIN_E, POE_DIR) print("Create email templates from MO files") make_templates() print("Main program MO files") # -n option added to remove all newlines from the translations result = result and process_po_folder(DOMAIN, PO_DIR, "-n") print("Remove temporary templates") remove_mo_files() print() if result: exit(0) else: print("WARNINGS present!") exit(1) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4388041 SABnzbd-4.3.2/tools/msgfmt.py0000755000000000000000000001644714625637243015251 0ustar00runnerstaff#! /usr/bin/env python3 # Written by Martin v. Löwis """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation. Usage: msgfmt.py [OPTIONS] filename.po Options: -o file --output-file=file Specify the output file to write to. If omitted, output will go to a file named filename.mo (based off the input file name). -n Remove all newlines (\\r\\n) from translations -h --help Print this message and exit. -V --version Display version information and exit. """ import os import sys import ast import getopt import struct import array import re from email.parser import HeaderParser __version__ = "1.1" MESSAGES = {} nonewlines = False # Detector for HTML elements RE_HTML = re.compile(b"<[^>]+>") def usage(code, msg=""): print(__doc__, file=sys.stderr) if msg: print(msg, file=sys.stderr) sys.exit(code) def add(id, str, fuzzy): """Add a non-fuzzy translation to the dictionary.""" global MESSAGES, nonewlines, RE_HTML if not fuzzy and str: if id.count(b"%s") == str.count(b"%s"): if nonewlines and id and (b"\r" in str or b"\n" in str) and RE_HTML.search(str): MESSAGES[id] = str.replace(b"\n", b"").replace(b"\r", b"") else: MESSAGES[id] = str else: print("WARNING: %s mismatch, skipping!") print(" %s" % id) print(" %s" % str) def generate(): "Return the generated output." global MESSAGES # the keys are sorted in the .mo file keys = sorted(MESSAGES.keys()) offsets = [] ids = strs = b"" for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) ids += id + b"\0" strs += MESSAGES[id] + b"\0" output = "" # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. # translated string. keystart = 7 * 4 + 16 * len(keys) # and the values start after the keys valuestart = keystart + len(ids) koffsets = [] voffsets = [] # The string table first has the list of keys, then the list of values. # Each entry has first the size of the string, then the file offset. for o1, l1, o2, l2 in offsets: koffsets += [l1, o1 + keystart] voffsets += [l2, o2 + valuestart] offsets = koffsets + voffsets output = struct.pack( "Iiiiiii", 0x950412DE, # Magic 0, # Version len(keys), # # of entries 7 * 4, # start of key index 7 * 4 + len(keys) * 8, # start of value index 0, 0, ) # size and offset of hash table output += array.array("i", offsets).tobytes() output += ids output += strs return output def make(filename, outfile): ID = 1 STR = 2 # Compute .mo name from .po name and arguments if filename.endswith(".po"): infile = filename else: infile = filename + ".po" if outfile is None: outfile = os.path.splitext(infile)[0] + ".mo" try: with open(infile, "rb") as f: lines = f.readlines() except IOError as msg: print(msg, file=sys.stderr) sys.exit(1) section = None fuzzy = 0 # Start off assuming Latin-1, so everything decodes without failure, # until we know the exact encoding encoding = "latin-1" # Parse the catalog lno = 0 for l in lines: l = l.decode(encoding) lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == "#" and section == STR: add(msgid, msgstr, fuzzy) section = None fuzzy = 0 # Record a fuzzy mark if l[:2] == "#," and "fuzzy" in l: fuzzy = 1 # Skip comments if l[0] == "#": continue # Now we are in a msgid section, output previous section if l.startswith("msgid") and not l.startswith("msgid_plural"): if section == STR: add(msgid, msgstr, fuzzy) if not msgid: # See whether there is an encoding declaration p = HeaderParser() charset = p.parsestr(msgstr.decode(encoding)).get_content_charset() if charset: encoding = charset section = ID l = l[5:] msgid = msgstr = b"" is_plural = False # This is a message with plural forms elif l.startswith("msgid_plural"): if section != ID: print("msgid_plural not preceded by msgid on %s:%d" % (infile, lno), file=sys.stderr) sys.exit(1) l = l[12:] msgid += b"\0" # separator of singular and plural is_plural = True # Now we are in a msgstr section elif l.startswith("msgstr"): section = STR if l.startswith("msgstr["): if not is_plural: print("plural without msgid_plural on %s:%d" % (infile, lno), file=sys.stderr) sys.exit(1) l = l.split("]", 1)[1] if msgstr: msgstr += b"\0" # Separator of the various plural forms else: if is_plural: print("indexed msgstr required for plural on %s:%d" % (infile, lno), file=sys.stderr) sys.exit(1) l = l[6:] # Skip empty lines l = l.strip() if not l: continue l = ast.literal_eval(l) if section == ID: msgid += l.encode(encoding) elif section == STR: msgstr += l.encode(encoding) else: print("Syntax error on %s:%d" % (infile, lno), "before:", file=sys.stderr) print(l, file=sys.stderr) sys.exit(1) # Add last entry if section == STR: add(msgid, msgstr, fuzzy) # Compute output output = generate() try: with open(outfile, "wb") as f: f.write(output) except IOError as msg: print(msg, file=sys.stderr) def main(): global nonewlines try: opts, args = getopt.getopt(sys.argv[1:], "nhVo:", ["help", "version", "output-file="]) except getopt.error as msg: usage(1, msg) outfile = None # parse options for opt, arg in opts: if opt in ("-h", "--help"): usage(0) elif opt in ("-V", "--version"): print("msgfmt.py", __version__) sys.exit(0) elif opt in ("-o", "--output-file"): outfile = arg elif opt in ("-n",): nonewlines = True # do it if not args: print("No input file given", file=sys.stderr) print("Try `msgfmt --help' for more information.", file=sys.stderr) return for filename in args: make(filename, outfile) if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.438884 SABnzbd-4.3.2/tools/extract_pot.py0000644000000000000000000001447214625637243016301 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ extract_pot - Extract translatable strings from all PY files """ import os import sys import re # Import version.py without the sabnzbd overhead with open("sabnzbd/version.py") as version_file: exec(version_file.read()) # Fixed information for the POT header HEADER = ( r"""# # SABnzbd Translation Template file __TYPE__ # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-%s\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: team@sabnzbd.org\n" "Language-Team: SABnzbd \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" """ % __version__ ) PO_DIR = "po/main" POE_DIR = "po/email" PON_DIR = "po/nsis" EMAIL_DIR = "email" DOMAIN = "SABnzbd" DOMAIN_EMAIL = "SABemail" DOMAIN_NSIS = "SABnsis" PARMS = "-d %s -p %s -w500 -k T -k TT -o %s.pot.tmp" % (DOMAIN, PO_DIR, DOMAIN) FILES = "SABnzbd.py sabnzbd/*.py sabnzbd/utils/*.py" FILE_CACHE = {} RE_LINE = re.compile(r"\s*([^: \t]+)\s*:\s*(\d+)") RE_CONTEXT = re.compile(r"#:\s*(.*)$") def get_a_line(line_src, number): """Retrieve line 'number' from file 'src' with caching""" global FILE_CACHE if line_src not in FILE_CACHE: FILE_CACHE[line_src] = [] for file_line in open(line_src, "r"): FILE_CACHE[line_src].append(file_line) try: # We include 2 lines extra, since sometimes the "logging.warning" # can be on the line above, due to code-formatting return "".join(FILE_CACHE[line_src][number - 3 : number]) except: return "" def get_context(ctx_line): """Read context info from source file and append to line.""" if not ctx_line.startswith("#:"): return ctx_line newlines = [] contexts = [] for item in ctx_line[2:].strip().split(): if m := RE_LINE.search(item): line_src = m.group(1) number = m.group(2) else: newlines.append(item) continue srcline = get_a_line(line_src, int(number)).strip("\r\n") context = "" if m := RE_CONTEXT.search(srcline): # Context was defined in the source file context = m.group(1) else: if "logging.error(" in srcline: context = "Error message" elif "logging.warning(" in srcline or "helpful_warning(" in srcline: context = "Warning message" if context and context not in contexts: contexts.append(context) # Remove line-number to prevent unnecessary updates of the POT-files item = item.split(":")[0] # Only add new texts if item not in newlines: newlines.append(item) # Build return value return_val = "#: " + ", ".join(newlines) + "\n" if contexts: # Syntax defined by GNU gettext for context-comments return_val = "#. " + " - ".join(contexts) + "\n" + return_val return return_val def add_tmpl_to_pot(prefix, dst_file): """Append english template to open POT file 'dst'""" with open(EMAIL_DIR + "/%s-en.tmpl" % prefix, "r") as tmpl_src: dst_file.write("#: email/%s.tmpl:1\n" % prefix) dst_file.write('msgid ""\n') for tmpl_line in tmpl_src: dst_file.write('"%s"\n' % tmpl_line.replace("\n", "\\n").replace('"', '\\"')) dst_file.write('msgstr ""\n\n') print("Creating POT file") if not os.path.exists(PO_DIR): os.makedirs(PO_DIR) # Determine location of PyGetText tool path, py = os.path.split(sys.argv[0]) PYGETTEXT = os.path.normpath(os.path.join(path, "pygettext.py")) cmd = "%s %s %s %s" % (sys.executable, PYGETTEXT, PARMS, FILES) os.system(cmd) print("Finished creating POT file") print("Post-process POT file") with open("%s/%s.pot.tmp" % (PO_DIR, DOMAIN), "r") as source_pot, open("%s/%s.pot" % (PO_DIR, DOMAIN), "w") as dest_pot: dest_pot.write(HEADER.replace("__TYPE__", "MAIN")) header = True for line in source_pot: if line.startswith("#:"): line = line.replace("\\", "/") if header: dest_pot.write("\n") header = False if header: # Skip header generated by pygettext continue elif line.startswith("#:"): line = get_context(line) dest_pot.write(line) os.remove("%s/%s.pot.tmp" % (PO_DIR, DOMAIN)) print("Finished post-process POT file") print("Creating email POT file") if not os.path.exists(POE_DIR): os.makedirs(POE_DIR) with open(os.path.join(POE_DIR, DOMAIN_EMAIL + ".pot"), "w") as dst_email: dst_email.write(HEADER.replace("__TYPE__", "EMAIL")) add_tmpl_to_pot("email", dst_email) add_tmpl_to_pot("rss", dst_email) add_tmpl_to_pot("badfetch", dst_email) print("Finished creating email POT file") # Create the NSIS POT file NSIS = "builder/win/NSIS_Installer.nsi" RE_NSIS = re.compile(r'LangString\s+\w+\s+\$\{LANG_ENGLISH\}\s+(".*)', re.I) if os.path.exists(NSIS): print("Creating NSIS POT file") if not os.path.exists(PON_DIR): os.makedirs(PON_DIR) src = open(NSIS, "r") dst = open(os.path.join(PON_DIR, DOMAIN_NSIS + ".pot"), "w") dst.write(HEADER.replace("__TYPE__", "NSIS")) dst.write("\n") for line in src: m = RE_NSIS.search(line) if m and "MsgLangCode" not in line: dst.write("#: %s\n" % NSIS) text = m.group(1).replace('$\\"', '\\"').replace("$\\", "\\\\") dst.write("msgid %s\n" % text) dst.write('msgstr ""\n\n') dst.close() src.close() print("Finished creating NSIS POT file") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4389622 SABnzbd-4.3.2/tools/pygettext.py0000644000000000000000000005200214625637243015771 0ustar00runnerstaff#! /usr/bin/env python3 # -*- coding: iso-8859-1 -*- # Originally written by Barry Warsaw # # Minimally patched to make it even more xgettext compatible # by Peter Funk # # 2002-11-22 Jrgen Hermann # Added checks that _() only contains string literals, and # command line args are resolved to module lists, i.e. you # can now pass a filename, a module or package name, or a # directory (including globbing chars, important for Win32). # Made docstring fit in 80 chars wide displays using pydoc. # # for selftesting try: import fintl _ = fintl.gettext except ImportError: _ = lambda s: s __doc__ = _( """pygettext -- Python equivalent of xgettext(1) Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the internationalization of C programs. Most of these tools are independent of the programming language and can be used from within Python programs. Martin von Loewis' work[1] helps considerably in this regard. There's one problem though; xgettext is the program that scans source code looking for message strings, but it groks only C (or C++). Python introduces a few wrinkles, such as dual quoting characters, triple quoted strings, and raw strings. xgettext understands none of this. Enter pygettext, which uses Python's standard tokenize module to scan Python source code, generating .pot files identical to what GNU xgettext[2] generates for C and C++ code. From there, the standard GNU tools can be used. A word about marking Python strings as candidates for translation. GNU xgettext recognizes the following keywords: gettext, dgettext, dcgettext, and gettext_noop. But those can be a lot of text to include all over your code. C and C++ have a trick: they use the C preprocessor. Most internationalized C source includes a #define for gettext() to _() so that what has to be written in the source is much less. Thus these are both translatable strings: gettext("Translatable String") _("Translatable String") Python of course has no preprocessor so this doesn't work so well. Thus, pygettext searches only for _() by default, but see the -k/--keyword flag below for how to augment this. [1] http://www.python.org/workshops/1997-10/proceedings/loewis.html [2] http://www.gnu.org/software/gettext/gettext.html NOTE: pygettext attempts to be option and feature compatible with GNU xgettext where ever possible. However some options are still missing or are not fully implemented. Also, xgettext's use of command line switches with option arguments is broken, and in these cases, pygettext just defines additional switches. Usage: pygettext [options] inputfile ... Options: -a --extract-all Extract all strings. -d name --default-domain=name Rename the default output file from messages.pot to name.pot. -E --escape Replace non-ASCII characters with octal escape sequences. -D --docstrings Extract module, class, method, and function docstrings. These do not need to be wrapped in _() markers, and in fact cannot be for Python to consider them docstrings. (See also the -X option). -h --help Print this help message and exit. -k word --keyword=word Keywords to look for in addition to the default set, which are: %(DEFAULTKEYWORDS)s You can have multiple -k flags on the command line. -K --no-default-keywords Disable the default set of keywords (see above). Any keywords explicitly added with the -k/--keyword option are still recognized. --no-location Do not write filename/lineno location comments. -n --add-location Write filename/lineno location comments indicating where each extracted string is found in the source. These lines appear before each msgid. The style of comments is controlled by the -S/--style option. This is the default. -o filename --output=filename Rename the default output file from messages.pot to filename. If filename is `-' then the output is sent to standard out. -p dir --output-dir=dir Output files will be placed in directory dir. -S stylename --style stylename Specify which style to use for location comments. Two styles are supported: Solaris # File: filename, line: line-number GNU #: filename:line The style name is case insensitive. GNU style is the default. -v --verbose Print the names of the files being processed. -V --version Print the version of pygettext and exit. -w columns --width=columns Set width of output to columns. -x filename --exclude-file=filename Specify a file that contains a list of strings that are not be extracted from the input files. Each string to be excluded must appear on a line by itself in the file. -X filename --no-docstrings=filename Specify a file that contains a list of files (one per line) that should not have their docstrings extracted. This is only useful in conjunction with the -D option above. If `inputfile' is -, standard input is read. """ ) import os import importlib.machinery import importlib.util import sys import glob import time import getopt import token import tokenize __version__ = "1.5" default_keywords = ["_"] DEFAULTKEYWORDS = ", ".join(default_keywords) EMPTYSTRING = "" # The normal pot-file header. msgmerge and Emacs's po-mode work better if it's # there. pot_header = _( """\ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\\n" "POT-Creation-Date: %(time)s\\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" "Last-Translator: FULL NAME \\n" "Language-Team: LANGUAGE \\n" "MIME-Version: 1.0\\n" "Content-Type: text/plain; charset=%(charset)s\\n" "Content-Transfer-Encoding: %(encoding)s\\n" "Generated-By: pygettext.py %(version)s\\n" """ ) def usage(code, msg=""): print(__doc__ % globals(), file=sys.stderr) if msg: print(msg, file=sys.stderr) sys.exit(code) def make_escapes(pass_nonascii): global escapes, escape if pass_nonascii: # Allow non-ascii characters to pass through so that e.g. 'msgid # "Hhe"' would result not result in 'msgid "H\366he"'. Otherwise we # escape any character outside the 32..126 range. mod = 128 escape = escape_ascii else: mod = 256 escape = escape_nonascii escapes = [r"\%03o" % i for i in range(mod)] for i in range(32, 127): escapes[i] = chr(i) escapes[ord("\\")] = r"\\" escapes[ord("\t")] = r"\t" escapes[ord("\r")] = r"\r" escapes[ord("\n")] = r"\n" escapes[ord('"')] = r"\"" def escape_ascii(s, encoding): return "".join(escapes[ord(c)] if ord(c) < 128 else c for c in s) def escape_nonascii(s, encoding): return "".join(escapes[b] for b in s.encode(encoding)) def is_literal_string(s): return s[0] in "'\"" or (s[0] in "rRuU" and s[1] in "'\"") def safe_eval(s): # unwrap quotes, safely return eval(s, {"__builtins__": {}}, {}) def normalize(s, encoding): # This converts the various Python string types into a format that is # appropriate for .po files, namely much closer to C style. lines = s.split("\n") if len(lines) == 1: s = '"' + escape(s, encoding) + '"' else: if not lines[-1]: del lines[-1] lines[-1] = lines[-1] + "\n" for i in range(len(lines)): lines[i] = escape(lines[i], encoding) lineterm = '\\n"\n"' s = '""\n"' + lineterm.join(lines) + '"' return s def containsAny(str, set): """Check whether 'str' contains ANY of the chars in 'set'""" return 1 in [c in str for c in set] def getFilesForName(name): """Get a list of module files for a filename, a module or package name, or a directory. """ if not os.path.exists(name): # check for glob chars if containsAny(name, "*?[]"): files = glob.glob(name) list = [] for file in files: list.extend(getFilesForName(file)) return list # try to find module or package try: spec = importlib.util.find_spec(name) name = spec.origin except ImportError: name = None if not name: return [] if os.path.isdir(name): # find all python files in directory list = [] # get extension for python source files _py_ext = importlib.machinery.SOURCE_SUFFIXES[0] for root, dirs, files in os.walk(name): # don't recurse into CVS directories if "CVS" in dirs: dirs.remove("CVS") # add all *.py files to list list.extend([os.path.join(root, file) for file in files if os.path.splitext(file)[1] == _py_ext]) return list elif os.path.exists(name): # a single file return [name] return [] class TokenEater: def __init__(self, options): self.__options = options self.__messages = {} self.__state = self.__waiting self.__data = [] self.__lineno = -1 self.__freshmodule = 1 self.__curfile = None self.__enclosurecount = 0 def __call__(self, ttype, tstring, stup, etup, line): # dispatch ## import token ## print('ttype:', token.tok_name[ttype], 'tstring:', tstring, ## file=sys.stderr) self.__state(ttype, tstring, stup[0]) def __waiting(self, ttype, tstring, lineno): opts = self.__options # Do docstring extractions, if enabled if opts.docstrings and not opts.nodocstrings.get(self.__curfile): # module docstring? if self.__freshmodule: if ttype == tokenize.STRING and is_literal_string(tstring): self.__addentry(safe_eval(tstring), lineno, isdocstring=1) self.__freshmodule = 0 elif ttype not in (tokenize.COMMENT, tokenize.NL): self.__freshmodule = 0 return # class or func/method docstring? if ttype == tokenize.NAME and tstring in ("class", "def"): self.__state = self.__suiteseen return if ttype == tokenize.NAME and tstring in opts.keywords: self.__state = self.__keywordseen def __suiteseen(self, ttype, tstring, lineno): # skip over any enclosure pairs until we see the colon if ttype == tokenize.OP: if tstring == ":" and self.__enclosurecount == 0: # we see a colon and we're not in an enclosure: end of def self.__state = self.__suitedocstring elif tstring in "([{": self.__enclosurecount += 1 elif tstring in ")]}": self.__enclosurecount -= 1 def __suitedocstring(self, ttype, tstring, lineno): # ignore any intervening noise if ttype == tokenize.STRING and is_literal_string(tstring): self.__addentry(safe_eval(tstring), lineno, isdocstring=1) self.__state = self.__waiting elif ttype not in (tokenize.NEWLINE, tokenize.INDENT, tokenize.COMMENT): # there was no class docstring self.__state = self.__waiting def __keywordseen(self, ttype, tstring, lineno): if ttype == tokenize.OP and tstring == "(": self.__data = [] self.__lineno = lineno self.__state = self.__openseen else: self.__state = self.__waiting def __openseen(self, ttype, tstring, lineno): if ttype == tokenize.OP and tstring == ")": # We've seen the last of the translatable strings. Record the # line number of the first line of the strings and update the list # of messages seen. Reset state for the next batch. If there # were no strings inside _(), then just ignore this entry. if self.__data: self.__addentry(EMPTYSTRING.join(self.__data)) self.__state = self.__waiting elif ttype == tokenize.STRING and is_literal_string(tstring): self.__data.append(safe_eval(tstring)) elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT, token.NEWLINE, tokenize.NL]: # warn if we see anything else than STRING or whitespace print( _('*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"') % {"token": tstring, "file": self.__curfile, "lineno": self.__lineno}, file=sys.stderr, ) self.__state = self.__waiting def __addentry(self, msg, lineno=None, isdocstring=0): if lineno is None: lineno = self.__lineno if not msg in self.__options.toexclude: entry = (self.__curfile, lineno) self.__messages.setdefault(msg, {})[entry] = isdocstring def set_filename(self, filename): self.__curfile = filename self.__freshmodule = 1 def write(self, fp): options = self.__options timestamp = time.strftime("%Y-%m-%d %H:%M%z") encoding = fp.encoding if fp.encoding else "UTF-8" print( pot_header % {"time": timestamp, "version": __version__, "charset": encoding, "encoding": "8bit"}, file=fp ) # Sort the entries. First sort each particular entry's keys, then # sort all the entries by their first item. reverse = {} for k, v in self.__messages.items(): keys = sorted(v.keys()) reverse.setdefault(tuple(keys), []).append((k, v)) rkeys = sorted(reverse.keys()) for rkey in rkeys: rentries = reverse[rkey] rentries.sort() for k, v in rentries: # If the entry was gleaned out of a docstring, then add a # comment stating so. This is to aid translators who may wish # to skip translating some unimportant docstrings. isdocstring = any(v.values()) # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by # file name and then by line number. v = sorted(v.keys()) if not options.writelocations: pass # location comments are different b/w Solaris and GNU: elif options.locationstyle == options.SOLARIS: for filename, lineno in v: d = {"filename": filename, "lineno": lineno} print(_("# File: %(filename)s, line: %(lineno)d") % d, file=fp) elif options.locationstyle == options.GNU: # fit as many locations on one line, as long as the # resulting line length doesn't exceed 'options.width' locline = "#:" for filename, lineno in v: d = {"filename": filename, "lineno": lineno} s = _(" %(filename)s:%(lineno)d") % d if len(locline) + len(s) <= options.width: locline = locline + s else: print(locline, file=fp) locline = "#:" + s if len(locline) > 2: print(locline, file=fp) if isdocstring: print("#, docstring", file=fp) print("msgid", normalize(k, encoding), file=fp) print('msgstr ""\n', file=fp) def main(): global default_keywords try: opts, args = getopt.getopt( sys.argv[1:], "ad:DEhk:Kno:p:S:Vvw:x:X:", [ "extract-all", "default-domain=", "escape", "help", "keyword=", "no-default-keywords", "add-location", "no-location", "output=", "output-dir=", "style=", "verbose", "version", "width=", "exclude-file=", "docstrings", "no-docstrings", ], ) except getopt.error as msg: usage(1, msg) # for holding option values class Options: # constants GNU = 1 SOLARIS = 2 # defaults extractall = 0 # FIXME: currently this option has no effect at all. escape = 0 keywords = [] outpath = "" outfile = "messages.pot" writelocations = 1 locationstyle = GNU verbose = 0 width = 78 excludefilename = "" docstrings = 0 nodocstrings = {} options = Options() locations = {"gnu": options.GNU, "solaris": options.SOLARIS} # parse options for opt, arg in opts: if opt in ("-h", "--help"): usage(0) elif opt in ("-a", "--extract-all"): options.extractall = 1 elif opt in ("-d", "--default-domain"): options.outfile = arg + ".pot" elif opt in ("-E", "--escape"): options.escape = 1 elif opt in ("-D", "--docstrings"): options.docstrings = 1 elif opt in ("-k", "--keyword"): options.keywords.append(arg) elif opt in ("-K", "--no-default-keywords"): default_keywords = [] elif opt in ("-n", "--add-location"): options.writelocations = 1 elif opt in ("--no-location",): options.writelocations = 0 elif opt in ("-S", "--style"): options.locationstyle = locations.get(arg.lower()) if options.locationstyle is None: usage(1, _("Invalid value for --style: %s") % arg) elif opt in ("-o", "--output"): options.outfile = arg elif opt in ("-p", "--output-dir"): options.outpath = arg elif opt in ("-v", "--verbose"): options.verbose = 1 elif opt in ("-V", "--version"): print(_("pygettext.py (xgettext for Python) %s") % __version__) sys.exit(0) elif opt in ("-w", "--width"): try: options.width = int(arg) except ValueError: usage(1, _("--width argument must be an integer: %s") % arg) elif opt in ("-x", "--exclude-file"): options.excludefilename = arg elif opt in ("-X", "--no-docstrings"): fp = open(arg) try: while 1: line = fp.readline() if not line: break options.nodocstrings[line[:-1]] = 1 finally: fp.close() # calculate escapes make_escapes(not options.escape) # calculate all keywords options.keywords.extend(default_keywords) # initialize list of strings to exclude if options.excludefilename: try: fp = open(options.excludefilename) options.toexclude = fp.readlines() fp.close() except IOError: print(_("Can't read --exclude-file: %s") % options.excludefilename, file=sys.stderr) sys.exit(1) else: options.toexclude = [] # resolve args to module lists expanded = [] for arg in args: if arg == "-": expanded.append(arg) else: expanded.extend(getFilesForName(arg)) args = expanded # slurp through all the files eater = TokenEater(options) for filename in args: if filename == "-": if options.verbose: print(_("Reading standard input")) fp = sys.stdin.buffer closep = 0 else: if options.verbose: print(_("Working on %s") % filename) fp = open(filename, "rb") closep = 1 try: eater.set_filename(filename) try: tokens = tokenize.tokenize(fp.readline) for _token in tokens: eater(*_token) except tokenize.TokenError as e: print("%s: %s, line %d, column %d" % (e.args[0], filename, e.args[1][0], e.args[1][1]), file=sys.stderr) finally: if closep: fp.close() # write the output if options.outfile == "-": fp = sys.stdout closep = 0 else: if options.outpath: options.outfile = os.path.join(options.outpath, options.outfile) fp = open(options.outfile, "w") closep = 1 try: eater.write(fp) finally: if closep: fp.close() if __name__ == "__main__": main() # some more test strings # this one creates a warning _('*** Seen unexpected token "%(token)s"') % {"token": "test"} _("more" "than" "one" "string") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.1532297 SABnzbd-4.3.2/locale/pl/LC_MESSAGES/SABnzbd.mo0000644000000000000000000016345414625637243017517 0ustar00runnerstaffDl0om0d0B2 <3I4=5''6O6j6 66666667 717P7i7?7.8>8F8RV8[89#9;9X9$u99 99'9'9: :: !: .: 9:C:Y:m:q:'u:::::*: ; ;);=;P;Y;/a; ;;!<&<%-<#S<w< <<<<)=0= P= q====!=6 >-C>q>>">6>> ??.(?'W? ????S? @@5@;@"J@8m@@@ @@@ @AA#5AYApA A*AAA AA3A B $B 0B=BDBLB`B gBrB BBB&B B)BC8C4ACvC?~CCCC DD,2D,_D1DDDDD'E*E5@E vE'EE E EEEE$EF F%F#ZVZ]ZcZhZ xZZ Z"Z+ZZZ [ [[/[ B[ P[/Z[[[[;[[c\"r\3\\\\!]!#]E]%c]]] ]] ] ]] ]*] ^"^'^ /^;^ A^(K^ t^~^^^^^^ ^^_/_J_`_Mg___#_ `%`D`RS`<```"a*a:aZajaaa-aaa aa a b b&b:bOb ab b bb b bbbbbbc&c FcScbcqcvc |c c ccccccd dd ee9e AeNeUe se }ee eeeeef f2f GfQf ff sfff)f0fgg4gRg ngzgg gggggggggh1hMhdhmh|h hhhhhh hh ii3iDiTigii.i iiiij jj(j1j#Ej ijtj{jjj j j4jkk3/k3ckkkk-k(kl$$lIlaltl&l:llol)kmm3mm m m n n $n1n @n JnTn ]nin zn'nn(n.n o-o-Go$uo$o1o1o#p+p2p:p @p Kp Vpcpspppp pppppq qq5q :q DqPq jquq qqq^r_s2xs5sAs#t>t=t %u+0u \ufu, v8v Av>KvvvvLw"Rw&uwAwww wEw;xZxrx.xxxxxxxy%y9yAySysy-yy/yyz (z2zGz-cz"z#z.z{{$+{P{d{ v{{{b{$ | .| 9|F|O|"c|||%| | |||| |} }}}"}1} K} Y}Rc}U}= ~!J~l~q~~E~B~+#A)eJ&)'Px  Àɀ΀Ѐ׀ۀ  !&@Ew4V/700h!!Չ:&2 Y gt{ /ۊF h&h5 >_-~ Í)΍*# )3J \ it7!-O c&m ;Ïɐ&Ґ$:J S_!.?'n -.&D;K̓.7BK +Ô"%> Ucaŕ"ו +=A* ˖  -'Lt . F\ t И% (;4pEƙ 6'B/r' ֚#8/?>o͛E'NEvĜ  !+'Sm5֝ * 5 BPb ~$)+kK!ԟ X Zh w0:۠19HD)ǡ-1 L%m' ɢޢ +=#Fj$-+ܣ;=D(%-Ѥ&&#>7b$##/-7&e)+* '8`go !gǧ&/.V;) L PY1ܩ(# 1Dv} Ǫ Ϫ ٪'!)<P0n Ϋ ګ-4 =%J0p):-! O\ m xLLϭ#3WMwGŮ @1r.$߯#3*N}y% 4?+F>rxƱ ?Jf~y@}9m#%I X"b  "0 +C5y  µ ϵ ܵ + 1<BHN ]+k83" 1>S k yFʷ[]vt72#V tȹ) 4F V`pw8 ֺ 5 N[s˻'&)@ j [!$4Y#l>4)5Dz7ɾ")-5<r y  ˿ѿ$; O]y $5 ?Ofz ,&&Ml{ !  ", > Kl Y +7V e#s#,3#6N dn v $#3&W~ ! $!F]q #! "% H#Tx| + !>F MZ?x46Tk~/+%$ @)M2wD|0tD #/>Zm~ 8A,X==,,ACnC  !6Fdz *(;Y_hz 5942bgDL6 ' 7"\;3)X jtzU8#:5S7  %4 ?R[&sO5 AA&%-A 8O:F !)8b} %9a:8 K.U    2 GU_\gI$-nUD(V+3cx4)  57>BRafhp x   !# SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Complete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid server address.Invalid server detailsInvalid stage logging in history for %sIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocation for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification Sent!NotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!ProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePushbulletPushoverPython VersionQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...ResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...SubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User script can flag job as failedUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.Which percentage of the linespeed should SABnzbd use, e.g. 50Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: pl Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3); SABnzbd nie może znaleźć plików interfejsu WWW w %s.
Proszę ponownie zainstalować SABnzbd.

SABnzbd wykrył dane zapisane w innej wersji SABnzbd
lecz nie może ponownie użyć tych danych.

Zaleca się zakończenie pobierania kolejki w innym programie.

Następnie należy uruchomić SABnzbd z opcją "--clean".
Spowoduje to wymazanie aktualnej kolejki i historii!
SABnzbd czyta plik "%s". SABnzbd wykrył brak pliku sqlite3.dll.

Niektóre źle działające programy antywirusowe usuwają ten plik.
Sprawdź swój program antywirusowy, spróbuj ponownie zainstalować SABnzbd i zgłoś problem dostawcy programu antywirusowego.

SABnzbd wymaga wolnego portu TCP/IP dla wewnętrznego serwera WWW.
Próbowano użyć portu %s na %s, ale nie jest on dostępny.
Inny program używa tego portu lub SABnzbd jest już uruchomiony.

Uruchom ponownie SABnzbd używając innego numeru portu. SABnzbd wymaga prawidłowego adresu hosta dla wewnętrznego serwera WWW.
Podano nieprawidłowy adres.
Bezpieczne wartości to localhost i 0.0.0.0

Uruchom ponownie SABnzbd używając prawidłowego adresu hosta. SABnzbd wydawany jest ABSOLUTNIE BEZ ŻADNEJ GWARANCJI. To jest wolne oprogramowanie i mile widziane jest dalsze rozpowszechnianie go przez ciebie na określonych warunkach. Program jest wydawany na licencji GNU GENERAL PUBLIC LICENSE w wersji 2 lub (według twojego wyboru) którejś z późniejszych wersji. %s artykułów posiadało niepasujące duplikaty%s artykułów było uszkodzonychBrakowało %s artykułówKatalog %s: błąd dostępu do %s%s nie jest prawidłową wartością w systemie ósemkowym%s nie jest prawidłowym adresem email+ Debugowanie+ Informacje+Usuń+Napraw+RozpakujKatalog kopii zapasowych .nzb0 oznacza najwyższy priorytet, 99 - najniższyProgram 7za... NIE znaleziono!UWAGA: Katalogi zostaną automatycznie utworzone po zapisaniu zmian. Możesz użyć ścieżek absolutnych, aby wskazać lokalizację poza domyślnym katalogiem bazowym.Dane nie zostaną przeniesione. Wymaga restartu SABnzbd!API (bez Konfiguracji)Klucz APIKod QR klucza APIKlucz API jest nieprawidłowy, użyj klucza API z sekcji Konfiguracja->Ogólne w zewnętrznym programie:Brak klucza API, należy wprowadzić klucz API z sekcji Konfiguracja->Ogólne do zewnętrznego programu:Klucz API ProwlPrzerwij zadania, które nie mogą zostać ukończonePrzerwano, nie można ukończyćPrzerwano, wykryto szyfrowaniePrzerwano, wykryto niepożądane rozszerzenieAkceptujBrak dostępuDziałanieDziałanie dla zaszyfrowanych plików RARDziałanie dla niepożądanych rozszerzeńDodajDodaj NZBDodawanie plików NZB Dodaj harmonogramDodaj serwerDodano NZBKatalog administracyjnyDotyczy kategoriiWiekWszystkoWszystkie pliki zostaną rozpakowane do jednego folderutakże wydania testoweZawszeToken aplikacjiToken aplikacji (wymagany)Czy na pewno wyłączyć SABnzbd?Czy jesteś pewien?ArgumentyLimit pamięci podręcznej artykułówIdentyfikator artykułuPrzynajmniejNajwyżejBłąd połączenia, sprawdź nazwę użytkownika i hasło.Automatyczne wznawianieAutomatycznie wstrzymaj pobieranie, jeśli pozostanie mniej miejsca niż podano.
W bajtach, opcjonalnie z przyrostkiem K, M, G, T. Przykład: "800M" lub "8G"PowrótZapasowyZła odpowiedź od Pushbullet (%s): %sZła odpowiedź od Pushover (%s): %sZły harmonogram %s o %s:%sPrzepustowośćNa dółPrzeglądajUmieszcza artykuły w pamięci podręcznej, aby ograniczyć częstotliwość dostępu do dysku.
W bajtach, opcjonalnie z przyrostkiem K, M, G. Przykład: "64M" lub "128M"AnulujNie można zmienić uprawnień %sNie można połączyć się z serwerem %s [%s]Nie można utworzyć kopii zapasowej %sNie można utworzyć katalogu %sNie można utworzyć ostatecznego katalogu %sNie można utworzyć tymczasowego pliku dla %sBrak szablonów wiadomości email w %sNie znaleziono szablonu: %s, próbuję użyć standardowego szablonuNie można uruchomić przeglądarki, prawdopodobnie nie została znalezionaNie można odczytać %sNie można odczytać obserwowanego katalogu %sNie można wysłać wiadomości, brak wymaganych danychNie można zapisać bazy danych historii, sprawdź prawa dostępu!Nie można zapisać pliku INI %sKategorieKategoriaNie zachowano zmian, zostaną one utracone.Zmiany wymagają restartu SABnzbd!Sprawdź wszystkieSprawdź przed pobraniemSprawdzaj aktualizacjeSprawdzanieInterwał sprawdzania (w minutach, co najmniej 15). Nieużywany podczas korzystania z harmonogramu!Lista czyszczeniaCzyszczenie %s nie powiodło się.WyczyśćWyzeruj licznikiKliknij, aby przetestować wprowadzone daneZamknięcie okna przeglądarki lub karty NIE zamknie SABnzbd.Katalog zakończonychSzybkość zapisu w katalogu zakończonychUkończoneKatalog dla ukończonych plikówKonfiguracjaPlik konfiguracyjnyPotwierdzaj usuwanie z historiiPotwierdzaj usuwanie z kolejkiBłąd połączenia %s@%s, komunikat=%sPołączenie udane!Połączenie nie powiodło się!PołączeniaNie można określić wyniku połączenia (%s)Obecne harmonogramyWłasnyDUPLIKATCodziennieUszkodzona baza danych historii, utworzono w jej miejscu nową, pustąSortowanie według datyFormat datyDzień miesiącaDekadaDomyślneDomyślny katalog bazowyUsuńUsuń wszystkoUsuń po pobraniuUsunąć wszystkie obiekty z kolejki?Usuwanie %s nie powiodło się!UrządzenieUrządzenie, do którego mają być wysyłane powiadomieniaUrządzenie(-a)Urządzenie(-a), do którego(-ych) mają być wysyłane powiadomieniaWyłącz zarządzanie limitemWyłączoneWyłączono HTTPS z powodu braku plików CERT oraz KEYOdrzućRozłącz serwer(y) Usenet kiedy kolejka jest pusta lub wstrzymanaRozłącz przy pustej kolejcePowiadomienie o pełnym dyskuBłąd dysku podczas tworzenia pliku %sDysk pełnyDysk pełny! Wstrzymuję pobieranieWykonuj dodatkową weryfikację na podstawie plików SFVBrak poprawnego uwierzytelnienia dla kanału %sCzy limit jest kasowany dziennie, tygodniowo czy miesięcznie?PobierzZakończono pobieraniePobieranie nie powiodło sięPobierz wszystkie pliki par2Pobieranie nieudane - Dane niedostępne na skonfigurowanych serwerachSzybkość zapisu w katalogu pobieraniaPobieranie może się nie udać, dostępne jedynie %s z wymaganych %sPobranePobrano w %s ze średnią %sB/sNp.np. 8 lub 20ZASZYFROWANYBŁĄD:Edytuj szczegóły NZBEmailPowiadomienia email po zakończeniu zadaniaAdresat wiadomości emailNadawca wiadomości emailKatalog szablonów emailAdres email, na który będą wysyłane powiadomieniaWiadomość wysłanaAwaryjnyBrakPusty plik NZB %sZnaleziono pusty wpis RSS (%s)WłączonyWłącz 7zipWłącz HTTPSWłącz NotifyOSDWłącz powiadomienia ProwlWłącz powiadomienia PushbulletWłącz powiadomienia PushoverWłącz sprawdzanie przy użyciu SFVWłącz powiadomienia WindowsWłącz dostęp do interfejsu przez HTTPSWłącz zmianę nazw katalogówWłącz, aby zmniejszyć użycie pamięci. Wyłącz, aby zapobiec blokowaniu kolejki przez powolne zadania.Włącz zarządzanie limitemWłącz rekursywne rozpakowywanieWłączonyZakończenie ścieżki znakiem gwiazdki (*) zapobiegnie tworzeniu katalogów dla zadań.Wprowadź URLTytuł odcinkaNumer odcinkaTytuł.odcinkaTytuł_odcinkaBłądBłąd "%s" podczas uruchamiania file_join na %sBłąd "%s" podczas wykonywania par2_repair na zestawie %sBłąd "%s" podczas uruchamiania rar_unpack na %sBłąd %s podczas uruchamiania par2_repair na zestawie %sBłąd %s: należy podać prawidłową nazwę użytkownika i hasło.Błąd tworzenia klucza i certyfikatu SSLBłąd importu %sBłąd ładowania %s, wykryto uszkodzony plikBłąd podczas usuwania %sBłąd zmiany nazwy "%s" na "%s"Błąd podczas dodawania %s, usuwanieWyłączenie systemu nie powiodło sięTylko błędyBłędy/OstrzeżeniaWyjście z SABnzbdRozszerzenieDostęp z zewnątrzDodatkowe parametry PAR2Rozpakowywanie...NieudaneBłąd logowania do serwera %s [%s]Nie udało się utworzyć (%s)Nie udało się przenieść %s do %sBłąd uwierzytelnienia na serwerze pocztowymBłąd zamykania bazy danych, sprawdź logiNie udało się zamknąć połączenia z serwerem pocztowymBłąd kompilacji wyrażenia regularnego dla wyszukiwania: %sBłąd połączenia z serwerem pocztowymHibernacja systemu nie powiodła sięNie udało się zaimportować %s plików z %sBłąd podczas inicjalizacji %s@%s: %sBłąd połączenia TLSNie udało się przenieść plikówNie udało się zmienić nazwy podobnego pliku %s na %sNie udało się pobrać RSS z %s: %sBłąd wysyłania wiadomości ProwlBłąd wysyłania wiadomości emailNie udało się wysłać wiadomości PushbulletNie udało się wysłać wiadomości PushoverWstrzymanie systemu nie powiodło sięNie udało się uruchomić interfejsu WWWNie udało się uruchomić interfejsu WWW: Błąd w tempfile.mkstempBłąd krytycznyBłąd krytyczny podczas zapisywania stanuBłąd krytyczny w module składającymKanałPobierzPobierz NZB z URLPobieraniePobieranie %s bloków...Pobieranie dodatkowych bloków...Plik zawierający wszystkie hasła, które będą używane do rozpakowywania zaszyfrowanych plików RARŁączenie pliku %s nie powiodło sięNazwa pliku lub ścieżka do certyfikatu HTTPSNazwa pliku lub ścieżka do łańcucha certyfikatów HTTPSNazwa pliku lub ścieżka do klucza HTTPSZestaw plikówNazwa plikuFiltrDziałania, które zostaną podjęte dla plików próbek (np. próbek wideo)Katalog zawierający zdefiniowane przez użytkownika szablony powiadomień emailKatalog monitorowany w poszukiwaniu plików .nzb.Katalog/ŚcieżkaKatalogiNazwa konta dla kont z uwierzytelnieniemHasło dla kont z uwierzytelnieniemDla serwerów: zapewnij zgodność nazw z WindowsWymuśWymuś rozłączenieWymuś pobranieForumWolne miejsceCzęstotliwośćPiątekOd SxxEyyPełne APIPełny interfejs WWWDalszą pomoc można uzyskać na naszejOgólneUtwórz nowy kluczPrzejdź do SABnzbdUruchom kreatora konfiguracjiPorty dla HTTP i HTTPS nie mogą być takie sameCertyfikat HTTPSŁańcuch certyfikatów HTTPSKlucz HTTPSPort HTTPSPomocHibernuj komputerUkryj szczegółyPokaż/ukryj ukończone plikiWysokiHistoria10 ostatnichLimit wyświetlanych pozycji historiiPrzytrzymaj klawisz Shift, aby zaznaczyć zakresStartStrona projektuHostHost, na którym ma nasłuchiwać SABnzbdJak długo lub do kiedy chcesz wstrzymać? (po angielsku!)Ile danych można pobrać w miesiącu (K/M/G)NIEKOMPLETNYParametry IONiceAdres IPv6BezczynnyJeśli pole będzie puste, standardowy port będzie obsługiwał tylko HTTPSJeśli ponownie otrzymasz ten sam błąd, spróbuj zmienić numer portu.
Działanie dla próbekIgnoruj foldery wewnątrz archiwówIgnoruję zduplikowany NZB "%s"Jeśli wybrano "Wstrzymaj", będzie trzeba ustawić hasło i wznowić zadanieW razie ponownego uruchomienia SABnzbd ten ekran zniknie automatycznie!W katalogachNiekompatybilny kanałZnaleziono niekompatybilny plik kolejki, nie można kontynuowaćKatalog niezakończonychNiekompletna sekwencja plików do połączeniaNieprawidłowy opis kanału RSS "%s"Błędny parametrNieprawidłowo zakodowane hasło %sNieprawidłowy adres serwera.Niewłaściwe dane serweraNieprawidłowy log etapu w historii dla %sZalecamy dodanie tej strony do zakładek i używanie tej zakładki do późniejszego dostępu do SABnzbd uruchomionego w tle.Zadanie nie powiodło sięZadanie ukończonePołącz plikiŁączenieJęzykUruchom przeglądarkę podczas uruchamianiaUruchom domyślną przeglądarkę podczas uruchamiania SABnzbdOgranicz prędkośćLista rozszerzeń plików, które mają zostać usunięte po pobraniu.
Na przykład: nfo lub nfo, sfvŁadowanieNie udało się wczytać %sLokalny adres IPv4Lokalizacja bazy danych administracyjnych i historycznych kolejki.
Można zmienić tylko kiedy kolejka jest pusta.Lokalizacja logów SABnzbd.
Wymaga restartu SABnzbd!Miejsce przechowywania ukończonych, przetworzonych plików.
Może zostać zmienione przez ustawienia kategorii.Miejsce przechowywania nieprzetworzonych plików.
Można zmienić tylko kiedy kolejka jest pusta.Miejsce przechowywania plików .nzbKatalog logówLogowanieUtracono połączenie z SABnzbd...NiskiMałe literyKompatybilność z WindowsDopasowanoMaksymalna przepustowość łączaMaksymalna ilość prób połączenia z serweremMaksymalna ilość próbZnaczenieMinimalna ilość wolnego miejsca w tymczasowym katalogu pobieraniaBrakujące artykułyŚredniPoniedziałekMiesiącWięcejTytuł filmuTytuł.FilmuTytuł_FilmuPrzenoszeniePrzenoszenie...Operacje na wieluKlucz NZBNZB dodany do kolejkiNazwaSerwer DNSNazwyNigdyDalejParametry niceBrak dostępuNie znaleziono szablonów wiadomości emailBrak katalogówNie podano adresatów, wiadomość nie została wysłanaNie znaleziono odpowiedniej metody uwierzytelnieniaBrakNormalnyNie dopasowanoNiedostępneCentrum powiadomieńWysłano powiadomienie!PowiadomieniaNotifyOSDIlość sekund pomiędzy kolejnymi skanami w poszukiwaniu plików .nzbOPCJONALNE hasło do kontaOPCJONALNA nazwa kontaBrakWykryto kolejkę w starszej wersji, użyj funkcji Status->Naprawa, aby ją przekonwertowaćPo ukończeniu kolejkiW którym dniu miesiąca lub tygodnia (1=poniedziałek) twój dostawca resetuje limit pobierania (opcjonalnie z gg:mm)Pobieraj artykuły tylko dla pierwszego pliku w kolejceOtwórz okno terminala i podaj linię (przykład):Otwórz katalog zakończonychOpcjonalnyOpcjonalne dodatkowe NZBOpcjonalne hasłoOpcjonalna nazwa użytkownikaOpcjonalnie podaj nazwę plikuLub przeciągnij i upuść pliki do okna!KolejnośćOryginalna nazwa plikuPorzucone zadaniaInne komunikatyParametryNumer fragmentuHasłoPlik z hasłamiHasło ukryte za ******, proszę wprowadzić je ponownieZabezpieczone hasłemŚcieżkaCiągZastępowane ciągiWstrzymajWstrzymaj wszystkieWstrzymaj pobieranie podczas przetwarzania końcowegoWstrzymaj naWstrzymaj na 1 godzinęWstrzymaj na 15 minutWstrzymaj na 2 godzinyWstrzymaj na 30 minutWstrzymaj na 5 minutWstrzymaj na 6 godzinWstrzymaj na...Wstrzymaj zadania o wysokim priorytecieWstrzymaj zadania o niskim priorytecieWstrzymaj zadania o normalnym priorytecieWstrzymaj przetwarzanie końcoweWstrzymanoWstrzymuje pobieranie po rozpoczęciu przetwarzania końcowego i wznawia je po zakończeniuWstrzymuję zduplikowany NZB "%s"Procent przepustowości łączaUprawnienia dla ukończonych plikówPrywatny klucz APIPrywatny klucz API Prowl (wymagany)Notatki osobisteNazwa hosta 0.0.0.0 wymaga adresu IPv6 do dostępu z zewnątrzPodaj szczegóły swojego głównego dostawcy UsenetPortPort, na którym ma nasłuchiwać SABnzbdPrzetwarzanie końcowe nie powiodło się dla %s (%s)Przetwarzanie końcowePrzetwarzanie końcowe tylko dla zweryfikowanych zadańPrzetwarzanie końcoweUruchomiono przetwarzanie końcoweSkrypt użytkownika przed zakolejkowaniemPredefiniowaneNaciśnij Klawisz start+R i podaj linię (przykład):WsteczPriorytetProblem zPrzetworzony ciągPrzetwarzanieProgram się nie uruchomił!ProwlPubliczny adres IPv4Wyczyść ukończone NZBWyczyść nieudane NZBWyczyść nieudane NZB i usuń plikiWyczyść historięWyczyść NZBWyczyść NZB i usuń plikiCzyszczenie kolejkiPushbulletPushoverWersja PythonaKolejkaZakolejkuj 10 pierwszychKolejka ukończonaLimit wyświetlanych pozycji kolejkiKolejka nie jest pusta, nie można zmienić katalogu.Naprawa kolejkiSzybkie sprawdzanie...Szybkie sprawdzanieZakończLimit pobieraniaPozostało limituOkres limituPrzekroczono limit, wstrzymywanie pobieraniaRSSInterwał sprawdzania RSSKanał RSS %s był pustyUruchomiono %sRzadko używane opcje. Jeśli chcesz się dowiedzieć, co oznaczają, kliknij przycisk Pomoc, aby przejść do strony Wiki.
Nie zmieniaj tych opcji bez uprzedniego przeczytania Wiki, ponieważ niektóre mają poważne skutki uboczne.
Domyślne wartości zostały umieszczone w nawiasach.Czytaj teraz wszystkie kanałyPobierz kanałCzytaj kanały RSSCzytaj wszystkie kanały RSSPrzeczytaj o tym w Wiki!OdświeżCzęstotliwość odświeżaniaOdrzućŚcieżki względne w stosunku doPozostałoUsuń NZBUsuń NZB i plikiUsuń serwerUsuń wszystkie zaznaczone plikiUsuń ukończone zadaniaUsuń nieudane zadaniaUsuwanie %s nie powiodło sięZmień nazwęNaprawaNaprawa nie powiodła się, brak wystarczającej ilości bloków naprawczych (brakuje %s)NaprawianieNaprawa nie powiodła się, %sNaprawianie...Powtórz testZastąp spacje w nazwach katalogówZastąp kropki w nazwach katalogówZastąp kropki w nazwach katalogów spacjamiZastąp spacje w nazwach katalogów podkreśleniamiWymagaWymaga konta ProwlWymaga konta PushbulletWymaga konta PushoverWymagaKatResetujResetuj limitDzień resetuRozwiązywanie adresuUruchom ponownieUruchom ponownie SABnzbdRestart bez logowaniaRestartowanie SABnzbd...WynikWznówWznów zadania o wysokim priorytecieWznów zadania o niskim priorytecieWznów zadania o normalnym priorytecieWznów przetwarzanie końcoweWznawianieCzas przechowywaniaPonówPonów wszystkiePonów wszystkie nieudane zadaniaUruchamianie skryptuWykonywanie skryptu...Uruchamianie skryptu użytkownika %sUruchomiono SABnzbd %sAdres hosta SABnzbdHasło SABnzbdPort SABnzbdSzybki kreator konfiguracji SABnzbdUżytkownik SABnzbdWersja SABnzbdSerwer WWW SABnzbdSABnzbd wykrył krytyczny błąd:SABnzbd został wyłączonySABnzbd będzie uruchomiony w tle.Serwer SMTPBłąd polecenia SQL, sprawdź logiSSLSobotaZapiszZapisz zmianyNie udało się zapisać %sZapisywanie...Przeszukaj obserwowany katalogHarmonogram dla nieistniejącego serwera %sHarmonogramSkryptKod zakończenia skryptu: %sSkryptySzukajNumer sezonuWybierz język interfejsu WWWZaznacz tylko jeśli twój dostawca zezwala na połączenia SSLPowiadomienia RSSWyślij z powrotem do kolejkiPowiadom, kiedy kanał RSS dodaje zadanie do kolejkiPowiadom, kiedy dysk jest pełen, a SABnzbd wstrzymanyWysłano %s do kolejkiSortowanie serialiSerwerSerwer %s używa niezaufanego certyfikatu HTTPSSerwer %s będzie ignorowany przez %s minutSzczegóły serweraNieprawidłowy adres serwera "%s:%s".Wymagane jest podanie adresu serweraOpis serweraNie udało się rozwiązać nazwy serweraSerwer wymaga podania nazwy użytkownika i hasła.Błąd po stronie serwera (kod: %s); nie udało się pobrać %s z %sSerweryUstawienia podane uprawnienia dla pobranych plików/katalogów.
W notacji ósemkowej. Przykład: "775" lub "777"Ustaw serwer swojego ISP dla poczty wychodzącejKonfiguracja ukończona!Czy pobieranie powinno zostać automatycznie wznowione w dniu resetuPokaż wszystkoPokaż nieudanePokaż logiTytuł serialuPokaż aktywne połączeniaPokaż szczegółyPokaż interfejsTytuł.serialuTytuł_serialuZakończWyłącz komputerWyłącz SABnzbdWyłączanieOdebrano sygnał %s, zapisywanie i zamykanie programu...RozmiarWeryfikacja niektórych plików względem "%s" nie powiodła sięPrzykro mi, nie rozumiem. Spróbuj ponownie.Wzorzec sortowaniaSortuj według wieku Najnowsze→NajstarszeSortuj według wieku Najstarsze→NajnowszeSortuj według nazwy A→ZSortuj według nazwy Z→ASortuj według rozmiaru Największe→NajmniejszeSortuj według rozmiaru Najmniejsze→NajwiększeSortowanieŹródłoSpecjalnePrędkośćOgranicz prędkośćUśpij komputerUruchom kreatora konfiguracjiRozpoczynanie naprawyUruchomienie/WyłączenieStatusStan i opcje interfejsuStopZatrzymywanie...WyślijNiedzielaWspomóż projekt!Nieobsługiwany błąd w module pobieraniaPrzełącznikiKatalogi systemoweWydajność systemu (Pystone)TEKSTZA DUŻYFolder tymczasowyTymczasowy katalog pobieraniaPrzetestuj emailPowiadomienie testoweTestuj serwerTestuję serwer...Przycisk "Napraw" ponownie uruchomi SABnzbd i spowoduje kompletne
odtworzenie zawartości kolejki, z zachowaniem już pobranych plików.
Kolejność elementów kolejki zostanie zmieniona.Pole wyboru obok nazwy kanału musi być zaznaczone, aby kanał był włączony i automatycznie sprawdzany w poszukiwaniu nowych wpisów.
Po dodaniu kanału będą pobierane tylko nowe wpisy - żaden istniejący już w kanale RSS wpis nie zostanie pobrany, chyba że klikniesz przycisk "Wymuś pobranie".Nie ustawiono nazwy hosta.Ilość połączeń dopuszczanych przez twojego dostawcęSerwer nie odpowiedział poprawnie na polecenie HELONie ustawiono maksymalnej liczby połączeń. Proszę umożliwić przynajmniej jedno połączenie.W katalogu pobierania istnieją porzucone zadania.
Możesz je usunąć (razem z plikami) lub wysłać z powrotem do kolejki.Ten klucz umożliwi innym programom dodawanie plików NZB do SABnzbdTen klucz umożliwi innym programom dostęp do SABnzbdTen miesiącSerwer nie obsługuje SSL na tym porcieTen tydzieńSABnzbd zostanie zrestartowane.
Użyj tej funkcji jeśli uważasz, że program ma problemy ze stabilnością.
Pobieranie zostanie wstrzymane przed restartem i wznowione po ponownym uruchomieniu.Nastąpi wysłanie testowej wiadomości na twoje konto.CzwartekUpłynął limit czasu odpowiedzi.Upłynął limit czasu odpowiedzi: spróbuj włączyć SSL lub połącz się z innym portem.Limit czasu odpowiedziTytułTo: %s From: %s Date: %s Subject: SABnzbd zgłasza przekroczenie dopuszczalnej zajętości dysku Cześć, SABnzbd przestał pobierać pliki, ponieważ dysk jest prawie pełen. Opróżnij trochę miejsca i wznów działanie SABnzbd ręcznie. DzisiajZbyt mało miejsca na dysku, wymuszanie WSTRZYMANIAZbyt wiele połączeń do serwera %s [%s]Zbyt wiele połączeń, proszę wstrzymać pobieranie lub spróbować ponownie późniejNa góręRazemRozwiązywanie problemówSpróbuj przewidzieć, czy pobieranie będzie udane przed jego rozpoczęciem (wolne!)Próba rozpakowania archiwum 7zip z użyciem hasła "%s"Próba weryfikacji SFVPróba pobrania NZB z %sPróba ustawienia statusu nieistniejącego serwera %sPróba rozpakowania archiwum RAR z użyciem hasła "%s"WtorekStrojenieTypNIEPOŻĄDANYPobieranie URL nie powiodło się; %sDziałanie modułu pobierania URL zostało przerwaneDostęp zabronionyOdblokujNiezdefiniowany serwer!Nieznany błąd podczas dekodowania %sNieznane działanie: %sUwierzytelnienie na serwerze pocztowym nie powiodło się z nieznanej przyczynyRozpakujRozpakowuj archiwa (rar, zip, 7z) wewnątrz archiwówZbyt głęboki poziom zagnieżdżenia podczas rozpakowywania [%s]Rozpakowano %s plików/katalogów w %sRozpakowywanieRozpakowywanie nie powiodło się, %sRozpakowywanie nie powiodło się, błąd CRCRozpakowywanie nie powiodło się, archiwum wymaga podania hasłaRozpakowywanie nie powiodło się, zbyt długa ścieżkaRozpakowywanie nie powiodło się, nie można znaleźć %sRozpakowywanie nie powiodło się, błąd zapisu lub zapełniony dysk?Bezużyteczny plik NZBBezużyteczny plik RARNiepożądane rozszerzenie w pliku RAR %sNiepożądane rozszerzeniaDostępna aktualizacja!Wczytaj NZBCzas działaniaUżyj globalnych ustawień interfejsuUżywaj tymczasowych nazw podczas przetwarzania końcowego. Należy wyłączyć tę opcję, jeśli system nie obsługuje jej prawidłowo.Uruchamiany zanim plik NZB zostanie umieszczony w kolejceUżyta pamięć podręcznaKatalogi użytkownikaKlucz użytkownikaKlucz użytkownika (wymagany)Skrypty użytkownika mogą oznaczyć zadanie jako nieudaneNazwa użytkownikaWartościPoprawnie zweryfikowano z użyciem plików SFVWeryfikowanieWeryfikowanie...WersjaBardzo niskiZobacz log skryptuCZEKAM %s sUWAGA:OczekujeOstrzeżenieOstrzeżeniaObserwowany katalogCzęstotliwość skanowania katalogu obserwowanegoInterfejs WWWŚrodaJeśli podczas pobierania okaże się, że brakuje zbyt dużej ilości danych, przerwij zadanieJeśli skrypt użytkownika zwróci niezerowy kod zakończenia, zadanie zostanie oznaczone jako nieudaneJaki procent dostępnej przepustowości ma wykorzystywać SABnzbd, np. 50Kto powinien być nadawcą wiadomości email?WikiPowiadomienia WindowsRokPrzed ustawieniem limitu przepustowości należy ustawić maksymalną przepustowośćTwoja wersja unrar to %s, zalecana jest wersja %s lub wyższa.
Prywatny klucz API Pushbullet (wymagany)[%s] Błąd "%s" podczas łączenia plików[%s] Błąd "%s" podczas rozpakowywania plików RAR[%s] Połączono %s plików[%s} Brak zestawów par2[%s] PAR2 otrzymał nieprawidłowe opcje, sprawdź ustawienia w sekcji Konfiguracja->Przełączniki[%s] Szybkie sprawdzenie OK[%s] Naprawiono w %s[%s] Zweryfikowano w %s, wszystkie pliki prawidłowe[%s] Zweryfikowano w %s, wymagana naprawaartykułówz dostosowaniem wielkości literddzieńdniwyłącz serwerwłącz serwerplikggodzinagodzinypozostałomręcznieminutaminutwyłączonewłączonelubstronaProgram par2 ... NIE znaleziono!sekundasekundsprawdź logitekstProgram unrar ... NIE znaleziono!tydzień././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993698.7005734 SABnzbd-4.3.2/locale/sv/LC_MESSAGES/SABnzbd.mo0000644000000000000000000015575714625637243017543 0ustar00runnerstaff<\0o]0d022 ,394-5'6?6Z6 s66666666617@7Y7?78.868RF8[88#9+9H9$e99 99'9'999: : : ):3:I:]:a:'e:::::*: ; ;;-;@;I;/Q; ;;<<%<#C<g< <<<<= = @= a====!=6=-3>a>p>">6>> ??.?'G? o?y???S? @@%@+@":@8]@@@ @@@ @@ A#%AIA`A sA*AAA AA3A B B B-B4BeEe ce mexe eeeeee2e 0f:f Of \fhff)f0ffgg;g Wgcgig yggggggggghh6hMhVheh khuhhhhh hh hii-i=iPipi.i iiiii ijjj#.j Rj]jdj{jj j j4jjk3k3Lkkkk-k(kk$ l2lJl]l&zl:llol)Tm~m3mm m m mm nn )n 3n=n FnRn cn'qnn(n.n n-o-0o$^o$o1o1o ppp#p )p 4p ?pLp\pmptpp pppppppqq #q -q9q Sq^q pq|qqGrHs2as5sAs t>t=t u+u EuOu,u!v *v>4vsv{vv5w";w&^wAwww wEw$xCx.wxxxxxxxxy"y*yTΗ$,=1j ט<.GH *ř˙ ۙ*0AS$k̚   7Sm7ޛiWn L  &*F'q&A47(V)+Þ(  %1 AMe { -ğ"*,0+]7)(-,B-o!31'%M,m*-Ţ*(G^"mͣգL$M-r')Ȥ 09B2| 4ĥ07*bi~  ɦҦ% (9,Iv  ɧק-3a eo"v<.֨  ".66Rm֩ KEb)ª/%/ Uc$yҫL^n 3qnuaS~Ycخ<Zc&lɯ1O`fnu y   ǰڰ߰ + C2N, ɱٱ +;WsFviӲ$=7b#ϳ''8`hx .Ǵ7 ='H p {ʵ ٵ:NjU޶(!(6_Nu4ķ )I%Yȸ3۸   &2 EOio* ݹ   !,5DH an& ƺغ )$(B Zdj  μؼ  ,BQnNŽ  : GTr).# > IUi x ̿ տ ""E ^ j x  )BXh&{* "'->U^&r!9 CV>m?8+O{%,3"Vl^1= Zd u   %*$O(W055*/*Z77   * 7D We$l   $.= Xe xMc4~0K0P@ O0\ 8P> %-I2|U";A)}   3T.h +  +2L2/4+!?ax *Z$, Q_o. $   #/?R[c ku*Km@!CIG"%-!\6'))+/5GW[]cjoqy}  SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Complete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid server address.Invalid server detailsInvalid stage logging in history for %sIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocation for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification Sent!NotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!ProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePushbulletPushoverPython VersionQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...ResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...SubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User script can flag job as failedUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.Which percentage of the linespeed should SABnzbd use, e.g. 50Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: sv Plural-Forms: nplurals=2; plural=(n != 1); SABnzbd kan inte hitta webbgränssnittets filer i %s.
Var vänlig installera om programmet.

SABnzbd har upptäckt sparad data från en annan version av SABnzbd
men kan inte återanvända datan från det andra programmet.

Färdigställ dina nedladdningar med det andra programmet först.

Därefter kan du starta det här programmet med alternativet "--clean".
Detta kommando kommer att ta bort din nuvarande kö och historik!
SABnzbd read the file "%s". SABnzbd upptäckte att filen sqlite3.dll saknas.

Det händer att bristfälligt designade virusprogram tar bort denna fil.
Var vänlig kontrollera ditt virusprogram, försök installera om SABnzbd och klaga till din återförsäljare.

SABnzbd behöver en ledig tcp/ip -port för sin interna webbserver.
Port %s på %s testades , men den är inte tillgänglig.
Någon annan applikation använder porten eller så körs redan SABnzbd.

Vänligen starta om SABnzbd med ett annat portnummer. SABnzbd behöver en giltig värdadress för dess interna webbserver.
Du har specifierat en ogiltig adress.
Säkra värdadresser är localhost och 0.0.0.0

Var vänlig starta om SABnzbd med en giltig värdadress. SABnzbd har ABSOLUT INGEN GARANTI Detta är gratis mjukvara, du är välkommen att sprida det under vissa omständigheter. Det är licensierat under GNU GENERAL PUBLIC LICENSE Version 2 eller (ditt val) en senare version. %s artiklar hade icke-matchande dubletter%s artiklar var felaktiga%s artiklar saknades%s mapp: %s åtkomst misslyckad%s är inte rätt siffervärde%s är inte en godkänd e-mail adress+ Debug+ Info+Ta bort+Reparera+Packar upp.nzb Reservmapp0 är högst prioritet, 99 är lägst prioritet7za binär... EJ funnen!OBS: Mappar kommer att skapas automatiskt när du Sparar. Du måste ange exakta sökvägar till dina mappar för att spara utanför standardmapparna.Data kommer inte tas bort. Kräver omstart av SABnzbd!API (ingen Konfigurering)API-nyckelAPI- eller QR-kodAPI-nyckel felaktig, använd api-nyckeln från Konfiguration-> Allmänt i ditt tredjepartsprogram:API-nyckel saknas, skriv in api-nyckeln från Konfiguration-> Allmänt i ditt tredjepartsprogram:API-nyckel för ProwlAvbryt jobb som inte kan kompletterasAvbrutet, kan inte slutförasAvbruten, kryptering detekterad.Avbruten, oönskad filändelse detekteradAccepteraÅtkomst nekadesÅtgärdHändelse när krypterade RAR är nerladdadHändelse när oönskad filändelse hittadLägg tillLägg till NZBLägg till NZB-filer Lägg till schemaLägg till serverNZB tillagdAdministrativ mappPåverkade kategorierÅlderAllaAlla filer kommer hamna i en mapp.Även testutgåvorAlltidApplikations TokenApplikations token (krav)Är du säker på att du vill stänga av SABnzbd?Är du säker?ArgumentCachestorlek för artiklarArtikel-IDMinstHögstAutentisering misslyckades, kontrollera användarnamn och lösenord.AutoåterupptagningAuto-pausa när fri plats är nära sin gräns.
I bytes, följt av K,M,G,T. Till exempel: "800M" or "8G"BakåtSäkerhetskopieraDålig respons från Pushbullet (%s): %sDålig respons från Pushover (%s): %sFel schema %s vid %s:%sBandbreddBottenBläddraSparar artiklar i minnet för att reducera diskåtkomst.
I bytes, följt av K,M,G. Till exempel: "64M" eller "128M"AvbrytDet gick inte att ändra rättigheter på %sKan ej ansluta till server %s [%s]Kan inte skapa backup-fil för %sKan ej skapa mapp %sKan inte skapa slutgiltig mapp %sKan inte skapa temp -fil för %sKan ej finna e-mail mallar i %sHittar inte webbmall: %s, försöker med standardmallKan inte starta webbläsaren, hittades troligtvis inteKan ej läsa %sKan ej läsa övervakad mapp %sKunde inte skicka, saknar nödvändig dataKan inte skriva till historikdatabasen, kontrollera åtkomsträttigheter!Kan inte skriva till INI filen %sKategorierKategoriÄndringarna har inte sparats och kommer att försvinna.Ändringar kräver omstart av SABnzbd!Markera allaKontrollera innan nerladdningKolla efter ny utgåvaKontrollerarKontrollintervall (i minuter, minst 15). Ej aktiv om du använder Schemaläggaren!Rensa listaRensning av %s misslyckades.RensaNollställ räknareKlicka här för att testa dina angivna serveruppgifter.SABnzbd kommer inte att stängas av om du stänger ett fönster eller en tab i webbläsaren.Färdig mappKomplett mapphastighetFärdigFärdig nedladdningsmappKonfigurationKonfig filBekräfta Historik-borttagningarBekräfta Kö-borttagningarAnslutning %s@%s misslyckades, meddelande=%sAnslutning lyckades!Anslutning misslyckades!AnslutningarDet gick inte att ansluta (%s)Aktuella schemanAnpassaDUBLETTDagligenSkadad hitsotrikdatabas, skapade en tom ersättareDatum sorteringDatumformatMånadsdagÅrtiondeStandardStandard basmappTa bortTa bort allaTa bort efter nedladdningTa bort alla saker från kön?Borttagning av %s misslyckades!EnhetEnheter där meddelande skall skickasEnhet(er)Enhet(er) där medellandet skall skickasAvaktivera kvothanteringAvaktiveradAvaktiverade HTTPS då CERT och KEY -filer saknasKastaKoppla ifrån usenet servrarna när kön är tom eller pausad.Koppla ifrån när kön är tomFull hårddisk notifieringDiskfel vid skapande av fil %sDisken är fullDisken är full! Pausar...Gör en extra kontroll med SFV filerHar inte giltig autentisering för flöde %sNollställs kvoten varje dag, vecka eller månad?NedladdningHämtningen slutfördesHämtning misslyckadesLadda ner alla par2 filerNerladdning misslyckades - Inte på din server eller servrarNerladdningsmapphastighetNerladdningen kan misslyckas, bara %s av krävda %s finns tillgängligtNedladdadHämtade i %s vid ett genomsnitt på %sB/sT.ex.Te.x 8 eller 20KRYPTERATFEL:Ändra NZB detaljerE-postE-post notifiering när jobb är slutförtE-post mottagareE-post avsändareMapp för E-mail mallarE-postadress att skicka e-post till.E-mail sändning lyckadesNödfallTomNZB filen %s är tomTom RSS post hittades (%s)AktiveraAktivera 7zipHTTPS AktiveraAktivera NotifyOSDAktivera Prowl-notiserAktivera Pushbullet-notiserAktivera Pushover-notiserAnvänd SFV-baserade kontrollerAktivera Windows-notiserAktivera åtkomst till webbkontrollen med HTTPS adress.Döp om mapparAktivera för lägre minnesanvändning. Avaktivera för att förhindra långsamma jobb att blockera kön.Aktivera kvothanteringAktivera rekursiv uppackningAktiveradAvsluta sökvägen med en asterisk * kommer förhindra jobb att skapa mapparAnge URLEpisodnamnEpisodnummerEpisod.NamnEpisod_NamnFelFel "%s" när du kör file_join på %sFel "%s" medans par2_repair kördes på %sFel "%s" när du kör rar_unpack på %sFel %s när du kör par2_repair på %sError %s: Du måste ange ett giltigt användarnamn och lösenord.Det gick inte att skapa SSL-nyckel eller certifikat.Det gick inte att importera %sLaddningsfel %s, felaktig fil detekteradFel vid borttagning av %sDet gick inte att döpa om "%s" till "%s"Det gick inte att lägga till %s, tar bortFel uppstod då systemet skulle stängasBara vid felFel/VarningAvsluta SABnzbdFiländelseExtern internetåtkomstExtra PAR2 parametrarExtraherar...MisslyckadesDet gick inte att logga in på server %s [%s]Skapande av (%s) misslyckadesDet gick inte att flyta %s till %sAutentisering till mailserver misslyckadesDet gick inte att stänga databasen, se loggDet gick inte att stänga e-mail anslutningDet gick inte att kompilera regex för sök-sträng: %sDet gick inte att ansluta till mailserverKunde inte sätta systemet i väntelägeDet gick inte att importera %s filer från %sMisslyckades att initiera %s@%s med orsak %sDet gick inte att initialisera TLS anslutningMisslyckades med att flytta filerDet gick inte att döpa om liknande fil: %s till %sDet gick inte att hämta RSS flödet från %s: %sMisslyckades att skicka ProwlmeddelandeDet gick inte att skicka e-mailMisslyckades att skicka pushbulletmeddelandeMisslyckades att skicka pushovermeddelandeDet gick inte att sätta systemet i vilolägeDet gick inte att starta webbgränssnittetMisslyckades att starta webbgränsnitt: Fel i tempfile.mkstempAllvarligt felKritiskt fel vid sparande av lägeKritiskt fel i AssemblerFlödeHämtaHämta NZB från URLHämtarHämtar %s block...Hämtar extra block...Fil som innehåller alla lösenord som ska prövas på krypterade RAR-filer.Filsammanslagning av %s misslyckadesFilnamn eller sökväg till HTTPS Certifikat.Filnamn eller sökväg till HTTPS-kedjaFilnamn eller sökväg till HTTPS Nyckel.FiluppsättningFilnamnFilterFiltrera ut sample-filer (ex. video samplingar).Mapp som innehåller användar-definierade e-mail mallar.Mapp som igenomsöks automatiskt efter .nzb filer.Mapp/SökvägMapparAnvändarnamn för e-post som kräver autentisering.Lösenord för e-post som kräver autentisering.För servrar: Gör att namn är kompatibla med Windows.TvingaTvinga frånkopplingTvinga nedladdningForumLedigt diskutrymmeFörekomstFredagFrån SxxEyyFull APIFullt WebgränsnittÖvrig hjälp kan du hitta på våranAllmäntGenerera Ny NyckelGå till SABnzbdGå till guidenHTTP och HTTPS portar kan inte vara likadanaHTTPS CertifikatHTTPS-kedjecertifikatHTTPS NyckelHTTPS-portHjälpViloläge PCGöm detaljerVisa/göm färdiga filerHögHistorikHistorik (10 senaste sakerna)Historik artikelgränsHåll in shiftknappen för att välja omfångHemWebbplatsAdressAdress som SABnzbd ska lyssna på.Hur lång tid eller tills då vill du pausa? (på engelska!)Hur mycket kan laddas ner denna månad (K/M/G)INKOMPLETTIONice parametrarIPv6-adressInaktivOm tom kommer standardporten endast lyssna till HTTPS.Om du får detta felmeddelande igen, var vänlig försök med en annan siffra.
Ignorera Sample-filerIgnorera alla mappar i arkivenIgnorerar dubblett för NZB "%s"Om "Pausad", så behöver du ange ett lösenord för att återuppta jobbet.Om SABnzbd startar om kommer denna skärm att försvinna automatiskt!In mappInkompatibel feedFelaktig köfil funnen, kan ej fortsättaOfullständig mappEj komplett sekvens av filer för ihopläggningFelaktigt RSS-flödesbeskrivning "%s"Fel parameterFelaktigt kodat lösenord %sOgiltig serveradressOgiltiga serverdetaljerFelaktig loggning i historiken av %sDet är rekommenderat att du sparar denna plats som ett bokmärke för att komma åt SABnzbd när det körs i bakgrunden.Jobb misslyckadesArbetet utfördSlår ihop filerSlår ihopSpråkStarta webbläsare vid uppstartStartar standard webbläsaren när SABnzbd startar.HastighetsbegränsningLista av filändelser som skall bli borttagna efter nerladdning.
Till exempel: nfo or nfo, sfvLaddarLaddning av %s misslyckadesLokal IPv4 adressPlats för köadministration och historiedatabas.
Kan bara ändras när kön är tom.Plats för sparade loggfiler från SABnzbd.
Kräver omstart av SABnzbd!Plats för att lagra bearbetade och färdiga nedladdningar.
Kan åsidosättas av användar-definierade kategorier.Plats för att lagra ej bearbetade nedladdningar.
Kan endast ändras när kön är tom.Plats där .nzb filer sparas.LoggmappLoggningFörlorade förbindelse till SABnzbd..LågSmå bokstäverGör Windows-kompatibelMatchadeMaximal linjehastighetMax antal omförsök per serverMax antal omförsökBetyderMinimal fri plats för temporär nedladdningsmappSaknade artiklarMedelMåndagMånadMerFilm NamnFilm.NamnFilm_NamnFlyttarFlyttar...Multi-operationerNZB-nyckelNZB tillagd i könNamnNamnserver /DNS LookupDöpningAldrigNästaBra parametrarIngen åtkomstInga e-postmallar funnaIngen mappIngen mottagare angiven, ingen e-post har skickatsIngen passande autentikationsmetod hittadesIngenNormalInte MatchadeEj tillgängligMeddelandecenterNotis skickad!MeddelandenNotifyOSDSekunder mellan skanningar för .nzb filer.VALFRITT AnvändarlösenordVALFRITT KontoanvändarnamnAvGammal kö hittad, använd Status -> Reparera för att konvertera könNär kön är färdigPå vilken dag i månaden eller veckan (1=Måndag) nollställer din ISP din kvot? (Alternativt med hh:mm)Bara artiklarna för början av könÖppna ett Terminal-fönster och skriv raden (exempel):Öppna färdig mappValfriValfri Kompletterande NZBVäljbart autentiserings lösenord.Väljbart autentiserings användarnamn.Alternativt ange ett filnamnEller dra och släpp filer i fönstret!OrdningOriginalfilnamnÖvergivna jobbAndra meddelandenParametrarDelnummerLösenordLösenordsfilLösenordet är dolt med ******, försök igenLösenordskyddadSökvägMönsterHjälp till SorteringssträngPausaPausa AlltPausa nedladdning under efterbehandlingPausa förPausa 1 timmePause 15 minuterPausa 3 timmarPausa 30 minuterPausa 5 minuterPausa 6 timmarPausa i...Pausa högprioriterade jobbPausa lågprioriterade jobbPausa normalprioriterade jobbPausa efterbehandlaPausadPausas nedladdning när efterbehandling börjar och återupptar nedladdning när efterbehandling är klar.Pausar dubblett för NZB "%s"Procent av linjehastighetRättigheter för färdiga nedladdningarPersonlig API-nyckelPersonlig API-nyckel för Prowl (krävs)Personliga noteringarTänk på att värdnamnet 0.0.0.0 behöver en IPv6-adress för extern åtkomstFyll i uppgifter om din primära usenet leverantör.PortPort som SABnzbd ska lyssna på.Efterbehandling misslyckades för %s (%s)EfterbehandlingEfterbehandla endast verifierade jobbEfterbehandlingEfterbehandling påbörjadKö-specifika användarskriptFörinställningarTryck på Startknappen+R och skriv raden (exempel):FöregåendePrioritetProblem medHanterade resultatBearbetarProgrammet startade inte!ProwlPublik IPV4 adressRensa färdiga NZB:erRensa Misslyckade NZB:er.Rensa Misslyckade NZB:er och ta bort filerTöm historikRensa NZB:erRensa NZB:er och ta bort filerRensa köPushbulletPushoverPython-versionKöKö (10 första sakerna)Kön färdigKö artikelgränsKön är inte tom, kan inte byta mapp.KöreparationSnabbkontroll...SnabbkontrollerarAvslutaKvotKvot kvarKvotperiodDin kvot är uppnådd, pausar nerladdningRSSRSS UppdateringsintervallRSS-flödet %s var tomtKörde %sSällan använda inställningar. För deras mening och förklaring, klicka på Hjälpknappen för att komma till Wiki-sidan.
Ändra inte dessa utan att kolla med Wiki först, då vissa kan ha seriösa sidoeffekter.
Standardvärdet är mellan paranteser.Läsa Alla Flöden NuLäs flödeLäs RSS-flödenLäs alla RSS-flödenLäs Wiki Help för detta!UppdateraUppdateringsfrekvensAvvisaRelativa mappar är baserade påÅterstårTa bort NZBTa bort NZB och filerTa bort serverTa bort alla markerade filerTa bort färdiga jobbTa bort misslyckade jobbBorttagning av %s misslyckadesRepareraMisslyckad reparation, finns ej tillräckligt med reparationsblock (%s saknas)ReparerarReparation misslyckades, %sReparerar...Gör om testErsätt mellanslag i mappnamnErsätt punkter i mappnamnErsätt punkter med mellanslag i mappnamnErsätt mellanslag med understreck i mappnamn.KräverKräver ett Prowl-kontoKräver ett Pushbullet-kontoKräver ett Pushover-kontoKräverKatÅterställÅterställ Kvot nuNollställ dagLösa adressStarta omStarta om SABnzbdStarta om utan loginStartar om SABnzbd...ResultatÅterupptaÅteruppta högprioriterade jobbÅteruppta lågprioriterade jobbÅteruppta normalprioriterade jobbÅteruppta efterbehandlaFortsätterRetensionstidFörsök igenStarta om allaStarta om alla misslyckade jobbKör skriptKör skript...Kör användarskript %sSABnzbd %s startadSABnzbd AdressSABnzbd LösenordSABnzbd-portSABnzbd Snabbstart GuideSABnzbd AnvändarnamnSABnzbd VersionSABnzbd WebbserverSABnzbd upptäckte ett allvarligt fel:SABnzbd nedstängning utförd.SABnzbd kommer nu att köras i bakgrunden.SMTP-serverSQL Kommando misslyckades, se loggSSLLördagSparaSpara ändringarSparar %s misslyckadesSparar..Scanna bevakad mappSchema för icke existerande server %sSchemaläggareSkriptSkriptets utgångskod är %sSkriptSökSäsongsnummerVälj språk till webbkontrollen.Välj bara om din leverantör tillåter SSL-anslutningar.Skicka RSS-notiserSkicka tillbaka i könSkicka E-post när ett RSS-flöde lägger till jobb till kön.Skicka e-mail när hårddisken är full och SABnzbd har pausat.Skickat %s till köSeriesorteringServerServer %s använder ett otillförlitlig HTTPS-certifikatServer %s kommer att ignoreras i %s minuterServeruppgifterServeradressen "%s:%s" är ej giltig.Kräver serveradressServerbeskrivningServernamn kunde inte läsasServern kräver användarnamn och lösenord.Server fel (serverkod %s); kunde inte få %s på %sServrarSätt rättigheter för färdiga filer och mappar.
Använd siffror. Till exempel: "755" or "777"Ställ in din ISP's server för utgående e-mail.Installationen är nu utförd!Skall nerladdning återupptas efter att kvot är nollställd?Visa allaVisa MisslyckadeVisa loggShow NamnVisa aktiva anslutningarVisa detaljerVisa gränssnittShow.NamnShow_NamnStäng AvStäng av PCStäng av SABnzbdPåbörjar nedstängning av SABnzbd..Signal %s mottagen, sparar och stänger...StorlekSome files failed to verify against "%s"Tyvärr, vi kunde inte tolka det. Försök igen.SorteringssträngSortera efter ålder Nyast→ÄldstSortera efter ålder Äldst→NyastSortera efter namn A→ZSortera efter namn Z→ASortera efter storlek Störst→MinstSortera efter storlek Minst→StörstSorteringKällaSpeciellHastighetHastighetsgränsSparläge PCStarta guideStartar reparationStarta/StängStatusStatus och gränsnittsinställningarStoppStänger...SkickaSöndagDonera och stöd detta projekt!Misstänker fel i nedladdareSwitcharSystemmapparSystemprestanda (Pystone)TEXTFÖR STORTemporär MappTemporär nedladdningsmappTesta E-postTesta notifikationTestserverTestar serverdetaljer...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.Kryssrutan bredvid flödesnamnet ska aktiveras för att flödet automatiskt ska kontrolleras för nya objekt.
När ett flöde läggs till kommer det bara att välja nya objekt och inte allt som redan finns i RSS-flöded så länge du inte klickar på "Tvinga nedladdning".Adressen är inte angiven.Antalet anslutningar som tillåts av din leverantörServern svarade inte ordentligt till hälsningenInga anslutningar är aktiverade. Var vänlig aktivera minst en anslutning.Det finns övergivna jobb i nedladdningsmappen.
Du kan välja mellan att radera dem (inklusive filer) eller skicka tillbaka dem i kön.Denna nyckel ger tredjepartsprogram möjlighet att lägga till NZB:er i SABnzbd.Denna nyckel ger tredjepartsprogram full tillgång till SABnzbd.Denna månadDen här servern tillåter in SSL på denna portDenna veckaDetta kommer att starta om SABnzbd.
Använd det när du tror att programmet har stabilitetsproblem.
Nerladdningar kommer att pusas innan omstarten och återupptas efteråt.Detta kommer att skicka ett test e-mail till ditt konto.TorsdagTimeoutTimeout: Försök aktivera SSL eller anslut via en annan port.TidsgränsTitelTill: %s Från: %s Datum: %s Ämne: SABnzbd rapporterar att disk är full Hej, SABnzbd har stoppat nerladdningen på grund av att din disk inte har tillräckligt med utrymme kvar. Frigör utrymme och återuppta nerladdningen manuellt. I dagFör lite diskutrymme pausar systemetFör många anslutningar till servern %s [%s]För många anslutningar, pausa en nedladdning eller försök igen senareToppTotaltFelsökFörsök att förutspå lyckad överföring innan nerladdningen påbörjas (saktare!)Provar 7zip med lösenord "%s"Försöker verifiera SFVFörsöker att hämta NZB från %sFörsöker att sätta status på icke existerande server %sFörsöker att packa upp med lösenord %sTisdagOptimeringTypOÖNSKADURL hämtning misslyckades; %sURLGRABBER KRASHADEOtillåten åtkomstTa bort blockeringOdefinerad server!Okänt fel under avkodning av %sOkänd åtgärd: %sOkänd autentikationmisslyckande i mailservernPacka uppPacka upp arkiv (rar,zip,7z) inuti arkiven.Nästling för djup [%s]Uppackad %s filer/mappar i %sPackar uppUppackning misslyckades, %sUppackning misslyckades, CRC-felUppackning misslyckades, arkivet kräver lösenordUppackning misslyckades, sökvägen är för långUppackning misslyckades, gick inte att hitta %sUppackning misslyckades, skrivfel eller disken full?Oanvändbar NZB filOanvändbar RAR-filOönskad filändelse i RAR-fil %sOönskade filändelserUppdatering tillgängligLadda upp NZBUpptidAnvända globala gränsnittsinställningarAnvänd temporära namn under efterbehandling. Avslaget när ditt system inte stöder det.Används innan en NZB tas in i kön.Använt cacheAnvändarmapparAnvändarnyckelAnvändarnyckel (krävs)Användarskript kan flagga jobb som misslyckatAnvändarnamnVärdenVerifieringen lyckades med SFV-filerVerifierarVerifierar...VersionMycket lågVisa skriptloggVÄNTA %s SEKUNDERVARNING:VäntarVarningVarningarÖvervakad MappSkanningsintervall för Övervakade mapparWebbkontrollsutseendeOnsdagUnder nerladdning och det märks att för mycket data saknas, avbryt jobbetNär ett användarskript returnerar ett icke-nollutgångsvärde, så kommer jobbet att flaggas som misslyckatVilken procent av linjehastigheten ska SABnzbd använda, te.x 50Vem ska vi skicka e-posten från?WikiWindows-notiserÅrDu måste ange maximal bandbredd innan du kan ange bandbreddsgränsDin UNRAR version är %s, vi rekommenderar version %s eller högre.
Din personliga API-nyckel (krävs)[%s] Fel "%s" under filsammanslagning[%s] Fel "%s" under uppackning av RAR fil(er)[%s] Slår ihop %s filer[%s] Ingen par2 sats[%s] PAR2 har fått felaktiga alternativ, ändra dessa via Config->Switches inställningarna[%s] Snabbkontroll OK[%s] Reparerad i %s[%s] Verifierad i %s, alla filer är ok[%s] Verifiering i %s, kräver reparationartiklarversal-justeradeddagdagaravaktivera serveraktivera serverfilhtimmetimmarkvarmmanuellminminuteravdenellersidapar2 binär... EJ funnen!seksekunderse loggfiltextunrar binär... EJ funnen!vecka././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.1031559 SABnzbd-4.3.2/locale/he/LC_MESSAGES/SABnzbd.mo0000644000000000000000000027504614625637243017501 0ustar00runnerstaffD l@om@d@BB SES\LSS*T1TKT kT TTTT!U6'U-^UUU"U<U?V6YVV VVGVlW<uWW.W'W "X,XBXXXaXSvXX XXXY"Y85YnY}YY YYUYZ $Z*0Z[ZuZ#ZZZ ZZZ*[;[\\ ]]Q-]] ]]3] ] ] ]]]^^3^G^ N^Y^o^ ^^ ^1^^_17_4i_9__&_ `)` :`(H`q``4`4``a?aaaa b'b @b,Kb,xbib1cAcJc]cmc'cc5cc d'dFd d e e e%e,e1eBe$Heme }ee#ee eeefff3f :fFf cfpffffff4gDgSYgggggHh Lh Vhch rh hh(h.h)h,i<Ai&~ii'iiij .j OjZj8ij.jj j jkk4kJk`k tkkkkkk%k!l6l+Vl l#ll!l*m!/mQm#fmm'm"mmn#+nOn!en0n!nnno1oQokoo oooooppp$p:pASpp'p!ppq)q2q;q-Bqpq/q!q qq&q"r9@rBzrrrrrr r sss )s5s>s QsrszsGs/s t tt/t@t'Qtytt t tttot LuYu huuuuuuuu uu uv v;+v>gv-v9v ww +w8wUw6ZwvwhxqxGx I Taq ũ̩ :F K/U  Ȫ ڪ ` !2:Cm5AF>ˮ= HMS+ ͯׯ,| >L V "&3AZ E+Ia.}̳Գ۳avJĴ-"P/W ĵε-6-"d#."ڶ"!$Di} J7.bL<$  )2F#U"y%Lҹ ) :GOX ht}2ɺغ  RUqcǻM+=y0 !:TjAoEB:+¾#)<QJc&¿/&-'T|    ".3MtRe;NZ118I@!'((*Q |BrPS b"kCX  vOA1yK)!5GN b =)=4 =JauX ""Bel>u"^1"* >HKA" 6 HS9e"eo) ,1*^ 0  i} =*-h08/306d7PV$ {>>hn`-S~ M-;@ |!hXr:_Yo$ $ ju>$3<Shw:SS*C Qc%G.v,*)+U \j,/@ 5N3;B@7x)/=@ ]JhAH ,)V$f:/ C  /2P&Q+ (+3 _ k x  2$$8<] ' 4=Vt ( <>%{ (I"f T   ' 33>@r4>P'=x8+!+M)yV7()` &$&9 V1b-$->=/|R4/4$d-1($27)jA),*-,X$*A/-G*u)+&!:\)r#&#6]Z&220Ev R2MC. 0+ E@ i      3 >  N [ k  }   .   a V^      O Z "k      ^ p  '   : &;5b 7GM6>G /? \@gfe>5!tu` _m_nF9*+V.jR-:,<ti$#I' q~[DN&, FS !$ FgnI _j[ ~ !/!!" " ""s"!9# [#f#|###=#*# #$ 0$;$!$H%JK%%%% _&m&v&B}&&vA'T'p ( ~(( ( ( ( ( ((!( ))8)=)Z)Cj) )) )))'*,*1@*6r*.** ** * +"+:+.Q+ + +<+"+*+",[+,,,,CR-1-2--A../ '/"2/"U/*x/,/// 0 0)0D0^0y00%1:1I1 [1f1Kz111112 212K2]2v22222 323)Q32{3233 3{4L4440 5-=5k55/636pK6I6777,G7t7=77778-8)88F 9 S9 ^9 k9y99!99999 :45:j:::':': : ;;;K2;~;0;;;@; (<6<K<a<w<|<<^=t=(=$=$===#>=>sN>$??? @*-@X@x@@@7@@8@)A2A DAOA nA|A,A A AAB(B >BCJBBFBBB B C-"C-PC=~CJC:DIBDDDDDD DEEE0EDEVE#uE#E2E2E6#FZFyF FF2F)F2F21GdG GG GG5GG H!!H\CHHHHH)HI-I>I'TI|II!AJ cJoJ*JJ JJJJJ K"K-4K bK mK&xK8KKK LL L 6L WLxbLL;L6MUMqMKM?MeN|N.N NN'NO2O'AO?iO>O<O%P.5PdP3PPP/PZQ rQ}QVRfR@R@RSS,SBS TS$bSSSS S SSSS T*T>T GT7hT@TTJTRBURU.U.VVFVVVVV W WpWWWWWWW)W (X 3X ?XJXQXcX$X XX!XXYYHY`Y{Y&YYYY YZZ.Z[~[*]?I]O]7]^O1^^_5_U__h_4f```=aaaUa :bHbzQbbc2c/ca%dddd]d$ e.e"Neqe(e=e(ef +f8f?f$Qfvffg;gMg3igig"hB*hmhCvh,h/hi i%:i7`iWi/i> jB_j3jjj1k0Fk"wkk kkk|kcTl1llcm0mn-nEnYnxn)n?nn o6omJo oo ooop#p :p Fp>Qp p pp6pp& q0qmBqvq'rjrR:s>ss4s tP tqttvteukjuu4v3v5w7wUwjqw#w+x,x:Cx6~x+x xxy yyy*y:yCyFyMyVy_ybykyry{yyyy#y yy yyy$yz SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %f% available of %d requested articles%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address%s is not a valid script%s is not writable at all. This blocks downloads.%s is not writable with special character filenames. This can cause problems.%s@%s: Received unknown status code %s for article %s+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!

Use Sorters to automatically organize your completed downloads. For example, put all episodes from a series in a season-specific folder. Or, put movies in a folder named after the movie.

Sorters are tried in order of appearance and can be reordered by dragging and dropping.
The first active sorter that matches both the affected category and job type is applied.

More options are available when Advanced Settings is checked.
Detailed information can be found on the Wiki.

ALTERNATIVEAPI (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAbort post-processingAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedAccount expiration dateActionAction when an unwanted extension is detectedAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdd SorterAdded NZBAdditionally, attempts to set the correct file extension based on the file signature if the extension is not present or meaningless.Adds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup.Administrative FolderAdvancedAffected CategoriesAffected Job TypesAgeAllAll files will go into a single folder.All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings.Allow proper releasesAlso test releasesAlwaysAlways use full screen widthAny propertyApplication TokenApplication token (required)Apply filtersArchiveAre you sure you want to remove these jobs?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle availabilityArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically sort jobs in the queue when a new job is added.Automatically sort queueBackBackupBackup FolderBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBlacklistBlocked attempt to create directory %sBottomBrowseBypass smart duplicate detection if PROPER, REAL or REPACK is detected in the download name.Cache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write a long filename to %s. This can cause problems.Cannot write a unicode filename to %s. This can cause problems.Cannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCategory folder cannot be a subfolder of the Temporary Download Folder.Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Certificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a theme.Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfiguration locked, cannot save settingsConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not connect to %s on port %s. It appears that %s operates as a web server (port 80), possibly an indexer, not a usenet server. You have to fill a usenet server.Could not determine connection result (%s)Could not load additional certificates from certifi packageCould not restore backupCreate a backup of the configuration file and databases in the Backup Folder.
If the Backup Folder is not set, the backup will be created in the Completed Download Folder.
Recurring backups can be configured on the Scheduling page.Create backupCurrent SchedulesCurrent umask (%o) might deny SABnzbd access to the files and folders it creates.CustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Apprise URLsDefault Base FolderDeleteDelete AllDelete after downloadDelete all completed jobsDelete all items from the queue?Deleting %s failed!DeobfuscateDeobfuscate corrected the extension of %d file(s)Deobfuscate final filenamesDeobfuscate renamed %d file(s)Deobfuscate skipped due to DVD/Bluray directoriesDetect duplicates based on analysis of the filename.Detect identical downloads based on name or NZB contents.DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDirect UnpackDirect Unpack was automatically enabled.Disable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue.Disconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDisk speedDo an extra verification based on SFV files.Do not have valid authentication for feed %sDo not use a folder in the application folder as your Scripts Folder, it might be emptied during updates.Does the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownload speed limited byDownloadedDownloaded in %s at an average of %sB/sDownloading will automatically resume if the minimum free space is available again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes.Duplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:EditEdit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmergency expireEmergency retryEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable Apprise notificationsEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Executed after the queue finishes downloading.Executes a custom scriptExit SABnzbdExtensionExternal internet accessExternal process priorityExtra PAR2 ParametersExtra history columnsExtra queue columnsExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to connect: %s %s@%s:%s (%s)Failed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to rename %s to %sFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Apprise messageFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send one or more Apprise NotificationsFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFatal error in DownloaderFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardGuessIt PropertyGuessIt.PropertyGuessIt_PropertyHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHidden FoldersHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory RetentionHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How many seconds your notification will continue to be retriedHow much can be downloaded this month (K/M/G)How often (in seconds) the same notification will be sentINCOMPLETEIONice ParametersIPv6 addressIdentical download detectionIdleIf empty, the standard port will only listen to HTTPS.If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name.If only the Default category is selected, notifications are enabled for jobs in all categories.If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In case of connection failures, the download queue will be paused for a few minutes instead of skipping this serverIn foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Internet BandwidthInvalid NZB file %s, skipping (error: %s)Invalid backup archiveInvalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job Name as FilenameJob failedJob finishedJobsJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesJoiningKeep all jobsKeyboard shortcutsLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLive ChatLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Location where the backups of the configuration file and databases are stored.
If left empty, the backup will be created in the Completed Download Folder.Log FolderLog inLog outLoggingLogin from too many different IP addresses to server %s [%s] - https://sabnzbd.org/multiple-adressesLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname.Minimum FilesizeMinimum Free Space for Completed Download FolderMinimum Free Space for Temporary Download FolderMissing articlesModerateModern web browsers and other clients will not accept self-signed certificates and will give a warning and/or won't connect at all.MondayMonthMoreMove all completed jobs to archiveMove and rename all episodes in the "tv" category to a show-specific folderMove and rename all movies in the "movies" category to a movie-specific folderMove jobs to the archive after specified number of daysMove jobs to the archive if the history exceeds specified number of jobsMovie NameMovie SortingMovie.NameMovie_NameMoviesMovingMoving...Multi-OperationsMulti-part LabelNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNetwork path "%s" should not be used hereNeverNextNext scan atNice ParametersNo accessNo email templates foundNo foldersNo matching earlier rar file for %sNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn queue finish scriptOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)One or more Apprise URLs could not be loaded.Only Get Articles for Top of QueueOnly external access requires loginOnly unpack and run scripts on jobs that passed the verification stage. If turned off, all jobs will be marked as Completed even if they are incomplete.Open a Terminal window and type the line (example):Open complete folderOpen folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOriginal Job NameOrphaned jobsOther / UnknownOther MessagesOverride the default URLs for specific notification types below, if desired.PROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermanently delete (skip archive)Permissions for completed downloadsPermissions setting of %s might deny SABnzbd access to the files and folders it creates.Personal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPost-processing was abortedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge LogsPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuick startQuitQuotaQuota for this account, counted from the time it is set. In bytes, optionally follow with K,M,G.
Warn when it reaches 0, checked every few minutes.Quota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!Received a DBus exception %sRefreshRefresh rateRefused connection from:Refused connection with hostname "%s" from:RejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove SorterRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRenaming the job will abort Direct Unpack.RepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.Replace underscores in folder nameReplace underscores with dots in folder names.RequiredRequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorRestore DefaultsRestore backupResultResumeResume high priority jobsResume jobs with categoryResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSOCKS5 ProxySQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSeason folderSecure connection to serverSecuritySelect a mode and list all (un)wanted extensions. For example: exe or exe, comSelect a web interface language.Select only if your provider allows SSL connections.Selected date rangeSend RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send notifications using Apprise to almost any notification serviceSent %s to queueSeperate multiple URLs by a commaSeriesSeries SortingSeries with air datesServerServer %s has used the specified quotaServer %s is expiring in %s day(s)Server %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Shift+Arrow key: Browse Queue and History pagesShould downloading resume after the quota is reset?Show AllShow ArchiveShow FailedShow LoggingShow NameShow active connectionsShow detailsShow folderShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSmart duplicate detectionSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by % downloaded Most→LeastSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeed up repairs by installing par2cmdline-turbo, it is available for many platforms.SpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)System loadTEXTTOO LARGETabbed layout
(separate queue and history)Tag jobTemp FolderTemporary Download FolderTest DataTest EmailTest NotificationTest ServerTest downloadTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The Completed Download Folder cannot be the same or a subfolder of the Temporary Download FolderThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe queue will resort every 30 seconds if % downloaded is selected.The server didn't reply properly to the helo greetingThere are no active servers!There are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo prevent all helpful warnings, disable Special setting 'helpful_warnings'.To: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR renamerTrying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse Sorting to automatically organize and rename your completed downloads.Use a comma and/or space to identify more than one URL.Use global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Use the specified SOCKS5 proxy for all outgoing connections.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying repairVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarn 5 days in advance of account expiration date.WarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb Interface ThemeWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be completed' are disabled.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?WhitelistWho should we say sent the email?WikiWill not work if a category folder is on a different disk.Windows NotificationsYearYou can set access rights for systems outside your local network.You must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] The command in build_command is undefined.[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!propertysecsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: ION, 2024 Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: he Plural-Forms: nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2; SABnzbd אינו יכול למצוא את קבצי ממשק הרשת שלו בנתיב %s.
אנא התקן את התוכנית שוב.

SABnzbd גילה נתונים שמורים מגרסה אחרת של SABnzbd
אבל אינו יכול להשתמש מחדש בנתונים של התוכנית האחרת.

ייתכן שתרצה לסיים תחילה את התור שלך עם התוכנית האחרת.

לאחר מכן, התחל תוכנית זו עם האפשרות "--clean".
זה ימחק את התור הנוכחי וההיסטוריה!
SABnzbd קרא את הקובץ "%s". SABnzbd גילה שהקובץ sqlite3.dll חסר.

מספר סורקי נגיפים ירודים מסירים קובץ זה.
אנא בדוק את סורק הנגיפים שלך, נסה להתקין מחדש את SABnzbd והתלונן למוכר של סורק הנגיפים שלך.

SABnzbd צריך פתחה חופשית של TCP/IP עבור שרת הרשת הפנימי שלו.
פתחה %s על %s נוסתה, אך היא אינה זמינה.
איזשהי תוכנה אחרת משתמשת בפתחה או SABnzbd כבר רץ.

אנא הפעל מחדש את SABnzbd עם מספר פתחה אחר. SABnzbd צריך כתובת מארח תקפה עבור שרת הרשת הפנימי שלו.
ציינת כתובת בלתי תקפה.
ערכים בטוחים הם localhost ו־0.0.0.0

אנא הפעל מחדש את SABnzbd עם כתובת מארח תקינה. SABnzbd מגיע ללא אחריות מוחלטת. זו תוכנה חינמית, ואתה מוזמן להפיצה מחדש תחת תנאים מסוימים. היא ברישיון תחת רישיון ציבורי כללי GNU גרסה 2 או (לבחירתך) כל גרסה שהיא מאוחרת יותר. %f% זמינים מתוך %d מאמרים מבוקשיםאל %s מאמרים יש כפילויות בלתי תואמות%s מאמרים עוותו%s מאמרים היו חסריםתיקייה %s: שגיאת גישה %s%s אינו ערך אוקטלי נכון%s אינה כתובת דוא״ל תקפה%s הוא לא תסריט תקף%s אינו בר־כתיבה בכלל. זה חוסם הורדות.%s אינו בר־כתיבה עם שמות קבצים עם תו מיוחד. זה יכול לגרום לבעיות.%s@%s: קוד בלתי ידוע של מעמד התקבל %s עבור מאמר %s+ ניפוי תקלים+ מידע+מחיקה+תיקון+פריקהתיקיית גיבוי .nzb0 הוא העדיפות הגבוהה ביותר, 100 הוא העדיפות הנמוכה ביותר7za בינארי… לא נמצא!
אם אימות מאופשר, תצטרך להיכנס שוב.הערה: תיקיות יווצרו באופן אוטומטי בעת שמירה. אתה יכול להשתמש בנתיבים מוחלטים כדי לשמור מחוץ לתיקיות ברירת המחדל.נתונים לא יועברו. דורש הפעלה מחדש של SABnzbd!

השתמש בממיינים כדי לארגן באופן אוטומטי את ההורדות השלמות שלך. לדוגמה, שים את כל הפרקים מסדרה בתיקייה של עונה מסויימת.

ממיינים מנוסים לפי סדר הופעתם ויכולים להסתדר מחדש על ידי גרירה ושחרור.
הממיין הפעיל הראשון שתואם אל הקטגוריה המושפעת ואל סוג העבודה הוא זה שמוחל.

עוד אפשרויות זמינות כאשר האפשרות הגדרות מתקדמות מסומנת.
מידע מפורט נמצא בוויקי.

חלופהAPI (ללא תצורה)מפתח APIקוד QR של מפתח APIמפתח API שגוי, השתמש במפתח ה־API מתצורה->כללי בתוכנית הצד השלישי שלך:מפתח API חסר, אנא הכנס את מפתח ה־API מתצורה->כללי לתוך תוכנית הצד השלישי שלך:מפתח API עבור Prowlבטל עבודות שאינן יכולות להיות שלמותבטל בתר־עיבודהעבודה "%s" בוטלה בגלל קובץ RAR מוצפן (במקרה שסיסמאות סופקו, כולן נוסו)בוטל, לא יכול להיות שלםבוטל, הצפנה התגלתהבוטל, סיומת בלתי רצויה התגלתהקבלגישה נדחתהתאריך תפוגת חשבוןפעולהפעולה כאשר סיומת בלתי רצויה מתגלהפעולה כאשר קובץ RAR יורדפעולה כאשר סיומת בלתי רצויה מתגלההוסףהוסף NZBהוסף קבצי NZBהוסף תזמוןהוסף שרתהוסף ממייןNZB התווסףבנוסף, מנסה להגדיר את סיומת הקובץ הנכונה על סמך חתימת הקובץ אם הסיומת אינה נוכחת או חסרת משמעות.מוסיף בחינה מוודאת של הגודל המצוין, ממולא בנתונים אקראיים. יכול לשמש כדי לוודא ההגדרה שלךתיקייה מינהליתמתקדםקטגוריות מושפעותסוגי עבודה מושפעיםגילהכולכל הקבצים יעברו לתוך תיקייה יחידה.כל שמות המשתמש, הסיסמאות ומפתחות API מוסרים באופן אוטומטי מהיומן ומהעותק הכלול של ההגדרות שלך.התר שחרורים תקיניםגם שחרורי בחינהתמידהשתמש תמיד ברוחב של מסך מלאקניין כלשהואסימון יישוםאסימון יישום (דרוש)החל מסנניםארכיוןהאם אתה בטוח שאתה רוצה להסיר עבודות אלו?האם אתה בטוח שאתה רוצה לכבות את SABnzbd?האם אתה בטוח?טיעוניםמגבלת מטמון מאמריםזמינות מאמרמזהי מאמרלפחותלכל היותראימות נכשל, בדוק שם משתמש/סיסמה.המשך באופן אוטומטיהשהה באופן אוטומטי כששטח פנוי הוא מתחת לערך זה.
בבתים, יכול לבוא עם K,M,G,T. לדוגמה: "800M" או "8G"מיין עבודות בתור באופן אוטומטי כאשר עבודה חדשה מתווספת.מיין תור באופן אוטומטיהקודםגיבויתיקיית גיבוייםתגובה רעה מאת Pushbullet (%s): %sתגובה רעה מאת Pushover (%s): %sתזמון גרוע %s ב־%s:%sרוחב פסרשימה שחורהניסיון נחסם ליצור תיקייה %sתחתיתעייןעקוף גילוי שכפולים חכם אם PROPER, REAL או REPACK מתגלים בשם ההורדה.הטמן מאמרים בזיכרון כדי להפחית גישת דיסק.
בבתים, יכול לבוא עם K,M,G. לדוגמה: "64M" או "128M"ביטוללא ניתן להשיג גישה אל קובץ PID בשם %sלא ניתן לשנות הרשאות של %sלא ניתן להתחבר אל השרת %s [%s]לא ניתן ליצור קובץ גיבוי עבור %sלא ניתן ליצור את התיקייה %sלא ניתן ליצור תיקייה סופית %sלא ניתן ליצור קובץ זמני עבור %sלא ניתן למצוא תבניות דוא״ל ב־%sלא ניתן למצוא תבניות רשת: %s, מנסה תבנית תקניתלא היה ניתן להפעיל את הדפדפן, כנראה שהוא לא נמצאלא ניתן לקרוא את %sלא ניתן לקרוא את התיקייה המושגחת %sלא ניתן לשלוח, נתונים דרושים חסריםבלתי ניתן לכתוב שם ארוך של קובץ אל %s. זה עשוי לגרום לבעיות.בלתי ניתן לכתוב שם יוניקוד של קובץ אל %s. זה עשוי לגרום לבעיות.לא ניתן לכתוב במסד נתוני ההיסטוריה, בדוק זכויות גישה!לא ניתן לכתוב אל קובץ INI %sקטגוריותקטגוריהתיקיית קטגוריה אינה יכולה להיות תת־תיקייה של תיקיית ההורדות הזמניות.אי־התאמה בשם המארח של התעודה: שם המארח של השרת אינו כתוב בתעודה. זו סוגיית שרת.תעודה בלתי תקפה. קרוב לוודאי שזו סוגית שרת.וידוא תעודהשינויים לא נשמרו, ויאבדו.שינויים ידרשו הפעלה מחדש של SABnzbd!סמן הכלבדוק לפני הורדהבדוק אחר שחרור חדשבודקבודק קבצי תוספתמרווח בדיקה (בדקות, לפחות 15). אינו פעיל כשאתה משתמש במתזמן!בחר ערכת נושא.רשימת ניקויניקוי של %s נכשל.נקהנקה מוניםלחץ כדי לבחון את הפרטים שהוכנסו.סגירה של חלונות/לשוניות כלשהם/כלשהן לא תסגור את SABnzbd.פריסה צפופהתיקייה שלמהמהירות תיקיית שלמיםהושלםתיקיית הורדות שלמותתיקיית ההורדות השלמות %s נמצאת במערכת קבצים FAT שמגבילה גודל מרבי של קובץ אל 4 ג״בתצורהקובץ תצורההתצורה נעולה, אי אפשר לשמור הגדרותאשר מחיקות היסטוריהאשר מחיקות תורהתחברות אל %s@%s נכשלה, הודעה=%sחיבור מוצלח!חיבור נכשל!חיבוריםקובץ RAR פגוםלא היה ניתן להתחבר אל %s על פתחה %s. נראה כי %s פועל כשרת רשת (פתחה 80), כנראה מדדן, לא שרת Usenet. אתה חייב למלא שרת Usenet.(%s) לא היה ניתן לקבוע תוצאת חיבורלא היה ניתן לטעון תעודות נוספות מחבילת תעודותלא היה ניתן לשחזר גיבויצור גיבוי של קובץ התצורה ומסדי הנתונים בתיקיית הגיבויים.
אם תיקיית הגיבויים לא הוגדרה, הגיבוי ייווצר בתיקיית ההורדות שהושלמו.
גיבויים חוזרים יכולים להיות מתוצרים בדף התזמון.צור גיבויתזמונים נוכחייםפקודת umask נוכחית (%o) עשויה לדחות גישה מן SABnzbd אל הקבצים והתיקיות שהוא יוצר.מותאם אישיתכפוליומימסד נתוני היסטוריה פגום, תחליף ריק נוצרמיון תאריכיםתסדיר תאריךיום בחודשעשורכישלון מפענח: אין זיכרוןברירת מחדלכתובות Apprise ברירות מחדלתיקיית יסוד ברירת מחדלמחקמחק הכלמחק לאחר הורדהמחק את כל העבודות השלמותלמחוק את כל הפריטים מהתור?מחיקת %s נכשלה!אי־האפלהאי־האפלה תיקנה את הסיומת של %d קבציםבטל ערפול של שמות קובץ סופייםאי־האפלה שינתה שם של %d קבציםאי־האפלה דולגה עקב תיקיות DVD/Blu-rayגלה שכפולים על סמך ניתוח של שם הקובץ.גלה הורדות זהות על סמך שם או תכני NZB.התקןמכשיר אליו הודעה תישלחמכשיר(ים)מכשירים אליהם הודעה תישלחפריקה ישירהפריקה ישירה אופשרה באופן אוטומטי.השבת ניהול מכסהמושבתHTTPS הושבת בגלל קבצים בלתי תקפים של CERT ו־KEYHTTPS הושבת בגלל קבצים חסרים של CERT ו־KEYהשלךנתק את כל החיבורים הפעילים אל שרתי Usenet. חיבורים ייפתחו מחדש לאחר מספר שניות אם יש פריטים בתור.התנתק משרת(י) Usenet כאשר התור ריק או מושהה.התנתק בתור ריקהתראות דיסק מלאשגיאת דיסק ביצירת קובץ %sדיסק מלאדיסק מלא! מאלץ השהיהמהירות דיסקבצע וידוא נוסף שמבוסס על קבצי SFV.אין אימות תקף עבור ההזנה %sאל תשתמש בתיקייה בתוך תיקיית היישום כתיקיית התסריטים שלך, היא עשויה להתרוקן במהלך עדכונים.האם המכסה מתאפסת כל יום, שבוע או חודש?הורדההורדה הושלמההורדה נכשלההורד את כל קבצי par2הורדה נכשלה - לא בשרת(ים) שלךמהירות תיקיית הורדותהורדה עשויה להיכשל, רק %s מתוך %s דרושים זמיניםמהירות הורדה מוגבלת ע״יהוּרדירד תוך %s בממוצע של %s ב/שביצוע הורדה ימשיך באופן אוטומטי אם השטח הפנוי המזערי זמין שוב.
זה תקף על תיקיית ההורדות הזמניות ותיקיית ההורדות השלמות.
השטח נבדק כל כמה דקות.NZB כפוללדוגמהלדוגמה 8 או 20מוצפןשגיאה:ערוךערוך פרטי NZBדוא״להתראת דוא״ל בעת השלמת עבודהמקבל דוא״לשולח דוא״לתיקיית תבניות דוא״לכתובת דוא״ל לשלוח אליה את הדוא״ל.דוא״ל הצליחחירוםתפוגת חרוםניסיון חוזר חרוםריקקובץ NZB ריק %sכניסת RSS ריקה נמצאה (%s)אפשראפשר חילוץ 7zipאפשר התראות Appriseאפשר HTTPSאפשר את NotifyOSDאפשר התראות Prowlאפשר התראות Pushbulletאפשר התראות Pushoverאפשר בדיקות מבוססות SFVאפשר התראות Windowsאפשר מתן גישה אל הממשק מכתובת HTTPS.אפשר שינוי שם תיקייהאפשר עבור פחות שימוש בזיכרון. השבת כדי למנוע מעבודות איטיות לחסום את התור.אפשר תסריט התראותאפשר ניהול מכסהאפשר פריקה נסיגתיתמאופשרסיום הנתיב עם כוכבית * תמנע יצירת תיקיות עבודה.הכנס כתובתשם פרקמספר פרקשם.פרקשם_פרקשגיאהשגיאה "%s" בזמן הרצת file_join על %sשגיאה "%s" בזמן הרצת par2_repair על הערכה %sשגיאה "%s" בזמן הרצת rar_unpack על %sשגיאה %s בזמן הרצת par2_repair על הערכה %sשגיאה %s: אתה צריך לספק שם משתמש וסיסמה תקפים.כישלון ביצירה של מפתח ותעודה של SSLשגיאה ביבוא %sשגיאה בטעינת %s, קובץ פגום התגלהשגיאה בהסרת %sשגיאה בשינוי שם "%s" אל "%s"שגיאה בזמן הוספת %s, מסירשגיאה בזמן כיבוי מערכתשגיאה בלבדשגיאות/אזהרותפירקנים חיוניים חסרים, הורדה אינה יכולה להתחיל.מבוצע לאחר שהתור יסיים להוריד.מבצע תסריט מותאם אישיתצא מן SABnzbdסיומתגישת אינטרנט חיצוניתעדיפות תהליך חיצוניפרמטרי PAR2 נוספיםיותר עמודות היסטוריהיותר עמודות תורמחלץ…הכשל עבודה (העבר להיסטוריה)נכשלכניסה נכשלה עבור שרת %s [%s]כישלון בעשייה (%s)כישלון בהעברת %s אל %sכישלון באימות שרת הדוא״לכישלון בסגירת מסד נתונים, ראה יומןכישלון בסגירת חיבור דוא״לכישלון בליקוט ביטוי רגולרי עבור מונח חיפוש: %sכישלון בהתחברות אל שרת דוא״לכישלון בהתחברות: %s %s@%s:%s (%s)כישלון בחריפת מערכתכישלון ביבוא %s קבצים מן %sכישלון באתחול %s@%s עם סיבה: %sכישלון ביזימת חיבור TLSכישלון בהעברת קבציםכישלון בקריאת קובץ הסיסמה %sכישלון בשינוי שם %s אל %sכישלון בשינוי שם של קובץ דומה: %s אל %sכישלון באחזור RSS מן %s: %sכישלון בשליחת הודעת Appriseכישלון בשליחת הודעת Prowlכישלון בשליחת התראת Windowsכישלון בשליחת דוא״לכישלון בשליחת התראת macOSכישלון בשליחת התראת Apprise אחת או יותרכישלון בשליחת הודעת Pushbulletכישלון בשליחת הודעת Pushoverכישלון בהיכוננות מערכתכישלון בהתחלת ממשק רשתכישלון בהתחלת ממשק רשת: כישלון בהעלאת קובץ: %sמכשיל NZB כפול "%s"כישלון ב־tempfile.mkstempשגיאה חמורהשגיאה חמורה במצב שמירהשגיאה חמורה ב־Assemblerשגיאה גורלית במורידןהזנהמשוךמשוך NZB מכתובתמושךמושך %s גושים…מושך גושים נוספים…קובץ שמכיל את כל הסיסמאות שינוסו על קבצי RAR מוצפנים.איחוד קבצים של %s נכשלשם קובץ או נתיב אל תעודת HTTPS.שם קובץ או נתיב אל שרשרת HTTPS.שם קובץ או נתיב אל מפתח HTTPS.קובץ לא על השרתערכת קבציםשם קובץמסנןסנן החוצה קבצי דוגמית (לדוגמה, דוגמיות וידאו).תיקייה שמכילה תסריטי משתמש.תיקייה שמכילה תבניות דוא״ל מוגדרות־משתמש.תיקייה לניטור אחר קבצי nzb.תיקייה/נתיבתיקיותעבור דוא״ל מאומת, שם חשבון.עבור דוא״ל מאומת, סיסמה.עבור שרתים: וודא שהשמות תואמים עם Windows.עבור שרתים בלתי מהימנים, ייתקל בהתעלמות במקרה של כישלונותאילוץאלץ ניתוקאלץ הורדהמאלץ ניתוקפורוםשטח פנויתדירותיום שישימסדרה SxxEyyמן SxxEyyAPI מלאממשק רשת מלאעזרה נוספת יכולה להימצא בכלליחולל מפתח חדשחולל תעודה חתומה־עצמית ומפתח. דורש הפעלה מחדש של SABnzbd!אל Glitter יש מספר מאפיינים (חדשים) שאתה עשוי לאהוב!לך אל SABnzbdלך לאשףקניין GuessItGuessIt.PropertyGuessIt_Propertyפתחות של HTTP ו־HTTPS אינן יכולות להיות אותו דברתעודת HTTPSתעודות שרשרת של HTTPSמפתח HTTPSפתחת HTTPSוידוא תעודת HTTPSעזרהעזור לנו לתרגם את SABnzbd לעברית!
הוסף מלל לא מתורגם או שפר תרגומים קיימים כאן:חרוף מחשבתיקיות מוסתרותהסתר פרטיםהסתר/הראה קבצים שלמיםגבוהההיסטוריההעבר להיסטוריה 10 פריטים אחרוניםשימור היסטוריהמגבלת פריטי היסטוריההחזק את מקש Shift כדי לבחור טווחביתדף הביתמארחמארח אשר SABnzbd צריך להאזין אליו.כמה זמן או עד מתי תרצה להשהות? (באנגלית!)כמה שניות ההתראה שלך תמשיך להיות מנוסה שובכמה ניתן להוריד החודש (ק״ב/מ״ב/ג״ב)באיזו תדירות (בשניות) אותה ההתראה תישלחבלתי שלםפרמטרי IONiceכתובת IPv6גילוי הורדה זההמנוחהאם ריק, הפתחה התקנית תאזין רק אל HTTPS.אם שמות קבצים של קבצים (גדולים) בתיקייה הסופית נראים מעורפלים או חסרי משמעות, שמותיהם ישונו אל שם העבודה.אם רק קטגורית ברירת המחדל נבחרת, התראות מאופשרות עבור עבודות בכל הקטגוריות.אם המארח או הפתחה של SABnzbd חשופים לאינטרנט, ההגדרות הנוכחיות שלך מאפשרות גישה חיצונית מלאה אל ממשק SABnzbd.אם אתה מקבל את הודעת השגיאה הזו שוב, אנא נסה מספר שונה.
התעלם מדוגמיותהתעלם מתיקיות כלשהן בתוך ארכיוניםמתעלם מן NZB כפול "%s"בעבודה "%s" יש סיומת בלתי רצויה בתוך קובץ RAR. הקובץ הבלתי רצוי הוא %sבמקרה של "השהיה", תצטרך לקבוע סיסמה ולהמשיך את העבודה.במקרה של הפעלה מחדש של SABnzbd המסך ייעלם באופן אוטומטי!במקרה של כישלונות חיבור, תור ההורדות יושהה למשך כמה דקות במקום דילוג על השרת הזהבתיקיותהזנה בלתי תואמתקובץ תור בלתי תואם נמצא, לא יכול להמשיךתיקייה בלתי שלמהרצף בלתי שלם של קבצים ברי־איחודתיאור הזנת RSS לא נכון "%s"פרמטר שגויסיסמה מקודדת באופן שגוי %sהגבר ביצועים ע״י אילוץ חוזק הצפנת SSL חלש יותר.קטגוריות / קבוצות של מדדןמדדנים יכולים לספק קטגוריה בתוך NZB אשר SABnzbd ינסה להתאים לקטגוריות המוגדרות למטה. בנוסף, אתה יכול להוסיף תנאים אל "קטגוריות/קבוצות של מדדן" כדי להתאים עוד קטגוריות. השתמש בפסיקים כדי להפריד תנאים. תווים כללים נתמכים בתנאים.
עוד מידע יכול להימצא בוויקי.רוחב־פס אינטרנטקובץ NZB בלתי תקף %s, מדלג (שגיאה: %s)ארכיון בלתי תקף של גיבויקבצי par2 בלתי תקפים או פרמטרי PAR2 בלתי תקפים, לא ניתן לוודא או לתקןכתובת שרת בלתי תקפה.פרטי שרת בלתי תקפיםרישום של אירוע בלתי תקף בהיסטוריה עבור %sסוגיותמומלץ ללחוץ לחיצה ימנית וליצור סימנייה למיקום זה ולהשתמש בסימנייה זו כדי להשיג גישה אל SABnzbd כאשר הוא רץ ברקע.העבודה "%s" כנראה מוצפנת עקב RAR עם אותו השם בתוך RAR זההעבודה "%s" כנראה מוצפנת: "סיסמה" בשם הקובץ "%s"שם עבודה בתור שם קובץעבודה נכשלהעבודה הסתיימהעבודותעבודות יתחילו להיפרק במהלך ההורדה כדי להפחית זמן בתר־עיבוד. עובד רק עבור עבודות שאינן צריכות תיקון.אחד קבציםמאחדשמור את כל העבודותקיצורי דרך במקלדתשפההפעל דפדפן בהזנקהפעל את דפדפן ברירת המחדל בעת התחלת SABnzbd.הגבל מהירותרשימת סיומות קבצים של קבצים שצריכים להימחק לאחר הורדה.
לדוגמה: nfo או nfo, sfvצ'אט חיטועןטעינת %s נכשלהכתובת IPv4 מקומיתאחסון מקומי (עוגיות) מושבת בדפדפן שלך, הגדרות ממשק יאבדו לאחר שתסגור את הדפדפן!מיקום עבור מנהלן התור ומסד נתוני ההיסטוריה.
ניתן לשינוי רק כאשר התור ריק.מיקום של קבצי יומן עבור SABnzbd.
דורש הפעלה מחדש של SABnzbd!מיקום לאחסון הורדות שהסתיימו, מעבודות במלואן.
ניתן להשתלטות ע״י קטגוריות מוגדרות־משתמש.מיקום לאחסון הורדות בלתי מעובדות.
ניתן לשינוי רק כאשר התור ריק.מיקום שבו קבצי .nzb יאוחסנו.מיקום שבו הגיבויים של קובץ התצורה ומסדי הנתונים מאוחסנים.
אם נשאר ריק, הגיבוי ייווצר בתיקיית ההורדות שהושלמו.תיקיית יומןהתחברהתנתקרושם ביומןכניסה מיותר מדי כתובות IP שונות אל שרת %s [%s] - https://sabnzbd.org/multiple-adressesחיבור אל SABnzbd אבד…נמוכהרישיות קטנהעשה תואם Windowsתואםמהירות קו מרביתמספר מרבי של ניסיונות חוזרים לשרתניסיונות חוזרים מרבייםמשמעותמזערימזערי: כאשר SSL מאופשר, וודא את זהות השרת ע״י שימוש בתעודותיו. קפדני: וודא ואכוף שם מארח תואם.גודל מזערי של קובץשטח פנוי מזערי עבור תיקיית הורדות שלמותשטח פנוי מזערי עבור תיקיית הורדות זמניותמאמרים חסריםבינוניתדפדפנים חדישים ולקוחות אחרים לא יקבלו תעודות חתומות עצמית ויתנו אזהרה או לא יתחברו בכלל.יום שניחודשעודהעבר את כל העבודות השלמות אל הארכיוןהעבר ושנה שם את כל הפרקים בקטגוריה "טלוויזיה" אל תיקייה של סדרה מסויימתהעבר ושנה שם את כל הסרטים בקטגוריה "סרטים" אל תיקייה של סרט מסוייםהעבר עבודות אל הארכיון לאחר מספר מצוין של ימיםהעבר עבודות אל הארכיון אם ההיסטוריה חורגת ממספר מצוין של ימיםשם סרטמיון סרטיםשם.סרטשם_סרטסרטיםמעבירמעביר…רב־תפעוליםתווית מרובת־חלקיםמפתח NZBNZB התווסף לתורשםשם שרת / חיפוש DNSמתן שמותנתיב הרשת "%s" לא אמור להיות בשימוש כאןאף פעםהבאהסריקה הבאה במועדפרמטרי Niceאין גישהתבניות דוא״ל לא נמצאואין תיקיותאין קובץ rar קודם תואם עבור %sנמענים לא ניתנו, דוא״ל לא נשלחשיטת אימות הולמת לא נמצאהאיןרגילהבלתי תואםלא זמיןמרכז ההתראותתסריט התראותהתראה נשלחה!תסריט ההתראה "%s" אינו קייםהתראותNotifyOSDמספר שניות בין סריקות אחר קבצי nzb.סיסמת חשבון רשותיתשם משתמש רשותי של חשבוןכבויתור ישן התגלה, השתמש במעמד->תיקון כדי להמיר את התורבסיום תורתסריט בסיום תורבאיזה יום של החודש או השבוע (1=יום שני) ספק האינטרנט שלך מאפס את המכסה? (לא חובה עם שש:דד)כתובת Apprise אחת או יותר לא יכלו להיטען.השג מאמרים רק עבור ראש התוררק גישה חיצונית דורשת כניסהפרוק והרץ רק על עבודות שעברו את שלב הוידוא. אם מכובה, כל העבודות יסומנו כשלמות אפילו אם הן בלתי שלמות.פתח חלון מסוף והקלד את השורה (דוגמה):פתח תיקיית השלמהפתח תיקייהרשותיקובץ NZB משלים רשותיסיסמת אימות רשותיתשם משתמש רשותי של אימותציין באופן רשותי שם קובץאו גרור ושחרר קבצים בחלון!סידורשם מקורי של קובץשם עבודה מקוריעבודות יתומותאחר / בלתי ידועהודעות אחרותדרוס את כתובות ברירות המחדל עבור סוגי התראה מסויימים שמצויינים למטה, אם תרצה בכך.מפיץ %s דקותפרמטריםמספר חלקיסיסמהקובץ סיסמהסיסמאות מוסוות באמצעות ******, אנא הכנס מחדשמוגן בסיסמהנתיבדפוסמפתח דפוסהשהההשהה הכלהשהה הורדה במהלך בתר־עיבודהשהה למשךהשהה למשך שעההשהה למשך 15 דקותהשהה למשך 3 שעותהשהה למשך 30 דקותהשהה למשך 5 דקותהשהה למשך 6 שעותהשהה למשך…השהה עבודות עם עדיפות גבוהההשהה עבודות עם קטגוריההשהה עבודות עם עדיפות נמוכההשהה עבודות עם עדיפות רגילההשהה בתר־עיבודמושהההעבודה "%s" הושהתה בגלל קובץ RAR מוצפן (במקרה שסיסמאות סופקו, כולן נוסו)משהה הורדה בתחילת בתר־עיבוד וממשיך בסיום.משהה NZB כפול "%s"אחוז של מהירות קומחק לצמיתות (דלג על ארכיון)הרשאות עבור הורדות שלמותהגדרת הרשאות של %s עשויה לדחות גישה מן SABnzbd אל הקבצים והתיקיות שהוא יוצר.מפתח API אישימפתח API אישי עבור Prowl (דרוש)הערות אישיותאנא הייה מודע ששם המארח 0.0.0.0 יצטרך כתובת IPv6 לצורך גישה חיצוניתאנא הכנס את הפרטים של ספק Usenet העיקרי שלך.פתחהפתחה אשר SABnzbd צריך להאזין אליה.בתר־עיבוד נכשל עבור %s (%s)בתר־עיבודבצע בתר־עיבוד רק על עבודות שוודאובתר־עיבודבתר־עיבוד התחילבתר־עיבוד בוטלרשומות יושהו עד שהן לפחות בגיל זה. הגדרת עדיפות עבודה אל אילוץ תדלג על העיכוב.תסריט קדם־תור סומן כנכשלתסריט משתמש של קדם־תורקדם־קביעותלחץ על מקש התחל+R והקלד את השורה (דוגמה):הקודםעדיפותבעיה עםתוצאה מעובדתמעבדהתוכנית לא התחילה!עיכוב רביהProwlכתובת IPv4 ציבוריתנקה הורדות שלמותנקה הורדות כושלותנקה הורדות כושלות ומחק קבציםנקה היסטוריהטהר יומניםטהר הורדותטהר הורדות ומחק קבציםטהר הורדות בדף הנוכחיטהר תורPushbulletPushoverגרסת פייתוןלתסריט פייתון "%s" אין ערכת הרשאות ביצוע (+x)תורהוסף לתור 10 פריטים ראשוניםתור הסתייםמגבלת פריטי תורהתור אינו ריק, לא ניתן לשנות תיקייה.תקן תורבדוק זריז…בדיקה זריזההתחלה זריזהצאמכסהמכסה עבור חשבון זה, נספרת מהזמן שהיא הוגדרה. בבתים, יכולה לבוא עם K,M,G.
הזהר כאשר המכסה מגיעה אל 0, היא נבדקת כל כמה דקות.מכסה שנותרהתקופת מכסהמכסה נוצלה, משהה הורדהקבצי RAR נכשלו בוידואקבצי RAR וודאו בהצלחהRSSמרווח בדיקת RSSהזנת RSS %s הייתה ריקההריץ את %sאפשרויות אשר בשימוש לעיתים רחוקות. עבור משמעותן והסברן, לחץ על כפתור העזרה ולך אל דף הוויקי.
אל תשנה אותן ללא בדיקת הוויקי תחילה, מאחר שלכמה מהן יש תופעות לוואי רציניות.
ערכי ברירת המחדל הם בין הסוגריים.קרא את כל ההזנות כעתקרא הזנהקרא הזנות RSSקרא את כל הזנות RSSקרא את עזרת וויקי על זה!חריגת DBus התקבלה %sרענןקצב רענוןחיבור מסורב מאת:חיבור מסורב עם שם המארח "%s" מאת:סרבתיקיות קרובות משפחה מבוססות עלנותרזכור אותיהסר NZBהסר NZB ומחק קבציםהסר שרתהסר ממייןהסר את כל הקבצים הנבחריםהסר עבודות נשלמותהסר עבודות נכשלותהסרת %s נכשלהמסיר עבודהמסיר עבודותשנה שםשינוי השם של העבודה יבטל פריקה ישירה.תקןתיקון נכשל, אין מספיק גושי תיקון (%s קצר)מתקןתיקון נכשל, %sמתקן…חזור על בחינההחלף רווחים בשמות תיקיותהחלף נקודות בשמות תיקיותהחלף נקודות ברווחים בשמות תיקיות.החלף רווחים בקווים תחתונים בשמות תיקיות.החלף קווים תחתונים בשמות תיקייההחלף קווים תחתונים בנקודות בשמות תיקייהדרושדורשדורש חשבון Prowlדורש חשבון Pushbulletדורש חשבון PushoverRequiresCatאפסאפס מכסה כעתיום איפוספותר כתובתהפעל מחדשהפעל מחדש את SABnzbdהפעל מחדש ללא כניסהמפעיל מחדש את SABnzbd…מפעיל מחדש בגלל אסמבלר שקרסמפעיל מחדש בגלל מורידן שקרסמפעיל מחדש בגלל בתר־מעבד שקרסשחזר ברירות מחדלשחזר גיבויתוצאההמשךהמשך עבודות עם עדיפות גבוהההמשך עבודות עם קטגוריההמשך עבודות עם עדיפות נמוכההמשך עבודות עם עדיפות רגילההמשך בתר־עיבודממשיךזמן שימורנסה שובנסה שוב הכלנסה שוב את כל העבודות הנכשלותמריץ תסריטמריץ תסריט…מריץ תסריט משתמש %sSABCTools מושבת: גרסה נכונה לא נמצאה! (%s נמצאה, מצפה אל %s)SABnzbd %s התחילמארח SABnzbdסיסמת SABnzbdפתחת SABnzbdאשף התחלה זריזה של SABnzbdשם משתמש SABnzbdגרסת SABnzbdשרת רשת SABnzbdSABnzbd גילה שגיאה חמורה:כיבוי SABnzbd הסתייםSABnzbd הותחל עם קידוד %s, הוא אמור להיות UTF-8. צפה לבעיות עם שמות Unicoded של קבצים וסיפריות בהורדות.SABnzbd ירוץ כעת ברקע.שרת SMTPייפוי כוח SOCKS5פקודת SQL נכשלה, ראה יומןSSLצפני SSLשבתשמורשמור שינוייםשמירת %s נכשלהשומר…סרוק תיקייה מושגחתתזמן עבור שרת בלתי קיים %sתזמוןתסריטקוד יציאת תסריט הוא %sתסריט החזיר קוד יציאה %s ופלט "%s"תסריטיםתיקיית תסריטיםחיפושמספר עונהתיקיית עונהחיבור מאובטח לשרתאבטחהבחר מצב וכתוב את כל הסיומות הבלתי רצויות. לדוגמה: exe או exe, comבחר שפת ממשק רשת.בחר רק אם הספק שלך מתיר חיבורי SSL.טווח נתונים נבחרהתראות שליחת RSSשלח חזרה לתורשלח דוא״ל כאשר הזנת RSS מוסיפה עבודות לתור.שלח דוא״ל כשהדיסק מלא ו־SABnzbd מושהה.שלח התראות ע״י שימוש בשירות Apprise אל כמעט כל שירות התראות%s נשלח לתורהפרד כתובות רבות ע״י פסיקסדרותמיון סדרותסדרות עם תאריכי שידורשרתהשרת %s השתמש במכסה המצויינתהשרת %s יפוג עוד %s ימיםהשרת %s משתמש בתעודת HTTPS בלתי מהימנההשרת %s משתמש בתעודה בלתי מהימנה [%s]השרת %s ייתקל בהתעלמות למשך %s דקותפרטי שרתכתובת השרת "%s:%s" אינה תקפה.כתובת שרת דרושההשרת לא היה יכול להשלים בקשהתיאור שרתשם השרת אינו פותר.השרת דורש שם משתמש וסיסמהשגיאת צד שרת (קוד שרת %s); לא היה ניתן להשיג את %s על %sשרתיםקבע דפוס הרשאות עבור קבצים ותיקיות שלמים.
בסימון אוקטלי. לדוגמה: "755" או "777"קבע את השרת של ספק האינטרנט שלך עבור דוא״ל יוצא.ההתקנה שלמה כעת!Shift+מקש חץ: עיין בתור ובדפי היסטוריההאם ההורדה תמשיך לאחר שהמכסה תתאפס?הראה הכלהראה ארכיוןהראה נכשליםהראה יומןשם סדרההראה חיבורים פעיליםהראה פרטיםתיקיית סדרההראה ממשקשם.סדרהשם_סדרהכבהכבה מחשבכבה את SABnzbdמכבהאות %s נתפס, שומר ויוצא…גודלגילוי שכפולים חכםמספר קבצים נכשלו בוידוא מול "%s"סליחה, לא יכולנו לפרש את זה. נסה שוב.מחרוזת מיוןמיין לפי % ירד הכי הרבה→הכי מעטמיין לפי גיל הישן ביותר←החדש ביותרמיין לפי גיל החדש ביותר←הישן ביותרמיין לפי שם א←תמיין לפי שם ת←אמיין לפי גודל הגדול ביותר←הקטן ביותרמיין לפי גודל הקטן ביותר←הגדול ביותרמיוןמקורמיוחדמהירותהאץ תיקונים ע״י התקנת par2cmdline-turbo, הוא זמין עבור פלטפורמות רבות.מגבלת מהירותהיכון מחשבהתחל אשףמתחיל תיקוןהזנק/כיבוימעמדאפשרויות של מעמד וממשקעצירהעוצר…קפדניהגשיום ראשוןתמוך במיזם, תרום!הורדה חשודה במורידןמתגיםתיקיות מערכתביצועי מערכת (Pystone)טעינת מערכתTEXTגדול מדיפריסה בלשוניות
(תור והיסטוריה נפרדים)הצמד תג לעבודהתיקייה זמניתתיקיית הורדות זמניותבחן נתוניםבחן דוא״לבחן התראהבחן שרתבחן הורדהבוחן פרטי שרת…הכפתור "תקן" יפעיל מחדש את SABnzbd ויעשה בנייה מחדש
מלאה של תוכן התור, תוך שימור קבצים שהורדו כבר.
זה ישנה את סדר התור.תיקיית ההורדות השלמות אינה יכולה להיות אותה תיקייה או תת־תיקייה של תיקיית ההורדות הזמניותתיבת הסימון ליד שם ההזנה צריכה להיות מסומנת כדי שההזנה תהיה מאופשרת ותסומן באופן אוטומטי עבור פריטים חדשים.
כאשר הזנה מתווספת, היא תאסוף רק פריטים חדשים ולא שום דבר שנמצא כבר בהזנת ה־RSS אלא אם תלחץ "אלץ הורדה".שם המארח לא נקבע.מספר החיבורים המותרים ע״י הספק שלךהתור ימוין כל 30 שניות אם האפשרות % ירד נבחרה.השרת לא הגיב כראוי לברכת השלוםאין שרתים פעילים!אין חיבורים שנקבעו. אנא קבע לפחות חיבור אחד.יש עבודות יתומות בתיקיית ההורדות.
אתה יכול לבחור למחוק אותן (כולל קבצים) או לשלוח אותן חזרה לתור.מפתח זה יתיר לתוכניות צד שלישי להוסיף קבצי NZB אל SABnzbd.מפתח זה יתן לתוכניות צד שלישי גישה מלאה אל SABnzbd.החודש הזהזה מונע הרצות תיקון מרובות ע״י הורדת כל קבצי par2 בעת הצורך.שרת זה אינו מתיר SSL על פתחה זוהשבוע הזה.SABnzbd זה יפעיל מחדש את
השתמש בזה כשאתה חושב שלתוכנית יש בעית יציבות.
הורדה תושהה לפני ההפעלה מחדש ותומשך לאחר מכן.זה ישלח דוא״ל בדיקה אל החשבון שלך.יום חמישיאזל הזמןפסק זמן חלף: נסה לאפשר SSL או להתחבר על פתחה שונה.פסק זמןכותרכדי למנוע את כל האזהרות המועילות, השבת את ההגדרה המיוחדת 'helpful_warnings'.אל: %s מאת: %s תאריך: %s נושא: SABnzbd מדווח על דיסק מלא היי, SABnzbd הפסיק להוריד, מאחר שהדיסק כמעט מלא. אנא פנה מקום והמשך את SABnzbd באופן ידני. היוםשטח דיסק קטן מדי, מאלץ השהיהיותר מדי חיבורים לשרת %s [%s]יותר מדי חיבורים, אנא השהה הורדה או נסה שוב מאוחר יותרראשסה״כפתור בעיותנסה לחזות השלמה מוצלחת לפני הורדה ממשית (איטי יותר!)מנסה 7zip עם הסיסמה "%s"מנסה משנה שם של RARמנסה וידוא מבוסס RARמנסה וידוא SFVמנסה למשוך קובץ NZB מן %sמנסה לקבוע מעמד של שרת בלתי קיים %sמנסה לחלץ עם הסיסמה "%s"יום שלישיכוונוןסוגבלתי רצוימשיכת כתובת נכשלה; %sתופס כתובות קרסלא היה ניתן לקשר את פתחה %s על %s. איזשהי תוכנה אחרת משתמשת בפתחה או SABnzbd כבר רץ.גישה בלתי מורשתבטל חסימהשרת בלתי מוגדר!שגיאה בלתי ידועה בעת פענוח %sפרוטוקול SSL בלתי ידוע: נסה להשבית SSL או להתחבר על פתחה שונה.פעולה בלתי ידועה: %sכישלון בלתי ידוע של אימות בשרת דוא״לפרוקפרוק ארכיונים (rar, zip, 7z) בתוך ארכיונים.פריקת קינון ארוכה מדי [%s]%s קבצים/תיקיות נפרקו תוך %sפורקפריקה נכשלה, %sפריקה נכשלה, שגיאת CRCפריקה נכשלה, ארכיון דורש סיסמהפריקה נכשלה, קובץ גדול מדי עבור מערכת הקבצים (FAT?)פריקה נכשלה, נתיב ארוך מדיפריקה נכשלה, לא היה ניתן למצוא את %sפריקה נכשלה, שגיאת כתיבה או דיסק מלא?ניסיון כניסה בלתי מוצלח מן %sקובץ NZB בלתי שמישקובץ RAR בלתי שמישסיומת בלתי רצויה בקובץ %s (%s)סיומת בלתי רצויה בקובץ rar %sסיומות בלתי רצויותעדכון זמין!העלה NZBמעלהזמן פעולההשתמש במיון כדי לארגן ולשנות שם באופן אוטומטי את ההורדות השלמות שלך.השתמש בפסיק, ברווח או בשניהם כדי לזהות יותר מכתובת אחת.השתמש בהגדרות ממשק עולמיותהשתמש בשמות זמניים במהלך בתר־עיבוד. השבת כאשר המערכת שלך אינה מתמודדת עם זה כראוי.השתמש בייפוי הכוח SOCKS5 המצוין עבור כל החיבורים היוצאים.בשימוש לפני ש־NZB נכנס לתור.מטמון בשימושתיקיות משתמשמפתח משתמשמפתח משתמש (דרוש)משתמש התחברמשתמש התחבר לממשק הרשתתסריט משתמש יכול לדגל עבודה כנכשלהשם משתמשערכיםוודא בהצלחה ע״י שימוש בקבצי SFVוודא תעודות בעת התחברות אל מדדנים ומקורות RSS ע״י שימוש ב־HTTPS.מוודאמוודא תיקוןמוודא…גרסהנמוכה מאודהצג יומן תסריטיםהמתן %s שניותאזהרה:ממתיןהזהר 5 ימים טרם תאריך תפוגת החשבון.אזהרהאזהרותתיקייה מושגחתמהירות סריקה של תיקייה מושגחתממשק רשתערכת נושא של ממשק רשתיום רביעיכאשר במהלך הורדה מתבהר שיותר מדי נתונים חסרים, בטל את העבודהכאשר תסריט המשתמש מחזיר קוד יציאה בלתי אפסי, העבודה תדוגל כנכשלה.כשאתה מנסה שוב עבודה, העבודות 'גילוי שכפולים' ו'בטל עבודות שאינן יכולות להיות שלמות' מושבתות.כאשר כתובת ה־IP שלך משתנה או כאשר SABnzbd מופעל מחדש, השיח יפוג.איזה אחוז ממהירות הקו צריך SABnzbd להשתמש, למשל 50איזה תסריט עלינו לבצע עבור התראות?רשימה לבנהמי עלינו לומר ששלח את הדוא״ל?וויקילא יעבוד אם תיקיית קטגוריה נמצאת בדיסק שונה.התראות Windowsשנהאתה יכול להגדיר זכויות גישה עבור מערכות מחוץ אל הרשת המקומית שלך.אתה חייב לקבוע רוחב פס מרבי לפני שאתה קובע מגבלת רוחב פסגרסת UNRAR שלך היא %s, אנחנו ממליצים על גרסה %s או גבוהה יותר.
קובץ הסיסמאות שלך מכיל יותר מ־30 סיסמאות, בחינת כל הסיסמאות האלו תיקח זמן רב. נסה לכתוב רק סיסמאות שימושיות.מפתח Pushbullet API האישי שלך (דרוש)[%s] שגיאה "%s" בזמן איחוד קבצים[%s] שגיאה "%s" בזמן פריקת קבצי RAR[%s] %s קבצים אוחדו[%s] אין ערכות par2[%s] PAR2 קיבל אפשרויות שגויות, בדוק את הגדרות תצורה->מתגים שלך[%s] בדיקה זריזה בסדר[%s] וידוא מבוסס RAR נכשל: %s[%s] תוקנו ב־%s[%s] הפקודה ב־build_command אינה מוגדרת.[%s] וודאו ב־%s, כל הקבצים נכונים[%s] וודאו ב־%s, תיקון דרושמאמריםמותאם־רישיותייוםימיםהשבת שרתאפשר שרתקובץששעהשעותנותרדידנידקהדקותכבויפועלאודףpar2 בינארי… לא נמצא!קנייןשניהשניותראה קובץ יומןtextunrar בינארי… לא נמצא!שבוע././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.0514262 SABnzbd-4.3.2/locale/da/LC_MESSAGES/SABnzbd.mo0000644000000000000000000017556214625637243017473 0ustar00runnerstaff[5o5d=67 89:';;; ;<$<D<L<S<[<c<k<1~<<A< =?====R=[K>>#>V>4?Q?$n?? ??'?'??@ @ @ '@ 2@<@R@[@o@s@'w@@@@@@ @* A 7A EAOAcAvAA/A AAGBLB%SB#yBB BBBBOCVC vC CCCC!D62D-iDDD"D6DE :EEENE.gE'E EEEEESF fFsFFF"F8FF GG /G9GSG ZGfGG#GGG GG*H.H@H GHQH3WH H H HHHHHH HI IqMq\qaq gq rq qqqqqq rrs s!s0sCs_s gsts{s s s ss ssst%t 8t EtStZt2at tt t ttt)u0.u_uhuuu uuu uuuvv'v=vNvUv\vvvvvvvvv vww)w;wHRww ww wwwxx(xHxbx.x yy:y >yJySy Xyeyvyy#y yyy,y zz$z +z9zUz ^z4zzz3z3{F{!W{y{{-{,{({|$"|G|!_|||&|:|}o})}}3}~ ~ ~ "~,~ D~Q~ `~ j~t~ }~~ ~'~~(~.~ --9-g$$11CKRZ ` k vȀ ̀ـ '0?\ a/k  Ɂԁ ˂̃25AN>=T M+ !,Ɔ >EMS" &0AW E3K.gʼnʉӉ,JL-؊/ߊ, LVk-6"#.3"b$Ό  b.$ ΍׍#"AJ%QLw Ď Ύێ !*9 S aRkUM=b0!ѐEBY+#ȑ)+J=&Ò&ג'& /=?CH Wejlqw|~ Óϓԓ\qPi•,0M>*9d{#%ԛ  !*5<r<ʜFS \ҝ]/&_ɞ)E"e )(ҟ "5 DR fp,נ  &' N \g<'%Ţ % .%"+!E g%@4$"6(YEȥ . '< dn V <@.P@ ϧݧ "5Q(h ͨ#ި )51g v "ө ة *"0 S(] 6A,"E!h /'۫9 =H^s.BԬ( GRW itz(ϭޭ( =KO^| !Ү.2Md2 OMY Ű Ұ߰(( )6)`=/ȱ!*E*^( Ͳ ڲ" ":S i!v /Գ%&,@-m8)Դ).(:W1ĵ*ܵ#+/I!y,*ȶ+$?d{ طݷ \$#'"͸#(190@%q9(ѹ ./?8oJ&8> NX_ oz$ûGֻ0O_+n ļ ѼܼŽʽӽ/@ EO"U@x4  2"FU-߿:J7F,*$!Oq< T.OT~" &0  "392Wn 9MeK6xVR oy!"!9A1I{     5AH O ]j )* +?&S z * @<nR# 29MUm(   / B L Vb-r ' ) ;I[ l z ^Or'"+7cYv1''O%_,4ax- !'>T"j  7FJ eq) 4!Suy  !3:Yi r| "*?3 s} ),GOf    8AJh   7DS]i  )<L^~{" 5 Ab fqy}( .D LZ _l 53:K#1//4d's)+62ilp*5(^ ft|  ' 8(C3l55**H;s;   $ <H [i$p  $*,3 `k}   /-@5vKBE d- (2-"A* lw}@)F/pG J#Nr:$) 1;@Ify!O#$7\)b"2@C**4/HZz 'j&U | ". *,3e`   " +5'Fn~NaI6?/"/X3E.&+(ToV,(3*\   29 BLRn SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAdvancedAffected CategoriesAgeAllAll files will go into a single folder.Allow proper releasesAlso test releasesAlwaysApplication TokenApplication token (required)Apply filtersAre you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCertificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sDuplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExecutes a custom scriptExit SABnzbdExtensionExternal internet accessExternal process priorityExtra PAR2 ParametersExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Invalid NZB file %s, skipping (error: %s)Invalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job Name as FilenameJob failedJob finishedJobsJoin filesJoiningKeep all jobsLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLog inLog outLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie SortingMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly external access requires loginOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOriginal Job NameOrphaned jobsOther MessagesPROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restore DefaultsResultResumeResume high priority jobsResume jobs with categoryResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSecure connection to serverSecuritySelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeperate multiple URLs by a commaSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETabbed layout
(separate queue and history)Tag jobTemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTest downloadTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: da Plural-Forms: nplurals=2; plural=(n != 1); SABnzbd kan ikke finde sin webgrænseflade filer i %s.
Venligst installer programmet igen.

SABnzbd har fundet gemt data fra en anden SABnzbd version
men kan ikke genbruge dataene fra det andet program.

Du ønsker måske at afslutte din kø først med det andet program.

Efter dette, start programmet med "- rene" valgmulighede.
Dette vil slette den nu værende kø og historik!
SABnzbd læser filen "%s". SABnzbd opdagede, at filen sqlite3.dll mangler .

Nogle dårligt designet virus-scannere fjernede denne fil .
Tjek venligst din virus-scanner, du kan prøve at geninstallere SABnzbd og klage til din virus-scanner leverandør .

SABnzbd har brug for en ledig TCP-/IP-port til sine interne webserver.
Port %s på %s blev forsøgt, men den er ikke til rådighed .
Nogle andre programmer bruger porten eller SABnzbd kører allerede.

Genstart venligst SABnzbd med et andet portnummer. SABnzbd har brug for en gyldig vært adresse til intern webserver .
Du har angivet en ugyldig adresse.
Sikkert valg er localhost og 0.0.0.0

Venligst genstart SABnzbd med en gyldig host adresse. SABnzbd kommer med ABSOLUT INGEN GARANTI. Det er gratis software, og du er velkommen til at videredistribuere det under visse betingelser. Den er licenseret under GNU General Public License version 2 eller (efter eget valg) enhver senere version. %s artikler havde ikke-matchende dubletter%s artikler misdannede%s artikler manglede%s mappe: %s adgang mislykkedes%s er ikke et korrekt ciffer værdi%s er ikke en godkendt e-mail adresse+ Fejlfinding+ Info+Slette+Reparere+Udpakke.nzb Backup mappe0 er højeste prioritet, 100 er den laveste prioritet7za binær... IKKE fundet!
Hvis godkendelse er aktiveret, skal du logge ind igen.OBS: Mapper vil blive oprettet automatisk, når du gemmer. Du kan bruge absolutte stier til at gemme uden for standardmapperne.Data vil ikke blive flyttet. Kræver SABnzbd genstartet!API (ingen konfiguration)API-nøgleAPI nøgle QR kodeForkert API-nøgle, anvend api-nøglen fra Konfiguration->Generelt i dit tredjepartsprogram:API-nøgle mangler, indtast api-nøglen fra Konfiguration->Generelt i dit tredjepartsprogram:API nøgle for ProwlAfbryd job, der ikke kan færdiggøresAfbrudt job "%s" på grund af krypterede RAR fil (hvis oplyst, alle adgangskoder blev forsøgt)Afbrudt, kan ikke afsluttesAfbrudt, kryptering registreretAfbrudt, uønsket extension fundetAcceptereAdgang nægtetUdførHandling når krypteret RAR er downloadetAktion når uønsket extension er fundetTilføjTilføj NZBTilføj NZB filer Opret planlægningTilføj serverTilføjet NZBAdministrativ mappeAvanceretPåvirkede KategorierAlderAlleAlle filer vil ligges ind i en enkelt mappe.Tillad reelle udgivelserTest også udgivelserAltidProgram tokenProgram token (krævet)Anvend filtreEr du sikker på du vil lukke SABnzbd?Er du sikker?ArgumenterCache størrelse af artiklerArtikel identifikatorMindstHøjstGodkendelse mislykkedes, kontrollere brugernavn/adgangskode.Automatisk genoptagAuto-pause, når ledig plads kommer under denne værdi.
I bytes, evt. efterfulgt af K, M, G, T. For eksempel: '800M 'eller '8 G'TilbageSikkerhedskopiDårlig respons fra pushbullet (%s): %sDårlig respons fra pushover (%s): %sForkert tidsplan %s ved %s:%sBåndbreddeBundenGennemseCache artikler i hukommelsen for at reducere diskadgang.
I bytes, efterfulgt af K,M,G. For eksempel: "64M" eller "128M"AnnullérDet lykkedes ikke at ændre rettigheder på %sKan ikke tilslutte til server %s [%s]Kan ikke oprette backup fil for %sKan ikke oprette mappe %sKan ikke oprette endelig mappe %sKan ikke oprette temp fil for %sKan ikke finde e-mail skabeloner i %sKan ikke finde webskabeloner: %s, forsøger med standardskabelonKan ikke starte browseren, sandsynligvis ikke fundetKan ikke læse %sKan ikke læse overvåget mappe %sKan ikke sende, mangler nødvendige dataKan ikke skrive til historik database, kontroller adgangsrettigheder!Kan ikke skrive til INI fil %sKategorierKategoriCertifikatkontrolÆndringerne er ikke gemt og vil blive mistet.Ændringer kræver genstart af SABnzbd!Tjek alleTjek før downloadKontroller for ny versionKontrollererTjekker ekstra filerKontrol af interval (i minutter, i hvert fald 15). Ikke aktiv, når du bruger skemaer!Ryd listenFjernelse af %s mislykkedes.RydNulstil tællerKlik for at teste de indtastede informationer.Lukning af alle browservinduer/faneblade vil ikke lukke SABnzbd.Kompakt layoutFærdig mappeKomplet mappe hastighedFærdigFærdig download mappeKonfigurationKonfigurations filBekræft Historik-fjernelseBekræft Kø-fjernelseForbindelse %s@%s mislykkedes, besked %sTilslutning lykkedes!Tilslutning mislykkedes!ForbindelserØdelagt RAR filDet lykkedes ikke at tilslutte (%s)Aktuel planlægningTilpasseDUPLIKEREDagligtBeskadigede historik database, skabte tom udskiftningDato sorteringDatoformatMånedsdagÅrtiDekoder fejl: Ikke mere hukommelseStandardStandard Base FolderSletFjern alleFjern efter downloadFjern alt fra køen?Fjernelse af %s mislykkedes!EnhedEnhed som meddelse skal sendes tilEnhed(er)Enhed(er) som meddelelse skal sendes tilDeaktivere kvota styringDeaktiveretHTTPS fejlede på grund af manglende CERT og KEY filerKassérAfbryd fra usenet-serverne når køen er tom eller sat på pause.Afbryd når køen er tomPåmindelse når harddisk er fyldtDiskfejl ved oprettelse af fil %sDisk fuldDisken er fuld! PauserUdfør en ekstra kontrol baseret på SFV-filer.Har ikke gyldig godkendelse til feed %sBliver kvota nulstillet hver dag, uge ​​eller måned?DownloaderOverførsel fuldførtDownload mislykkedesDownload alle par2 filerDownload mislykkedes - ikke på din server (e)Download mappe hastighedOverførslen kan mislykkes, kun %s af det krævede %s tilgængeligHentetHentede i %s med et gennemsnit på %sB/sDublet NZBEks.F.eks. 8 eller 20KRYPTEREDEFEJL:Ændre NZB detaljerE-mailE-mail påmindelse når job er fuldførtE-mail modtagereE-mail sendereE-mail-mappe skabelonerE-mail adresse hvor den skal sendes til.E-mail afsendelse mislykkedesNødsituationTomTom NZB fil %sTom RSS post blev fundet (%s)AktivereAktivere 7zipHTTPS AktiveringAktiver NotifyOSDAktivere Prowl notifikationAktiver Pushbullet notifikationerAktivere Pushover anmeldelserAktiver SFV-baseret kontrolAktiver Windows notifikationerAktiver adgang til interface fra en HTTPS-adresse.Aktiver mappe omdøbningAktiver til mindre brug af hukommelse. Deaktiver for at forhindre langsom job fra at blokerer køen.Aktivere notification scriptAktivere kvota styringAktivere rekursive udpakningAktiveretSlutter stien med en stjerne *, vil forhindre oprettelse af ​​job mapper.URLEpisodenavnEpisodenummerEpisode.NavnEpisode_NavnFejlFejl "%s" når du køre file_join på %sFejl "%s" mens par2_repair kørte på %sFejl "%s" når du køre rar_unpack på %sFejl %s når du kører par2_repair på %sFejl %s: Du skal angive et gyldigt brugernavn og adgangskode.Fejl ved oprettelse af SSL-nøgle og certifikatDet lykkedes ikke at importere %sDownloadnings fejl %s, ødelagt fil fundetFejl ved fjernelse af %sDet lykkedes ikke at omdøbe "%s" til "%s"Det lykkedes ikke at tilføje %s, sletteFejl ved lukning af systemKun ved fejlFejl/AdvarselUdfører et brugerdefineret scriptAfslut SABnzbdEndelseEksterne internetadgangEkstern proces prioritetEkstra PAR2 parameterUdpakning...Mislykkes job (flyt til historik)MislykkedesDet lykkedes ikke at logge på serveren %s [%s]Oprettelse af (%s) mislykkedesDet lykkedes ikke at flytte %s til %sGodkendelse til mailserver mislykkedesDet lykkedes ikke at lukke databasen, se logDet lykkedes ikke at lukke e-mail tilslutningDet lykkedes ikke at kompilere regex for søgestreng: %sDet lykkedes ikke at tilslutte mailserverDet lykkedes ikke systemet at gå i dvaleDet lykkedes ikke at importere %s filer fra %sDet lykkedes ikke at initialisere %s@%s med begrundelse %sDet lykkedes ikke at initialisere TLS tilslutningKunne ikke flytte filerKunne ikke omdøbe lignende fil: %s til %sMislykkedes at hente RSS fra %s: %sKunne ikke sende Prowl beskedDet lykkedes ikke at sende Windows notificationDet lykkedes ikke at sende e-mailDet lykkedes ikke at sende pushbullet beskedDet lykkedes ikke at sende pushover beskedDet lykkedes ikke systemet at gå i standbyKunne ikke starte web-interfaceKunne ikke starte web-grænseflade: Fejler dublet NZB "%s"Fejl i tempfile.mkstempAlvorlig fejlFatal fejl ved lagring af stateFatal fejl i AssemblerFeedHentHent NZB fra URLHenterHenter %s block...Henter ekstra block...Fil, der indeholder alle adgangskoder. Vil blive brugt på adgangskode beskyttede RAR filer.Filsammenlægning af %s mislykkedesFilnavn eller sti til HTTPS Certifikat.Filnavn eller sti til HTTPS kæde.Filnavn eller sti til HTTPS Nøgle.Fil ikke på serverFil sætFilnavnFilterFiltrerer prøve filer (f.eks. video eksempler).Mappe, der indeholder bruger-scripts.Mappe, der indeholder brugerdefinerede e-mail-skabeloner.Mappe til at gennemsøge for .nzb filer.Mappe/SøgestiMapperBrugernavn for e-mail som kræver godkendelse.Adgangskode for e-mail som kræver godkendelse.For servere: Kontroller navne er kompatibel med Windows.For upålidelige servere, vil blive ignoreret længere i tilfælde af fejlTvingeGennemtving afbrydelseGennemtving downloadTvinge afbrydelseForumLedig diskpladsForekomstFredagFra Show SxxEyyFra SxxEyyFuld APIFuld webinterfaceØvrig hjælp kan du finde på voresGenereltGenerere Ny NøgleGenerer ny selvsigneret certifikat og nøgle. Kræver SABnzbd genstart!Glitter har nogle (nye) egenskaber, du kan lide!Gå til SABnzbdGå til guidenHTTP og HTTPS porte kan ikke være de sammeHTTPS CertifikatHTTPS kæde certifikaterHTTPS NøgleHTTPS Portverifikation HTTPS certifikatHjælpHjælp os med at oversætte SABnzbd på dit sprog!
Tilføj uoversatte tekster eller forbedrede eksisterende oversættelser her:Sæt computer i dvaleSkjul detaljerSkjul/vis komplette filerHøjHistorikHistorik (de 10 seneste poster)Historik elementbegrænsningHold Skiftetasten nede for at vælge et områdeHjemStartsideVærtAdresse som SABnzbd ska lytte på.Hvor længe eller indtil hvornår du vil standse? (på engelsk!)Hvor meget der kan downloades i denne måned (K/M/G)UFULDSTÆNDIGIONice parametreIPv6 adresseInaktivHvis tom, vil standard-porten kun lytte til HTTPS.Hvis du får denne fejlmeddelelse igen, prøv et andet portnummer.
Ignorer Sample-filerIgnorere hvilken som helst mappe indeni arkivIgnorerer identiske NZB "%s"I "%s" uønsket extension i RAR fil. Uønsket fil er "%s" I tilfælde af "Pause", skal du angive en adgangskode og genoptage jobbet.I tilfælde af SABnzbd genstart vil denne skærm forsvinde automatisk!I mappeInkompatibel feedØdelagt kø-fil fundet, kan ikke fortsætteUfuldstændig mappeUfuldstændig sekvens af filsammenlægningForkert RSS-feed beskrivelse "%s"Fejl parameterForkert kodet adgangskode%sØge ydeevnen ved at tvinge en lavere SSL-kryptering styrke.Indekseringen kategorier/grupperIndeksatorer kan levere en kategori inde NZB som SABnzbd vil forsøge at matche de kategorier defineret nedenfor. Derudover kan du føje betingelser til ' indekseringen kategorier/grupper til at matche flere kategorier. Brug kommaer til at adskille vilkår. Jokertegn i vilkårene er understøttet.
Der findes mere information i wikien.Ødelagt NZB fil %s, springer over (årsag=%s)Invalide par2 filer eller invalide PAR2 parametre, kan ikke bekræfte eller reparereUgyldig server adresse.Ugyldige serverdetaljerForkert logning i historiken av %sProblemerDet anbefales, at du højreklikker og bogmærker denne placering, og bruger dette bogmærke for at få adgang SABnzbd, når det kører i baggrunden.Job Navn som FilnavnJobbet misllykedesJob afsluttetJobsSammenlægger filerSammenlæggerBehold alle jobsSprogStart web browser ved opstartStarter standard web browser når SABnzbd starter.HastighedsbegrænsningListen over filtypenavne, der skal slettes efter download.
For eksempel: nfo eller nfo, sfvIndlæserDownloadning af %s mislykkedesLokal IPv4 adressseLocalStorage (cookies) er deaktiveret i din browser, indstillinger for brugergrænsefladen vil gå tabt, når du lukker browseren!Placering for kø administrativ og historik database.
Kan kun ændres, når køen er tom.Placering af logfiler for SABnzbd.
Kræver genstart af SABnzbd!Sted at opbevare færdige, fuldt forarbejdede downloads.
Kan tilsidesættes af bruger-definerede kategorier.Sted at gemme uforarbejdede downloads.
Kan kun ændres, når køen er tom.Sted hvor .nzb filer gemmes.Log mappeLog inLog udLogningMistet forbindelsen til SABnzbd..LavSmå bogstaverGør Windows kompatibelMatchedeMaksimal linje hastighedMaksimalt antal forsøg per serverMaksimalt antal forsøgBetyderMinimalMinimum fri plads til midlertidige download mappeMangler artiklerModeratMandagMånedMereFilm NavnFilm sorteringFilm.NavnFilm_NavnFlytterFlytter...Multi-operationerNZB nøgleNZB tilføjet i køenNavnNameserver/DNS LookupNavngivningAldrigNæsteGod parameterIngen adgangIngen e-mail skabeloner fundetIngen mappeIngen modtagere givet, ingen e-mail sendtIngen egnet godkendelsesmetode blev fundetIngenNormalMatchede ikkeIkke tilgængeligNotification CenterNotification ScriptNotifikation sendt!Notification scriptet "%s" findes ikkeMeddelelserNotifyOSDSekunder mellem skanninger for .nzb filer.VALGFRIT BrugeradgangskodeVALGFRIT konto brugernavnSlået fraGamle kø opdaget, brug Status->Reparation for at konvertere køNår køen er færdigPå hvilken dag i måneden eller ugen (1 = mandag) nulstiller din internetudbyder kvota? (Valgfrit med tt: mm)Kun artiklerne fra starten af køenKun ekstern adgang kræver loginÅben et terminalvindue og tast linjen (eksempel):Åben færdig mappeValgfriValgfri Supplerende NZBValgfrit adgangskode.Valgfrit brugernavn.Angiv et valgfrit filnavnEller trække og slippe filer i vinduet!RækkefølgeOriginalfilnavnOprindelig Job NavnForældreløse jobsAndre beskederPROPAGATING %s minParameterDelnummerAdgangskodeAdgangskode-filAdgangskode maskeret med ******, forsøg igenBehov adgangskodeStiMønsterHjælp til SorteringsstrængPausePause altPause downloading under efterbehandlingPause iPause 1 timePause 15 minutterPause 3 timerPause 30 minutterPause 5 minutterPause 6 timerPause i...Pause høj prioritets jobsPause jobs med kategoriPause lav prioritets jobsPause normal prioritets jobsPause efterbehandlingSat på pausePauset job "%s" på grund af krypterede RAR fil (hvis oplyst, alle adgangskoder blev forsøgt)Pauser downloadet i begyndelsen af efterbehandling og igen når den er færdig.Pause duplikeret NZB "%s"Procentvis af linje hastighedTilladelser til fuldførte overførslerPersonlig API nøglePersonlig API nøgle for Prowl (påkrævet)Personlige notaterVær opmærksom på at 0.0.0.0 værtsnavn har brug for en IPv6-adresse for ekstern adgangAngiv detaljerne fra din primære usenet udbyder.PortPort som SABnzbd ska lytte på.Efterbehandling mislykkedes for %s (%s)EfterbehandlingEfterbehandling kun verificerede jobsEfterbehandlingEfterbehandling i gangIndlæg vil blive sat på pause indtil de har mindst denne alder. Indstilling af job prioritet til Tvang vil springe forsinkelsen over.Før-kø script job markeret som mislykkedetFør kø bruger scriptForudindstillingerTryk Startkey + R og skriv linjen (eksempel):ForrigePrioritetProblem medForarbejdede resultatForløbProgrammet startede ikke!Propagation delayProwlOffentlig IPv4 adresseRens komplette NZB'erRens mislykket NZB'erRens mislykket NZB'er & slet filerTøm historikRens NZB'erRens NZB'er & slet filerRens NZBs på den aktuelle sideRens køenPushbulletPushoverPython-versionPython script "%s" har ikke udfør (+x) tilladelsessætKøKø (de første 10 poster)Kø færdigKøen elementbegrænsningKøen er ikke tom, kan ikke skifte mappe.Kø reparationHurtig kontrol...Hurtig kontrollerendeAfslutKvotaKvota tilbageKvota periodeKvote brugt, pause downloadingRAR filer kunne ikke bekræfteRAR filer kontrolleres med succesRSSRSS Opdaterings intervalRSS Feed %s er tomKørte %sSjældent anvendte indstillinger. Deres betydning og forklaring, klik på knappen Hjælp for at gå til siden Wiki.
Ændre ikke disse uden at kontrollere wiki'en først, da disse kan give alvorlige side følger.
Standardværdierne er mellem parenteserne.Læs alle Feeds nuLæs FeedLæs RSS feedsLæs alle RSS feedsLæs mere om dette på Wiki Help!OpdatereOpdateringsfrekvensAfviseRelative mapper er baseret påTilbageværendeHusk migFjern NZBFjern NZB & slet filerFjern serverFjern alle valgte filerFjern fuldførte jobFjern mislykkede jobsFjernelse af %s mislykkedesFjernelse af jobFjernelse af jobsOmdøbeReparérReparation mislykkedes, ikke nok reparation blokke (%s mangler)ReparererReparation mislykkedes, %sReparerer...Gentagelse testErstat mellemrum i mappenavnErstat punktummer i mappenavnErstat punktum med mellemrum i mappenavn.Erstat mellemrum med understreg i mappenavn.KræverKræver en Prowl kontoKæver en Pushbullet kontoKræver en Pushover kontoKræver CatNulstilNulstil kvota nuNulstil dagServer løsningGenstartGenstart SABnzbdGenstart uden loginGenstarter SABnzbd...Gendan standardværdierResultatGenoptagGenoptag høj prioritets jobsGenoptag jobs med kategoriGenoptag lav prioritets jobsGenoptag normal prioritets jobsGenoptag efterbehandlingGenoptagerTilgængelighed i dageForsøg igenPrøv igen allePrøv igen alle mislykkede jobKøre scriptKør script...Kør bruger script %sSABCTools deaktiveret: Der blev ikke fundet nogen korrekt version (Fandt v%s, forventede v%s)SABnzbd %s startetSABnzbd AdresseSABnzbd adgangskodeSABnzbd PortSABnzbd Hurtigstart’s GuideSABnzbd brugernavnSABnzbd versionSABnzbd WebserverSABnzbd fandt en alvorlig fejl:SABnzbd lukning udførtSABnzbd blev startet med kodning %s, dette bør være UTF-8. Forvent problemer med Unicoded fil- og mappenavne i downloads.SABnzbd vil nu køre i baggrunden.SMTP-serverSQL Kommando mislykkedes, se logSSLSSL-chifreLørdagGemGem ændringerGemmes %s mislykkedesGemmer..Scan overvåget mappeTidsplan for ikke-eksisterende server %sPlanlægningScriptScript exit kode er %sScript returnerede exit kode %s og output "%s"ScriptsScripts mappeSøgSæsonnummerSikker forbindelse til serverSikkerhedVælg et web-grænseflade sprog.Vælg kun hvis din udbyder tillader SSL-forbindelser.Send RSS meddelelserSend tilbage til køenSend e-mail når en RSS-feed tilføjer job i køen.Send e-mail når harddisken er fyldt og SABnzbd er pauset.Sendt %s til køAdskil flere URL-adresser med kommaSerie sorteringServerServer %s bruger et upålideligt HTTPS-certifikatServer %s bruger et upålidelig certifikat [%s]Server %s vil blive ignoreret for i %s minutterServerdetaljerServeradressen "%s:%s" er ikke gyldigt.Kræver serveradresseServeren kunne ikke fuldføre anmodningenServerbeskrivelseServernavnet løser ikkeServeren kræver brugernavn og adgangskode.Server fejl (server kode %s); kunne ikke få %s på %sServerAngive tilladelses mønster for afsluttede filer.
Anvend ciffer. For eksempel: "755" eller "777"Indtast ISP's server for udgående e-mail.Installationen er nu fuldført!Skal download genoptages efter kvotaen er nulstillet?Vis AltVis mislykketVis logVis navnVis aktive forbindelserVis detaljerVis grænsefladeVis.NavnVis_NavnLuk nedLuk computerAfslut SABnzbdPåbegynder lukning af SABnzbdSignal %s modtaget, gemmer og lukker...StørrelseSome files failed to verify against "%s"Vi kunne desværre ikke fortolke denne. Prøv igen.SorteringsstrengSortere efter alder Nyeste→ÆldstSortere efter alder Ældst→NyesteSortere efter navn A→ZSortere efter navn Z→ASortere efter størrelse Størst→MindstSortere efter størrelse Mindst→StørstSorteringKildeSpecielHastighedHastighedsbegrænsningSæt computer i standbyStart guideStarter reparationStart/lukningStatusStatus og grænseflade indstillingerStopStandser...StrengTilføjSøndagStøt projektet, donér!Suspect fejl i downloaderParameterSystemmapperSystem Performance (Pystone)TEKSTFOR STORTabbed layout
(separat kø og historie)Marker jobMidlertidig mappeMidlertidig download mappeTest E-mailAfprøv notifikationTestserverTest overførselTester serverdetaljer..."Reparation" knappen vil genstarte SABnzbd og lave en komplet
rekonstruktion af køens indhold, bevare allerede downloadede filer.
Dette vil ændre køens orden.Afkrydsningsfeltet ud for feed navn skal afkrydses for at feeds vil være aktiveret og automatisk kontrolleres for nye emner.
Når et feed er tilføjet, vil det kun hente nye informationer og ikke noget, der allerede findes i RSS-feed, medmindre du trykker på "Force Download".Værtsnavnet er ikke indstillet.Antallet af forbindelser tilladt af din udbyderServeren svarede ikke korrekt til helo hilsenDer er ingen forbindelser angivet. Angiv mindst én forbindelse.Der er forældreløse jobs i download mappen.
Du kan vælge at slette dem (herunder filer) eller sende dem tilbage til køen.Denne nøgle vil give 3. parts programmer til at tilføje NZBs til SABnzbd.Denne nøgle vil give 3. parts programmer fuld adgang til SABnzbd.Denne månedDette forhindrer flere reparationer kører ved at downloade alle par2 filer når det er nødvendigt.Denne server tillader ikke SSL på denne portDenne ugeKnappen vil genstarte SABnzbd.
Andvend den hvis du oplever stabilitets problem.
Downlodning vil blive sat på pause før genstart og genoptages automatisk igen efter genstart.Dette vil sende en test e-mail til din konto.TorsdagTimeoutTimeout: Forsøg at aktivere SSL eller tilslut via en anden port.TidsudløbTitelTo: %s From: %s Date: %s Subject: SABnzbd rapportere Disk Fuld Hej, SABnzbd er stoppet med at downloade, fordi disken er næsten fuld. Vær venlig at give plads og genoptage SABnzbd manuelt. I dagFor lidt diskplads tvinger system i PAUSEAlt for mange forbindelser til serveren %s [%s]Alt for mange forbindelser, pause en download eller forsøg igen senereØverstTotaltFejlfindingPrøv at forudsige en vellykket afslutning, før selve download (langsom!)Forsøger 7zip med adgangskode "%s"Forsøger RAR-baseret kontrolForsøger SFV verifikationForsøger at hente NZB fra %sForsøger at sætte status på ikke eksisterende server %sForsøger unrar med adgangskode "%s"TirsdagJusteringTypeUØNSKETURL hentning mislykkedes; %sURLGRABBER CRASHEDUautoriseret adgangOphæv blokeringUdefineret server!Ukendt fejl under afkodning af %sUkendt SSL protokol: Prøv at deaktivere SSL eller forbinder på en anden port.Ukendt handling: %sUkendt godkendelsesfejl i mailserverUdpakUdpakke arkiver (rar, zip, 7z) i arkiver.Udpakning af nesting for dybt [%s]Udpakket %s filer/mapper i %sUdpakkerUdpakning mislykkedes, %sUdpakning mislykkedes, CRC-fejlUdpakning mislykkedes, arkivet kræver adgangskodeUdpakningen fejlede, da filen er for stor til filsystemet (FAT?)Udpakningen mislykkedes, stien er for langUdpakning mislykkedes, kunne ikke finde %sUdpakning mislykkedes, skrivefejl eller disken fuld?Mislykkede login forsøg fra %sFejl, Ubrugelig arkivfilUbrugelig RAR filUønsket extension i rar fil %sUønsket extensionOpdatering tilgængelig!Upload NZBUploaderOppetidBrug globale grænseflade indstillingerBrug midlertidig navne under efterbehandling. Deaktiver når dit system ikke kan håndtere det ordentligt.Brugt før, en NZB kommer ind i køen.Brugt chaceBrugermapperBruger nøgleBruger nøgle (krævet)Bruger logget indBruger logget på webgrænsefladenBruger-script kan markere et job som mislykketBrugernavnVærdierKontrolleret korrekt ved hjælp af SFV filerKontroller certifikater, når du opretter forbindelse til indeksører og RSS-kilder ved hjælp HTTPS.BekræfterBekræftelse...UdgaveMeget lavVis scriptlogVENT %s sekunderADVARSEL:VenterAdvarselAdvarslerOvervåget MappeSkannings interval for overvåget mappeWebgrænsefladeOnsdagNår under download det bliver klart, at for meget data mangler, afbryd jobbetNår bruger scriptet returnerer et non-zero exit code, vil jobbet blive markeret som mislykkedes.Når din IP-adresse ændres eller SABnzbd genstarter, udløber sessionen.Hvilken procentdel af linje hastighed bør SABnzbd bruge, fx 50Hvilke script skal vi udføre for notification?Hvem skal vi sige sendte e-mailen?WikiWindows NotifikationerÅrDu skal angive den maksimale båndbredde, før du kan angive en båndbredde begrænsningDin Unrar version er %s, vi anbefaler version %s eller højere.
Din personlige Pushbullet API nøgle (krævet)[%s] Fejl "%s" under filsammenlægning[%s] Fejl "%s" under udpakning af RAR filer[%s] Sammen lagte %s filer[%s] Ingen par2 sæt[%s] PAR2 modtog forkerte indstillinger, tjek din konfiguration->Skifter indstillinger[%s] Hurtig kontrol OK[%s] RAR-baserede kontrollen mislykkedes: %s[%s] Repareret i %s[%s] Bekræftelse i %s, alle filer er ok[%s] Bekræftelse i %s, kræver reparationartiklersag-justeretddagdagedeaktivere serveraktivere serverfilhtimetimertilbagemmanueltminutminutterslået frapåellersidepar2 binær... IKKE fundet!sekundsekunderse logfiltekstunrar binær... IKKE fundetuge././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993698.751334 SABnzbd-4.3.2/locale/pt_BR/LC_MESSAGES/SABnzbd.mo0000644000000000000000000016504514625637243020110 0ustar00runnerstaff,1o-1d13 3 55'67*7 C7d77777777178)8?8889R9[i99#9V9R:o:$:: ::':':;!;); 8; E; P;Z;p;;;';;;;;*; (< 6<@<T<g<p</x< <<8===%D=#j== ====@>G>a> > >>>>!?6=?-t???"?6?)@ E@P@.Y@'@ @@@@S@ CAPAfAlA"{A8AAA AB!B (B4BNB#fBBB B*B;B'CQ9CC CC3C C C CCD DD &D1D GDhD|D&D D)DDD4E45EjE?rEEEE F F,&F,SF1FFFFF'FG54G jG'uGG G GGGG$GG HH#0HTH dHnHtHHH H HHHH I+ICI4`IISIIJ1JH9J J JJ J JJ(J.J) K,JK<wK&KK'KL(LDL dL LL8L L LLM M,M3MSMfM%}M!MM+M N2N!MN*oN!NN'N"NO9O!OOqOOOOO PP,PEPJPPPcPlPPAPP'P!Q>Q^QgQpQ-wQ/Q!Q QR& R"2R9URRRRR R RR RRR R S(S 9S GS'TS|SS S SS S SSSSTT *TKT PTZT_T;~T-T TT UU6UGNUU"UU<UE!VDgV VV,VV%W#.WRWfWWW'WW hX sX XXXX5X XnXgYoYYcYHYoAZ]Z)[ 9[D[L[i[ m[x[[[$[[[0[\*\3\:\@\ E\ P\ [\f\ m\w\\\\\\\\\ \\ ]"]+3]_]d] k] w]]] ] ]/]]^(^;,^h^cx^"^3^3_H_Q_!k_!__%___ `` (` 3`?` H`*V` ``` `` `(` ```a a5aIa [ahaaaaaUaM'bubb#bb%bcRc<fccc"cccd*dBdXd-`ddd dd ddddde !e Be Pe[e ue eeeeeee&e ff"f1f6f fx=x x+x y$y,yy y> zHzPzVz {"{&3{AZ{{{ {E{{|0|.L|{||||||||||}1}-D}r}/y}}} }}~-!~"O~#r~.~~~$~" 4?Fbd$   "!DM%T z  ǀπ׀ R!Ut=ʁ!*/EEJB+ӂ#)#MbJtӃ&'6 ?MOSX guz|DŽ˄ ӄ߄^'$‹1!7)Y :ʍ"(O #a3m.hG%!֐)" *8*?0j ˑ,2,8e#+  & > I4T?F)M'w!Ҕהߔl(u+.ʕ4".(Q6z3LH2{.5×T*N y 4,Ø 5\AǙΙ*B Nc "Ԛ&;Q b:l:S J X b;n Ϝۜ  /P j1v4 ;4S M( DP6m.4ӟ%74UI#! % 1?E\,c,ס +4!I k u#!( 02Q^ A[G ¤פ%0 &Q.xE%1'YlǦ ڦ>& 6@[ s",ا0$6:['#ڨ65U-mש#!$6 [!| êߪ 5TN!4ū+.&Ujz88' )/0'`Lխݭ  ) 5 ?L'c)ʮ # /; AO"` 1ү (!@J* ԰?Q+} S̱G Nh EԲ,4&a" 13ɴ ۴/ByU ϵڵXor/ $C IU p~+Ƹ ܸ;$5 >LQ V a lw  ¹ " 41?:qʺۺ <$a"y T{(7!($J-o&Ľʽ )/+A mw /ܾ  6K ^ l!"ҿgO^!&+%Qa`A# (.W.j4- 6 AN cq'  9 EPYkp=5:@O#a!  (- V`v!~ & )C\eCm  $"056f  '= R\n! +  #$?%d  & +L`p("=/ $%)18L _k+ !) 94n;E&>U4^+.!% =!^L |(U ~9  *; L Yf o} )1<<;R;((33P    'F LW^$f   '5L \}#2!V2xBH7KB T*^ 3K I -(NdioG 4#&X    #A:Y :7'<K&i43::4o.  )sE)  72js,{   ".6 e sXqOK'QJ5*$.L1~1-.049N`hjo u #$ SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Complete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCould not determine connection result (%s)Could not load additional certificates from certifi packageCurrent SchedulesCurrent umask (%o) might deny SABnzbd access to the files and folders it creates.CustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Exit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid server address.Invalid server detailsInvalid stage logging in history for %sIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocation for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification Sent!NotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!ProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePushbulletPushoverPython VersionQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...SubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User script can flag job as failedUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.Which percentage of the linespeed should SABnzbd use, e.g. 50Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: pt_BR Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2; SABnzbd não pode encontrar seus arquivos da interface web em %s.
Por favor instale o programa novamente.

SABnzbd detectou dados salvos de outra versão do SABnzbd
mas não pode reutilizar os dados do outro programa.

Você pode querer terminar sua fila antes com o outro programa.

Após isso inicie este programa com a opção "--clean".
Isto irá apagar a fila atual e histórico!
SABnzbd leu o arquivo "%s". SABnzbd detectou que o arquivo sqlite3.dll está faltando.

Alguns anti-vírus mal projetados removem este arquivo.
Por favor, verifique o seu anti-vírus, tente reinstalar o SABnzbd e reclame com o seu fornecedor de anti-vírus.

SABnzbd precisa de uma porta tcp/ip livre para seu servidor web interno.
A porta %s em %s foi tentada, mas não está disponível.
Algum outro software usa a porta ou o SABnzbd já está rodando.

Por favor reinicie o SABnzbd com um número de porta diferente. SABnzbd precisa de um endereço de host válido para seu servidor web interno.
Você especificou um endereço inválido.
Valores seguros são localhost e 0.0.0.0

Por favor reinicie o SABnzbd com um endereço de host correto. SABnzbd não possui QUALQUER GARANTIA. É software livre, e você está convidado a redistribuí-lo sob certas condições. Está licenciado sob a LICENÇA PÚBLICA GERAL GNU Versão 2 ou (a seu critério) qualquer versão posterior. %s artigos tinham duplicatas não-correspondentes%s artigos estavam malformados%s artigos estavam faltandopasta %s: %s erro de acesso%s não é um valor octal correto%s não é um endereço de e-mail válido+ Debug+ Info+Excluir+Reparar+DescompactarPasta de Backup de .nzb0 é a prioridade mais alta, 99 é a prioridade mais baixaaplicativo 7za... NÃO encontrado!NOTA: Pastas serão criadas automaticamente ao salvar. Você pode usar caminhos absolutos para salvar fora das pastas padrão.Dados não serão movidos. Será necessário reiniciar o SABnzbd!API (sem Configuração)Chave APIAPI Key QR CodeChave de API incorreta. Use a chave de API de Configuração->Geral em seu programa de terceiros:Chave de API faltando. Por favor insira a chave de API de Configuração->Geral em seu programa de terceiros:Chave API para ProwlCancela tarefas que não podem ser concluídasTarefa "%s" abortado por causa de arquivo RAR encripitado (se fornecido, todos as senhas foram tentadas)Cancelado, não é possível concluirCancelado, criptografia detectadaCancelado, extensão indesejada detectadaAceitarAcesso negadoAçãoAção quando RAR criptografado é baixadoAção quando extensão indesejada for detectadaAdicionarAdicionar NZBAdicionar arquivos NZB Adicionar AgendamentoAdicionar ServidorNZB AdicionadoPasta AdministrativaCategorias AfetadasIdadeTodosTodos os arquivos irão em uma única pasta.Também versões de testesSempreToken da aplicaçãoToken da aplicação (obrigatório)Tem certeza de que quer encerrar o SABnzbd?Você tem certeza?ParâmetrosLimite de Cache de ArtigosIdentificador de artigoNo mínimoNo máximoFalha de autenticação, verifique usuário / senha.Retomar automaticamentePausar automaticamente quando o espaço livre estiver abaixo deste valor.
Em bytes, opcionalmente seguido de K,M,G,T. Por exemplo: "800M" ou "8G"VoltarBackupResposta incorreta do Pushbullet (%s): %sResposta incorreta do Pushover (%s): %sAgendamento %s incorreto em %s:%sLargura de bandaBaseNavegarManter artigos em memória para reduzir o acesso a disco.
Em bytes, opcionalmente seguido de K,M,G. Por exemplo: "64M" ou "128M"CancelarNão é possível acessar arquivo PID %sNão é possível alterar permissões de %sNão é possível conectar ao servidor %s [%s]Não é possível criar um arquivo de backup para %sNão é possível criar a pasta %sNão é possível criar a pasta final %sNão é possível criar um arquivo temporário para %sNão é possível encontrar modelos de e-mail em %sNão foi possível encontrar o template web: %s. Tentando o template padrãoNão é possível iniciar o navegador. Provavelmente não foi encontradoNão é possível ler %sNão é possível ler a Pasta de Assistidos %sNão foi possível enviar, faltam dados obrigatóriosNão é possível gravar os dados de histórico, verifique as permissões de acesso!Não é possível gravar no arquivo INI %sCategoriasCategoriaAs alterações não foram salvas e serão perdidas.Mudanças exigirão um reinício do SABnzbd!Selecionar todosVerifique antes de baixarProcurar por nova versãoVerificandoIntervalo de verificação (em minutos, ao menos 15). Inativo quando você usar o Agendador!Lista de LimpezaA limpeza de %s falhou.LimparLimpar ContadoresClique para testar os detalhes informados.Fechar qualquer janela/aba do navegador NÃO vai fechar o SABnzbd.Pasta de FinalizadosCompletar velocidade da pastaConcluídoPasta de Downloads ConcluídosConfiguraçãoArquivo de ConfiguraçãoConfirmar Exclusões do HistóricoConfirmar Exclusões da FilaA conexão a %s@%s falhou. Mensagem=%sConexão com Sucesso!Conexão falhou!ConexõesNão foi possível determinar o resultado da conexão (%s)Não foi possível carregar certificado do pacote certifi.Agendamentos AtuaisMascara atual (%o) pode negar ao SABnzbd acesso aos arquivos e diretórios criados.PersonalizadoDUPLICADODiariamenteDados de histórico danificados, criado um substituto vazioOrdenação por dataFormato da dataDia do mêsDécadaPadrãoPasta Inicial PadrãoEliminarExcluir TodosExcluir após downloadEliminar todos os itens da fila?A exclusão de %s falhou!DispositivoDispositivo para qual a mensagem deve ser enviadaDispositivo(s)Dispositivo(s) para qual a mensagem deve ser enviadaDesativar gerenciamento de cotaDesativadoHTTPs desabilitado por caus de arquivo CERT e KEY invalidosHTTPS desabilitado pela falta de arquivos CERT e KEYDescartarDesconecte do(s) servidor(es) Usenet quando a fila estiver vazia ou pausada.Desconecte quando fila vaziaNotificações de Disco CheioErro de disco na criação do arquivo %sDisco cheioDisco cheio! Forçando PausaFazer uma verificação extra baseada em arquivos SFV.Não há autenticação válida para o feed %sA quota é restabelecida a cada dia, semana ou mês?DownloadDownload concluídoO download falhouBaixar todos os arquivos PAR2O download falhou - Não está em seu(s) servidor(s)Velocidade de download da pastaO download pode falhar. Somente %s de %s necessários estão disponíveisBaixadosBaixado em %s a uma média de %sB/sEx.Ex: 8 ou 20CRIPTOGRAFADOERRO:Editar Detalhes do NZBE-mailNotificar por e-mail na conclusão da tarefaDestinatário do E-mailE-mail do RemetentePasta de Modelos de E-mailEndereço de e-mail para receber os e-mails.E-mail enviado com sucessoEmergencialEsvaziarArquivo NZB %s vazioEntrada RSS vazia encontrada (%s)HabilitarAtivar 7zipHabilitar HTTPSHabilitar NotifyOSDAtivar notificações ProwlHabilitar notificações PushbulletHabilitar notificações PushoverHabilitar verificações baseadas em SFVHabilitar notificações WindowsAtivar acesso à interface por um endereço HTTPS.Habilitar renomeação de pastaAtive para menor uso de memória. Desative para impedir que trabalhos lentos bloqueiem a fila.Ativar gerenciamento de cotaAtiva descompactação recursivaAtivoPara evitar a criação de pastas de trabalho, adicione um asterisco (*) depois do caminho.Digite a URLNome do EpisódioNúmero do EpisódioNome.EpisódioNome_EpisódioErroErro "%s" ao executar file_join em %sErro "%s" ao executar par2_repair no conjunto %sErro "%s" ao executar rar_unpack em %sErro %s ao executar par2_repair no conjunto %sErro %s: Você precisa fornecer um nome de usuário e senha válidos.Erro ao criar chave SSL e certificadoErro ao importar %sErro ao carregar %s. Arquivo corrompido detectadoErro ao remover %sErro ao renomear "%s" para "%s"Erro ao adicionar %s. RemovendoErro ao desligar o sistemaSomente para errosErros/AvisosMódulos essenciais estão faltando, não é possível baixar.Sair do SABnzbdExtensãoAcesso externo da InternetParâmetros Extras PAR2Extraindo...FalhouFalha de logon ao servidor %s [%s]Falha ao criar (%s)Falha ao mover %s para %sFalha ao autenticar com o servidor de e-mailFalha ao fechar o banco de dados. Consulte o logFalha ao fechar a conexão de e-mailFalha ao compilar a expressão para o termo pesquisado: %sFalha ao conectar ao servidor de e-mailFalha ao hibernar o sistemaFalha ao importar %s arquivos de %sFalha ao iniciar %s@%s devido as seguintes razões: %sFalha ao iniciar a conexão TLSFalha ao mover arquivosFalha ao renomear arquivo similar: %s para %sFalha ao obter RSS de %s: %sFalha ao enviar mensagem ProwlFalha ao enviar o e-mailFalha ao enviar mensagem pushbulletFalha ao enviar mensagem pushoverFalha ao colocar o sistema em esperaFalha ao iniciar a interface webFalha ao iniciar a interface web Falha em tempfile.mkstempErro fatalErro fatal ao salvar estadoErro fatal no AssemblerFeedObterBuscar NZB de uma URLObtendoObtendo %s blocos...Obtendo blocos extras...Arquivo contendo todas as senhas que serão testadas em arquivos RAR criptografados.A união de arquivos de %s falhouNome do arquivo ou caminho para o certificado HTTPS.Nome de arquivo ou caminho da Cadeia HTTPS.Nome do arquivo ou caminho para a chave HTTPS.Conjunto de arquivosNome do arquivoFiltroExclui arquivos de amostra. Exemplo: amostras de vídeo.Pasta contendo modelos de e-mail definidos pelo usuárioPasta para monitorar por arquivos .nzb.Pasta/CaminhoPastasNome da conta, para e-mails com autenticação.Senha, para e-mails com autenticação.Para servidores: tenha certeza que os nomes são compatíveis com o Windows.ForçarForçar DesconexãoForçar DownloadFórumEspaço DisponívelFrequênciasexta-feiraDe SxxEyyAPI completaInterface Web completaMais ajuda pode ser encontrada em nossoGeraisGerar Nova ChaveIr para o SABnzbdIr para o assistentePortas HTTP e HTTPS não podem ser iguaisCertificado HTTPSCadeia de Certificados HTTPSChave HTTPSPorta HTTPSAjudaHibernar o PCOcultar detalhesEsconder/Exibir arquivos completosAltaHistóricoHistórico dos últimos 10 itemsLimite de itens no históricoSegure a tecla shift para selecionar um intervaloInícioPágina inicialHostComputador onde o SABnzbd ficará ativo.Por quanto tempo ou até quando você quer pausar? (em Inglês!)Quanto pode ser baixado neste mês (K/M/G)INCOMPLETOParâmetros IONiceEndereço IPv6InativoSe estiver vazio, a porta padrão só irá funcionar com HTTPS.Se você receber esta mensagem de erro outra vez, tente um número diferente.
Ignorar amostrasIgnorar qualquer pasta arquivadaIgnorando NZB duplicado "%s"Em "%s" extensão não necessária em arquivo RAR. Arquivo não necessário é %s Em caso de "Pausa", você precisa definir uma senha e retomar a tarefa.No caso de reinício do SABnzbd, esta janela irá desaparecer automaticamente!Em pastasFeed incompatívelEncontrado arquivo de fila incompatível. Não é possível continuarPasta de Não-FinalizadosSequência de arquivos multiparte incompletaDescrição de feed RSS incorreta "%s"Parâmetro incorretoSenha %s codificada incorretamenteEndereço do servidor inválido.Detalhes inválidos do servidorRegistro inválido de etapa no histórico para %sRecomenda-se que você adicione este local como favorito para acessar o SABnzbd quando ele estiver sendo executado em segundo plano.Tarefa com falhaTarefa concluídaUnir arquivosUnindoIdiomaAbrir navegador ao iniciarAbrir o navegador padrão ao iniciar o SABnzbd.Limitar VelocidadeLista de extensões de arquivo que devem ser excluídos após o download.
Por exemplo: nfo ou nfo, sfvCarregandoFalha ao carregar %sEnderaço IPv4 localLocalização do banco de dados de histórico e administrador de fila.
Só pode ser alterado quando a fila estiver vazia.Local dos arquivos de log do SABnzbd.
Será necessário reiniciar o SABnzbd!Local para armazenar downloads concluídos, totalmente processados​​.
Pode ser anulado por categorias definidas pelo usuário.Local para armazenar downloads não processados.
Só pode ser alterado quando a fila estiver vazia.Local onde os arquivos .nzb serão armazenados.Pasta de LogLogsConexão perdida com SABnzbd..BaixaMinúsculasTornar Windows compatívelCorrespondidoVelocidade máxima da linhaNúmero máximo de tentativas por servidor.Máximo de tentativasSignificadoEspaço livre mínimo para a pasta temporária de downloadsArtigos faltandoModeradasegunda-feiraMêsMaisNome FilmeNome.FilmeNome_FilmeMovendoMovendo...Multi-OperaçõesChave NZBNZB adicionado à filaNomeNome do servidor / DNS LookupNomeandoNuncaPróxParâmetros NiceSem acessoNenhum modelo de e-mail encontradoSem pastasNenhum destinário fornecido, e-mail não enviadoNenhum método de autenticação apropriado foi encontradoNenhumNormalNão EncontradoNão disponívelCentro de NotificaçõesNotificação Enviada!NotificaçõesNotifyOSDQuantidade de segundos entre as varreduras de arquivos .nzb.Senha OPCIONAL da contaNome de usuário OPCIONAL da contaDesligadoFila antiga detectada, use "Situação -> Reparação da fila" para converter a filaAo terminar a filaEm que dia do mês ou da semana (1 = segunda-feira) seu provedor de Internet redefine sua quota? (Opcionalmente com hh: mm)Apenas Obter Artigos para o Topo da FilaAbra uma janela de terminal e digite a linha (exemplo):Abrir pasta de finalizadosOpcionalNZB Suplementar OpcionalSenha de autenticação opcional.Usuário de autenticação opcional.Opcionalmente, especifique um nome de arquivoOu arraste e solte arquivos na janela!OrdemNome do arquivo originalTrabalhos órfãosOutras MensagensParâmetros:Número do EpisódioSenhaArquivo de senhasSenha mascarada em ******, digite novamentecom senhaCaminhoModeloModelo do padrãoPausarPausar TodosPausar o download durante o pós-processamento.Pausa dePausar por 1 horaPausar por 15 minutosPausar por 3 horasPausar por 30 minutosPausar por 5 minutosPausar por 6 horasPausar por...Pausa tarefas de alta prioridadePausa tarefas de baixa prioridadePausa tarefas de prioridade normalPausar o pós-processamentoPausadoTarefa "%s" pausado por causa de arquivo RAR encripitado (se fornecido, todos as senhas foram tentadas)Pausar o download no início do pós-processamento e retomar quando concluído.Pausando NZB duplicado "%s"Percentual de velocidade da linhaPermissões para downloads concluídosChave API pessoalChave API pessoal para Prowl (obrigatório)Notas pessoaisEsteja ciente de que o nome de host 0.0.0.0 vai precisar de um endereço IPv6 para acesso externoPor favor insira os detalhes de seu provedor de usenet primário.PortaPorta onde o SABnzbd será ativado.O pós-processamento falhou para %s (%s)Pós-processamentoPós-processar apenas os trabalhos verificadosPós-processamentoPós-processamento iniciadoScript de usuário de pré-filaPredefiniçõesAperte a tecla Windows+R e digite a linha (exemplo):AnteriorPrioridadeProblema comResultado ProcessadoProcessamentoO programa não iniciou!ProwlEndereço IPv4 públicoLimpar NZBs TerminadosLimpar NZBs FalhadosLimpar NZBs Falhados & Excluir ArquivosLimpar HistóricoLimpar NZBsLimpar NZBs & Excluir ArquivosLimpar FilaPushbulletPushoverVersão do PythonFilaFila dos primeiros 10 itemsFila concluídaLimite de itens na filaA fila não está vazia. Não será possível mudar de pasta.Reparação da filaVerificação Rápida...Verificação RápidaSairQuotaQuota restantePeríodo da quotaQuota esgotada, pausando o downloadRSSIntervalo de verificação de RSSO feed RSS %s estava vazio%s executadoOpções raramente utilizadas. Para seu significado e explicação, clique no botão Ajuda para ir para a página Wiki.
Não altere estas sem checar o Wiki em primeiro lugar, já que algumas têm sérios efeitos colaterais.
Os valores padrão estão entre parênteses.Ler Todos os Feeds AgoraLer FeedLer feeds RSSLer todos os feeds RSSLeia a sessão ajuda no Wiki sobre isso!AtualizarTaxa de atualizaçãoRecusarCaminho base das pastas relativasRestanteRemover NZBRemover NZB & Excluir ArquivosRemover servidorRemover todos os arquivos selecionadosRemover trabalhos encerradosRemover tarefas com falhaA remoção de %s falhouRenomearRepararReparação falhou. Blocos de reparação insuficientes (faltam %s)ReparandoReparação falhou, %sReparando...Repetir testeSubstituir espaços no nome da pastaSubstituir pontos no nome da pastaSubstituir pontos por espaços no nome da pasta.Substituir espaços por sublinhado no nome das pastas.RequerRequer uma conta ProwlNecessária uma conta PushbulletNecessário uma conta PushoverRequiresCatReiniciarRedefinir Quota agoraPrimeiro dia do cicloResolvendo endereçoReiniciarReiniciar SABnzbdReinicie sem loginReiniciando SABnzbd...Reiniciado por falha de assemblerReiniciado por falha de downloadReiniciado por falha de pós processamento.ResultadoContinuarContinua tarefas de alta prioridadeContinua tarefas de baixa prioridadeContinua tarefas de prioridade normalContinuar o pós-processamentoContinuarTempo de retençãoRepetirRepetir todosAtualizar todos os trabalhos com falhaExecutando scriptExecutando script...Executando script de usuário %sSABnzbd %s iniciadoHost do SABnzbdSenha do SABnzbdPorta do SABnzbdAssistente de Início Rápido do SABnzbdUsuário do SABnzbdVersão do SABnzbdServidor Web do SABnzbdSABnzbd detectou um erro fatal:Encerramento do SABnzbd concluídoSABnzbd iniciou com codificado %s, deveria ser UFT-8. Esperado problemas com arquivos e nomes de diretórios Unicode nos downloades.SABnzbd agora será executado em segundo plano.Servidor SMTPO comando SQL falhou. Consulte o logSSLsábadoGravarSalvar AlteraçõesFalha ao salvar %sSalvando...Varrer pasta de assistidosAgendamento para um servidor inexistente %sAgendamentoScriptCódigo de saída do script é %sScriptsBuscaNúmero da TemporadaSelecione um idioma para a interface web.Selecione somente se seu provedor permitir conexões SSL.Enviar notificações RSSEnviar de volta para a filaEnviar e-mail quando um feed RSS adicionar tarefas à fila.Enviar e-mail quando o disco estiver cheio e SABnzbd estiver pausado.Enviados %s para a filaOrdenação de SériesServidorServidor %s usa um certificado HTTPS não confiávelO servidor %s será ignorado por %s minutosDetalhes do ServidorEndereço de servidor "%s:%s" não é válido.Endereço do servidor necessárioDescrição do servidorNome de servidor não encontradoServidor requer usuário e senha.Erro do servidor (código do servidor %s); não foi possível obter %s de %sServidoresDefinir padrão de permissões para arquivos/pastas concluídos.
Em notação octal. Por exemplo: "755" ou "777"Define o servidor para envio de e-mails.A configuração está completa!O download deve retomar quando a quota for restabelecida?Mostrar TodosMostrar FalhadosMostrar LogsNome do ShowExibir conexões ativasMostrar detalhesExibir interfaceNome.do.ShowNome_do_ShowEncerrarDesligar o PCEncerrar o SABnzbdEncerrandoSinal %s encontrado. Salvando e saindo...TamanhoAlguns arquivos falharam na verificação de "%s"Perdão, não conseguimos interpretar isso. Tente novamente.String de ordenaçãoOrdenar por Idade Mais novo→Mais antigoOrdenar por Idade Mais antigo→Mais novoOrdenar por Nome A→ZOrdenar por Nome Z→AOrdenar por Tamanho Maior→MenorOrdenar por Tamanho Menor→MaiorOrdenaçãoCódigo fonteEspecialVelocidadeLimite de velocidadePC em esperaIniciar o AssistenteIniciando reparaçãoInicialização/EncerramentoSituaçãoEstado e opções de interfacePararParando...EnviardomingoApoie o projeto. Faça uma doação!Erro suspeito no downloaderOpçõesPastas de SistemaPerformance do Sistema (Pystone)TEXTOMUITO GRANDEPasta temporáriaPasta Temporária de DownloadsTestar E-mailNotificação de testeTestar ServidorTestando detalhes do servidor...O botão "Reparar" irá reiniciar o SABnzbd e fazer uma reconstrução
completa do conteúdo da fila, preservando arquivos já baixados.
Isto modificará a ordem da fila.A caixa de seleção ao lado do nome do feed deve ser assinalada para que o feed seja ativado e automaticamente verificado por novos itens.
Quando um feed é adicionado, ele só vai pegar novos itens e não algo que já esteja no feed RSS a menos que você pressione "Forçar Download".O nome do host não foi definido.O número de conexões permitidas por seu provedorO servidor não respondeu propriamente a chamada de reconhecimentoNão há conexões definidas. Por favor, defina pelo menos uma conexão.Existem tarefas órfãs na pasta de downloads.
Você pode optar por excluí-las (incluindo arquivos) ou enviá-las de volta para a fila.Esta chave permitirá que programas de terceiros adicionem NZBs ao SABnzbd.Esta chave dará a programas de terceiros pleno acesso ao SABnzbd.Este mêsEste servidor não permite SSL nesta portaEsta semanaIsto irá reiniciar o SABnzbd.
Use-o quando você achar que o programa tem um problema de estabilidade.
Os downloads serão pausados antes de reiniciar e retomados depois.Isto irá enviar um e-mail de teste para sua conta.quinta-feiraTempo esgotadoTempo esgotado: Tente habilitar o SSL ou conectar em uma porta diferente.Tempo limiteTí­tuloPara: %s De: %s Data: %s Assunto: SABnzbd informa Disco Cheio Olá, SABnzbd parou de baixar porque o disco está quase cheio. Por favor, arrume espaço e continue SABnzbd manualmente. HojeMuito pouco espaço em disco. Forçando PAUSEExcesso de conexões ao servidor %s [%s]Excesso de conexões, por favor pause o download ou tente novamente mais tardeTopoTotalResolução de problemasTentar prever a conclusão bem sucedida de um futuro download? (lento!)Testando 7zip com a senha "%s"Tentando verificação SFVTentando obter NZB de %sTentando definir o status do servidor inexistente %sTentando descompactar com a senha "%s"terça-feiraAjustes finosTipoINDESEJADOA busca da URL falhou; %sURLGRABBER PAROU DE FUNCIONARAcesso não autorizadoDesbloquearServidor não definido!Erro desconhecido ao decodificar %sAção desconhecida: %sFalha de autenticação desconhecida no servidor de e-mailDescompactarDescompacta os arquivos (rar, zip, 7z) dentro de arquivos.Aninhamento de descompactação com muitos níveis [%s]Descompactados %s arquivos/pastas em %sDescompactandoA descompactação falhou. %sA descompactação falhou. Erro de CRCA descompactação falhou. O arquivo exige uma senhaDescompactação falhou, o caminho é muito extensoA descompactação falhou. Não foi possível encontrar %sA descompactação falhou. Erro de escrita ou disco cheio?Arquivo NZB inutilizávelArquivo RAR inutilizávelA extensão indesejada está no arquivo rar %sExtensões indesejadasAtualização Disponível!Enviar NZBTempo ativoUsar configurações globais de interfaceUsar nomes temporários durante o pós-processamento. Desative quando seu sistema não lidar com isso corretamente.Utilizado antes de um NZB entrar na fila.Cache utilizadoUsar PastasChave do usuárioChave do usuário (obrigatório)O script do usuário pode marcar um trabalho como falhoUsuárioValoresVerificado com sucesso. Usando arquivos SFV.VerificandoVerificando...VersãoMuito BaixaExibir Log do ScriptEspere %s segundo(s)AVISO:AguardandoAlertaAlertasPasta de AssistidosVelocidade de Varredura na Pasta de AssistidosInterface Webquarta-feiraQuando durante o download ficar claro que muitos dados estão faltando, cancela a tarefaQuando um script do usuário retornar um código de saída diferente de zero, o trabalho será marcado como falhoQual percentual de velocidade da linha o SABnzbd deve utilizar, por exemplo, 50Quem devemos dizer que enviou o e-mail?WikiNotificações WindowsAnoVocê deve definir a largura de banda máxima antes de definir um limite de bandaSua versão UNRAR é %s, nós recomendamos a versão %s ou superior.
Chave Pushbullet API pessoal (necessária)[%s] Erro "%s" na união de arquivos[%s] Erro "%s" ao descompactar os arquivos RAR[%s] Unidos %s arquivos[%s] Nenhum conjunto par2[%s] PAR2 recebeu opções incorretas. Verifique em Configuração->Opções[%s] Verificação Rápida OK[%s] Reparado em %s[%s] Verificado em %s. Todos os arquivos corretos[%s] Verificado em %s. É necessário repararartigosajuste de maiúsculasddiadiasdesativar o servidorativar o servidorarquivohhorahorasrestantesmmanualminmindesligadoligadooupáginaaplicativo par2... NÃO encontrado!segsegundosveja o arquivo de logtextoaplicativo unrar... NÃO encontrado!semana././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993698.848013 SABnzbd-4.3.2/locale/it/LC_MESSAGES/SABnzbd.mo0000644000000000000000000000057514625637243017512 0ustar00runnerstaff$,O-Project-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Language-Team: Italian (https://app.transifex.com/sabnzbd/teams/111101/it/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: it Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2; ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993698.424686 SABnzbd-4.3.2/locale/cs/LC_MESSAGES/SABnzbd.mo0000644000000000000000000007455714625637242017515 0ustar00runnerstaff &.GRO[VUr$    / = B %I #o &    !=!X!v!!!6!-!"+""I"6l"" ""l"<@#'}###### # $*$;$ N$Z$;k$$ $$3$ $$% &%G% [% e%(s%%4%4%& >&H&a&j&}&&'& & &&&&''' 3' ?'L'd' l'v'(|'.')','&+(R('e(((((8(#) <)J)Q)q))%)!))+* /*P*!k*!**#*"* +#(+L+!b+!++++,,9, U,a,},,,,,,,,- --"-)-1-'B-j- |--o- - ...#.9.K. P. Z. e.r.w..,..%.# /./B/FU// / //}/ >0 I0W0 `0l0~00000000000 001 1 #1-1"F1+i111 1'1 11;1%252J2P2_2 r2 }222 2 2222223333L3d33U333R4"c444 44444 5 '5 55@5Z5 y55<5555&5"616@6 E6 P6q6u666666+6 7 7 %707J7`7s77727 77 7 7788'8/8E8'[8(8+8888 9$9-9 39=9S9b9t9H999 9::&:9:Y:s::;;; ";/;@;I; ];h;o;,;;;;; ;;3<F<&W<"~<,<(<$<=4=Q=Y= b= n= {=== == ='===>>> > >+>;>L>S> X>d>k>>>> > >> >5> 5?+@? l?v??"?&???? @.(@W@w@@@@@@@@-@A#A CAMAbA-~A6A"A#B.*B"YB|B"B$BB B B B C#C%>C dCnC CCC CCCC C CCCECB*DmD#D)ECEJXEEE&E'EFF F%F 4FBFDFIFOFQFXF\FaFeFhFkFFF FFFF#hH(H"HH HHI I II 7IeBImIdJ{J#J-JJJ KK"K 1K ?KKKTK4dKKK*K(K(K$L",L(OL$xL"LL1L'M.7MDfM7MM'M*NAFN!N N NqN:0O"kO OOOO O P P/PIP[PdPAzPP PP>PQ#$Q HQ"RQuQ QQ-QQ8Q:'R*bR R"R RRRR.S?S PS\ScSiS xSS"S S SSS ST'T60T(gT4T2TT.U=U'[U(UU>UU V V.(VWVoV3V4V)V8W0SW W)W(W W*X#DX$hX)XX'X(X&%Y'LY)tY Y!YYY9Z!IZkZrZZZZZZ ZZZ[ [['*[R[ d[ o[zz[ [\\\ #\D\U\[\ n\ {\ \\\0\\+]<]\]q]X] ]]] ^^^^^^^^ _ __#_+_F_ [_e_m_s_{______3_6#`Z` c` n`$z` ``D``(a:aCaTa ea oa|a aa aaaaabb%3bYb%wb(b bfb!9c[cUtc ccd dd,d Bdcd.ddd%d"e#e 6e:Deeee.eeeff+$fPfTfkf ffff%fg g g(gGgdgg gg=ggg h h'h-h>hRhZhuh$h%h(hhi"%iHi bioi xi&iii"iNiFj [j ijvj jj$jjj2kkkkkk kl "l/l6l1Tllll l"ll7l0m%Gmmm6m*m'mn(4n]n ensnnnnn nn n-no&o/o 5oAoJo]ofoxoo o oooo oopp)p>p.]p p*p ppp3p*q?qFqcq|q7qqqq qr r*r%@rfr5yrr"r rr r*sOHs<s.s5t(:tct&}t)tt ttuu-.u/\u uu uu uu u u uuvvvavD{vv+Dw1pwwMw x"x85x*nxxxxxxxxxxxxxxxxyy%y,yLyhy%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address%s is not a valid script+ Debug+ Info+Delete+Repair+Unpack7za binary... NOT found!API KeyAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:Aborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAccess deniedAddAdd NZBAdd NZB files Add ServerAdded NZBAdvancedAgeAre you sure?Authentication failed, check username/password.BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBlocked attempt to create directory %sCancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCertificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Changes will require a SABnzbd restart!CheckingChecking extra filesCleanup of %s failed.Complete FolderComplete folder speedCompletedConfigConfiguration locked, cannot save settingsConnection failed!ConnectionsCorrupt RAR fileCould not load additional certificates from certifi packageCustomDUPLICATEDailyDamaged History database, created empty replacementDay of monthDecoder failure: Out of memoryDefaultDelete all items from the queue?Deleting %s failed!Device(s)Direct UnpackDirect Unpack was automatically enabled.Disable quota managementDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDisk error on creating file %sDisk fullDisk full! Forcing PauseDownloadDownload CompletedDownload FailedDownload folder speedDownloaded in %s at an average of %sB/sDuplicate NZBENCRYPTEDERROR:EmailEmail succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)Enable 7zipEnable HTTPSEnable quota managementEnabledEnter URLErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingErrors/WarningEssential modules are missing, downloading cannot start.Executes a custom scriptExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send pushbullet messageFailed to send pushover messageFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File join of %s failedFoldersForceForce DisconnectForumFridayGeneralGenerate New KeyHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS PortHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHide detailsHighHistoryHistory Last 10 ItemsHistory RetentionHomeHome pageINCOMPLETEIPv6 addressIdleIgnoring duplicate NZB "%s"Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterInternet BandwidthInvalid par2 files or invalid PAR2 parameters, cannot verify or repairIssuesJob failedJob finishedJobsJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesKeep all jobsLanguageLimit SpeedLoading %s failedLocal IPv4 addressLog inLog outLoggingLowMaximum line speedMissing articlesMondayMonthMoreMovingMoving...NZB added to queueNameNameserver / DNS LookupNo accessNo email templates foundNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot availableNotification script "%s" does not existNotificationsOffOld queue detected, use Status->Repair to convert the queueOn queue finishOpen complete folderOrderOther MessagesPROPAGATING %s minParametersPasswordedPathPausePause AllPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pausing duplicate NZB "%s"Percentage of line speedPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPost Processing Failed for %s (%s)Post-processing startedPriorityProblem withProgram did not start!Public IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue not empty, cannot change folder.Quick Check...Quick CheckingQuitQuota leftQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRead RSS feedsRead all RSS feedsRefused connection from:Refused connection with hostname "%s" from:RemainingRemember meRemove NZBRemove NZB & Delete FilesRemove completed jobsRemove failed jobsRemoving %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testResetReset Quota nowResolving addressRestartRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorRestore DefaultsResumeResume high priority jobsResume jobs with categoryResumingRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd PasswordSABnzbd PortSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSecuritySelect a web interface language.Send RSS notificationsSend email when an RSS feed adds jobs to the queue.Sent %s to queueServer %s has used the specified quotaServer %s is expiring in %s day(s)Server %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer address "%s:%s" is not valid.Server address requiredServer name does not resolveServersShow AllShow FailedShow LoggingShow detailsShow interfaceShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSortingSourceSpecialSpeedSpeedlimitStandby PCStarting RepairStartup/ShutdownStatusStopStopping...SundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem Performance (Pystone)TOO LARGETest EmailTest NotificationTest downloadThe server didn't reply properly to the helo greetingThis monthThis server does not allow SSL on this portThis weekThursdayTodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]TotalTrying 7zip with password "%s"Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTypeUNWANTEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown action: %sUnknown authentication failure in mail serverUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUpdate Available!Upload NZBUsed cacheUser FoldersUser logged inUser logged in to the web interfaceVerified successfully using SFV filesVerifyingVerifying repairVerifying...VersionVery LowWAIT %s secWaitingWarningWarningsWeb InterfaceWednesdayWikiYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredddaydaysdisable serverenable serverhhourhoursmmanualminminsoffonorpar2 binary... NOT found!secsecondssee logfileunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: cs Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3; Adresář %s: chyba přístupu k %s%s není hodnota v osmičkové soustavě%s není validní emailová adresa%s neni validní skript+ Ladění+ Info+Smazat+Opravit+RozbalitProgram 7za... nenalezen!API klíčNesprávný API klíč, použijte api klíč z Nastavení->Obecné ve vašem programu třetí strany:Chybějící API klíč , prosím zadejte api klíč z Nastavení->Obecné do svého programu třetí strany:Ukončený úkol "%s" z důvodu zaheslovaného RAR souboru (vyzkoušeli jsme všechna zadaná hesla)Zrušeno, nelze dokončitUkončeno, detekováno šifrováníPřerušeno, nalezena neočekávaná připonaPřístup odepřenPřidatPřidat NZBPřidat NZB souboryPřidat serverNZB přidánoPokročiléStáříJste si jistí?Přihlášené selhalo, zkontrolujte jméno a heslo.ZpětZálohaNesprávná odpověd z Pushbullet (%s): %sNesprávná odpověd z Pushover (%s): %sZablokován pokus vytvořit adresář %sZrušitNelze přistoupit k PID souboru %sNelze změnit oprávnění adresáře %sNelze se připojit k serveru %s [%s]Nelze vytvořit zálohu souboru %sNelze vytvořit adresář %sNelze vytvořit složku dokončených souborů %sNelze vytvořit dočasný soubor pro %sNepodařilo se najít poštovní šablony v %sŠablona pro web nebyla nalezena: %s, zkouším standardní šablonuNelze spustit webový prohlížeč, nejspíš nenalezenNelze číst %sNelze číst ze "Sledované" složky %sNelze odeslat, chybějí požadovaná dataNelze zapisovat do databáze historie, zkontrolujte oprávnění!Nelze zapisovat do INI souboru %sKategorieKategorieCertifikát nesouhlasí se jménem serveru: jméno serveru není obsaženo v certifikátu. Toto je chyba serveru.Certifikát není validní. Pravděpodobně chyba serveru.Změny vyžadují restart SABnzbd!KontrolujiKontroluji další souboryČištění %s selhalo.Složka dokončenýchRychlost složko pro dokončenéDokončenoNastaveníKonfigurace uzamčena, nelze uložit nastaveníSpojení selhalo!SpojeníPorušený RAR souborNezdařilo se nahrát dodatečné certifikáty z balíku certifi.VlastníDUPLIKÁTDenněPoškozená databáze historie, nahradtě prázdnou databázíDen v měsíciChyba dekodéru: nedostatek pamětiVýchozíSmazat všechny položky z fronty?Mazání %s selhalo!ZařízeníPřímé rozbaleníPřímé rozbalení bylo automaticky zapnuto.Vypnout správu kvótHTTPS vypnuto z důvodu nevalidních CERT a KEY souborůHTTPS vypnuto z důvodu chybějících CERT a KEY souborůProbém s vytvořením souboru %s na diskuPlný diskPlný disk! Vynucené pozastaveníStahováníStahování dokončenoStahování selhaloRychlost složky pro downloadStaženo do %s s průměrnou rychlostí %s B/sDuplikátní NZBŠIFROVANÉCHYBA:EmailEmail funčníPrázdnýPrázdný NZB soubor %sPrázdný RSS záznam nalezen (%s)Povolit 7zipPovolit HTTPSPovolit správu kvótZapnutoZadejte URLChybaChyba "%s" v průběhu file_join pro %sChyba "%s" při spoustění par2_repair na skupině %sChyba "%s" v průběhu rar_unpack pro %sChyba %s při spoustění par2_repair na skupině %sChyba při vytváření SSL klíče a certifikátuChyba při importu %sNelze nahrát %s, detekován porušený souborChyba při odstraňování %sNezdařilo se přejmenovat "%s" na "%s"Chyba při přidávání %s, odstraněnoChyby/výstrahyChybí základní moduly, stahování nemůže být spustěno.Spustit vlastní skriptRozbaluji...SelhaloPřihlášení k serveru %s se nezdařilo [%s]Chyba vytváření (%s)Chyba přesunu %s do %sNezdařilo se přihlášení k poštovnímu serveruNezdařilo se uzavření databáze, zkontrolujte logNezdařilo se uzavřít spojení pro mailNepodařilo se zkompilovat regex pro hledaný výraz: %sPřipojení k poštovnímu serveru se nezdařiloNezdařilo se hibernovat systémNezdařilo se importovat %s souborů z %sNezdařilo se inicializovat TLS spojeníNezdařilo se přesunout souboryNezdařilo se přečíst soubor s hesly %sNezdařilo se stáhnout RSS z %s:%sNepodařilo se odeslat Prowl zprávuNepodařilo se odeslat Windows oznámeníNezdařilo se odeslat e-mailNepodařilo se odeslat macOS oznámeníNezdařilo se odeslat pushbullet zprávuNezdařilo se odeslat pushover zprávuNezdařilo se spustit webové rozhraníNepodařilo se spustit webové rozhraní:Nezdařilo se nahrát soubor: %sNezdařilo se duplikovat NZB "%s"Chyba v tempfile.mkstempNeopravitelná chybaNeopravitelná chyba při ukládání stavového souboruNeopravitelná chyba v AssembleruKanálZískat NZB z URLStahujiStahuji %s bloků...Stahuji extra bloky...Spojování souboru %s selhaloSložkyVynucenéVynucené odpojeníFórumPátekObecnéGenerovat nový klíčHTTP a HTTPS porty nemohou být stejnéHTTPS certifikátHTTPS portNápovědaPomozte nám přeložit SABnzbd do vaší řeči!
Doplňte chybějící texty nebo vylepšete existující překlad:Hibernovat PCSkrýt detailyVysokáHistorieHistorie posledních 10 položekRetence historieDomůDomovská stránkaNEKOMPLETNÍIPv6 adresaNečinnýIgnoruji duplikátní NZB "%s"Nekompatibilní kanálNekompatibilní soubor fronty, nelze pokračovatSložka nedokončenýchNekompletní sekvence spojovaných souborůŠpatný popis RSS kanálu "%s"Nesprávný parametrRychlost internetuNesprávné par2 soubory nebo nesprávné parametry PAR2, nelze zkontrolovat ani opravitProblémyÚkol neuspěšnýÚkol dokončenÚlohyÚkol se začne rozbalovat během stahování pro redukci času post-procesingu. Funguje pouze pro úkoly, které nepotřebují opravu.Spojit souboryZachovat všechny úkolyJazykOmezit rychlostNačítání %s selhaloMístní IPv4 adresaPřihlásitOdhlásitProtokolNízkáMaximální rychlost linkyChybějící částiPondělíměsícVícePřesunPřesouvám...NZB přidáno do frontyJménoDNS server / DNS dotazyBez přístupuNenalezeny poštovní šablonyNebyli zadáni přijemci, žádný email neodeslánŽádná použitelná autentizační metoda nenalezenaŽádnýNormálníNedostupnéNotifikační skript "%s" neexistujeUpozorněníVypnutoStará fronta nalezena, použijte Status->Repair pro konverzi frontyPři dokončení frontyOtevřít složku s kompletními souboryPořadíOstatní zprávyPROPAGUJI %s minParametryZaheslovánoCestaPozastavitPozastavit všePozastavit naPozastavit na 1 hodinuPozastavit na 15 minutPozastavit na 3 hodinyPozastavit na 30 minutPozastavit na 5 minutPozastavit na 6 hodinPozastavit úkoly s vysokou prioritouPozastavit úkoly v kategoriiPozastavit úkoly s nízkou prioritouPozastavit úkoly s normální prioritouPozastavenoPozastavený úkol "%s" z důvodu zaheslovaného RAR souboru (vyzkoušeli jsme všechna zadaná hesla)Pozastavuji duplikátní NZB "%s"Procento rychlosti linkyPozor, hostitelská adresa 0.0.0.0 bude vyžadovat IPv6 adresu pro externí přístupPostprocesing selhal pro %s (%s)Začal post-procesing PrioritaProblém sProgram se nespustil!Veřejná IPv4 adresaVymazat všechny dokončené NZBVymazat všechny selhalé NZBVymazat všechny selhalé NZB a smazat souboryVyprázdnit historiiVymazat všechny NZBVymazat všechny NZB a smazat souboryVymazat NZB na aktuální stránceVyprázdnit frontuVerze pythonuPython skript "%s" nemá nastaveno právo spuštění (+x)FrontaFronta prvních 10 položekFronta dokončenaFronta nené prázdná, nelze změnit složku.Rychlá kontrola...Rychlá kontrolaVypnoutZbývající kvótaKvóta přesažena, pozastavuji stahováníRSSInterval konctroly RSSRSS kanál %s byl prázdnýSpuštěno %sČíst RSS kanályČíst všechny RSS kanályOdmítnuto spojení z:Odmítnuté spojení s hostem "%s" z:ZbýváZapamatuj si měOdstranit NZBOdstranit NZB a smazat souboryOdstranit dokončené úkolyOdstranit neúspěšné úkolyOdstraňování %s selhaloPřejmenovatOpravitOprava se nezdařila, nedostatek bloků k opravě (chybí %s)OpravujiOprava selhala, %sOpravuji...Opakovat testResetVynulovat kvótuPřekládám adresuRestartRestart bez přihlášeníRestartuji SABnzbd...Restartuji protože selhal assemblerRestartuji protože selhal downloaderRestartuji protože postprocessor selhalObnovit výchozíObnovit stahováníObnovit úkoly s vysokou prioritouOnovit úkoly v kategoriiObnovováníOpakovatOpakovat všeOpakovat všechny nedokončené úkolyBěžící skriptSpouštím skript...Spouštím uživatelský skript %sSABCTools vypnut: Nenalezena správná verze! (Nalezena v%s, očekávána v%s)SABnzbd %s spustěnoSABnzbd hesloSABnzbd portSABnzbd uživatelské jménoSABnzbd verzeSABnzbd webový serverSABnzbd detekovalo závažnou chybu:Vypnutí SABnzbd dokončenoSABnzbd spuštěno s kódováním %s, zatímco doporučené je UTF-8. Očekávejte problémy se jmény souborů a adresářů při stahování.Spustění SQL příkazu selhalo, zkontrolujte logSSLSobotaUložitUložit změnyUkládání %s selhaloUkládám...Zkontrolovat sledovanou složkuPlánováníSkriptNavratový kód skriptu je %sSkript vrátil návratový kód %s a výstup "%s"SkriptySložka se skriptyVyhledáváníBezpečnostVyberte jazyk webového rozhraní.Odeslat RSS upozorněníOdeslat email když RSS kanál přidá úkol do fronty.Odesláno %s do frontyServer %s vyčerpal nastavenou kvótuServer %s vyprší za %s dnůServer %s používá nedůvěryhodný certifikát [%s]Server %s bude ignorován po dobu %s minutAdresa serveru "%s:%s" není správná.Adresa serveru je vyžadovánaNebylo možné přeložit jméno serveruServeryZobrazit všeZobrazit neúspěšnéZobrazit protokolZobrazit detailyZobrazit rozhraníVypnoutVypnout PCVypnout SABnzbdVypínáníZachycen signál %s, ukládám a ukončuji...VelikostŘazeníZdrojSpeciálníRychlostOmezení rychlostiUspat PCSpouštím opravuSpuštění/VypnutíStavZastavenoZastavuji...NedělePodpořte projekt!Nejspíše chyba downloaderuPřepínačeVýkon systému (Pystone)PŘÍLIŠ VELKÝOtestovat emailOtestovat notifikaceOtestovat rychlost stahováníServer neodpověděl správně na HELO pozdravTento měsícTento server nepovoluje SSL na tomto portuTento týdenČtvrtekDnesPříliš málo místa na disku, přenos POZASTAVENPříliš mnoho spojení k serveru %s [%s]CelkemZkouším 7zip s heslem "%s"Zkouším SFV ověřeníZkouším stáhnout NZB z %sZkouším aktualizovat stav neexistujícího serveru %sZkouším unrar s heslem "%s"ÚterýTypNECHTĚNÝNeoprávněný přístupOdblokovatNedefinovaný server!Neznámá chyba při dekódování %sNeznámá akce: %sNeznámá chyba přihlášení k poštovnímu serveruRozbalitSoubory/složky %s rozbaleny do %sRozbalujiRozbalení selhalo, %sRozbalování selhalo, CRC chybaRozbalení selhalo, archiv vyžaduje hesloRozbalování selhalo, soubor je příliš velký pro souborový systém (FAT?)Rozbalování selhalo, cesta k souboru je příliš dlouhá.Rozbalování selhalo, nezdařilo se najít %sRozbalování selhalo, chyba zápisu nebo plný disk?Nezdařený pokus o přihlášení od %sNepoužitelný RAR souborNechtěná přípona v souboru %s (%s)Neočekávaná přípona v rar souboru %sDostupná aktualizace!Nahrát NZBVyužití cacheUživatelská složkaUživatel přihlášenUživatel přihlášen do webového rozhraníÚspěšně ověřeno s využitím SFV souborůOvěřujiOvěřuji opravuKontroluji...VerzeVelmi nízkáČEKÁNÍ %s sČekáníVýstrahyVýstrahyWebové rozhraníStředaWikiRokMusíte nastavit maximální rychlost linky předtím než začnete nastavovat limity pro přenosNalezen UNRAR verze %s, doporučujeme verzi %s nebo vyšší.
Vaš soubor s hesly obsahuje více než 30 záznamů, použití všech těchto hesel vude trvat dlouho. Zkuste omezit počet hesel.[%s] Chyba "%s" během spojování souborů[%s] Chyba "%s" během rozbalování RAR souborů[%s] Spojeno %s souborů[%s] Špatné nastavení PAR2, zkontrolujte volby v Konfigurace->Přepínače[%s] Rychlá kontrola OK[%s] opraveno v %s[%s] Zkontrolováno v %s, všechny soubory jsou spravné[%s] Zkontrolováno v %s, je nutná opravaddendnídeaktivovat serverpovolit serverhhodinahodinmručněminutaminutvypnutozapnutoneboProgram par2... nenalezeno!sekundasekundvíce v protokolovacím souboruProgram unrar... nenalezen!týden././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.2015984 SABnzbd-4.3.2/locale/ru/LC_MESSAGES/SABnzbd.mo0000644000000000000000000016543614625637243017534 0ustar00runnerstaff\%o%dM&' ()*'+++ +,4,T,\,c,k,s,{,,?-S-[-Rk-[-. !./.6.:. B. O. Z.d.z....*. . ...// 7/C//// ///~0 0 0001!816Z1-1111 22.2'K2s222S2 2 33%3"438W33 333 333 4 4*,4W4i4 p4z4 4 44444 44 4554#5X5?`55555, 6,761d6666 6'66 6 777)7$/7T7 d7q7#777777 7884,8a8Sv88H8 9 %929 A9 N9([9.9)9,9< :&G:n:':::: : ;#; 2;<; R;`;g;;;%;!;;+< E<f<!<!<<'<"=%=;=T=r= ======A=>'6>^>~>>>->/>!> ?#?&+?"R?u?{??? ? ?? ??? ? @@ $@ .@9@ >@ K@X@]@e@{@@@-@ @@@6@G+AsAA AA,AA%A# BDBXBxBB'BB ZC gCrCzCC5C CCcCHUDoD]E)lE EEE EE$EEE0E.F?FFFLF QF \F gFrF yFFFFFFFFFF F"FG"G )G5G HG/VGGGGGcG"2H3UHHH!H!HHII&I 5IAI JI*XIII II I(I IIIJJ,J@J RJ_JuJM|JJ#JR K<\KKK"KKKL L8LNL-VLLL LL LLLL L M ,M7M QM]McM&xM MMMMM M M MNN(N>NEN7O JOTOcOO OOO O OO OO PP2P JPTP iPvPP)P0P Q QQ$Q 4Q>QPQXQnQQQQQQQQQ QR R!R[=3\ q\ |\\,+]X] a]>k]]]]l^"r^A^^^ ^E^4_L_.h________ ``%` E`O`d`-`#`.`aa%ab,a$a a aaa%a b bb!b 1b=bFbNbVb_bnb b b!bbb#b)bc/cJAccc&c'c ddddd +d9d>d@dEdKdPdRdYd]dbdfdidnddd dddddfeIgikmAoJq#eq&q1qYq^_Q`QFA5;Pq?•JRM@ # &1D#U=y6PL@Ԙ- IiVs04e --  &GVNe "7FU2d#ʝ7ٝ S+NΞߞp'?G%y7rS?ơ)C03t4IݢA'!i¤7ˤ_'c q٧C֨  &jEʩf۩#Bf }ת !& H/UͫD*g< + L#)p< ׭&MҮh =<O!.q,ܰ G7 !ʱWD(d-*-,,A"n6ȳIwH cQ 7[K,[DY #6+Jv/)%B Ll/Ϲ1޹K%\" ź кۺL\*`'ǻ$6T#e5Ҿ/&%Bh*.Y@s<QpC%$!?a,|2&@S qC4'Fn9<cz4%$ 28JL6xV/)2%\ BN,=Yjc&M!o#'#5Uu!\ 6GC![[ KeK]][ %6##Z~OC^ |.4' 1/Q.Zo"bo:b?*NqypN~ '^+~hMap.A+%Q<h.<K&Dro'&AhZN+9&`q 4 )!FIh H 299;s*@!4#JX   "36E L Waf9n  :  SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AcceptAccess deniedActionAddAdd NZBAdd ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAlwaysAre you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad schedule %s at %s:%sBandwidthBottomCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Complete FolderCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnection Successful!ConnectionsCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDate SortingDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable HTTPSEnable NotifyOSDEnable SFV-based checksEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExtensionExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailure in tempfile.mkstempFatal errorFeedFetchFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree SpaceFrequencyFridayFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTPS CertificateHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHighHistoryHistory Last 10 ItemsHomeHostHost SABnzbd should listen on.How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnoring duplicate NZB "%s"In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid server address.Invalid server detailsInvalid stage logging in history for %sIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedLoading %s failedLocation for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMatchedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNamingNeverNextNice ParametersNo email templates foundNo foldersNo recipients given, no email sentNoneNormalNot MatchedNotification Sent!NotificationsNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOpen a Terminal window and type the line (example):OptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOrderOriginal FilenameOther MessagesPart NumberPasswordPassword filePassword masked in ******, please re-enterPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Purge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueueQueueQueue First 10 ItemsQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemove NZBRemove NZB & Delete FilesRemove ServerRemoving %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScriptsSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer requires username and password.ServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStarting RepairStartup/ShutdownStatusStopStopping...SundaySupport the project, Donate!SwitchesSystem FoldersTEXTTOO LARGETemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeURL Fetching failed; %sUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpdate Available!UptimeUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWho should we say sent the email?WikiYear[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredcase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: ru Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3); Не удаётся найти файлы веб-интерфейса SABnbzd в %s.
Переустановите программу.

Обнаружены сохранённые данные из другой версии SABnzbd,
но данные другой программы нельзя повторно использовать.

Возможно, стоит сначала завершить очередь в другой программе.

После этого запустите данную программу с параметром «--clean».
При этом текущая очередь и журнал будут удалены!
Служба SABnzbd читает файл «%s». Обнаружено, что отсутствует файл sqlite3.dll.

Этот файл мог быть удалён плохо настроенной антивирусной программой.
Попробуйте проверить параметры своей антивирусной программы, переустановите SABnzbd и сообщите о проблеме поставщику этого антивирусного ПО.

Службе SABnzbd требуется свободный порт TCP/IP для встроенного веб-сервера.
Был проверен порт %s на %s, но он оказался недоступен.
Возможно, этот порт используется другой программой, или служба SABnzbd уже запущена.

Перезапустите службу SABnzbd, указав другой номер порта. Службе SABnzbd требуется действительный адрес сервера для встроенного веб-сервера.
Указан недействительный адрес.
Допустимые значения: localhost и 0.0.0.0

Перезапустите службу SABnzbd, указав действительный адрес сервера. SABnzbd предоставляется БЕЗ КАКОЙ-ЛИБО ГАРАНТИИ. Это свободное программное обеспечение, и его можно распространять при соблюдении определённых условий. Она распространяется по лицензии GNU GENERAL PUBLIC LICENSE версии 2 или (по вашему выбору) любой более поздней версии. %s статей содержат несовпадающие повторы%s статей с ошибками%s статей отсутствуетКаталог %s: ошибка доступа %s%s не является правильным восьмеричным значением%s не является допустимым адресом электронной почты+ отладка+ информация+удалить+исправить+распаковатьПапка для хранения копий NZBПРИМЕЧАНИЕ. Папки будут созданы автоматически при сохранении. Можно использовать абсолютные пути для сохранения за пределами папок по умолчанию.Данные не будут перемещены. Требуется перезапуск SABnzbd!Ключ APIQR-код ключа APIНеправильный ключ API. Используйте в сторонней программе ключ API из раздела «Настройка -> Общие»:Отсутствует ключ API. Введите в сторонней программе ключ API из раздела «Настройка -> Общие»:ПринятьДоступ запрещёнДействиеДобавитьДобавить NZBДобавить заданиеДобавить серверДобавлен NZBАдминистративная папкаЗадействованные категорииВозрастВсеВсегдаОстановить SABnzbd?Уверены?АргументыОграничить кэш статейИдентификатор статьиОшибка проверки подлинности. Проверьте имя и пароль.Автоматически возобновлятьЗагрузка останавливается при уменьшении свободного места до этого значения.
В байтах, после числа можно добавить K, M, G или T. Пример: «800M» или «8G»НазадРезервныйНедопустимое расписание %s в %s:%sТрафикВ конецКэширование статей в памяти для уменьшения количества обращений к диску.
В байтах, после числа можно добавить K, M или G. Пример: «64M» или «128M»Не удаётся изменить права доступа %sНе удаётся подключиться к серверу %s [%s]Не удаётся создать файл резервной копии для %sНе удаётся создать каталог %sНе удаётся создать конечную папку %sНе удаётся создать временный файл для %sНе удаётся найти шаблонны электронных писем в %sНе удаётся найти шаблон веб-интерфейса: %s. Выполняется попытка использовать стандартный шаблонНе удаётся запустить браузер. Возможно, он не было найденНе удаётся прочитать %sНе удаётся прочитать наблюдаемую папку %sНе удаётся записать INI-файл %sКатегорииКатегорияИзменения не были сохранены и будут потеряны.Для применения изменений необходимо перезапустить SABnzbd!Проверять перед загрузкойПроверять наличие обновленийПроверкаИнтервал проверки (в минутах, не менее 15). Если используется планировщик, этот параметр не отключён.Список очисткиНе удалось очистить %s.ОчиститьСбросить счётчикиНажмите, чтобы проверить введённые данные.Если закрыть окна или вкладки браузера, служба SABnzbd НЕ будет остановлена.Полная папкаЗавершеноПапка завершённых загрузокНастройкаФайл конфигурацииПодтвердите удаление журналаПодтвердите удаление очередиПодключение установлено!СоединенияНе удалось определить результат подключения (%s)Текущие заданияДругойПОВТОРежедневноСортировка датыДень месяцаДесяткипо умолчаниюБазовая папка по умолчаниюУдалитьУдалить всёУдалить после загрузкиУдалить из очереди все элементы?Не удалось удалить %s!отключеноHTTPS отключён, поскольку отсутствуют файлы CERT и KEYОтменитьОтключаться от серверов Usenet, если очередь пуста или приостановлена.Отключаться, если очередь пустаУведомления о нехватке места на дискеОшибка диска при создании файла %sНа диске нет места Принудительная приостановкаВыполнять дополнительную проверку по SFV-файлам.Неправильные учётные данные для ленты %sСбрасывается ли квота каждый день, неделю или месяц?ЗагрузитьЗагрузка завершенаНе удалось загрузитьЗагруженоЗагружено за %s со средней скоростью %sБ/сНапример,Например, 8 или 20ЗАШИФРОВАНОШИБКАИзменить данные NZBЭл. почтаУведомление по электронной почте после завершения заданияПолучательОтправительПапка шаблонов электронных писемАдрес электронной почты получателя уведомлений.Электронное письмо успешно отправленоПустоПустой NZB-файл %sОбнаружена пустая запись RSS (%s)ВключитьВключить HTTPSИспользовать NotifyOSDИспользовать проверку по SFVДоступ к интерфейсу по протоколу HTTPS.Переименовывать папкиВключите, что уменьшить использование памяти. Отключите, чтобы медленные задания не блокировали очередь.ВключенЕсли завершить путь звёздочкой (*), папки заданий не будут создаваться.Введите URLНазвание эпизодаНомер эпизодаНазвание.эпизодаНазвание_эпизодаОшибка «%s» выполнения file_join для %sОшибка «%s» выполнения par2_repair для набора %sОшибка «%s» выполнения rar_unpack для %sОшибка %s выполнения par2_repair для набора %sОшибка %s: укажите действительное имя пользователя и пароль.Не удалось создать ключ SSL и сертификатОшибка импорта %sОшибка загрузки %s: обнаружен повреждённый файлОшибка удаления %sОшибка переименования «%s» и «%s»Не удалось добавить %s: удалёнНе удалось завершить работу системыТолько при ошибкахОшибки и предупрежденияРасширениеДополнительные параметры PAR2Извлечение...ОшибкаОшибка входа на сервер %s [%s]Не удалось создать (%s)Не удалось переместить %s в %sОшибка входа на почтовый серверНе удалось закрыть базу данных (см. журнал)Не удалось разорвать соединение с почтовым серверомНе удалось составить регулярное выражение поиска: %sНе удалось подключиться к почтовому серверуНе удалось перевести систему в состояние гибернацииНе удалось импортировать %s файлов из %sНе удалось установить TLS-соединениеНе удалось переместить файлыНе удалось переименовать похожий файл: %s в %sНе удалось получить RSS-ленту из %s: %sНе удалось отправить электронное письмоНе удалось перевести систему в состояние снаНе удалось запустить веб-интерфейсОшибка в tempfile.mkstempКритическая ошибкаЛентаЗагрузитьЗагрузказагрузка %s блоков...Загрузка дополнительных блоков...Файл, содержащий все пароли, которые будут испробованы для зашифрованных RAR-файлов.Не удалось объединить файлы %sНазвание файла или путь к сертификату HTTPS.Название файла или путь к ключу HTTPS.Набор файловНазвание файлаФильтрОтфильтровывать файлы образцов (например, образцы видео).Папка, содержащая пользовательские шаблоны электронной почты.Папка для поиска NZB-файлов.Папка или путьПапкиИмя пользователя учётной записи (для электронной почты с проверкой подлинности).Пароль учётной записи (для электронной почты с проверкой подлинности).принудительныйПринудительно отключитьЗагрузить принудительноФорумсвободно на дискеЧастотапятницаДополнительные сведения доступны на нашемОбщиеСоздать новый ключПерейти к SABnzbdЗапустить мастерСертификат HTTPSКлюч HTTPSПорт HTTPSСправкаперевести ПК в спящий режимСкрыть подробностивысокийИсторияПоследние 10 элементов историиГлавнаяАдресАдрес, по которому будет доступна служба SABnzbd.Объем, который можно загрузить в месяц (K/M/G)НЕПОЛНЫЙПараметры IONiceБездействиеЕсли не указать, будет доступен только стандартный порт с HTTPS.Если снова появляется это сообщение об ошибке, попробуйте указать другой номер порта.Игнорировать образцыПропущен повторяющийся NZB-файл «%s»В папкахНесовместимая лентаНайден несовместимый файл очереди. Продолжение работы невозможноНеполная папкаНеполная последовательность файлов, которые можно объединитьНеправильное описание RSS-ленты «%s»Неправильный параметрНеправильно закодированный пароль %sНедопустимый адрес сервера.Недопустимые данные сервераНедопустимый этап ведения журнала для %sРекомендуется щёлкнуть страницу правой кнопкой мыши и добавить этот адрес в закладки, а затем использовать эту закладку для доступа к службе SABnzbd, работающей в фоновом режиме.Задание завершеноОбъединить файлыОбъединениеЯзыкОткрывать браузер при запускеОткрывать веб-браузер по умолчанию при запуске SABnzbd.Ограничение скоростиОшибка загрузки %sМесто для хранения и базы данных очереди и журнала.
Изменить можно только тогда, когда очередь пуста.Место для хранения файлов журнала SABnzbd.
Требуется перезапуск SABnzbd!Место для сохранения готовых, полностью обработанных загрузок.
Можно переопределить в пользовательских категориях.Место для хранения необработанных загрузок.
Изменить можно только тогда, когда очередь пуста.Место, где будут сохраняться NZB-файлыПапка журналаЖурналнизкийНижний регистрСоответствующиеМаксимальное число повторных попыток для каждого сервераЧисло попытокЗначениеМинимальное свободное место в папке временной загрузкиОтсутствуют статьипонедельникМесяцПодробнееНазвание фильмаНазвание.фильмаНазвание_фильмаПеремещениеПеремещение...Пакетные операцииКлюч NZBNZB-файл добавлен в очередьНазваниеИменованиеНикогдаСледующаяПараметры NiceНе найдены шаблоны электронных писемБез папокПолучатели не указаны. Электронное письмо не отправленоНичегообычныйНет соответствийУведомление отправленоУведомленияЧисло секунд между для поисками NZB-файлов.НЕОБЯЗАТЕЛЬНЫЙ парольНЕОБЯЗАТЕЛЬНОЕ имя пользователяВыкл.По окончании очередиДень месяца или недели (1 — понедельник), когда провайдер сбрасывает квоту. (дополнительно можно указать чч:мм)Загружать статьи только из начала очередиОткройте окно командной сроки и введите команду (пример):ДополнительныйДополнительный NZB (необязательно)Необязательный пароль для входа.Необязательное имя пользователя для входа.Имя файла (необязательно)ПорядокИсходное название файлаДругие сообщенияНомер частиПарольФайл паролейПароль скрыт под ******. Повторите пароль.ПутьШаблонКлючи шаблонаПриостановитьПриостановить всеПриостановить загрузку во время пост-обработкиПриостановить наПриостановить на 1 часПриостановить на 15 минутПриостановить на 3 часаПриостановить на 30 минутПриостановить на 5 минутПриостановить на 6 часовПриостановить на...Приостановить пост-обработкуПриостановленоПриостановить загрузку с началом пост-обработки и возобновить по её окончании.Приостановлен повторяющийся NZB-файл «%s»Права доступа для завершённых загрузокУчтите, что для имени компьютера 0.0.0.0 потребуется IPv6-адрес для внешнего доступаВведите данные своего основного поставщика услуг Usenet.ПортПорт, по которому будет доступна служба SABnzbd.Ошибка пост-обработки для %s (%s)Пост-обработкаОбрабатывать только проверенные заданияПост-обработкаЗапущена пост-обработкаПользовательский сценарий до помещения в очередьГотовые шаблоныНажмите клавиши STARTKEY+R и введите команду (пример):НазадПриоритетПроблема сОбработанный результатОбработкаПрограмма не запустилась!Удалить завершённые NZBУдалить неудачные NZBУдалить неудачные NZB и стереть файлыОчистить историюУдалить NZBУдалить NZB и стереть файлыОчистить очередьОчередьПервые 10 элементов очередиОчередь не пустая, папку нельзя изменить.Исправление очередиБыстрая проверка...Быстрая проверкаВыйтиКвотаОсталось квотыПериод квотыКвота исчерпана. Загрузка приостановленаRSSИнтервал опроса RSS-лентRSS-лента %s была пустойЗапущено %sРедко используемые параметры. Их описание можно просмотреть на вики-странице, доступной по кнопке «Справка».
Не изменяйте эти параметры, не изучив сначала вики-страницу, поскольку их изменение может иметь серьезные последствия.
В скобках показаны значения по умолчанию.Прочитать все лентыПрочитать лентуЧитать RSS-лентыОписание см. на вики-странице.ОбновитьЧастота обновленияОтклонитьОтносительный путь для папокосталосьУдалить NZBУдалить NZB и стереть файлыУдалить серверНе удалось удалить %sПереименоватьИсправитьОшибка исправления: недостаточно блоков восстановления (не хватает %s)ИсправлениеНе удалось исправить: %sИсправление...Заменять пробелы в названиях папокЗаменять точки в названиях папокЗаменять точки на пробелы в названиях папок.Заменять пробелы на символы подчёркивания в названиях папок.ТребуетсяТребуется категорияСброситьСбросить квотуДень сброса трафикаРазрешение адресаПерезапуститьПерезапустить без входаПерезапуск SABnzbd...РезультатВозобновитьВозобновить пост-обработкуСрок храненияПовторитьЗапуск сценарияЗапуск сценария...Запуск пользовательского сценария %sСервер SABnzbdПароль SABnzbdПорт SABnzbdМастер быстрого запуска SABnzbdИмя пользователя SABnzbdВерсия SABnzbdВеб-сервер SABnzbdОбнаружена критическая ошибка:Завершение работы SABnzbd законченоСлужба SABnzbd теперь будет выполняться в фоновом режиме.Сервер SMTPОшибка команды SQL (см. журнал)SSLсубботаСохранитьСохранить измененияОшибка сохранения %sСохранение...Сканировать наблюдаемую папкуРасписание для несуществующего сервера %sРасписаниеСценарийСценарииНомер сезонаВыберите язык веб-интерфейса.Включайте, только если вашим провайдером разрешены SSL-соединения.Отправлять RSS-уведомленияОтправлять электронное письмо, когда в очередь добавляется задание из RSS-ленты.Отправлять электронное письмо, когда на диске нет места и загрузка SABnbzd приостановлена.%s отправлено в очередьСортировка сериаловСерверСервер %s будет игнорироваться %s мин.Данные сервераАдрес сервера «%s:%s» является недопустимым.Требуется адрес сервераДля сервера требуется имя пользователя и пароль.СерверыШаблон прав доступа для завершенных файлов и/или папок.
В восьмеричном формате. Пример: «755» или «777»Укажите сервер своего провайдера для исходящей почты.Настройка завершена.Возобновлять загрузку после сброса квоты?Показать всеПоказать неудачныеПоказать журналНазвание сериалаПоказать подробностиПоказать интерфейсНазвание.сериалаНазвание_сериалаВыключитьвыключить ПКЗакрыть SABnzbdЗавершение работыПолучен сигнал %s. Выполняется сохранение и выход...РазмерНекоторые файлы не прошли проверку «%s»Строка сортировкиСортировать по возрасту от новых к старымСортировать по возрасту от старых к новымСортировать по названию от А до ЯСортировать по названию от Я до АСортировать по размеру от крупных к мелкимСортировать по размеру от мелких к крупнымСортировкаИсточникОсобаяСкоростьОграничить скоростьперевести ПК в режим ожиданиязапуск исправленияЗапуск/остановкаСостояниеОстановитьОстановка...воскресеньеПоддержите проект. Сделайте пожертвование!ПереключателиСистемные папкиТЕКСТСЛИШКОМ БОЛЬШОЙПапка временной загрузкиПроверить электронную почтуТестовое уведомлениеПроверить серверДанные проверки сервера...Эта кнопка перезапустит SABnzbd и полностью
перестроит содержимое очереди, не трогая уже загруженные файлы.
При этом порядок очереди будет изменён.Чтобы включить ленту и автоматически проверять обновление её содержимого, установите флажок напротив её названия.
После добавления ленты загружаться будут только новые её элементы, а не те, что были опубликованы раньше (если только на нажать кнопку «Загрузить принудительно»).Не задано имя компьютера.Количество подключений, разрешённое провайдеромПодключения не настроены. Добавьте хотя бы одно подключение.В папке загрузки есть осиротевшие задания.
Их можно удалить (вместе с файлами) или поставить обратно в очередь.По этому ключу сторонние программы смогут загружать файлы в доступ к SABnzbd.По этому ключу сторонние программы смогут получить полный доступ к SABnzbd.за этот месяцза эту неделюЭта кнопка перезапустит SABnzbd.
Используйте её, когда программа работает нестабильно.
Загрузка будет приостановлена до перезапуска и снова возобновлена после запуска.Отправка тестового письма на указанный почтовый ящикчетвергВремя ожидания истеклоТайм-аут. Попробуйте включить SSL или использовать другой порт.Время ожиданияНазваниеTo: %s From: %s Date: %s Subject: SABnzbd: на диске нет места Привет. Система SABnzbd остановила загрузку, поскольку на диске почти не осталось свободного места. Освободите место на диске и возобновите работу SABnzbd вручную. за сегодняПриостановка из-за нехватки места на дискеСлишком много подключений. Приостановите загрузку или повторите попытку позжеВ началовсегоУстранение неполадокПопытаться спрогнозировать успешное завершение до фактической загрузки (медленнее!)Проверка SFV-суммыПопытка загрузить NZB с %sПопытка установить статус для несуществующего сервера %sПопытка распаковки RAR-архива с паролем «%s»вторникТонкая настройкаТипНе удалось загрузить URL: %sРазблокироватьНеизвестная ошибка декодирования %sНеизвестное действие: %sРаспаковатьРаспаковка %s файлов или папок в %sРаспаковкаНе удалось распаковать: %sНе удалось распаковать: ошибка CRCОшибка распаковки: архив защищён паролемОшибка распаковки: не удаётся найти %sНе удалось распаковать: ошибка записи или на диске нет места?Пустой NZB-файлДоступно обновление!Время работыИспользовать временные названия при пост-обработке. Отключите, если ваша система обрабатывает это неправильно.Используется до того, как NZB помещается в очередь.Используемый кэшПользовательские папкиИмя пользователяЗначенияПроверка SFV-сумм прошла успешноПроверкаПроверка...ВерсияПросмотреть журнал сценарияОЖИДАНИЕ %s сПРЕДУПРЕЖДЕНИЕожиданиеПредупреждениепредупрежденийНаблюдаемая папкаЧастота сканирования наблюдаемой папкиВеб-интерфейссредаОт кого будут отправляться уведомленияВики-сайтГод[%s] Ошибка объединения файлов: %s[%s] Ошибка распаковки RAR-файлов: %s[%s] Объединено файлов: %s[%s] Нет PAR2-файлов[%s] Программе PAR2 переданы неправильные параметры. Проверьте параметры в разделе «Настройка -> Переключатели»[%s] Быстрая проверка прошла успешно[%s] Исправлено за %s[%s] Проверено за %s. Ошибок нет[%s] Проверено за %s. Требуется исправлениеcase-adjustedдденьднейотключить сервервключить серверфайлччасчасовосталосьмвручнуюминминутвыкл.настр.Исполняемый файл par2... НЕ найденссекундсм. журналтекстИсполняемый файл unrar... НЕ найденнеделя././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993698.8008842 SABnzbd-4.3.2/locale/ro/LC_MESSAGES/SABnzbd.mo0000644000000000000000000020202114625637243017504 0ustar00runnerstaffM4o4d]56 789'::: ;$;D;d;l;s;{;;;1;;A;+<?<<==R=[k==#=V=T>q>$>> >>'>'>?#?+? :? G? R?\?r???'?????*? *@ 8@B@V@i@r@/z@ @@:A?A%FA#lAA AAAABBIBcB B BBBB!C6?C-vCCC"C6C+D GDRDG[DlD<E.ME'|E EEEEESE LFYFoFuF"F8FFFF GGU9GG G*GGG#G#H:H MHYH*jH;HHH HH3H .I ;I GITI[IzIII II III&I !J)+J UJ(cJJJ4J4JK? K`KzKK KK,K,L1.L`LiL|LL'LL5L M'#M KMYM ^M kMuM|MM$MM MM#MN N*N0NBN]N dN pN}NNNNNN4OQOSfOOOOPHP YP cPpP P PP(P.P)P,!Q<NQ&QQ'QQQR ;R \RgR8vRR R RRR SS#SCSVS%mS!SS+S T"T!=T*_T!TT#T'T" U0U#MUqU!U!UUUV"VBV\VwV VVVVVVVVWA*WlW'W!WWWX XX-X/GX!wX XX&X"X9X1Y7YHYWYjY pY {YY YYY YYY Y Y' Z1ZCZ [Z eZpZ uZ ZZZZZZ Z[ [[[;3[-o[ [[ [[6[G\K\"Z\}\<\E\D] a]l],~]]%]#]^^F;^^^'^^^Hk_;_ _ _}` ````5` `n`mauaaqac bHpbob])c)c cccccc ccdd$2dWdgd0odddddd d d dd ddee*e/eGeNeTeYe iese e"e+eee e e f f4f'Gf of }f/ffff;f+gc;g"g#g3gh/h8h!Rh!thh%hhh hii "i -i9i Bi*Pi {iii ii i(i iiijj/jCj Ujbj{jjjjUjM!kokk#kk%kkR l<`lll"lllm$mn GnTn enpnnnnnn n n oo .o :oEoNo<]ooooo&o o pp'p,p 2p =p Jpkpppppppq qqqr*r 2r+?rkrrr r r rr rrr ss /s = +) U_,1 :>DE"K&nA׆ۆ E4Sq.ԇ)a<̈--/4d -܉6 "A#d."ڊ"$!FZ l wb$ . 9FOc#r"Œ%Ɍ  ( 8DMU]fu RUMP=0܎! /4JEOB؏+`#)ڐJL&`/&ˑ' #137< KY^`ekpry} ÒȒo" ( &%E"k  ›K(.NWN4 fu"*n۞Jg"Ÿ,˟2+ 3?Uix.# 32Q  ˡ֡=ߡ,Ƣ*֢(* JU \f " &C'j&Ĥ"@7O+I!+ M W]aq@16r.ا! !.\Lۨ(F"i x ʩ JV.j"Ъ &*9=d īͫ8ԫ  (5=]f~ &Ӭ * #-1_/t! ƭ<ѭ=LMT"Ů%ۮ  .'%V<| ïگ=N6n % װ  #%)O`p. ñͱѱ& '8M jŲ3x4!ϳ"K e q } %7д&5/Fe.۵.2Rp 95J Y-c%Ʒ4%!/G!w'/='/W+o4&й .G(b%'(ٺ$!''IqԻ  #=:Z!'#߼"& BO_0f-(Ž %"*DM ˾  #5=s{, $ +8$J oy2$E<:  7\$/Kb(F 3'(7"`N'5]fZNUr">x jRSx- > K Y e"q  $ (86o    + 6A P] w*7 #7&L s 5[#Oes#,6*$a !''$AHa p| ;  &13et,+=+i rY))-,o;K&)#M*\#3s )  -C[u{-"7 GR[<k!+*:Pckq)$# 7B` ~$, 6 ?`g w#)8 IVC^  ,+ 682o   )5 FRf&$%,4 CP$c Z0? O!\~$ (  8B*\ %G  "'=J;A8M]3d2*%+D&U.|D{2t+  &2JY k w  #3G^FuF,,0D]D $8I\b +  * /89r  x 6@(]=NLC 3)@j2Atx\ '(gV 61W ZV hu,: A3Y( #3J6,(6,;T(t. +(wT0  .K0\+&  ,5FY k u !d|OeD2.w-YPJ}+.E9tS/!Ik04).038M_ginry{   SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCategory folder cannot be a subfolder of the Temporary Download Folder.Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Changes have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfiguration locked, cannot save settingsConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not determine connection result (%s)Could not load additional certificates from certifi packageCurrent SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDirect UnpackDirect Unpack was automatically enabled.Disable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sDuplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Executes a custom scriptExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job failedJob finishedJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLog inLog outLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly external access requires loginOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesPROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPost-processing was abortedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRefused connection with hostname "%s" from:RejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...ResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...SubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETabbed layout
(separate queue and history)Temp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The Completed Download Folder cannot be the same or a subfolder of the Temporary Download FolderThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerifyingVerifying repairVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] The command in build_command is undefined.[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: ro Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1)); SABnzbd nu poate găsi fişierele de la interfaţa-web %s.
Vă rugăm să reinstalaţi programul din nou.

SABnzbd a detectat informaţii salvate de la o altă versiune SABnzbd
dar nu poate să refolosească informaţiile de la cealaltă versiune de program.

Ar fi bine să terminaţi coada mai întâi cu cealaltă versiune de program.

După aceia , porniţi programul cu opţiunea "--clean".
Aceasta va şterge coada curentă şi istoricul!
SABnzbd citeşte fişierul "%s". SABnzbd a detectat că fişierul sqlite3.dll lipseşte.

Unele antivirusuri şterg acest fişier.
Vă rugăm să verificaţi antivirusul , încercaţi să reinstalaţi SABnzbd şi plângeţivă autorului antivirusului.

SABnzbd are nevoie de un tcp/ip port liber pentru serverul său intern.
Portul %s de pe %s a fost încercat , dar nu este disponibil.
Alt program foloseşte portul sau SABnzbd este deja pornit.

Vă rugăm să reporniţi SABnzbd cu un număr de port diferit. SABnzbd are nevoie de o adresă gazdă validă pentru serverul său intern.
Dvs. a-ţi specificat o adresă invalidă.
Valori sigure sunt localhost şi 0.0.0.0

Vă rugăm să reporniţi SABnzbd cu o adresă gazdă bună. SABnzbd vine cu ABSOLUT NICI O GARANŢIE. Acesta este software gratis, şi sunteţi binevenit să-l redistribuiţi în anumite condiţii. Este licenţiat sub GNU General Public License versiunea 2 sau (la opţiunea dumneavoastră) orice versiune ulterioară. %s articolele au avut duplicate diferite%s articolele au fost incorecte%s articolele au fost lipsădosarul %s: eroare accesare %s%s nu este o valoare octală corectă%s nu este o adresă email validă+ Depanare+ Info+Ştergere+Reparare+DezarhivareDosar Copie de Siguranţă .nzb0 este prioritatea cea mai ridicată, 99 este prioritatea cea mai scăzutăFişier executabil 7za ... Indisponibil!
Dacă este activată autentificarea v-a trebuie să vă logați din nou.NOTĂ:Dosarele vor fi create automat când se Salvează. Puteţi utiliza căi absolute pentru a salva în afara dosarelor implicite.Informaţiile vor nu vor fi mutate. Necesită repornire SABnzbd!API (fără Configurare)Cheie APICheie API sau Cod QRCheie API incorectă, Folosiţi cheia api din Configurare->General în programul dumneavoastră terţ:Cheie API lipsă, vă rugăm să introduceţi cheia api de la Configurare->General în programul dumneavoastră terţCheie API pentru ProwlAnulează sarcini care nu pot fi terminateSarcina „%s” a fost anulată din cauza fișierului RAR criptat (toate parolele oferite au fost încercate)Anulat nu poate fi finalizatTerminat, encriptare detectatăOprit, extensii nedorite detectateAcceptăAcces interzisAcțiuneAcțiuni când se descarcă un RAR encriptatAcțiune când se detectează o extensie nedorităAdaugăAdaugă NZBAdaugă fișiere NZB Adaugă PlanificareAdaugă ServerNZB-uri AdăugateDosar AdministrativCategorii AfectateVârstaToateToate fișierele merg într-un singur directorTesteaza şi versiuni de încercareÎntotdeaunaToken de AplicațieToken de Aplicație (necesar)Sunteţi sigur că doriţi să inchideţi SABnzbd?Sunteţi sigur?ArgumenteLimită Cache ArticoleIdentificator ArticolCel puținCel multAutentificare nereuşită, verifică nume utilizator/parolă.Auto repornireAuto-pauză când spaţiul liber este sub această valoare.
În octeţi, urmaţi opţional de K, M, G, T. De exemplu: "800M" sau "8G"ÎnapoiServer SecundarRăspuns greșit de la Pushbullet (%s): %sRăspuns greșit de la Pushover (%s): %sProgramator Greşit %s la %s:%sDescărcatCoadăRăsfoireStochează articolele în memorie pentru a reduce acesul disc.
În octeţi, opţional urmaţi de K,M,G. De exemplu : "64M" sau"128M"AnuleazăNu pot accesa fișierul PID %sNu pot schimba permisiunile lui %sNu mă pot conecta la serverul %s [%s]Nu pot crea copie de rezervă pentru %sNu pot crea dosarul %sNu pot crea dosar final %sNu pot crea fişier temporar pentru %sNu pot gasi şabloane email în %sNu se poate găsi şablon web:%s, se încearcă şablon standardNu pot porni navigatorul web, probabil nu a fost găsitNu pot citi %sNu pot citi Dosar Urnărire %sNu pot trimite, informații necesare lipsăNu pot scrie în baza de date ISTORIC, verificaţi permisiunile de acces.Nu pot scrie în fişierul INI %sCategoriiCategorieDirectorul de categorii nu poate fi un subdirector al directorului de descărcări temporare.Neportivire certificat: denumirea serverului nu este listată în certificat. Aceasta este o problemă de server.Certificat invalid. Este cel mai probabil o problemă de server.Modificările nu au fost salvate, şi vor fi pierdute.Modificările vor necesita repornirea SABnzbd!Selectează totVerifică înainte de descărcareVerifică Versiuni NoiSe verificăSe verifică fișierele extraInterval verificare (în minute, cel puţin 15). Inactiv când se foloseşte Planificatorul!Listă CurăţenieŞtergerea lui %s nereuşită.ŞtergeResetează StatisticiClic pentru a testa detaliile introduse.Închidere a oricărei ferestrele browser/file NU va închide SABnzbd.Aspect compactDosar CompletVitează completă directorFinalizatDosar Descărcări FinalizateDirectorul de descărcări finalizate %s se află pe sistem de fișiere FAT, limitând dimensiunea maximă a fișierului la 4GBConfigurareFişier ConfigurareConfigurație blocată, nu pot salva setărileConfirmă Ştergere IstoricConfirmă Ştergere CoadăConectare %s@%s eșuată, mesaj=%sConexiune Reuşită!Conectare eșuată!ConexiuniFișier RAR coruptNu pot determina reultatul conexiunii (%s)Nu pot încărca certificate adiționale din pachetul certifiPlanificări CurentePersonalizatDUPLICATZilnicBază de date Istoric coruptă, creat un nou fişier golSortare DatăFormat datăZi din lunăDeceniuEroare decodare: lipsă memorieImplicitDosar de Bază ImplicitŞtergeȘterge totŞterge după descărcareŞtergeţi toate obiectele din coadă?Ştergere %s nereuşită!DispozitivDispozitiv la care să se trimită mesajulDispozitiv(e)Dispozitiv(e) la care să se trimită mesajulDezarhivare directăDezarhivarea directă a fost activată automat.Dezactivează gestionarea cotelorDezactivatHTTPS dezactivat din cauza fișierelor invalide CERT și KEYDezactivează HTTPS din cauza lipsei fişierelor CERT şi KEYIgnorăDeconectează de la serverul(ele) Usenet când coada e goală sau în pauză.Deconectează când Coada e GoalăNotificări Disc PlinEroare disc la crearea fişierului %sDisc plinDisc plin! Pauză ForţatăFă o verificare extra bazată pe fişiere SFVAutentificare invalida pentru flux %sCota se resetează în fiecare zi, săptămână sau lună ?DescarcăDescărcare terminatăDescărcarea a eșuatDescarcă toate fișierele par2Descărcare euată, - Nu este pe serverul(ele) dumneavoastrăViteză de descărcare directorDescărcarea ar putea eşua, doar %s din %s disponibilDescărcateDescărcat în %s cu o medie de %sB/sNZB duplicatDe ex.De ex. 8 sau 20ENCRIPTATEROARE:Editează Detalii NZBEmailNotificări Email Sarcină TerminatăDestinatar EmailExpeditor EmailDosar Şabloane EmailAdresă de email către care se trimite email.Email reuşitUrgențăGolFişier NZB gol %sValoare RSS gasită a fost goală (%s)ActiveazăActivează 7zipActivează HTTPSActivează NotifyOSDActivează notificări ProwlActivează notificare PushbulletActivează notificări PushoverActivează verficări SFVActivează notificări WindowsPermite acesarea interfeţei de la o adresă HTTPS.Activează redenumire dosarActivează pentru folosire de memorie mai puţină. Dezactivaţi pentru a preveni ca sarcinile lente să blocheze coada.Activează scriptul de notificareActivează gestionarea cotelorActivează dezarhivarea recursivăActivatFinalizarea unei căi cu un asterix * va preveni crearea de dosare sarcini.Introdu URLNume EpisodNumăr EpisodNume.EpisodNume_EpisodEroareEroare "%s" în timpul file_join a %sEroare "%s" în timpul rulării par2_repair pe setul %sEroare "%s" în timpul rar_unpack a %sEroare %s în timpul rulării par2_repair pe setul %sEroare %s: Trebuie să furnizaţi un nume utilizator şi parolă validEroare la crearea cheiei şi certificatlui SSLEroare importare %sEroare încărcare %s, fişier corupt detectatEroare ştergere %sEroare redenumire "%s" în "%s"Eroare adăugare %s, ştergemEroare la oprirea sistemuluiDoar-eroriErori/AvertismenteLipsesc module esențiale, descărcarea nu poate începe.Execută script personalizatÎnchide SABnzbdExtensieAcces extern la internetParametri Extra PAR2Dezarhivare...NereuşitAutentificare nereuşită la serverul %s [%s]Facere nereuşită (%s)Mutare %s în %s nereuşităAutentificare server mail nereuşităÎnchidere bază de date nereuşită, vedeţi jurnalÎnchidere conexiune mail nereuşităCompilarea unei căutări regex nereuşită: %sConectare server mail nereuşităPunere sistem în hibernare nereuşităImportare %s a fişierelor de la %s nereuşităNu am putu inițializa %s@%s din cauza următorului motiv: %sIniţializare conexiune TLS nereuşităNu am putu muta fişierEșuare la citirea fișierului cu parole %sRedenumire fişiere similare : %s în %s nereuşităDescărcare %s: %s din RSS nereuşităNu am putu trimite mesajul ProwlNu am putut trimite notificări în FereastrăTrimitere email nereuşiăEșuare la trimiterea notificării macOSNu am putu trimite mesajul pushbulletNu am putut trimite mesajul de pushoverPunere sistem în aşteptare nereuşităPornirea interfeţei-web nereuşităNu am putu porni interfața web: Eșuare la încărcarea fișierului: %sEșuare duplicat NZB „%s”Eroare în tempfile.mkstempEroare fatalăEroare fatală la salvareEroare fatală în AssemblerFluxDescarcăDescarcă NZB din URLDescărcareDescărcare %s blocuri...Descărcare blocuri extra...Fişier ce conţine parole pentru fişiere RAR encriptate.Unirea fişierului %s nereuşităNume fişier sau cale Certificat HTTPS.Nume fişier sau cale cheie HTTPS.Nume fişier sau cale Cheie HTTPS.Fișierul nu este pe serverSet fişiereNume de fișierFiltruIgnoră fişiere monstră (de ex. monstre video)Dosar ce conţine şabloane email utilizator.Dosar pentru supraveghere fişiere .nzb.Dosar/CaleDirectoarePentru email autentificat, nume cont.Pentru email autentificat, parola.Pentru servere: asigurați-vă că numele sun comparibile cu WindowsForțeazăForţează DeconectareaDescărcare ForţatăForțează deconectareaForumSpațiu liberFrecvenţăVineriDe la SxxEyyAPI CompletInterfață Web completăAjutor suplimentar poate fi găsit pe pagina noastrăGeneralGenerează o Cheie NouăDu-te la SABnzbdDute la vrăjitorPorturile HTTP și HTTPS nu pot fi aceleașiCertificat HTTPSCertificate Cheie HTTPSCheie HTTPSPort HTTPSAjutorHibernare PCAscunde detaliileAscunde/arată fișierele finalizateRidicatăIstoricIstoric Ultimele 10 ObiecteLimită maximă la IstoricȚine-ți tasta shift pentru a selecta un intervalPagina de pornirePagină de pornireGazdăNume Gazdă unde SABnzbd va asculta.Cât timp sau până când doriți să întrerupeți? (în Engleză!)Cât de mult poate fi descărcat în acestă lună (K/M/G)INCOMPLETParametri IONiceAdresa IPv6InactivDacă e gol, portul standard va asculta doar în HTTPS.Dacă primiţi acest mesaj de eroare din nou, vă rugăm să încercaţi un alt număr.
Ignoră MonstreIgnoră orice director din interiorul arhivelorIgnorăm duplicat NZB "%s"Extensie nedorită în fișierul RAR al „%s”. Fișierul nedorit este %sÎn cazul "Întrerupere", dumneavoastră trebuie să introduceți parola și să reluați sarcina.În cazul repornirii SABnzbd acest ecran va dispărea în mod automat!În dosareFulx RSS incompatibilFişier coadă găsit incompatibil, nu pot înaintaDosar IncompletSecvenţă incompletă de unire fişiereDescriere flux RSS incorectă "%s"Parametru IncorectParolă %s codificată greşitFișiere par2 invalide sau parametri PAR2 invalizi, nu pot verifica sau reparaAdresă server invalidăDetalii server invalideJurnal istoric stagii invalid pentru %sProblemeEste recomandat să faceţi clic dreapta şi să faceţi o scurtatură , pe care să o folosiţi pentru a accesa SABnzbd când rulează în fundal.Sarcina „%s” este probabil criptată din cauza unui RAR cu același nume în acest RARSarcina „%s” este probabil criptată: „parolă” în fișierul „%s”Sarcină eșuatăSarcină terminatăSarcinile vor începe dezarhivarea pe parcursul descărcării pentru a reduce timpul de postprocesare, Funcționează doar pentru sarcinile care nu necesită reparare.Uneşte fişiereleUnimLimbăPorneşte Navigator Web la PornirePorneşte navigatorul web implicit când se porneşte SABnzbd.Limitare de VitezăListă de extensii fișiere ce trebuie să fie șterse după descărcare.
De exemplu: nfo or nfo, sfvSe încarcăÎncărcarea %s nereuşităAdresa IPv4 localăStocarea locală (module cookie) sunt dezactivate în browserul dumneavoastră, setările de interfață vor fi pierdute la încridegea browserului!Locaţia coadei admin şi istoricul bazei de date.
Poate fi folosit doar când coada e goală.Locaţie a fişierelor jurnal ale SABnzbd.
Necesită repornire SABnzbd!Locație pentru stocare , a descărcărilor procesate complet.
Poate fi suprascris de categoriile definite de utilizator.Locaţie de stocare a descărcărilor neprelucrate.
Poate fi schimbată doar atunci când coada este goală.Locaţie unde fişierele .nzb vor fi stocate.Dosar JurnalAutentificareDeconectareJurnalizareAm pierdut conexiunea cu SABnzbd..ScăzutăLitere MiciFă Windows compatibilPotriviteViteză maximă a conexiuniiNumăr Maxim reîncercări pe serverNumăr Maxim reîncercăriSemnificaţieMinim de Spaţiu Liber pentru Dosar Descărcare TemporarArticole lipsăModeratLuniLunăMai multNume FilmNume.FilmNume_FilmMutareMutare...Operaţii-MultipleCheie NZBNZB adăugat în coadăNumeServer de nume/Căutare DNSRedenumireNiciodatăUrmătorulParametri NiceFără accesŞabloane email negăsiteFără dosareDestinatar necunoscut, niciun email trimisNu am găsit nici o metodă potrivită de autentificareNiciunulNormalNepotrivitIndisponibilCentru NotificăriScipt de NotificareNotificare Trimisă!Scriptul de notificare "%s" nu existăNotificăriNotificăOSDNumărul de secunde între scanarea de fişiere .nzb.Parolă Cont OPŢIONALNume Cont OPŢIONALOpritCoadă de descărcare veche detectată, utilizează Stare->Reparare pentru a converti coadaLa terminarea coadei de descărcareÎn ce zi a lunii sau săptămână (1=Luni) ISP dumneavoastră resetează cota? (Opțional cu hh:mm)Ia Articole doar din Vârful CoadeiDoar accesul extern necesităr autentificareDeschide fereastra Terminal şi scrie linia (exemplu):Deschide dosar descărcări completeOpţionalNZB Suplimentar OpţionalParolă autentificare opţionalăNume Utilizator autentificare opţionalOpţional specifică un nume de fişierSau trage fișierele în fereastră!OrdineNume de Fişier OriginalSarcini orfaneAlte MesajeSE PROPAGHEAZĂ %s minParametriiNumăr ParteParolăFișier paroleParolă ascunsă în ******, Vă rugăm să re-introduceţiParolatCaleȘablonModel CheiePauzăPauză ToateÎntrerupe Descărcarea în Timpul Post-ProcesarePauză timp dePauză timp de o orăPauză timp de 15 minutePauză timp de 3 orePauză timp de 30 minutePauză timp de 5 minutePauză timp de 6 orePauză timp de...Întrerupe sarcinile cu prioritate ridicatăÎntrerupte sarcinile cu prioritate redusăÎntrerupe sarcinile cu prioritate normalăPauză post-procesareÎntreruptSarcina „%s” a fost întreruptă din cauza fișierului RAR criptat (toate parolele oferite au fost încercate)Întrerupe descărcare la începerea post procesării şi reporneşte când e terminată.Întrerupem duplicat NZB "%s"Procent din viteza conexiuniiPermisiuni pentru descărcări finalizateCheie API personalăCheie API personală pentru Prowl (necesară)Note personaleVă rugăm să fiţi conştienţi că numele gazdei 0.0.0.0 va avea nevoie de o adresa IPv6 pentru acces externVă rugăm să introduceţi detaliile furnizorului dvs principal de usenet.PortPortul pe care SABnzbd îl va asculta.Post Procesare Nereuşită pentru %s (%s)Post procesarePost-Procesează Doar Sarcinile VerificatePost-procesarePost-procesare pornităPost-procesarea a fost întreruptăArticolele vor fi întrerupte până ce vor avea cel puțin vechimea aceasta. Dacă setați prioritatea descărcării ca Forțat evitați această întârziere.Scriptul pre-coadă a marcat sarcina ca nereușităScript utilizator Pre-CoadăPresetăriApasă Start+R şi scrie linia (exemplu):PrecedentPrioritateProblemă cuRezultat ProcesatÎn curs de procesareAplicaţia nu a pornit!Întârziere de propagareProwlAdresa IPv4 publicăŞterge NZB-uri CompleteŞterge NZB-uri nereuşiteŞterge NZB-uri Nereuşite & Fişiere ŞterseŞterge IstoriculŞterge NZB-uriŞterge NZB-uri & Fişiere ŞterseGoleşte CoadăPushbulletPushoverVersiune PythonScriptul Python „%s” nu are permisiuni de executare (+x)CoadăPune la Coadă Primele 10 ObiecteCoadă finalizatăLimită maximă la coadăCoada nu este goală, nu pot schimba dosar.Coadă reparareVerificare Rapidă...Verificare RapidăIeșireCotăCotă rămasăPerioadă CotăCotă epuizată, întrerupem descărcareaVerificarea fișierelor RAR a eșuatFișierele RAR verificate cu succesRSSInterval Verficare RSSFluxul RSS %s a fost golDurată %sOpţiuni folosite rar. Pentru explicaţiile şi semnificaţia lor, click pe meniul Ajutor şi vizitează pagina Wiki.
Nu modificaţi aceste setări fără a verifica mai întâi pagina Wiki , pentru că unele pot cauza probleme serioase .
Valorile originale sunt în paranteze .Citeşte Toate Fluxurile AcumCiteşte FluxCiteşte fluxuri RSSCitește toate feed-urile RSSCiteşte Ajutorul Wiki despre asta !ReîmprospăteazăRată actualizareConectare refuzată cu gazda „%s” de la:RespingeDosarele relative se bazează peRămasȚine-mă minteŞterge NZBŞterge NZB & Fişiere ŞterseŞterge ServerElimină toate fișierele selectateElimină sarcinile finalizateElimină sarcini nereuşiteŞtergerea %s nereuşităElimin sarcinaElimin sarcinileRedenumeșteReparăReparare nereuşită, blocuri reparare insuficiente (%s mai puţin)Se reparăReparare nereuşită, %sReparare...Repetă testÎnlocuieşte Spaţiile din Numele DosarelorÎnlocuieşte punctele din Numele DosarelorÎnlocuieşte puntele cu spaţii în numele dosarelor.Înlocuieşte spaţiile cu _ în numele dosarelor.NecesităNecesită cont ProwlNecesită un cont PushbulletNecesită cont PushoverNecesităCategoriaReseteazăResetează Cota acumZi resetareReolvare adresăReporneșteRepornește SABnzbdReporneşte fără autorizareRepornim SABnzbd...RezultatReiaReia sarcinile cu prioritate ridicatăReia sarcinile cu prioritate redusăReia sarcinile cu prioritate normalăReia post-procesareReluareTimp RetenţieReîncearcăReîncearcă toateReîncearcă toate sarcinile eșuateRulare scriptRulare script...Rulare script utilizator %sSABCTools dezactivat: nu s-a găsit o versiune corectă! (Găsită v%s, se așteaptă v%s)SABnzbd %s pornitGazdă SABnzbdParolă SABnzbdPort SABnzbdVrăjitor Pornire-Rapidă SABnzbdNume Utilizator SABnzbdVersiune SABnzbdServer Web SABnzbdSABnzbd a detectat o eroare fatală:Închidere SABnzbd terminatăSABnzbd a fost pornit cu encodarea %s, aceasta trebuie să fie UTF-8. Pot apărea probleme cu denumiri de fișiere și directoare Unicode în descărcări.SABnzbd va rula acum în fundal.Server SMTPComandă SQL Nereuşită, vedeţi jurnalSSLSâmbătăSalveazăSalvează ModificărileSalvarea %s nereuşităSalvăm..Scanează dosar urmărirePlanificare pentru un server inexistent %sPlanificareScriptCodul de ieșire a scriptului este %sScriptul a returnat codul de ieșire %s și rezultatele următoare "%s"Script-uriCautăNumăr SezonAlegeţi o limbă interfaţă web.Selectează doar dacă furnizorul dvs. permite conexiuni SSL.Trimite notificări RSSTrimite înapoi la coadăTrimite email când un flux RSS adaugă sarcini în coadă.Trimite email când discul este plin şi SABnzbd este întrerupt.Trimis %s în coadăSortare SerialeServerServerul %s utilizează un certificat HTTPS nesigurServerul %s utilizează un certificat nesigur [%s]Serverul %s va fi ignorat pentru %s minuteDetalii ServerAdresa server "%s:%s" nu este validăAdresă server necesarăDescriere serverNumele de server nu se rezolvă la DNSServerul necesită nume utilizator şi parolăEroare la server (codul server %s); nu am putu lua %s în data de %sServereSetează permisiunile pentru fişierele/directoarele finalizate.
În valori octale. De exemplu: "755" sau "777"Setează serverul dvs. ISP pentru trimitere email.Instalarea este acum completă!Se reia descărcarea după resetarea cotei?Arată toateArată NereuşiteArată JurnalizareaNume SerialArată conexiuni activeArată detaliiArată interfațaNume.SerialNume_SerialÎnchidereÎnchide PCÎnchide SABnzbdÎnchidereSemnal %s prins, salvez şi ies...MărimeUnele fişiere nu au fost verificate corect cu "%s"Ne pare rău, nu am putut interpreta informațiile. Încearcă din nou.Şir Caractere SortareSortează după Vârstă Cel mai Nou→Cel mai VechiSortează după Vârstă Cel mai Vechi→Cel mai NouSortează după Nume A→ZSortează după Nume Z→ASortează după Mărime Cel mai Mare→Cel mai MicSortează după Mărime Cel mai Mic→Cel mai MareSortareSursăSpecialVitezăLimitare de VitezăRepaus PCPorneşte VrăjitorPornire RepararePornire/ÎnchidereStareOpțiuni stare și interfațăStopSe oprește...TrimiteDuminicăSusţine proiectul, Donează!Eroare suspectă în sistemul de descprcareComutatoareDosare SistemPerfromanță Sistem (Pystone)TEXTPREA MAREInterfață tabelară
(coadă și istoric separate)Dosar TemporarDosar Descărcare TemporarEmail TestNotificări TestTest ServerTestez detalii server...Butonul "Reparare" va reporni SABnzbd şi face o reconstrucţie completă
a conţinutului coadei de descărcare , menţinând fişierele deja descărcate.
Acest lucru va modifica ordinea în coada de descărcare.Directorul de descărcări finalizate nu poate fi același, sau un subdirector al directorului de descărcări temporareCaseta de lângă numele fluxului trebuie să fie selectată pentru ca fluxul să fie verificat de obiecte noi automat.
Când un flux este adăugat , el va lua doar obiectele noi şi nu cele deja existente, cu excepţia când apăsaţi "Descărcare Forţată".Numele gazdei nu este setat.Numărul de conexiuni permis de furnizorServerul nu a răspuns în mod corect la cererea de inițiereNu sunt conexiuni stabilite. Vă rugăm să stabiliţi cel puţin o conexiune.Sunt sarcini orfane în dosarul de descărcare.
Puteţi alege în a le şterge (inclusiv fişierele) sau a le trimite înapoi în coadă.Această cheie va permite programelor terţe să adauge NZB-uri în SABnzbd.Această cheie va oferi programelor terţe acces deplin la SABnzbd.Luna aceastaAcest server nu permite SSL pe acest portSăptămâna aceastaAcest lucru va reporni SABnzbd.
Folosiţi-l atunci când credeţi că programul are o problemă de stabilitate.
Descărcarea va fi oprită înainte de repornire şi reluată ulterior.Acesta va trimite un email test către contul dvs.JoiA depăşit timpul alocatA depăşit timpul alocat : Încercaţi să activaţi SSL sau conectarea pe un port diferit.Timp ExpirareTitluFrom: %s To: %s Date: %s Subject: SABnzbd raporteaza Disc Plin Salut, SABnzbd sa oprit din descarcare, deoarece discul este aproape plin. Va rugam sa faceti loc si reluati SABnzbd manual. AziPrea puţin spaţiu disc forţez PAUZĂPrea multe conexiuni la serverul %s [%s]Prea multe conexiuni, vă rugăm să întrerupeţi descărcarea sau să încercaţi din nou mai târziuVârfTotalDepanareÎncearcă să prezici decărcarea cu succes înaintea descărcării reale (mai lent!)Încerc 7zip cu parola "%s"Încerc verificare RARÎncerc verificare SFVÎncerc să descarc NZB de la %sÎncerc să setez starea unui server nexistent %sÎncerc unrar cu parola "%s"MarţiOptimizăriTipNEDORITDescărcare URL nereuşită; %sURLGRABBER S-A BLOCATNu pot rezerva portul %s pe %s. Alt software utilizează portul sau SABnzbs rulează deja.Acces neautorizatDeblocheazăServer nedefinit!Eroare Necunoscută în timpul decodării %sAcţiune necunoscută: %sEroare necusnoscută la autentificarea la serverul de mailDezarhiveazăDezarhivează arhivele (rar, zip, 7z) conținute în alte arhive.Numărul de arhive încorporate este prea mare [%s]Dezarhivat %s fişierele/dosarele în %sDezarhivareDezarhivare nereuşită, %sDezarhivare nereuşită, eroare CRCDezarhivare nereuşită, arhiva necesită o parolăDezarhivare eșuată, fișier prea mare pentru sistemul de fișiere (FAT?)Dezarhivare eșuată, calea este prea lungăDezarhivare nereuşită, nu pot găsi %sDezarhivare nereuşită, eroare scriere sau disc plin?Încercare de conectare nereușită de la %sFişier NZB InutilizabilFișier RAR ce poate fi folositExtensie nedorită în fișierul %s (%s)Extensii fișier nedorite în fișierul rar %sExtensii nedoriteActualizare Disponibilă!Încarcă NZBÎncărcareDurata FuncţionăriiFolosește setările globale de interfațăFoloseşte nume temporare în timpul post procesării. Dezactivaţi când sistemul dvs. nu gestionează aceasta corect.Folosit înainte ca un NZB să intre în coadă.Cache FolositDosare UtilizatorCheie UtilizatorCheie Utilizator (necesară)Utilizator logatUtilizatorul s-a autentificat în interfața webSarcina cu script a utilizatorului a eșuatNume de UtilizatorValoriVerificare reuşită cu fişierele SFVSe verificăSe verifică reparareaVerificare...VersiuneFoarte scăzutăVezi Jurnal ScriptAŞTEAPTĂ %s secATENŢIE:Se așteaptăAvertismentAtenționăriDosar MonitorizatViteză Scanare Dosar MonitorizatInterfață WebMiercuriAtunci când e clar că o sarcină va eșua din cauza lipsei de date pe server(e), anulează sarcinaCând un script de utilizator returnează o ieșire diferit de codul de ieșire, sarcina v fi marcată ca fiind nereușită.Atunci când modificați adresa IP sau dacă SABnzbd este repornit sesiunea dumneavoastră va expira.Ce procent din viteza conexiuni poate fi utilizat de SABnzbd, ex. 50Ce script să fie executat pentru notificări?Cine ar trebui să spunem că a trimis email?WikiNotificări WindowsAnTrebuie să seta-ţi lățimea de bandă maximă înainte de a seta o limită de viteză.Versiunea ta de UNRAR este %s, noi recomandăm versiunea %s sau mai mare.
Fișierul tău cu parole conține peste 30 de parole, verificarea tuturor necesită mult timp. Listează doar parolele utile.Cheie personală API Pushbullet (necesară)[%s] Eroare "%s" în timpul unirii fişierelor[%s] Eroare "%s" în timpul dezarhivării fişierelor RAR[%s] Unit %s fişierele[%s] Niciun set par2[%s] PAR2 a primit opţiuni incorecte, verifică setările Configurare->Comutatoare[%s] Verficare Rapidă OK[%s] verificarea RAR a eșuat: %s[%s] Reparat în %s[%s] Comanda din build_command este nedefinită.[%s] Verificat în %s, toate fişierele sunt corecte[%s] Verificat în %s, reparare necesarăarticoleajustare nume fişierdziziledezactivează serveractivează serverfișierhorăorerămasmmanualminminutedezactivatactivatsaupaginăbinar par2 ... Negăsit!secsecundevezi fişier jurnaltextbinar unrar... Negăsit!săptămână././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993698.593483 SABnzbd-4.3.2/locale/zh_CN/LC_MESSAGES/SABnzbd.mo0000644000000000000000000017240614625637243020102 0ustar00runnerstaffZ5o5d-67 89:'w;;; ;;<4<<<C<K<S<[<1n<<A<<?====R=[;>>#>V>$?A?$^?? ???'?'?@ @@ "@ /@ :@D@Z@c@w@{@'@@@@@ @*@ )A 7AAAUAhAqA/yA AA9B>B EB%SB#yBB BBBBOCVC vC CCCC!D62D-iDDD"D6DE :EEENE.gE'E EEEESE QF^FtFzF"F8FFFG G$GU>GG GGG#GGH 'H3H*DHoHH HH3H H H HHHI I4I ;IFI \I}II&I I)II J4JJJ?RJJJJ JJ,K,3K1`KKKKK'KK5L JL'UL }LL L LLLLL$LL L M##MGM WMaMgMyMM M MMMMNN6N4SNNSNN O$O?OHGO O OO O OO(O.O).P,XP<P&PP'P$Q6QRQ rQ QQQ Q QQQ RR5R J Wa y    '( .3 b-n-$ʀ$11Fx ȁف #@\et / Ђ܂  9257Am>4=s M+ 6@, >%dlr&",&OAv ‰Eω4Rj.Պ݊ aJ͋-+Y/` ͌׌-66"m#."$*Oc u b$ 7 BOXl#{"ˏ%ҏL E O\dm } Ԑ RU?M=0!!Rt:yʒEϒB+X#)ғJD&X&'  !&(-38:AEJNQTYsw ihH˘ ʚ$tڜ$'08@H-]#9zKdƞΞ[ݞY9gğ,E*d/* "-@S cq $Ρ#3 R`g z1 ĢѢY`g w. Ԥ )I6h'ǥץ$@\w~ $( U jw $Aç ">E_[ ¨Ϩ  #18Mk ~B ۩ .5K R_oŪ2.;5qͫ&&+6b i v$8ݬ * K` dqz˭ۭ+6=DVs z Ю";NTɯܯ< +3:BJ&Q.x6,ް8 Dc't!ұ ,B Q[q!޲' $3X1q³"ճ%6&Ip´ִ%<"Vy !ݵ   D9~!ն   "',!T6v$ҷ *$;=Hy¸ɸ ܸ $ 8 FQ3c>2! 0!= _l | w % 2?\`gŻ?&# J V dp.wC$"O>N*ݽ 3$X!k8Ѿ 7%]v%`TKo  /BYI `a5OsX[l@PW^e  !u **   % 3@ P]e| *$BF M W a n{ $H]Zm!= G]du  %C JT [,h  ! +<L \f g69p#B55kr * u*~$;  % ,9@ Q^dw   %0 9.Gv}'     &3Ri  " . 5 ?Jeu + %2D T!a!33 (A Xel -&?Xt  'Nn!6%/6 =J[j$ 0 !(DK2i 0/6 U _/i/#!5Qa$zL a*X (   % 3A HU d.q*0 77H''114;BIP W dq  "9>8G $l$0p@h;E+2^e68?4F{2$9!^3 [+ Kl4& 3hJFE-V0, &'@7h+#;+V W&? fs ' :& an~    <TP[5(7+`96P(_$TS#h2# #'7GNU\cjqx%% SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedAccount expiration dateActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAdvancedAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Apply filtersAre you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBackup FolderBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCertificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sDuplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:EditEdit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExecutes a custom scriptExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Invalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Location where the backups of the configuration file and databases are stored.
If left empty, the backup will be created in the Completed Download Folder.Log FolderLog inLog outLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname.Minimum Free Space for Completed Download FolderMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie SortingMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly external access requires loginOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesPROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge LogsPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restore DefaultsResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSecure connection to serverSecuritySelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeperate multiple URLs by a commaSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETabbed layout
(separate queue and history)Temp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?Who should we say sent the email?WikiWill not work if a category folder is on a different disk.Windows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Kangwei Li , 2023 Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: zh_CN Plural-Forms: nplurals=1; plural=0; SABnzbd 无法找到位于 %s 的 web 界面文件。
请重新安装本程序。

SABnzbd 侦测到其他 SABnzbd 版本已保存的数据
但无法重新使用其他程序的数据。

您可能需要先完成其他程序的队列。

之后再使用 "--clean" 选项启动本程序。
该选项将清除当前队列及历史!
SABnzbd 读取到的文件是 "%s"。 SABnzbd 侦测发现缺少 sqlite3.dll 文件。

一些很差劲的病毒扫描程序会移除此文件。
请检查您的病毒扫描程序,尝试重新安装 SABnzbd 并向病毒扫描程序厂商反映。

SABnzbd 的内部 web 服务器需要一个空闲的 tcp/ip 端口。
已尝试端口 %s(位于 %s),但不可用。
有其他软件占用了该端口,或者 SABnzbd 已经在运行,

请使用其他端口号重启 SABnzbd。 SABnzbd 的内部 web 服务器需要有效的主机地址。
您指定的地址无效。
安全的值有 localhost 与 0.0.0.0

请使用适当的主机地址重启 SABnzbd。 SABnzbd *不负任何担保责任*。 这是一款自由软件,欢迎您在约定的条件下传播。 本软件依 GNU GENERAL PUBLIC LICENSE 第 2 版或 (若您愿意) 任意较新版本授权。 %s 篇文章存在未匹配的重复%s 篇文章损坏%s 篇文章缺失%s 目录: %s 访问出错%s 不是有效的八进制值%s 不是有效的电子邮箱地址+ 调试+ 信息+删除+修复+解压.nzb 备份文件夹0 为最高优先级,100 为最低优先级7za 可执行程序... *未*找到!
若启用身份认证,您将需要重新登录。注: 保存时将自动创建文件夹。您可以使用绝对路径以保存到默认文件夹以外的地方。数据不会自动移动。需要重启 SABnzbd 才能生效!API (不允许配置)API KeyAPI Key QR 码API Key 不正确,请在第三方程序中使用“配置”->“常规”中的 api key:缺 API Key,请将“配置”->“常规”中的 api key 输入到第三方程序中:Prowl 的 API 密钥中止无法完成的任务"%s" 任务已终止,因其包含加密 RAR 文件 (已尝试所有的密码,如果提供了的话)已中止,无法完成已中止,发现加密文件已中止,侦测到不需要的扩展名接受访问被拒绝账户到期时间动作下载到加密的 RAR 文件时采取的操作侦测到不需要的扩展名时的操作添加添加 NZB添加 NZB 文件 添加定时任务添加服务器已添加 NZB管理文件夹高级影响分类发布时间全部所有文件保存到单个目录。同时检索测试版本信息总是应用程序 token应用程序令牌 (必填)应用过滤器是否确定要关闭 SABnzbd?是否确定?参数文章缓存限制文章 id至少至多身份认证失败,请检查用户名/密码。自动续传当剩余空间低于该值时自动暂停。
单位为字节,可选添加 K、M、G、T 后缀。例如: "800M" 或 "8G"返回备份备份文件夹Pushbullet 响应异常 (%s): %sPushover 响应异常 (%s): %s定时任务 %s 存在问题,时间为 %s:%s带宽置底浏览在内存中缓存文章,以减轻硬盘访问压力。
单位为字节,可以选择加上 K、M、G 后缀。例如: "64M" 或 "128M"取消无法更改 %s 的权限无法连接到服务器 %s [%s]无法为 %s 创建备份文件无法创建目录 %s无法创建最终文件夹 %s无法为 %s 创建临时文件无法找到 email 模板:%s无法找到 web 模板: %s,正在尝试标准模板无法启动浏览器,可能未找到无法读取 %s无法读取监视文件夹 %s无法发送,缺少必要的数据无法写入“历史记录”数据库,请检查访问权限!无法写入 INI 文件 %s分类分类证书验证更改未保存,改动将丢失。变更需要重启 SABnzbd 才会生效!全选下载前检查检查新版本正在检查检查间隔 (分钟,最小值为 15)。若使用“定时任务”则不会有效!清理列表%s 清理失败。清除清除统计点击可测试所输入的信息。关闭浏览器窗口/标签页 *不会* 导致 SABnzbd 关闭。精简外观完成文件夹完成文件夹写入速度完成完成下载文件夹已完成文件夹 %s 位于 FAT 文件系统上,这样会有最大文件为 4GB 的限制。配置配置文件确认历史删除确认队列删除连接 %s@%s 失败,消息=%s连接成功!连接失败!连接损坏的 RAR 文件无法判断连接结果 (%s)当前定时任务自定义*重复*每天“历史记录”数据库已损坏,已创建空数据库代替日期排序日期格式每月特定一天年代解码器失败:内存不足默认默认基本文件夹删除全部删除下载后删除删除队列中全部项?删除 %s 失败!设备信息发送的目标设备设备信息发送的目标设备禁用配额管理禁用由于缺少 CERT 及 KEY 文件,已禁用 HTTPS舍弃队列为空或暂停时从 Usenet 服务器断开连接。清空队列时断开磁盘已满通知创建文件 %s 时磁盘出错磁盘空间已满磁盘已满! 强制暂停根据 SFV 文件进行额外验证。feed %s 无有效的身份认证凭据配额会每天、每周或每月重置吗?下载下载完成下载失败下载所有 par2 文件下载失败 - 不在该服务器上下载文件夹读写速度下载可能会失败,只有 %s 块 (需要 %s) 可用已下载已下载,耗时 %s,平均速度 %sB/s重复的 NZB 文件如如 8 或 20*加密*错误:编辑编辑 NZB 详情Email任务完成 Email 通知Email 收件者Email 发送者邮件模板文件夹发送 email 的目标电子邮箱地址。成功发送电子邮件紧急清空空 NZB 文件 %s发现空的 RSS 条目 (%s)启用启用 7zip启用 HTTPS启用NotifyOSD启用 Prowl 通知启用 Pushbullet 通知启用 Pushover 通知启用基于 SFV 的检查启用 Windows 通知启用 HTTPS 地址访问界面。启用文件夹重命名启用可减少内存占用。禁用可避免慢速任务拖慢队列进度。启用通知脚本启用配额管理启用递归解压启用路径末尾加上星号 * 可避免创建任务文件夹。输入 URL集 名集数集.名集_名错误"%s" 对 %s 运行 file_join 时出错"%s" 对集合 %s 执行 par2_repair 时出错出现错误 "%s",正对 %s 执行 rar_unpack 操作%s 对集合 %s 执行 par2_repair 时出错错误 %s: 您需要提供有效的用户名与密码。创建 SSL key 及证书出错导入 %s 出错无法加载 %s,侦测到损坏文件移除 %s 时出错将 "%s" 重命名为 "%s" 出错加载 %s 出错,正在移除关闭系统时出错仅当发生错误时错误/警告执行自定义脚本退出 SABnzbd扩展名外部互联网访问额外的 PAR2 参数正在提取...失败的任务 (移动到历史)失败无法登录服务器 %s [%s]创建失败 (%s)将 %s 移动到 %s 失败无法在邮件服务器上验证身份无法关闭数据库,参见日志无法关闭邮件连接为搜索关键词编译正则表达式失败: %s无法连接到邮件服务器系统休眠失败导入 %s 文件失败,来自 %s无法初始化 %s@%s,原因为: %s无法发起 TLS 连接移动文件失败重命名相似文件失败: %s 为 %s无法检索 %s 的 RSS: %s无法发送 Prowl 消息无法发送 Windows 通知无法发送 e-mail无法发送 pushbullet 信息无法发送 pushover 信息系统待机失败web 界面启动失败无法启动 web 界面: 失败于重复的 NZB 文件 "%s"tempfile.mkstemp 出错致命错误保存状态时遇到致命错误Assembler 出现致命错误Feed装取从 URL 装取 NZB正在装取正在装取 %s 块...正在装取额外块...包含要对加密 RAR 文件进行尝试的所有密码的文件。%s 文件合并失败HTTPS 证书文件名或路径。HTTPS 链文件名或路径。HTTPS Key 文件名或路径。服务器上无此文件文件集文件名过滤器过滤样本文件 (如视频样本)。包含用户脚本的文件夹。包含用户定义的电子邮件模板的文件夹。要监视 .nzb 文件的文件夹。文件夹/路径文件夹email 身份认证所用的账号名称。email 身份认证所用的密码。供服务器使用: 确保名称与 Windows 系统兼容。对于不稳定的服务器,在失败后将会被忽略更长的时间强制强制断开连接强制下载正在强制断开连接论坛剩余空间频率周五来自剧目 SxxEyy来自 SxxEyy完整 API完整 Web 界面更详尽的帮助可以在我们的网站上找到常规生成新的 Key生成新的自签名证书和密钥。需要重启 SABnzbd!你可能会喜欢一些 Glitter 的(新)功能!转到 SABnzbd转到向导HTTP 与 HTTPS 端口不能相同HTTPS 证书HTTPS 链证书HTTPS KeyHTTPS 端口HTTPS 证书验证帮助帮助我们来本地化 SABnzbd !
您可以在这里来添加未被翻译的文字或者改进现有的翻译:电脑休眠隐藏详情隐藏/显示已完成文件高历史最近十条历史记录历史数目限制按 shift 键可选择范围主页主页主机SABnzbd 应监听的主机。您希望在多久之后/什么时候暂停? (用英语作答!)本月能下载多少数据量 (K/M/G)*不完整*IONice 参数IPv6 地址空闲若留空,则将监听 HTTPS 标准端口。如果您再次收到本错误信息,请尝试其他数字。
忽略样本文件忽略压缩包中的文件夹结构正在忽略重复 NZB "%s"RAR 文件“%s”中出现不需要的扩展名。不需要的文件名为 %s 若选择“暂停”,您将需要设置密码并手动续传对应任务。SABnzbd 重启后本画面将自动消失!分文件夹feed 不兼容发现不兼容的队列文件,无法继续处理未完成文件夹可合并的文件队列不完整RSS feed 描述不正确 "%s"参数不正确密码编码错误 %s降低 SSL 的加密难度以便获得更高的性能。索引 Categories / Groups索引可以在 NZB 文件中提供分类信息,SABnzbd 会尝试在以下分类中匹配。另外,您可以在 "索引 Categories / Groups" 中添加关键词来匹配更多的分类。使用逗号来分开关键词,关键词中可使用通配符。
你可以在维基中查看更多的相关信息。服务器地址无效。服务器信息无效%s 历史信息中 stage 日志无效问题建议您右击鼠标并将该链接加入书签以便在 SABnzbd 在后台运行时访问它。任务 "%s" 可能受加密保护,RAR 文件中存在相同名称的 RAR 文件。任务 "%s" 可能受加密保护:文件名 "%s" 中有 "password" 字符任务失败任务已完成合并文件正在合并语言启动时启动浏览器启动 SABnzbd 时启动默认 web 浏览器。限速下载后应删除的文件扩展名列表。
例如: nfo 或 nfo, sfv正在加载加载 %s 失败本地 IPv4 地址您的浏览器已禁用 LocalStorage (cookies)。界面设置将在您关闭浏览器后丢失!队列管理及历史数据库的存放位置。
仅当队列为空时可以修改。SABnzbd 日志文件的位置。
需要重启 SABnzbd 才能生效!存储完成且已完全处理的下载数据的位置。
可以通过用户定义分类额外调整。存储未处理下载数据的位置。
仅当队列为空时可以更改。存储 .nzb 文件的位置。备份配置文件和数据库的位置。
如果留空,备份将存放于完成下载文件夹中。日志文件夹登录注销日志失去与 SABnzbd 的连接..低大小写确保与 Windows 兼容已匹配最大线路速度各服务器重试的最多次数最多重试次数释义最小最小:启动 SSL 时,使用服务器自己的证书来验证身份。严格:验证并强制 hostname 一致。完成下载文件夹的最小剩余空间临时下载文件夹的最小剩余空间缺失文章适中周一月更多影片 名称电影排序影片.名称影片_名称正在移动正在移动...多选操作NZB KeyNZB 已添加到队列名称域名服务器 / DNS 查询命名从不后Nice 参数无权访问未找到 email 模板不分文件夹未给定收件人,电子邮件未发出未找到合适的身份验证方法无常规未匹配不可用通知中心通知脚本通知已发送!通知脚本 "%s" 不存在通知屏显通知扫描 .nzb 文件的间隔时间。*可选* 账号密码*可选* 账号用户名关侦测到旧版队列,请使用“状态”→“修复”转换队列队列完成时您的 ISP 会在每月或每周的哪天 (1=星期一) 重置配额? (可选加上 hh:mm)只获取队列最顶端的文章只对外部访问要求登录请打开“终端”窗口并输入下面一行命令 (例):打开完成文件夹可选可选补充 NZB可选身份验证密码。可选身份验证用户名。可以选择指定文件名或将文件拖拽到本窗口!序号原始文件名孤立任务其他信息传播延迟生效,等待 %s 分钟参数分段号密码密码文件密码会以 ****** 显示,请重新输入有密码路径匹配匹配符释义暂停全部暂停后期处理过程中暂停下载暂停暂停 1 小时暂停 15 分钟暂停 3 小时暂停 30 分钟暂停 5 分钟暂停 6 小时暂停...暂停高优先级任务暂停低优先级任务暂停常规优先级任务暂停后期处理已暂停"%s" 任务已暂停,因其包含加密 RAR 文件 (已尝试所有的密码,如果提供了的话)开始后期处理时暂停下载,完成后续传。正在暂停重复 NZB "%s"线路速度的百分比完成下载权限个人 API keyProwl 的个人 API 密钥 (必填)注释请注意 0.0.0.0 主机名需要 IPv6 地址才能从外部访问请输入您的主 usenet 提供商的详细信息。端口SABnzbd 应监听的端口。后期处理失败:%s (%s)后期处理仅对经验证的任务进行后期处理后期处理后期处理已开始在文章发布时长尚不足该值时暂停下载文章。将任务优先级设为“强制”可跳过此延迟。预队列脚本将任务标记为失败的加入队列前执行的用户脚本预设请按 开始菜单键+R 并输入下面一行命令 (例):上一步优先级问题处理结果处理程序未启动!传播延迟Prowl公网 IPv4 地址清除已完成 NZB清除失败 NZB清除失败 NZB 并删除文件清空历史清除日志清空 NZB清空 NZB 并删除文件清理本页的 NZB 文件清空队列PushbulletPushoverPython 版本Python 脚本 "%s" 不具有执行 (+x) 权限队列将前十项加入队列队列已完成队列数目限制队列非空,无法变更文件夹。队列修复快速检查...快速检查退出配额剩余配额配额周期配额已耗尽,暂停下载RAR 文件验证失败RAR 文件验证成功RSSRSS 检查间隔RSS Feed %s 为空执行 %s极少用到的选项。要获取其含义及解释,请点击“帮助”按钮访问 Wiki 页面。
在查看 Wiki 之前请不要更改这些选项,它们会有很严重的副作用。
括号中为默认值。立即读取全部 Feed读取 Feed读取 RSS feed读取所有 RSS feed关于该项请参阅 Wiki 帮助!刷新刷新频率否决基于相对文件夹剩余记住我移除 NZB移除 NZB 并删除文件移除服务器移除已选文件移除已完成任务移除失败任务移除 %s 失败正在移除任务正在移除任务重命名修复修复失败,修复块不足 (缺 %s 块)正在修复修复失败,%s正在修复...重复测试替换文件夹名称中的空格替换文件夹名称中的点号将文件夹名称中的小数点替换成空格。将文件夹名称中的空格替换成下划线。需要需要 Prowl 账号需要 Pushbullet 账号需要 Pushover 账号需要分类重置立即重置配额重置时间正在解析地址重启重新启动 SABnzbd清除登录身份凭据设置并重新启动正在重新启动 SABnzbd...恢复默认值结果续传继续高优先级任务继续低优先级任务继续常规优先级任务继续后期处理恢复中保存期限重试全部重试重新尝试下载所有已失败任务正在执行脚本正在执行脚本...正在执行用户脚本 %sSABCTools 已禁用:未找到正确的版本!(找到 v%s,要求 v%s)SABnzbd %s 已启动SABnzbd 主机SABnzbd 密码SABnzbd 端口SABnzbd 快速上手向导SABnzbd 用户名SABnzbd 版本SABnzbd Web 服务器SABnzbd 侦测到致命错误:SABnzbd 关闭完成SABnzbd 以 %s 编码启动了,正常应该是 UTF-8。会导致下载文件夹中统一标准编码的文件和文件夹名称出现问题。SABnzbd 将在后台运行。SMTP 服务器SQL 命令执行失败,参见日志SSLSSL 加密算法周六保存保存更改保存 %s 失败正在保存..扫描监视文件夹定时任务的服务器不存在 %s定时任务脚本脚本退出代码为 %s脚本返回退出代码 %s 及输出内容 "%s"脚本脚本文件夹搜索季数到服务器的安全连接安全选择 web 界面的语言。仅当您的服务商允许 SSL 连接时选择。发送 RSS 通知发回队列RSS feed 添加任务到队列时发送 email。磁盘已满、SABnzbd 暂停时发送 email。已将 %s 发送到队列以逗号来分开多个链接TV 排序服务器服务器 %s 使用的 HTTPS 证书不受信任%s 服务器使用了不受信任的证书 [%s]服务器 %s 将被忽略 %s 分钟服务器详情服务器地址 "%s:%s" 无效。服务器地址必填服务器无法完成请求服务器描述服务器名无法解析服务器需要用户名与密码。服务器端错误 (服务器代码 %s);无法获取 %s (服务器 %s)服务器设置完成文件/文件夹的权限值。
八进制记法。例如: "755" 或 "777"设为您 ISP 的 email 出站服务器。设置完成!配额重置后是否自动续传下载?显示全部项只显示失败项显示日志节目 名称显示活动连接显示详情显示界面节目.名称节目_名称关闭电脑关闭关闭 SABnzbd正在关闭捕捉到 %s 信号,正在保存并退出...尺寸部分文件的验证结果与 "%s" 不符抱歉,无法理解您的输入。请重试。排序字串按发布时间排序 最新→最早按发布时间排序 最早→最新按名称排序 A→Z按名称排序 Z→A按尺寸排序 最大→最小按尺寸排序 最小→最大排序来源特殊速度限速电脑待机启动向导正在开始修复启动/关闭状态状态与界面选项停止正在停止...严格提交周日支持该项目,捐助!下载器疑似错误参数系统文件夹系统性能 (Pystone)TEXT*太大*标签化外观
(分别显示队列与历史记录)临时文件夹临时下载文件夹测试邮件测试通知测试服务器正在测试服务器详细情况...“修复”按钮可重启 SABnzbd 并执行完整的
队列内容重建操作,同时将保留已下载的文件。
队列的顺序会有所改变。需要勾选 feed 名称旁边的复选框才能启用并自动检查新项。
添加 feed 后,它将只选取新项目,而不选取已经处于 RSS feed 当中的项,除非您按“强制下载”。主机名未设置。提供商所允许的连接数服务器未正确回复 helo 问候未设置连接。请设置至少一个连接。下载目录中存在孤立任务。
您可以选择删除任务 (及其文件) 或将它们发回队列。该 key 将允许第三方程序将 NZB 添加到 SABnzbd 中。该 key 将授予第三方程序 SABnzbd 的完整权限。本月当需要时下载所有的 par2 文件以避免多次运行修复。该服务器不允许在该端口使用 SSL本周这将重新启动 SABnzbd。
如果您认为程序存在稳定性问题,请使用该项。
重启前将暂停下载,之后将继续下载。这将发送一封测试邮件到您的账号当中。周四超时超时: 请尝试启用 SSL 或连接其他端口。超时标题To: %s From: %s Date: %s Subject: SABnzbd 报告磁盘已满 Hi, 由于磁盘几乎已满,SABnzbd 已停止下载。 请腾出空间再手动让 SABnzbd 续传。 今天磁盘空间过低,强制 *暂停*服务器 %s 连接数过多 [%s]连接数过多,请先暂停下载或稍后再试置顶总计疑难解决在实际下载之前尝试预测可以成功下载的完整程度 (会减慢下载进度!)正在尝试 7zip,密码 "%s"正在尝试基于 RAR 的验证正在尝试 SFV 验证正在尝试从 %s 装取 NZB正在尝试设置不存在的服务器 %s 的状态正在尝试 unrar,使用密码 "%s"周二调节类型不需要URL 装取失败; %s*URLGRABBER 已崩溃*绑定端口 %s 在 %s 上失败。其它的程序正在使用此端口或者说 SABnzbd 正在运行。未授权访问解封未定义服务器!解码 %s 时发生未知错误未知的 SSL 协议:尝试禁用 SSL 或者连接不同的端口。未知操作: %s邮件服务器出现未知身份验证错误解压解压压缩包内的压缩包 (rar, zip, 7z)。解压嵌套层级过深 [%s]已解压 %s 个文件/文件夹,耗时 %s正在解压解压失败,%s解压失败,CRC 错误解压失败,压缩文件需要密码解压失败,文件太大文件系统不支持 (FAT?)解压失败,路径过长解压失败,找不到 %s解压失败,写入出错或磁盘已满?%s 中有失败的登陆请求不可用的 NZB 文件无法使用的 RAR 文件rar 文件中出现不需要的扩展名 %s不需要的扩展名有更新可用!上传 NZB正在上传启动时间使用全局界面设置后期处理过程中使用临时名称。若您的系统无法正常处理请禁用。用于在 NZB 进入队列前执行。已用缓存用户文件夹用户 key用户密钥 (必填)用户已登录用户已在 web 界面登录用户脚本可将任务标记为失败用户名值成功使用 SFV 文件验证当用 HTTPS 方式连接索引和RSS源时验证证书。正在验证正在验证...版本非常低查看脚本日志*等待* %s 秒警告:等待警告警告信息监视文件夹监视文件夹扫描速度Web 界面周三下载时若发现缺失数据过多,则中止对应任务用户脚本返回非零的退出代码时,对应的任务将被标记为失败。每当您的 IP 地址发生变化,或当 SABnzbd 重启,登录会话将自动过期。SABnzbd 应占用的线路速度的百分比,如 50应该执行哪个脚本来发出通知?我们应该说是谁发送了这封 email?Wiki当某分类的路径位于另一磁盘上时不生效。Windows年设置带宽限制前,您必须设置最大带宽值您的 UNRAR 程序版本为 %s,我们建议使用 %s 或更高版本。
您自己的 Pushbullet API key (必填)[%s] "%s" 合并文件时出错[%s] "%s" 解压 RAR 文件时出错[%s] 已合并 %s 个文件[%s] 无 par2 集合[%s] PAR2 收到的选项不正确,请检查您的“配置”->“参数”设置[%s] 快速检查 OK[%s] 基于 RAR 的验证失败: %s[%s] 已修复,耗时 %s[%s] 验证耗时 %s,所有文件均完好无损[%s] 验证耗时 %s,需要修复篇文章大小写已调整天天天禁用服务器启用服务器文件小时小时小时剩余分钟手动分钟分钟关开或页par2 可执行程序... *未* 找到!秒秒查看日志文件textunrar 可执行程序... *未* 找到周././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993698.369232 SABnzbd-4.3.2/locale/sr/LC_MESSAGES/SABnzbd.mo0000644000000000000000000020416014625637242017515 0ustar00runnerstaffDl0om0d0B2 <3I4=5''6O6j6 66666667 717P7i7?7.8>8F8RV8[89#9;9X9$u99 99'9'9: :: !: .: 9:C:Y:m:q:'u:::::*: ; ;);=;P;Y;/a; ;;!<&<%-<#S<w< <<<<)=0= P= q====!=6 >-C>q>>">6>> ??.(?'W? ????S? @@5@;@"J@8m@@@ @@@ @AA#5AYApA A*AAA AA3A B $B 0B=BDBLB`B gBrB BBB&B B)BC8C4ACvC?~CCCC DD,2D,_D1DDDDD'E*E5@E vE'EE E EEEE$EF F%F#ZVZ]ZcZhZ xZZ Z"Z+ZZZ [ [[/[ B[ P[/Z[[[[;[[c\"r\3\\\\!]!#]E]%c]]] ]] ] ]] ]*] ^"^'^ /^;^ A^(K^ t^~^^^^^^ ^^_/_J_`_Mg___#_ `%`D`RS`<```"a*a:aZajaaa-aaa aa a b b&b:bOb ab b bb b bbbbbbc&c FcScbcqcvc |c c ccccccd dd ee9e AeNeUe se }ee eeeeef f2f GfQf ff sfff)f0fgg4gRg ngzgg gggggggggh1hMhdhmh|h hhhhhh hh ii3iDiTigii.i iiiij jj(j1j#Ej ijtj{jjj j j4jkk3/k3ckkkk-k(kl$$lIlaltl&l:llol)kmm3mm m m n n $n1n @n JnTn ]nin zn'nn(n.n o-o-Go$uo$o1o1o#p+p2p:p @p Kp Vpcpspppp pppppq qq5q :q DqPq jquq qqq^r_s2xs5sAs#t>t=t %u+0u \ufu, v8v Av>KvvvvLw"Rw&uwAwww wEw;xZxrx.xxxxxxxy%y9yAySysy-yy/yyz (z2zGz-cz"z#z.z{{$+{P{d{ v{{{b{$ | .| 9|F|O|"c|||%| | |||| |} }}}"}1} K} Y}Rc}U}= ~!J~l~q~~E~B~+#A)eJ&)'Px  Àɀ΀Ѐ׀ۀ  !&@E1҅s[fP-8$5C!y ƌ ьߌ %1#Ur! 2?[~ݏ\Ct8!,@Q oA|. *B-T%. &-B p"'ǓZbu +6(G3p/ ԕ =˖' ,15^5-ʗ:{3g"H:,^'7LHaY *&;bq) :G;gn#*6a;r'Ý4& *G&r+ߞ 3'![} :֟ ,43a . 10&W8n b;*S/~âWۢE3Wyѣ%'+.QZ[ʤ&77ow  ʥKإ$C+\9%¦ 0?Sl- ֧B(4k,D0q6Lbz DL?CJWΫF&mTݬ22*]zǭ2ܭ&6NEaSM5<BI8M7/>8-Sf70##C!g[$& 1R-nγ'3bM2G5+;a ϵWܵE4AzڶmuY<Ϸ !#? cn Ÿ/  !BV&v"۹ &5 \g3~8ʺ ,,5;bO )[9[-1r_Lҽ#7S['H׾+ #Lp-,fR :#Tx ?R!%G}+Iu# 3Q"b-L!)KZ mx (/G Zet%B2)\k|&$ Re,w!=_.[)"CP,g*, *4FUNu   8%^t   ('A&i)0w2v*L!53iI{]#1,9^H21RF%"H)]!$E#,P1a "T(} %:#>b'Jr> ! (=5s1*CZmm| '<38p_R \!k4Pg/FDJb.  !&5!\"~$ 9&X4*7M(c  6F'n &W)]KW@Z z,&$1 N [>|EY4Q9*<P do -:A#eNwN22HF{F ' 6!C&e!) !2 J WPd'# 2=P:e+y&kK.T bUHd+E[NY\ v H+S%s -E2^1#  1.DY&p#5C1F=x$//>Ln;/'*Cn) (?%+7I/"(6_ v %# "Yf@} Lq,9/%+U#!1!SHuG!03:CUevy      6Aa SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Complete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid server address.Invalid server detailsInvalid stage logging in history for %sIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocation for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification Sent!NotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!ProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePushbulletPushoverPython VersionQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...ResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...SubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User script can flag job as failedUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.Which percentage of the linespeed should SABnzbd use, e.g. 50Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: sr 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); SABnzbd не може да нађе датотеке веб интерфејса у %s.
Молимо да поново инстлирате програм.

SABnzbd је нашао сачуване податке неке друге верзије SABnzbd-а
али не може да искористи податке са другог програма.

Морате прво де завршите ред са другом верзијом програма.

После тога, покренути овај програм са опцијом "--clean".
То ће обрисати актуелни ред и хронилогију!
SABnzbd чита датотеку "%s". SABnzbd је нашао да недостаје датотека 'sqlite3.dll'.

Неки лоши против-вирусни програми уклањају ту датотеку.
Проверите против-вирусни програм, поново инсталирајте SABnzbd и пошаљите жалбу својим продавацу против-вируса.

SABnzbd-у је потребан слободан tcp/ip порт за интерни веб сервер.
Покушан је порт %s на %s, али није доступан.
Неки други програм користи тај порт или SABnzbd већ ради.

Поново покрените SABnzbd са другим портом. SABnzbd-у је потребна важећа хост адреса за интерни веб сервер.
Унели сте погрешну адресу.
Сигурне вредности су localhost и 0.0.0.0

Поново покренути SABnzbd са добром хост адресом. SABnzbd долази БЕЗ ИКАКВЕ ГАРАНЦИЈЕ. Ово је бесплатан програм, и ви сте добродошли да га делите под одређеним условима. Лиценциран је под GNU GENERAL PUBLIC LICENSE верзија 2 или (по вашем избору) касније верзије. %s артикла нису дупликате%s артикла нису добро формирани%s артикла недостајуФасцикла %s: %s грешка приступа%s nije ispravna oktalna vrednost%s nije ispravna email adresa+ Дебаг+ Инфо+Обриши+Поправи+ИздвојФасцикла копије .нзб0 je najveći prioritet, 99 je najniži prioritet7za program...NIJE pronađenБЕЛЕШКА: Фасцикле ће бити аутоматски креиране приликом Сачувавања. Могуће је коришћење апсолутне путање за сачувавање ван подразумеваних фасцикли.Податци неће бити премештени. Потребно поновно покретање SABnzbd-а!API (без подешавања)API кључQR Код АПИ кључаAPI кључ је погрешан, унети у спољни програм API кључ из Подешавања->Опште:API кључ недостаје, унети у спољни програм API кључ из Подешавање->Опште:API кључ за ProwlПоништи рад који не може да се завршиПоништено, не може да се завршиPrekinuto, detektovana enkripcijaPrekinuto, detektovana neželjena ekstenzijaПрихватиПриступ одбијенАкцијаАкција када је шифрован РАР преузетRadnja kada je otkrivena neželjena ekstenzijaДодајДодај NZBDodaj NZB datoteke Dodaj rasporedДодај серверНЗБ додатФасцикла АдминистратораПогођене категоријеСтаростСвеSve datoteke će biti smeštene u jedan folderИ пробне верзијеУвекToken aplikacijeToken aplikacije (obavezan)Da li ste sigurni da želite ugasiti SABnzbd?Да ли сте сигурни?АргументиЛимит кеша артиклаИдентифација артиклаNajmanjeНајвишеАутентификација погрешна, проверити име/лозинку.Automatski nastaviПаузирај када је простор испод ове вредност.
У бајтовима, опционо додати K,М,G,T. НПР: "800M" или "8G"НазадРезервноPogrešan odgovor Pushbullet-a (%s): %sNeodgovarajući odgovor od strane Pushover (%s): %sЛоша планификација %s у %s:%sПротокДноPregledajКеширати артикле у меморији. То смањује приступ диска.
У бајтовима, опционо додати K,M,G. Пример: "64M" или "128M"ОткажиНе може да се промене дозволе од %sNeuspešno povezivanje na server %s[%s]Ne može se kreirati sigurnosna kopija za %sНемогуће креирати фасциклу %sНемогуће креирање фасцикле %sNemoguće kreiranje privremene datoteke za %sНемогуће наћи модел е-поруке у %sНемогуће наћи веб модел: %s, програм покушава са стандардним моделомНемогуће је покренути претраживач, вероватно није нађенНеуспешно читање %sНеуспешно читање надгледане фасцикле %sNemoguće poslati, nedostaju obavezni podaciНе могу да пишем у бази дневника, проверите дозволе!Ne može da se upiše u INI datoteku %sКатегоријеКатегоријаПромене су изгубљене јер нису сачуване.За апликацију промена, поново покренути програм!Proveri sveПровери пре преузимањаПровери нове верзијеПровераИнтервал провере (у минутима, макар 15). Неактивно када користите планер!Списак чишћењаЧишћење %s није успело.ОчистиИспразни бројачеКликнути за пробу унетих детаља.Затварање прозора/језичка претраживаче НЕЋЕ затворити SABnzbd.Комплетна фасциклаBrzina foldera za kompletirana preuzimanjaЗавршеноФасцикла за завршена преузимањаПодешавање; Датотека подешавањаПотврда брисања хронологијеПотврда брисања редаPovezivanje na %s@%s neuspešno, poruka=%sУспешно привезивање!Veza neuspešna!ВезеNemoguće odrediti rezultate konekcije (%s)trenutni rasporediПрилагођеноДУПЛИКАТДневноBaza dnevnika je oštećena, kreirana prazna zamenaСређивање датумомФормат датумаДан у месецуДекадаПодразумеваноПодразумевана основна фасциклаОбришиИзбриши свеОбриши после преузимањаОбрисати све ставке са реда?Neuspešno brisanje %s!УређајUređaj na koji bi poruka trebala biti poslataUređaj(i)Uređaj(i) na koje bi poruke trebale biti poslateОнемогући управљање квотаОнемогућеноHTTPS onemogućen zbog nedostajućih CERT i KEY datotekaОдбациИскључи се са сервера када је ред празан или паузиран.Заустави везу када је ред празанОбавештење пуног дискаGreška na disku prilikom kreiranja datoteke %sДиск је пунDisk je pun! Tera PauseУради још једну проверу базирану на SFV датотеке.Немам важећу аутентификацију за фид %sКвота је ресетована сваки дан, недеље или месец?ПреузмиПреузимање завршеноНеуспешно преузимањеПреузми све par2 датотекеНеуспешно преузимање - није на вашем серверуBrzina foldera za preuzimanjeПреузимање је можда погрешно. има %s од потребних %sПреузетоПреузето за %s на просек од %sБ/сНпр.Нпр 8 или 20ШИФРИРАНОГРЕШКА:Уреди детаље NZB-аЕ-поштаНотификација е-поштом при завршетку радаЕ-пошта примаоцаЕ-пошта слањаФасцикла модела е-поштеАдреса на коју се шаље е-порука.Упешно слање е-поштеХитноПразноПразан NZB %sNađen prazan RSS unos (%s)ОмогућиОмогући 7zipАктивирај HTTPSУпали „NotifyOSD“Омогући Prowl нотификацијеOmogući Pushbullet notifikacijeOmogući Pushover notifikacijeУпали SFV провереWindows notifikacijeПриступ интерфејсу преко HTTPS адресе.Упали преименовање фасциклеУпали за мању употребу меморије. Угасити ради спречавања блокирања реда спорим радовима.Омогући управљање квотаОмогући рекурсивни издвојОмогућеноЗавршавање путање са звездицом * ће спречити креацију фасцикле за рад.Унесите УРЛИме епизодеБрој епизодеИме.ЕпизодеИме_епизодеГрeшкaГрешка "%s" док сам покренуо 'file_join' на %sГрешка "%s" при покретања 'par2_repair' на скупу %sГрешка "%s" док сам радио 'rar_unpack' на %sГрешка %s при покретања 'par2_repair' на скупу %sГрешка %s: Требате да унесете важеће име/лозинку.Грешка креације SSL кључа и сертификатаГрешка увоза %sГрешка учитавање %s, покварена датотека нађенаGreška pri uklanjanju %sГрешка преименовања "%s" у "%s"Грешка додавања %s, уклањањеGreška pri gašenju sistemaСамо-ГрешкеГрешке/УпозорењаЗатвори SABnzbdЕкстензијаЕкстерни приступ интернетуДодатни параметри PAR2Распакујем...НеуспешноНеуспешно пријављивање на сервер %s [%s]Neuspešno kreiranje (%s)Neuspešno premeštanje %s u %sНеуспешна аутентификација на серверу е-поштеНеуспешно затварање базе, видети извештајНеуспешно затварање везе е-поштеNeuspešna kompilacija regularne ekspresije za termin pretrage: %sНеуспешно привезивање на сервер е-поштеНеуспешна хибернација системаНеуспешан унос %s датотеке са %sNeuspešna inicijalizacija %s@%s iz razloga: %sНеуспешна иницијализација TLS везеНеуспешно премештање датотекаНеуспешно преименовање сличне датотеке: %s у %sНеуспешно преузимање RSS од %s: %sНеуспешно слање Prowl порукеNeuspešno slanje e-mail porukeNeuspešno slanje Pushbullet porukeNeuspešno slanje Pushover porukeНеуспено постављање система у стању приправностиNeuspešno pokretanje web interfejsaNeuspešno pokretanje web interfejsa: Грешка у tempfile.mkstempФатална грешкаFatalna greška pri snimanju trenutnog stanjaFatalna greška u Assembler-uFeedПреузмиPovuci NZB sa URLДобављамУчитавање %s блокова...Преузимање екстра блокова...Датотека са свим лозинкама за шифроване РАР датотеке.Спој датотеке %s није успелоДатотека или путања до HTTPS сертификата.Датотека или путања до HTTPS ChainДатотека или путања до HTTPS кључа.Збир датотекаИме датотекеФилтерФилтрирај примерне датотеке (нпр. видео пример).Фасцикла где се налазе модели е-поште.Фасцикла за надгледање .nzb датотека.Фасцикла/ПутањаФасциклеАко је потребна аутентификација за слање е-поште, унети име.Ако је потребна аутентификација за слање е-поште, унети лозинку.Za servere: osiguraj da su imena kompatibilna sa Windows-om.ФорсирајНатерај искључењеНатерај преузимањеФорумСлободан просторФреквенцијаПетакOd SxxEyyЦео APIЦео веб интерфејсДаља помоћ се може наћи наОпштеГенериши нов кључИди на SABnzbdПокрени асистентHTTP i HTTPS portovi ne mogu biti istiHTTPS сертификатHTTPS Chain цертификатиHTTPS кључHTTPS портПомоћХибернацијаСакриј детаљеSakrij/prikaži sve završene datotekeВисокХронологијаХронологија задњих 10 ставкаLimit stavki u istorijiDržite taster shift pritisnut da bi ste odabrali rasponКућаПочетна страницаХостХост на којем SABnzbd слуша.Koliko dugo ili dokle želite da pauzirate? (na engleskom!)Колико може да се преузме овог месеца (К/М/Г)НЕПОТПУНОПараметри 'IONice'IPv6 adresaМирoвањеАко је празно, стандардни порт ће слушати само HTTPS.Ако опет имате ову грешку, покушајте други број.
Игнориши примереIgnoriši foldere unutar arhivaИгнорисање дуплог NZB-а "%s"Ако је "Пауза", требате да поставите лозинку и да наставите рад.U slučaju ponovnog pokretanja SABnzbd-a ovaj prozor će nestati automatski!У фасцикламаНекомпатибилан ФидНекомпатибилан ред нађен, на могу да наставимНекомплетна фасциклаНепотпуна секвенца датотеке за спајањеПогрешан опис RSS фида "%s"Погрешан параметарPogrešno šifrovana lozinka %sПогрешна адреса сервера.Погрешни детаљи сервераПогрешне етапе извештаја можете наћи у хронологији за %sПрепоручено је да поставите ову локацију као 'маркер' тако да Вам је приступ SABnzbd омогућен док он ради у позадини.Неуспешан радпосао завршенПрилепити датотекеСпајањеЈезикПокрени претраживач при покретањуПокрени Веб претраживач при покретању SABnzbd-а.Ограничење брзинеЛиста ектензије за брисање после преузимања.
На пример: nfo или nfo, sfvУчитавамUčitavanje %s neuspešnoLokalna IPv4 adresaЛокацију за ред и хронологију базе.
Промене су могуће само када је ред празан.Смештај извештаја SABnzbd-а.
Потребно је поновно покретање SABnzbd-а!Смештај завршених, процесираних преузимања.
Може се заобићи у дефинисаним категоријама.Смештај непроцесираних преузимања.
Промене су могуће само када је ред празан.Смештај за сачувавање .нзб датотека.Фасцикла извештајаБележењеIzgubljena konekcija sa SABnzbdНизакМала словаNapravi Windows kompatibilnimОдговараМакс брзина линијеМакс покушаја по серверуМакс покушајаЗначењеМинимални простор за привремену фасциклуНедостају артиклиУмереноПонедељакМесецВишеИме филмаИме.ФилмаИме_филмаПремештањеПремештање...Мулти-операцијеNZB кључNZB додат у редИмеNameserver/DNS PretragaИменовањеНикадСледећеПараметри 'Nice'Без приступаНема модела е-порукеНема фасциклеНема примаоце, е-порука није посланаNije pronađen odgovarajući metod autentifikacijeНиједноНормаланНе одговараНедоступноЦентар за обавештењаОбавештење послато!ОбавештењаNotifyOSDБрој секунди између 2 провере .nzb датотекаЛозинка (ОПЦИОНО)Корисничко име (ОПЦИОНО)ИскљученоСтари ред је нађен, употребити Статус->Поправи за претварање редаКада се ред завршиКоји дан месеца или недеље (1=понедељак) Ваш провајдер ресетује квоту? (опционо са hh:mm)Само артикли на врху редаОтворите прозор терминала и унети линију (пример):Otvori fasciklu završenihОпционоДодатне опције NZB-аЛозинка за аутентификацију (опционо)Корисничко име за аутентификацију (опционо)Опционо специфирати имеIli prevucite i pustite datoteke u prozor!РедоследОригинално име датотекеZapušteni posloviОстале порукеParametriБрој делаЛозинкаЛозинка датотекеЛозинка сакривена испод ******, поновите уносZahteva lozinkuПутањаМоделМодел кључаПаузаПаузирај свеПаузирај док се пост-процесираПаузирај заПаузирај 1 сатПаузирај 15 минутаПаузирај 3 сатаПаузирај 30 минутаПаузирај 5 минутаПаузирај 6 сатиПаузирај за...Pauziraj poslove sa visokim prioritetomPauziraj poslove sa niskim prioritetomPauziraj poslove sa normalnim prioritetomПаузирај пост-процесирањеПаузираноПаузирај преузимања на почетку пост-процесирања и настави после.Паузирам због дуплог NZB-а "%s"Постатак брзине линијеДозволе за фасциклу завршених преузимањаLični API ključЛични API кључ за Prowl (потребно)Lične zabeleškeObratite pažnju, hostu 0.0.0.0 će trebati IPv6 adresa za pristup spoljaОвде унети детаље вашег примарног 'usenet' провајдера.ПортПорт на који SABnzbd чека везе.Грешка пост-процесирања за %s (%s)Накнадна обрадаПост-процесирај само проверени пословиПост-процесирањеПост-процесирање покренутоКориснички скрипт пре-редаПредподешавањаСтиснути Startkey+R и унети линију (пример):ПретходноПриоритетПроблем саРезултат обрађивањаОбрађивањеПрограм није покренут!ProwlJavna IPv4 adresaОчисти завршене NZBОчисти NZB са грешкомОчисти NZB са грешком и обриши датотекеОчисти хронологијуОчисти NZBОчисти NZB и обриши датотекеОчисти редPushbulletPushoverВерзија Python-аРедУ ред прве 10 ставкеРед завршенLimit stavku u reduPед није празан, фасцикла се не може променити.Поправљење редаБрза провера...Брза ПровераИзлазКвотаОстала квотаПериод квотеKvota utrošena, pauziram preuzimanjaRSSИнтервал RSS провереRSS фид %s је празан%s покренутоОпције ретко коришћене. За њихово значење и објашњење, клинути на дугме Помоћ за одлазак на Вики страницу.
Немојте их мењати пре не провере на Вики, пошто неке имају озбиљне нежељене ефекате.
Подразумеване вредности су између заграда.Сада читај све фидовеЧитај фидЧитај RSS фидовеPročitani svi RSS kanaliЗа више информација, читајте Вики!ОсвежиБрзина освежавањаОдбациРелативност фасцикле је базираноПреосталоУклони NZBУклони NZB и обриши датотекеУклони серверUkloni sve odabrane fajloveUkloni završene posloveУклони неуспешна послаBrisanje %s neuspešnoПреименујПоправиПогрешна поправка, нема довољно блокова за поправку (фали %s)ПоправљањеNeuspešna popravka, %sPopravljanje...Ponovi testРазмени размаке у имену фасциклеРазмени тачке у имену фасциклеРазмени тачке са размацима у имену фасцикле.Размени размаке са _ у имену фасцикле.ЗахтевиПотребан Prowl налогZahteva Pushbullet nalogZahteva Pushover nalogПотребанCatРесетујРесетуј квотуДан ресетовањаРешавање адресеПоново покрениPonovo pokreni SABnzbdPonovno pokretanje bez prijaveПоновно покретање SABnzbd-а...РезултатНаставиНастави радови са високим приоритетомНастави радови са ниским приоритетомНастави радови са нормалним приоритетомНастави пост-процесирањеNastavlja seВреме задржавањаПокушај опетPonovo pokušaj svePonovo pokušaj sve neuspešne posloveПокретање скриптаПокретање скипта...Покретање скрипта %sSABnzbd %s покренутSABnzbd хостЛозинка SABnzbd-аSABnzbd ПортАсистент брзог-покретања SABnzbd-аКорисничко име SABnzbd-аВерзија SABnzbd-аSABnzbd Веб серверSABnzbd је нашао фаталну грешку:Гашење SABnzbd је завршеноSABnzbd ће сада радити у позадини.СМТП серверNeuspešna SQL komanda, videti izveštajССЛСуботаСачувајСачувај променеSnimanje %s neuspešnoSnimanje...Скенирај надгледану фасциклуПланификација за непостојећи сервер %sПланирањеСкриптKod prekida skripte je %sСкриптеПретрагаБрој сезонеЈезик веб интерфејсаОдабрати САМО ако Ваш провајдер допушта SSL везе.Пошаљи RSS нотификацијеPošalji nazad u redПошаљи е-поруку када RSS фид дода рад у ред.Пошаљи е-поруку када је диск пун и SABnzbd паузиран.%s послат у редСортирање серијеСерверServer %s koristi nepouzdan HTTPS sertifikatServer %s će biti ignorisan %s minutaДетаљи сервераAdresa servera "%s:%s" je neispravnaПотребна је адреса сервераOpis serveraIme servera se ne može odreditiСерверу су потребни име и лозинка.Greška na strani servera (kod greške %s); nemoguće dobiti %s na %sСервериПоставља дозволе за завршене датотеке/фасцикле.
У октал. На пример: "755" или "777"Унети сервер излазних е-поруке вашег провајдера.Подешавање је сада завршено!Да се настави преузимање после ресета квоте?Прикажи свеПрикажи погрешнеПокажи извештајИме серијеPrikaži aktivne konekcijeПрикажи детаљеPokaži interfejsИме.серијеИме_СеријеУгасиУгаси рачунарУгаси SABnzbdГашењеSignal %s primljen, snimanje i napuštanje...ВеличинаНеке датотеке нису проверене "%s"Žao nam je, nismo mogli to da interpretiramo. Pokušajte ponovo.Уреди низСреди по старост Новије→СтаријеСреди по старост Старије→НовијеСреди по имену A→ZСреди по имену Z→AСреди по величини Веће→МањеСреди по величини Мање→ВећеСортирањеИзворПосебноБрзинаОграничење брзинеУ стање приправностиПокрени чаробњакаПокретање пооправљањаПокретање/ГашењеСтатусOpcije statusa i interfejsaЗауставиЗаустављам...ПошаљиНедељаПодржите пројекат, дајте добровољан прилог!Sumnja u grešku u programu za downloadПрекидачиСистемске фасциклеPerformanse sistema (Pystone)ТЕКСТПРЕВЕЛИКОПривременоПривремена фасцикла преузимањаПробна е-порукаProbno obaveštenjeПробај серверПробам детаље сервера...То поново покреће SABnzbd и ради пуну
реконструкцију садржаја реда, чувајући већ преузете датотеке.
То мења ред реда.Кутијица поред имена фида треба да буде одабрана да би фид био омогућен и да провери нове ставке.
Када је фид додат, ће узети нове ставке а не оне које су већ у RSS фиду осим ако стиснете "Натерај преузимање".Име хоста није унето.Број веза дозвољене од стране провајдераServer nije pravilno odgovorio na helo pozdravВезе нису подешене. Подесити макар једну везу.Постоје усамљени радови у фасцикли преузимања.
Можете да их обришете (укључујући датотеке) или да их поново пошаљете у ред.Кључ допушта да други програми додају NZB у SABnzbd.Овај кључ допушта пун приступ SABnzbd-а другим програмима.Овог месецаOvaj server ne dozvoljava SSL na ovom portuОве седмицеОво поново покреће SABnzbd.
Користити ако мислите да програм има проблем стабилности.
Преузимање ће бити паузирано и наставиће се после.То ће послати пробну е-поруку Вашем малогу.ЧетвртакВреме је истеклоИстекло време: Покушајте да упалите SSL или да се привежете на други порт.Време истеклоНасловZa: %s Od: %s Datum: %s Tema: SABnzbd prijavljuje Disk Pun Zdravo, SABnzbd je stao sa downloadom zato što je disk skoro pun. Molimo Vas napravite mesta i pokrenite download u SABnzbd ručno. ДанасPremalo prostora na disku, prisiljena PAUZAPreviše konekcija ka serveru %s [%s]Превише конекција, паузирајте преузимање или поновите каснијеВрхУкупноРеши проблемПокуша да предвиди успешан завршетак пре стварног преузимања (спорије!)Покушавам 7zip са лозинком "%s"Pokušaj SFV proverePokušaj da se učita NZB sa %sПокушај постављања статуса за непостојећи сервер %sProba raspakivanja sa lozinkom "%s"УторакШтеловањеТипNEŽELJENIПогрешно учитавање УРЛ-а; %sURLGRABBER SE SRUŠIONeautorizovan pristupДеблокирајServer nije definisan!Nepoznata greška pri dešifrovanju %sНепозната акција: %sNepoznata greška pri autentifikaciji na email serverРаспакујИздвој архиве (rar, zip, 7z) унутра архиве.Previše ugnježdenih nivoa pri raspakivanju [%s]Издвојено %s датотека/фасцикла у %sРаспакивањеNeuspešno raspakivanje, %sNeuspešno raspakivanje, CRC greškaNeuspešno raspakivanje, arhiva zahteva lozinkuNeuspešno raspakivanje, putanja je predugačkaПогрешно распакивање, не може да се нађе %sNeuspašno raspakivanje, greška u pisanju ili je disk pun?NZB датотека неупотребљиваNeupotrebljiva RAR datotekaNeželjena ekstenzija je u rar datoteci %sNeželjene ekstenzijeНова верзија доступна!Pošalji NZB; РадиKoristi globalna podešavanja interfejsaКористи привремено име при пост-процесирање. Угасити уколико га Ваш систем то не прихвата како треба.Коришћено пре него што NZB уђе у ред.; КешКорисничке фасциклеKorisnički ključKorisnički ključ (obavezan)Korisničke skripte mogu uznačiti posao kao neuspešanКорисничко имеВредностиУспешна провера преко СФВПроверавањеПроверавање...; ВерзијаВрло нискоВиди извештај скриптаЧекање %s секПАЖЊА:ЧекамУпозорењеУпозорењаНадгледана фасциклаИнтервал скенирањаВеб интерфејсСредаКада током преузимања постаје јасно да превише података недостаје, прекинути посаоKada korisnička skripta vrati kod koji nije nula, posao će biti označen kao neuspešanКоји постотак брзине линије SABnzbd треба да користи, нпр. 50Е-пошта одакле долази нотификацијаВикиWindows notifikacijeГодинаТребате да поставите максимални проток пре него што поставите ограничењеVerzija vašeg UNRAR-a je %s, mi preporučujemo verziju %s ili noviju.
Vaš lični Pushbullet API ključ (obavezan)[%s] Грешка "%s" при споја датотеке[%s] Greška "%s" pri raspakivanju RAR datoteka[%s] Спојено %s датотеке(а)[%s] Нема par2 датотеке[%s] 'PAR2' је примио погрешне опције, проверите параметри Подешавање->Прекидачи[%s] Брза Провера ОК[%s] Поправљено за %s[%s] Проверено за %s, све датотеке су добре[%s] Проверено за %s, потребна је поправкаartikliПрилагођено-словодданданаOnemogući serverOmogući serverдатотекассатсата(и)осталомручномин.мин.искљ.укљ.илистраниpar2 program...NIJE pronađen!сек.секунди(е)видети извештајтекстunrar program...NIJE pronađen!седмица././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993698.543638 SABnzbd-4.3.2/locale/nl/LC_MESSAGES/SABnzbd.mo0000644000000000000000000025370514625637243017514 0ustar00runnerstaffD l@om@d@BB SES\LSS*T1TKT kT TTTT!U6'U-^UUU"U<U?V6YVV VVGVlW<uWW.W'W "X,XBXXXaXSvXX XXXY"Y85YnY}YY YYUYZ $Z*0Z[ZuZ#ZZZ ZZZ*[;[\\ ]]Q-]] ]]3] ] ] ]]]^^3^G^ N^Y^o^ ^^ ^1^^_17_4i_9__&_ `)` :`(H`q``4`4``a?aaaa b'b @b,Kb,xbib1cAcJc]cmc'cc5cc d'dFd d e e e%e,e1eBe$Heme }ee#ee eeefff3f :fFf cfpffffff4gDgSYgggggHh Lh Vhch rh hh(h.h)h,i<Ai&~ii'iiij .j OjZj8ij.jj j jkk4kJk`k tkkkkkk%k!l6l+Vl l#ll!l*m!/mQm#fmm'm"mmn#+nOn!en0n!nnno1oQokoo oooooppp$p:pASpp'p!ppq)q2q;q-Bqpq/q!q qq&q"r9@rBzrrrrrr r sss )s5s>s QsrszsGs/s t tt/t@t'Qtytt t tttot LuYu huuuuuuuu uu uv v;+v>gv-v9v ww +w8wUw6ZwvwhxqxGx I Taq ũ̩ :F K/U  Ȫ ڪ ` !2:Cm5AF>ˮ= HMS+ ͯׯ,| >L V "&3AZ E+Ia.}̳Գ۳avJĴ-"P/W ĵε-6-"d#."ڶ"!$Di} J7.bL<$  )2F#U"y%Lҹ ) :GOX ht}2ɺغ  RUqcǻM+=y0 !:TjAoEB:+¾#)<QJc&¿/&-'T|    ".3M[Rjo~X G)h!$Z>8V] c n y&+H@=P~\ ,8 P\hwhI9`u$%!J'l  /6++ W aour !09 ?`"&I\m5, %; Ygp:y9X\z '% );AhJ >%H)n1)' (=$fD.'/B|rU~+ Q_iI4**_' V $` A& 8$Ejsc 7%N!t$ *D")L ; GhU  F /< M"W z ")">(V.+SH.Kw( 66-GuCA #I1/8&h  .801$6G,dK 6 W, = G S_en3 ) '1EY^u #!@b"~~<YrS 05"S.v2C-J1e$0& 0B@X8 3)I%s $""0@$q9#+& *G,r!+ 5%*[%#!$67!n'$&*$0O %"#$8@"`\'./7)g! #  I92/;^1   )?^g`B#3BUh/{ o   1* \ ht${>4/:D  <mA"D@[A`# 6- AVLv6 4. c Y{   0  4 k> c X g      b  n z    -  m  l v |  m O,h,zT eoxq & B$O#t |222b]Ly-        'HM g5r  *4?,t    *54j!C+]3:7.3> Ab ku"%<PbXs    1 Q]aipv(    '#K'k* t)Q {*)(r  2  ^ 6S!!!! !.! ""*"D"2"##9/#i# p# {## ######$,/$\$ z$$$"$ $ $$ $3 %A%J%c%u%7%%%% % & && &'%'%=')c'''' ''((((&);)P)X)h)+))) ) ))"* )*3*&I*p******?* >+7H+ ++ + +++0+A",(d,5,, ,!,(,&"- I-V-^- q-{-----5-6.9E... ..&..&/)*/T/ f/ p/{//'////U0W0m0 r0}0000 0&000$1 1 1$11 222 2(2 A2K2"a2 222$22222 3#3 >3mJ33>3 44/4WL4K4I4:5W5r5y55545#565816.j66#66(6 778574n77K777/8A@8N8 8 8 8 8 99 )9 69D9 V9 a9 l9 v99 9-99%9:9A5: w:7:1:1:' ;'H;1p;1;;;;;c;X< i<t<<<<<< <<<<<=.= 5=C=_=p=v=@==== = > > > *>%8>^>T?X?V@1o@[@0@.AKLAALBJlB BdB*'C RC\C!!D CDMDJfD DDuD9EF( F'3FJ[FFFFPF(G>G^GvGG;G"G H HH &H0HHHa_HH HH+HJ IkI/I I@I$I#J CJMJcJ-JDJ)J%K.BKqKKK(K,KL)L =LJLSLSdLALLlMAMCM NN+N=N[NnN.NNN*NNN GOSOiOxO OO O OO6O O P P P Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %f% available of %d requested articles%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address%s is not a valid script%s is not writable at all. This blocks downloads.%s is not writable with special character filenames. This can cause problems.%s@%s: Received unknown status code %s for article %s+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!

Use Sorters to automatically organize your completed downloads. For example, put all episodes from a series in a season-specific folder. Or, put movies in a folder named after the movie.

Sorters are tried in order of appearance and can be reordered by dragging and dropping.
The first active sorter that matches both the affected category and job type is applied.

More options are available when Advanced Settings is checked.
Detailed information can be found on the Wiki.

ALTERNATIVEAPI (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAbort post-processingAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedAccount expiration dateActionAction when an unwanted extension is detectedAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdd SorterAdded NZBAdditionally, attempts to set the correct file extension based on the file signature if the extension is not present or meaningless.Adds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup.Administrative FolderAdvancedAffected CategoriesAffected Job TypesAgeAllAll files will go into a single folder.All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings.Allow proper releasesAlso test releasesAlwaysAlways use full screen widthAny propertyApplication TokenApplication token (required)Apply filtersArchiveAre you sure you want to remove these jobs?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle availabilityArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically sort jobs in the queue when a new job is added.Automatically sort queueBackBackupBackup FolderBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBlacklistBlocked attempt to create directory %sBottomBrowseBypass smart duplicate detection if PROPER, REAL or REPACK is detected in the download name.Cache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write a long filename to %s. This can cause problems.Cannot write a unicode filename to %s. This can cause problems.Cannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCategory folder cannot be a subfolder of the Temporary Download Folder.Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Certificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a theme.Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfiguration locked, cannot save settingsConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not connect to %s on port %s. It appears that %s operates as a web server (port 80), possibly an indexer, not a usenet server. You have to fill a usenet server.Could not determine connection result (%s)Could not load additional certificates from certifi packageCould not restore backupCreate a backup of the configuration file and databases in the Backup Folder.
If the Backup Folder is not set, the backup will be created in the Completed Download Folder.
Recurring backups can be configured on the Scheduling page.Create backupCurrent SchedulesCurrent umask (%o) might deny SABnzbd access to the files and folders it creates.CustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Apprise URLsDefault Base FolderDeleteDelete AllDelete after downloadDelete all completed jobsDelete all items from the queue?Deleting %s failed!DeobfuscateDeobfuscate corrected the extension of %d file(s)Deobfuscate final filenamesDeobfuscate renamed %d file(s)Deobfuscate skipped due to DVD/Bluray directoriesDetect duplicates based on analysis of the filename.Detect identical downloads based on name or NZB contents.DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDirect UnpackDirect Unpack was automatically enabled.Disable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue.Disconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDisk speedDo an extra verification based on SFV files.Do not have valid authentication for feed %sDo not use a folder in the application folder as your Scripts Folder, it might be emptied during updates.Does the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownload speed limited byDownloadedDownloaded in %s at an average of %sB/sDownloading will automatically resume if the minimum free space is available again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes.Duplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:EditEdit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmergency expireEmergency retryEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable Apprise notificationsEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Executed after the queue finishes downloading.Executes a custom scriptExit SABnzbdExtensionExternal internet accessExternal process priorityExtra PAR2 ParametersExtra history columnsExtra queue columnsExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to connect: %s %s@%s:%s (%s)Failed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to rename %s to %sFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Apprise messageFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send one or more Apprise NotificationsFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFatal error in DownloaderFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardGuessIt PropertyGuessIt.PropertyGuessIt_PropertyHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHidden FoldersHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory RetentionHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How many seconds your notification will continue to be retriedHow much can be downloaded this month (K/M/G)How often (in seconds) the same notification will be sentINCOMPLETEIONice ParametersIPv6 addressIdentical download detectionIdleIf empty, the standard port will only listen to HTTPS.If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name.If only the Default category is selected, notifications are enabled for jobs in all categories.If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In case of connection failures, the download queue will be paused for a few minutes instead of skipping this serverIn foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Internet BandwidthInvalid NZB file %s, skipping (error: %s)Invalid backup archiveInvalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job Name as FilenameJob failedJob finishedJobsJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesJoiningKeep all jobsKeyboard shortcutsLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLive ChatLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Location where the backups of the configuration file and databases are stored.
If left empty, the backup will be created in the Completed Download Folder.Log FolderLog inLog outLoggingLogin from too many different IP addresses to server %s [%s] - https://sabnzbd.org/multiple-adressesLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname.Minimum FilesizeMinimum Free Space for Completed Download FolderMinimum Free Space for Temporary Download FolderMissing articlesModerateModern web browsers and other clients will not accept self-signed certificates and will give a warning and/or won't connect at all.MondayMonthMoreMove all completed jobs to archiveMove and rename all episodes in the "tv" category to a show-specific folderMove and rename all movies in the "movies" category to a movie-specific folderMove jobs to the archive after specified number of daysMove jobs to the archive if the history exceeds specified number of jobsMovie NameMovie SortingMovie.NameMovie_NameMoviesMovingMoving...Multi-OperationsMulti-part LabelNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNetwork path "%s" should not be used hereNeverNextNext scan atNice ParametersNo accessNo email templates foundNo foldersNo matching earlier rar file for %sNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn queue finish scriptOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)One or more Apprise URLs could not be loaded.Only Get Articles for Top of QueueOnly external access requires loginOnly unpack and run scripts on jobs that passed the verification stage. If turned off, all jobs will be marked as Completed even if they are incomplete.Open a Terminal window and type the line (example):Open complete folderOpen folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOriginal Job NameOrphaned jobsOther / UnknownOther MessagesOverride the default URLs for specific notification types below, if desired.PROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermanently delete (skip archive)Permissions for completed downloadsPermissions setting of %s might deny SABnzbd access to the files and folders it creates.Personal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPost-processing was abortedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge LogsPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuick startQuitQuotaQuota for this account, counted from the time it is set. In bytes, optionally follow with K,M,G.
Warn when it reaches 0, checked every few minutes.Quota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!Received a DBus exception %sRefreshRefresh rateRefused connection from:Refused connection with hostname "%s" from:RejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove SorterRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRenaming the job will abort Direct Unpack.RepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.Replace underscores in folder nameReplace underscores with dots in folder names.RequiredRequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorRestore DefaultsRestore backupResultResumeResume high priority jobsResume jobs with categoryResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSOCKS5 ProxySQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSeason folderSecure connection to serverSecuritySelect a mode and list all (un)wanted extensions. For example: exe or exe, comSelect a web interface language.Select only if your provider allows SSL connections.Selected date rangeSend RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send notifications using Apprise to almost any notification serviceSent %s to queueSeperate multiple URLs by a commaSeriesSeries SortingSeries with air datesServerServer %s has used the specified quotaServer %s is expiring in %s day(s)Server %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Shift+Arrow key: Browse Queue and History pagesShould downloading resume after the quota is reset?Show AllShow ArchiveShow FailedShow LoggingShow NameShow active connectionsShow detailsShow folderShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSmart duplicate detectionSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by % downloaded Most→LeastSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeed up repairs by installing par2cmdline-turbo, it is available for many platforms.SpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)System loadTEXTTOO LARGETabbed layout
(separate queue and history)Tag jobTemp FolderTemporary Download FolderTest DataTest EmailTest NotificationTest ServerTest downloadTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The Completed Download Folder cannot be the same or a subfolder of the Temporary Download FolderThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe queue will resort every 30 seconds if % downloaded is selected.The server didn't reply properly to the helo greetingThere are no active servers!There are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo prevent all helpful warnings, disable Special setting 'helpful_warnings'.To: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR renamerTrying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse Sorting to automatically organize and rename your completed downloads.Use a comma and/or space to identify more than one URL.Use global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Use the specified SOCKS5 proxy for all outgoing connections.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying repairVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarn 5 days in advance of account expiration date.WarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb Interface ThemeWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be completed' are disabled.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?WhitelistWho should we say sent the email?WikiWill not work if a category folder is on a different disk.Windows NotificationsYearYou can set access rights for systems outside your local network.You must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] The command in build_command is undefined.[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!propertysecsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2024 Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: nl Plural-Forms: nplurals=2; plural=(n != 1); SABnzbd kan de web-interface bestanden niet vinden in %s.
Installeer het programma opnieuw.

SABnzbd heeft opgeslagen data van een andere SABnzbd versie gevonden
maar kan de data van deze andere versie niet opnieuw gebruiken.

Rond zo nodig eerst je werk met de andere versie af.

Herstart daarna deze versie met de optie "--clean".
Dit zal de huidige downloads en geschiedenis wissen!
SABnzbd las het bestand "%s". SABnzbd heeft ontdekt dat het bestand sqlite3.dll ontbreekt.

Sommige slecht ontworpen virusscanners verwijderen dit bestand.
Controleer je virus scaner, probeer SABnzbd opnieuw te installeren en klaag bij je leverancier.

SABnzbd heeft een vrije TCP/IP poort nodig voor de interne webserver.
Poort %s op %s is geprobeerd, maar is niet beschikbaar.
Een ander programma gebruikt de poort al of SABnzbd is al actief.

Start SABnzbd met een ander poort nummer. SABnzbd heeft een geldig host adres voor de interne webserver.
Je hebt een onbruikbaar adres opgegeven.
Veilige waarden zijn localhost en 0.0.0.0

Start SABnzbd met een geldig host adres. SABnzbd wordt aangeboden ZONDER ENIGE VORM VAN GARANTIE. Het is vrije software en je mag het, onder bepaalde voorwaarden, verder verspreiden. De licentie is de GNU GENERAL PUBLIC LICENSE Versie 2 of (naar eigen keuze) een latere versie. %f% van %d opgevraagde artikelen%s artikelen hadden afwijkende duplicaten%s artikelen zijn misvormd%s artikelen ontbreken%s directory: fout %s bij toegang%s is geen correct octaal getal%s is geen geldig e-mailadres%s is geen geldig script.Het is niet mogelijk bestanden te schrijven in %s. Hierdoor kan er niet gedownload worden.Het is niet mogelijk bestanden met speciale tekens op te slaan in %s. Dit geeft mogelijk problemen bij het verwerken van downloads.%s@%s: Onbekende statuscode %s ontvangen voor artikel %s+Debug+Info+Opschonen+Repareren+UitpakkenMap voor het bewaren van NZB-bestanden0 is de hoogste en 99 de laagste prioriteit7za-programma niet gevonden.
Als authenticatie ingeschakeld is, zal je opnieuw moeten inloggen.Let op: mappen worden vanzelf aangemaakt bij "Opslaan".De bestanden worden niet verplaatst. SABnzbd moet herstart worden!

Gebruik Sorteren om automatisch je voltooide downloads te organiseren. Bijvoorbeeld het automatisch verplaatsen van alle afleveringen van een serie in een seizoensspecifieke map. Of plaats films in een map met de naam van de film.

Sorteringen worden in de getoonde volgorde geprobeerd en kunnen worden herschikt door ze te slepen.
De eerste actieve Sortering die overeenkomt met zowel de betreffende categorie als het type taak wordt toegepast.

Meer opties zijn beschikbaar wanneer Geavanceerde instellingen zijn aangevinkt.
Gedetailleerde informatie is te vinden op de Wiki.

ALTERNATIEFAPI (geen Configuratie)API-sleutelQR-code van de API-sleutelAPI-sleutel incorrect; vul de API-sleutel van 'Configuratie' => 'Algemeen' in bij het externe programma:API-sleutel ontbreekt; vul de API-sleutel van 'Configuratie' => 'Algemeen' in bij het externe programma:API-sleutel voor ProwlDownload afbreken als deze zeker niet kan worden voltooidNabewerking afbrekenDownload "%s" is afgebroken vanwege een versleuteld RAR bestand (indien aanwezig, zijn alle wachtwoorden geprobeerd).Afgebroken, kan niet voltooid wordenAfgebroken, versleuteling ontdektAfgebroken, ongewenste extensie ontdektAccepterenToegang geweigerdVerloopdatumActieActie bij ontdekken van een ongewenste extensieActie wanneer versleuteld RAR-bestand wordt gedownloadActie bij ontdekken van ongewenste extensieToevoegenNZB toevoegenVoeg NZB-bestanden toe Taak toevoegenVoeg server toeSortering toevoegenDownload toegevoegdAls de bestandsextensie van een bestand ontbreekt of verhaspelt is, zal er geprobeerd worden de correcte extensie te vinden op basis van de inhoud van het bestand.Voeg een test NZB (gevuld met willekeurige data) toe aan de wachtrij. Hiermee kan je controleren of alles goed werkt.Administratieve mapGeavanceerdBeïnvloede categorieënType downloadsLeeftijdallesAlle bestanden gaan in één mapAlle gebruikersnamen, wachtwoorden en API-sleutels worden automatisch verwijderd uit het logbestand en de bijgevoegde kopie van je instellingen.Sta verbeterde downloads toeOok test versiesAltijdGebruik de volledige schermbreedteAlle eigenschappenApplicatie tokenApplicatie token (verplicht)Filters toepassenArchiefWeet je zeker dat je deze downloads wilt verwijderen?Weet je zeker dat je SABnzbd wilt afsluiten?Weet je het zeker?ParametersArtikelbuffer grootteBeschikbaarheid van artikelenArtikelnummerMinimaalMaximaalInloggen mislukt, controleer gebruikersnaam en wachtwoord.Automatisch doorgaanDownload wordt gepauzeerd als er te weinig ruimte vrij isDe wachtrij wordt automatisch gesorteerd wanneer er een nieuwe opdracht wordt toegevoegdWachtrij automatisch sorterenTerugReserveBackup mapSlecht antwoord van Pushbullet (%s): %sSlecht antwoord van Pushover (%s): %sFoutieve taak %s om %s:%sBandbreedteBlacklistPoging om map %s aan te maken geblokkeerdOnderBladerenSla slimme detectie van dubbele downloads over als de naam van de download PROPER, REAL of REPACK bevat.Bewaar de artikelen in het werkgeheugen (verminderd schijf gebruik).
In bytes, in K,M,G notatie. Bijvoorbeeld: "64M" of "128M"AnnulerenKan het PID bestand %s niet benaderenToegangsrechten van %s niet aan te passenVerbinding maken met server %s [%s] niet mogelijkBackupbestand maken voor %s niet mogelijkNiet mogelijk directory %s aan te makenKan bestemmingsmap %s niet makenKan geen tijdelijk bestand maken voor %sGeen e-mailsjablonen te vinden in %sWebsjabloon %s niet te vinden; het standaardsjabloon wordt gebruikt.Kan de web-browser niet starten, geen gevonden%s kan niet gelezen wordenBewaakte map %s kan niet gelezen wordenVersturen kan niet, vereiste gegevens ontbrekenBestanden met lange bestandsnamen kunnen niet worden opgeslagen in %s. Dit kan voor problemen zorgen tijdens het downloaden.Bestanden met speciale karakters in de bestandsnaam kunnen niet worden opgeslagen in %s. Dit kan voor problemen zorgen tijdens het downloaden.Naar de geschiedenis-database schrijven niet mogelijk, controleer de toegangsrechten.Schrijven naar het INI-bestand %s lukt nietCategorieënCategorieEen Categorie specifieke map mag niet een map in de Tijdelijke download map zijn.Servernaam komt niet overeen met de servernamen in het certificaat. Dit is een server-probleem.Certificaat niet geldig. Dit is hoogstwaarschijnlijk een server-probleem.CertificaatverificatieWijzigingen niet opgeslagen en zullen verloren gaan.Wijzigingen worden pas actief na herstart!Selecteer allesControle vóór downloadenPeriodieke controle voor nieuwe versiesControlerenControleren van extra bestandenMinuten tussen het uitlezen (minimaal 15). Niet actief bij gebruik van de Taakplanner!Kies een stijl voor de webinterface.Opschoon lijstOpschonen van %s misluktWissenTellers op nulKlik om de verbinding te testen.Afsluiten van het browservenster zal SABnzbd niet stoppen.Compacte weergaveMap voltooidSnelheid van verwerkte downloads mapVoltooidMap voor verwerkte downloadsDe map voor voltooide downloads %s staat op een FAT systeem, de maximale file omvang is dan maar 4GInstellingenInstellingen bestandConfiguratie geblokkeerd, kan instellingen niet opslaanBevestig verwijderen uit geschiedenisBevestig verwijderen uit wachtrijVerbinding %s@%s mislukt, bericht=%sSuccesvol verbonden!Verbinding mislukt!VerbindingenBeschadigd RAR-bestandKon geen verbinding maken met %s op poort %s. Het lijkt erop dat %s functioneert als een webserver (poort 80), mogelijk een indexer, geen usenetserver. Vul een usenetserver in.Kan verbindingsresultaat niet bepalen (%s)Extra certificaten uit het certifi pakket konden niet geladen wordenDe backup kon niet hersteld wordenMaak een backup van de configuratie en de database in de Backup Map.
Als er geen Backup Map is ingesteld wordt de backup aangemaakt in de Map voor verwerkte downloads.
Automatische backups kunnen worden ingesteld via de Taakplanner.Maak backupHuidige takenHuidige umask (%o) zou kunnen beletten dat SABnzbd toegang heeft tot de aangemaakte bestanden en mappen.AangepastDUBBELDagelijksBeschadigde geschiedenis-database, is vervangen door een lege databaseDatum sorterenDatumnotatieDag van de maandDecenniumDecoder fout: onvoldoende geheugenStandaardStandaard Apprise-URL'sBasis mapVerwijderAlles wissenVerwijderen na downloadVerwijder alle voltooide downloadsVerwijder alle downloads uit de wachtrij?Verwijderen van %s mislukt.Bestandsnaam verbeterenExtensie van %d bestand(en) gecorrigeerdVerbeter bestandsnamen van voltooide downloadsBestandsnamen van %d bestand(en) aangepast.Verbetering van bestandsnamen overgeslagen omdat er DVD/Bluray mappen gevonden zijnDetecteer dubbele downloads op basis van de analyse van de bestandsnaam.Detecteer identieke downloads op basis van de naam of de inhoud van de NZB.ApparaatApparaat dat de berichten moet ontvangenApparatenApparaat of apparaten die het bericht moeten ontvangenDirect UitpakkenDirect Uitpakken is automatisch ingeschakeld.Schakel quotum beheer uitUitHTTPS uitgeschakeld omdat de CERT en KEY-bestanden niet geldig zijnHTTPS is uitgeschakeld vanwege ontbrekende CERT- en KEY-bestandenVerwerpenVerbreek alle actieve verbindingen naar usenet servers. Verbindingen worden na een paar seconden weer geopend als er nog downloads in de wachtrij staan.Verbreek verbindingen wanneer de wachtrij leeg is of er gepauzeerd wordt.Verbreek verbindingen wanneer er niets te doen isStuur een e-mail wanneer de harde schijf vol isSchrijffout bij opslaan van bestand %sSchijf is volSchijf is vol; gedwongen pauzeHardeschijfDoe een extra verificatie m.b.v. SFV-bestandenGeen geldige inlog gegevens beschikbaar voor RSS-feed %sAls de Map voor scripts zich in de SABnzbd installatie-map bevindt kan deze automatisch verwijderd worden tijdens updates. We adviseren een andere locatie te gebruiken voor je scripts.Wordt het quotum elke dag, week of maand gereset?DownloadDownload voltooidDownload misluktDownload alle PAR2-bestandenDownload mislukt - Niet meer op je server(s)Snelheid van download mapDownload mislukt waarschijnlijk, slechts %s van de benodigde %s beschikbaarDownloadsnelheid beperkt doorGedownloadGedownload in %s met een gemiddelde snelheid van %sB/sHet downloaden zal automatisch hervat worden als de minimale vrije ruimte weer beschikbaar is.
Is van toepassing op zowel de tijdelijke als verwerkte download map.
Wordt elke paar minuten gecontroleerd.Dubbele downloadVoorbeeldBv. 8 of 20VERSLEUTELDFOUT:WijzigenBewerk download detailsE-mailStuur een e-mail na het voltooien van elke downloadOntvangerAfzenderMap met e-mailsjablonenAdres waarnaar de e-mail verstuurd wordt.E-mail verzondenNoodgevalEinde van noodgevalNoodgeval herhalingLeegNZB-bestand %s is leegLege RSS-feed gevonden (%s)Inschakelen7Zip toestaanApprise-meldingen activerenActiveer HTTPSNotifyOSD activerenProwl meldingen activerenPushbullet meldingen activerenPushover meldingen activerenVoer SFV-gebaseerde controles uitWindows meldingen activerenWebinterface beschikbaar via HTTPSGebruik tijdelijke mapnamenAanzetten zal leiden tot minder geheugen gebruik.
Uitzetten om te voorkomen dat langzame downloads de wachtrij blokkeren.Notificatie script activerenSchakel quotum beheer inRecursief uitpakken toestaanActiefAls het pad eindigt met een ster *, dan worden geen aparte download mappen gemaakt.URLAflevering NaamAflevering NummerAflevering.NaamAflevering_NaamFoutFout %s bij 'file_join' op %sFout '%s' bij reparatie van set %sFout "%s" bij uitvoeren van 'rar_unpack' op %sFout %s bij uitvoeren van par2-reparatie op set %sFout %s: Je moet een geldige gebruikersnaam en wachtwoord invullen.Fout bij aanmaken SSL-sleutel en -certificaatFout bij importeren van %sFout bij inladen van %s, corrupt bestand gevondenFout bij verwijderen van %sFout bij hernoemen van "%s" tot "%s"Fout bij toevoegen van %s, wordt weer verwijderdFout bij het afsluiten van het systeemAlleen bij foutenFouten/WaarschuwingenEssentiële onderdelen ontbreken, er kan niet gedownload worden.Script wordt uitgevoerd nadat de wachtrij is gedownload.Voer een zelfgemaakt script uitStop SABnzbdExtensieExterne toegangExterne process prioriteitExtra PAR2 parametersExtra kolommen aan geschiedenis toevoegenExtra kolommen aan wachtrij toevoegenUitpakken...Keur download afMisluktAanmelden bij server %s mislukt [%s]Aanmaken (%s) misluktVerplaatsen van %s naar %s misluktAanmelden bij e-mailserver misluktHet lukt niet om de database te sluiten, zie logBeëindigen e-mailverbinding misluktHet compileren van 'regex' voor de zoekterm lukt niet: %sVerbinding met e-mailserver misluktKon geen verbinding maken: %s %s@%s:%s (%s)Kan systeem niet in slaapstand krijgenImporteren van %s bestanden van %s misluktInitialisatie van %s@%s mislukt, vanwege: %sTLS-verbinding misluktVerplaatsen van bestanden misluktKan het wachtwoord bestand niet uitlezen %sHernoemen van %s naar %s misluktHernoemen van gelijkaardig bestand %s naar %s misluktKan RSS-feed "%s" niet lezen vanwege: "%s"Verzenden van Apprise-bericht misluktVerzenden van Prowl-bericht misluktVersturen Windows-melding misluktVerzenden van e-mail is misluktKon macOS notificatie niet verzendenKon één of meerdere Apprise-meldingen niet verzendenPushbullet-bericht sturen misluktPushover-bericht sturen misluktKan het systeem niet in standby krijgenWebinterface kan niet gestart wordenWebinterface kon niet gestart worden: Kon het volgende bestand niet uploaden: %sDownload '%s' geweigerd omdat het een dubbele isProbleem met tempfile.mkstempFatale foutOnherstelbare fout bij opslaan statusOnherstelbare fout in de AssemblerOnherstelbare fout in de DownloaderFeedOphalenHaal NZB op via URLOphalen%s herstelblokken downloaden...Extra herstelblokken downloaden...Bestand met alle wachtwoorden die uitgeprobeerd moeten worden op versleutelde RAR-bestanden.Samenvoegen van bestanden %s is misluktNaam of pad naar het HTTPS-Certificaatbestand.Bestandsnaam of padnaam van HTTPS chain-bestandNaam of pad van het HTTPS-sleutelbestand.Bestand bestaat niet op de serverBestandsverzamelingBestandsnaamFilterWat te doen met "sample"-bestanden?Map met scripts van de gebruikerMap met e-mailsjablonen..nzb bestanden in deze map worden automatisch toegevoegd aan de wachtrij.Map/PadMappenWanneer authenticatie nodig is, de gebruikersnaam.Wanneer authenticatie nodig is, het wachtwoord.Voor opslag op servers: gebruik namen die werken op WindowsVoor onbetrouwbare servers, deze zullen langer worden genegeerd wanneer ze fouten veroorzaken.ForcerenVerbreek verbindingenForceer downloadVerbinding verbrekenForumVrije ruimteFrequentieVrijdagVanaf Serie SxxEyyVanaf SxxEyyVolledige APIVolledig webinterfaceVoor meer informatie bekijk deAlgemeenMaak een nieuwe sleutelMaak een nieuw zelf-ondertekend certificaat en sleutel. SABnzbd moet dan opnieuw gestart worden.Glitter heeft enkele (nieuwe) functies die je mogelijk aanspreken!Ga naar SABnzbdGa naar WizardGuessIt EigenschapGuessIt.EigenschapGuessIt_EigenschapHTTP- en HTTPS-poort kunnen niet hetzelfde zijnHTTPS-certificaatHTTPS chain-bestandHTTPS-sleutelbestandHTTPS PoortHTTPS certificaatverificatieHulpHelp ons om SABnzbd in jouw taal te vertalen!
Met nieuwe vertalingen of verbeteringen kun je hier terecht:PC slapenVerborgen mappenVerberg detailsToon/verberg voltooide bestandenHoogGeschiedenisGeschiedenis Laaste 10 ItemsGeschiedenis bewarenItems in geschiedenisHoudt Shift toets ingedrukt om meer te selecterenStartpaginaStartpaginaServerHost adres waar op SABnzbd luistert.Voor hoe lang of tot wanneer wilt u pauzeren? (in het Engels!)Hoeveel seconden moet de notificatie herhaald wordenHoeval mag deze maand worden gedownload (K/M/G)Hoevaak moet de notification herhaald worden (in seconden)ONVOLLEDIG"IONice" parametersIPv6-adresIdentieke downloaddetectieRustIndien leeg, werkt de standaard poort uitsluitend met HTTPS.Als bestandsnamen van (grote) bestanden na een voltooide download onlogisch of verhaspelt lijken (obfuscated), worden ze vervangen door de naam van de download.Notificaties zullen worden verstuurd voor alle downloads als de Standaard categorie geselecteerd is.Als de Host of Poort open is gesteld naar het internet zorgen de huidige instellingen ervoor dat de webinterface volledig beschikbaar is voor externen.Als je dit bericht weer krijgt, probeer dan een ander nummer.
Negeer samplesNegeer mappen binnen archievenDubbele download "%s" overgeslagenOngewenste extensie ontdekt in "%s". Het ongewenste bestand is "%s" Als je "Pause" kiest, dan dien je een wachtwoord in te stellen en de download vrij te gevenWanneer SABnzbd opnieuw is gestart, gaat dit venster vanzelf weg!Het downloaden zal een aantal minuten gepauzeerd worden wanneer deze server niet beschikbaar is.In mappenOngeschikte RSS-feedOnbruikbaar wachtrij bestand gevonden, kan niet verderTijdelijke download mapOnvolledige reeks van samenvoegbare bestandenFoutieve RSS-feed definitie "%s"Incorrecte parameterFoutief gecodeerd wachtwoord %sVerhoog de prestaties door een eenvoudigere SSL versleuteling toe te passen.Indexer Categorieën / GroepenIndexers kunnen een categorie in de NZB plaatsen en SABnzbd zal die proberen toe te passen op onderstaande categorieën. Daarnaast kun je patronen invullen in de kolom "Indexer Categorieën/Groepen". Gebruik komma's om patronen te scheiden. Joker tekens (? en *) zijn toegestaan.
Meer informatie op de Wiki.Internet BandbreedteCorrupte NZB %s wordt overgeslagen (foutmelding: %s)Ongeldig backup bestandOngeldige par2 bestanden of ongeldige Par2 parameters, kan niet verifiëren en repareren.Ongeldige servernaamOngeldige servergegevensOngeldig loggen van fase in geschiedenis voor %sProblemenTip: maak een "Bladwijzer" of "Favoriet" voor deze locatie, zodat je SABnzbd gemakkelijk terug kunt vinden.Download "%s" is waarschijnlijk versleuteld omdat en een RAR met dezelfde naam in de hoofd RAR zit.Download "%s" is waarschijnlijk versleuteld, omdat "password" in de naam "%s" voor komt.Downloadnaam als BestandsnaamDownload misluktDownload voltooidDownloadsHet uitpakken van downloads wordt al gestart tijdens het downloaden. Dit verkort de tijd die nodig is voor het nabewerken. Dit werkt alleen als de download niet beschadigd is.SamenvoegenSamenvoegenBehoud alle downloadsSneltoetsenTaalStart webbrowser bij opstartenStart de web browser wanneer SABnzbd opstart.Beperk snelheidLijst van extensies die na downloaden verwijderd moeten worden.
Voorbeeld: nfo of nfo, sfvLive ChatLadenInlezen van %s misluktLokaal IPv4-adres"Local Storage" (cookies) is uitgeschakeld in je web browser, niet alle instellingen zullen worden onthouden.Map waar de wachtrij en geschiedenisdatabase worden opgeslagen.
Kan alleen gewijzigd worden als de wachtrij leeg is.Map waarin de log bestanden worden opgeslagen
Vereist een herstart.(kan aangepast worden door de categorieën).Map om onbewerkte downloads op te slaan
Kan alleen gewijzigd worden als de wachtrij leeg is.Map waar reserve kopieën opgeslagen worden.Map waar de backups van de configuratie en databases worden opgeslagen.
Als deze map niet is ingesteld worden de backups aangemaakt in de Map voor verwerkte downloads.Map voor loggingAanmeldenAfmeldenLoggenTeveel verschillende IP-adressen probeerde in te loggen op server %s [%s] - https://sabnzbd.org/multiple-adressesVerbinding met SABnzbd verbrokenLaagKleine lettersMaak compatibel met WindowsGeselecteerdMaximale snelheid internetverbindingMaximaal aantal pogingen per serverMaximum aantal pogingenBetekenisMinimaalMinimaal: wanneer SSL geactiveerd is, controleer de identiteit van de server m.b.v. de certificaten. Strikt: controleer en vereis dat het geldige certificaat bij deze servernaam hoort.Minimale bestandsgrootteMinimale vrije ruimte voor verwerkte downloads mapMinimale vrije ruimte voor tijdelijke download mapOntbrekende artikelenGematigdSelf-signed (onofficiële) certificaten worden door moderne webbrowsers en andere programma's meestal niet geaccepteerd waardoor deze een foutmelding geven of helemaal niet kunnen verbinden.MaandagmaandMeerVerplaats alle voltooide downloadsnaar het archiefVerplaats en hernoem alle afleveringen in de "tv" categorie naar een specifieke map voor de serie.Verplaats en hernoem alle films in de categorie "films" naar een specifieke map voor de film.Verplaats voltooide downloads naar het archief na het opgegeven aantal dagenVerplaats voltooide downloads naar het archief als de geschiedenis het opgegeven aantal voltooide downloads overschrijdt.Film NaamFilm sorterenFilm.NaamFilm_NaamFilmsVerplaatsenVerplaatsen...Meervoudige bewerkingMeervoudig labelNZB-sleutelDownload aan wachtrij toegevoegdNaamNameserver / DNS opzoekenNaamgevingWe raden af hier de netwerk-locatie "%s" te gebruikenNooitVolgendeWordt uitgevoerd om"Nice" parametersGeen toegangGeen e-mailsjablonen gevondenGeen mappenGeen voorgaand rar-bestand gevonden bij %sGeen geadresseerden opgegeven, e-mail niet verstuurdGeen geschikte authenticatiemethode gevondenGeenNormaalVerworpenNiet beschikbaarBerichtencentrumNotificatie ScriptMelding verzondenMeldingsscript '%s' bestaat nietMeldingenNotifyOSDAantal seconden tussen het lezen van de bewaakte map.OPTIONEEL: Account wachtwoordOPTIONEEL: Account gebruikersnaamUitOude wachtrij gevonden, gebruik Status->Reparatie om te converterenNa afronden wachtrijScript voor na het afronden van de wachtrijOp welke dag van de maand of week (1=maandag) wordt het quotum gereset? (Eventueel met hh:mm)Eén of meerdere Apprise-URL's konden niet worden geladen.Download alleen artikelen van het begin van de wachtrijAlleen voor externe toegang is aanmelden nodigUitpakken en scripts worden alleen uitgevoerd op opdrachten die succesvol geverifieerd zijn. Als deze optie uitgeschakeld is zullen alle opdrachten gemarkeerd worden als succesvol, zelfs als dat niet zo is.Open een "Terminal" venster en type deze regel in (voorbeeld):Open map met voltooide downloadsOpen mapOptioneelEventuele extra NZBWachtwoord voor web login.Gebruikersnaam voor web login.Geef eventueel een andere naamOf sleep bestanden in dit venster!VolgordeOriginele bestandsnaamOriginele DownloadnaamVerweesde downloadsAnders / OnbekendAndere berichtenOverschrijf hieronder, indien gewenst, de standaard-URL's voor specifieke meldingstypen.VERSPREIDINGSWACHTTIJD %s minParametersVolgnummerWachtwoordWachtwoordenbestandWachtwoord gemaskeerd met ******, voer opnieuw inVersleuteldPadPatroonUitlegPauzeAlles pauzerenOnderbreek downloaden tijdens nabewerkenPauzeerPauzeer 1 uurPauzeer 15 minutenPauzeer 3 uurPauzeer 30 minutenPauzeer 5 minutenPauzeer 6 uurPauzeer...Pauzeer downloads met prioriteit "Hoog"Pauzeer downloads met categoriePauzeer downloads met prioriteit "Laag"Pauzeer downloads met prioriteit "Normaal"Pauzeer nabewerkenGepauzeerdDownload "%s" is gepauzeerd vanwege een versleuteld RAR bestand (indien aanwezig, zijn alle wachtwoorden geprobeerd)Onderbreek downloaden tijdens nabewerken.Dubbele download "%s" gepauzeerdPercentage van snelheid internetverbindingPermanent verwijderen (archief overslaan)Toegangsrechten voor verwerkte downloadsIngestelde rechten van %s zouden kunnen beletten dat SABnzbd toegang heeft tot de aangemaakte bestanden en mappen.Persoonlijke API-sleutelPersoonlijke API-sleutel voor Prowl (noodzakelijk)Persoonlijke aantekeningenLet op: als je 0.0.0.0 als hostnaam gebruikt, heb je voor externe toegang een IPv6-adres nodigVul hier de gegevens van je primaire Usenet server in.PoortPoort waar op SABnzbd luistert.Nabewerking van %s mislukt (%s)NabewerkingVerwerk alleen correct geverifieerde downloadsNabewerkingNabewerken gestartNabewerking is afgebrokenDownloads zullen gepauzeerd worden tot ze minimaal deze leeftijd hebben. Instellen van prioriteit Forceren zal de download meteen starten.Wachtrij filter script heeft de download afgekeurdWachtrij-filter scriptStandaardinstellingenGebruik Windowstoets-R en type deze regel in (voorbeeld):VorigePrioriteitProbleem metBewerkt resultaatNabewerkingProgramma is niet opgestart!VerspreidingswachttijdProwlOpenbaar IPv4-adresVerwijder voltooide downloadsVerwijder mislukte downloadsVerwijder mislukte downloads incl. bestandenWis de volledige geschiedenisLogs wissenVerwijder alle downloadsVerwijderen incl. bestandenVerwijder downloads op deze paginaWis wachtrijPushbulletPushoverPython versiePython-script '%s' heeft geen uitvoerpermissie (+x)WachtrijWachtrij Eerste 10 ItemsWachtrij voltooidItems in wachtrijWachtrij is niet leeg, andere map kiezen niet mogelijk.Wachtrij reparatieSnelle Controle...Snelle controleSnel beginnenAfsluitenQuotumQuotum voor dit account, wordt geteld vanaf het moment dat het voor het eerst ingesteld wordt. In bytes, in K,M,G notatie.
Er wordt een waarschuwing gegeven als het quotum bereikt is, dit wordt elke paar minuten gecontroleerd.Quotum overQuotum periodeQuotum verbruikt, download is gestoptRAR bestanden zijn niet verifieerbaarRAR bestanden zijn succesvol geverifieerdRSSRSS-feed uitlees intervalRSS-feed %s is leeg%s is klaarZelden gebruikte opties. Voor betekenis en uitleg, klik op de Help knop om naar de Wiki te gaan.
Wijzig hier niet zonder eerst de uitleg op de Wiki te lezen. Er kunnen nadelige bijwerkingen optreden.
De standaard instellingen staan tussen haakjes.Alle feeds nu uitlezenUitlezenUitlezen RSS-feedsLees alle RSS-feeds uitLees de Wiki pagina over dit onderwerpDBus foutmelding %s VerversVerverssnelheidVerbinding geweigerd van: Verbinding met hostnaam "%s" geweigerd van:Titel Bevat NietMaplocaties gebaseerd opNog te doenMij onthoudenVerwijder downloadVerwijder download incl. bestandenVerwijderSortering verwijderenVerwijder alle geselecteerde bestandenVerwijder voltooide downloadsVerwijder mislukte downloadsVerwijderen van %s misluktItem aan het verwijderenItems aan het verwijderenNaamAls je de naam wijzigt zal het Direct Uitpakken gestopt worden.ReparatieReparatie mislukt, te weinig herstelblokken (%s tekort)ReparerenReparatie mislukt, %sRepareren...Herhaal testVervang spaties in mapnamenVervang punten in mapnamenVervang punten door spaties in namen van mappen.Vervang spaties door onderliggende streepjes in namen van mappen.Vervang onderstrepingstekens in mapnamenVervang onderstrepingstekens door punten in mapnamen.VereistTitel BevatEen Prowl account is noodzakelijkHiervoor is een Pushbullet account nodigHiervoor is een Pushover account nodigCategorie IsHerstelQuotum nu resettenReset dagAdres opzoekenHerstartStart SABnzbd opnieuwHerstarten zonder loginSABnzbd herstart nu...SABnzbd wordt herstart omdat de assembler is gecrashtSABnzbd wordt herstart omdat de downloader is gecrashtSABnzbd wordt herstart omdat de postprocessor is gecrashtBeginwaarden terugzettenBackup herstellenResultaatDoorgaanHervat downloads met prioriteit "Hoog"Hervat downloads met categorieHervat downloads met prioriteit "Laag"Hervat downloads met prioriteit "Normaal"Hervat nabewerkenHervattenBewaartijdOpnieuwAlles opnieuw proberenProbeer alle mislukte downloads opnieuwScript uitvoerenScript uitvoeren...Gebruiker script %s looptSABCTools uitgeschakeld, geen bruikbare versie gevonden! (V%s gevonden, V%s verwacht)SABnzbd %s is gestartHostWachtwoordPoortSABnzbd Snelstart HulpGebruikersnaamSABnzbd versieWebserverSABnzbd heeft een fatale fout ontdekt:SABnzbd is afgeslotenSABnzbd is gestart met de codering %s, dit zou UTF-8 moeten zijn. Je kunt, bij het downloaden, problemen krijgen met Unicode namen van bestanden en mappen.SABnzbd is actief op de achtergrond.SMTP-serverSOCKS5 ProxySQL-commando mislukt, zie logbestandSSLSSL-sleutelsZaterdagOpslaanOpslaanOpslaan van %s lukt nietOpslaan..Bewaakte map uitlezenTaak voor niet bestaande server %sTaakplannerScriptExit code van het script is %sScript gaf code %s en resultaat '%s'ScriptsMap voor scriptsZoekenSeizoen NummerMap per seizoenBeveiligde verbinding met de serverBeveiligingKies een stand en voer een lijst van alle (on)gewenste extensies in. Voorbeeld: exe or exe, comKies een taal.Vink dit alleen aan als je provider SSL-verbindingen toestaat.DatumbereikVerstuur een e-mail voor RSSStuur terug naar de wachtrijVerstuur een e-mail wanneer een RSS-feed downloads
aan de wachtrij heeft toevoegd.Stuur een e-mail wanneer SABnzbd gestopt is vanwege een volle harde schijf.Stuur meldingen met behulp van Apprise naar bijna elke bestaande service.%s naar de wachtrij gestuurdZet komma's tussen de URLsSeriesSerie sorterenSeries met datumsServerHet beschikbare quotum voor server %s is verbruikt. Server %s verloopt over %s dag(en).Server %s gebruikt een onbetrouwbaar HTTPS-certificaatServer %s gebruikt een niet betrouwbaar certificaat [%s]Server %s wordt gedurende %s minuten genegeerdServer instellingenServeradres "%s:%s" is niet geldig.Serveradres verplichtDe server kon de opdracht niet uitvoerenServernaamServernaam niet te vindenServer heeft een gebruikersnaam en een wachtwoord nodig.Server fout (code is %s); kon geen %s van %s krijgenServersZet toegangsrechten voor verwerkte bestanden/mappen, alleen octale notatie!Het adres van de e-mailserver van je internet provider.Alles ingesteld!Shift+Pijltoets: Blader door de wachtrij- en geschiedenispagina'sMoet het downloaden automatisch doorgaan bij het ingaan van het nieuwe quotum?Toon AllesToon archiefToon mislukteDownload logSerie NaamToon actieve verbindingenToon detailsMap per serieToon webinterfaceSerie.NaamSerie_NaamAfsluitenPC afsluitenSABnzbd afsluitenAfsluitenSignaal %s ontvangen, opslaan en afsluiten...OmvangSlimme detectie van dubbele downloadsSommige bestanden konden niet geverifieerd worden met "%s"Sorry, het opgegeven kunnen wij niet verwerken. Probeer nogmaals.SorteertekstSorteer Op % Gedownload Meest→MinstSorteer op Leeftijd Nieuw→OudSorteer op Leeftijd Oud→NieuwSorteer op Naam A→ZSorteer op Naam Z→ASorteer op Omvang Groot→KleinSorteer op Omvang Klein→GrootSorterenBronSpeciaalSnelheidVersnel reparaties door par2cmdline-turbo te installeren. Beschikbaar voor veel besturingssystemen.Maximum snelheidPC standbyWizard startenReparatie startenOpstarten/AfsluitenStatusStatus en webinterface optiesStopAfsluiten...StriktVerstuurZondagSteun het project, doneer!Vedachte fout in downloaderOptiesSysteemmappenSysteemprestaties (Pystone)SysteembelastingTEKSTTE GROOTWeergave in tabs
(wachtrij en geschiedenis apart weergeven)Label downloadTijdelijke mapTijdelijke download mapTestgegevensE-mail testenTest meldingTest ServerTest downloadServer instellingen aan het testen...De "Repareren" knop herstart SABnzbd met een complete
reconstructie van de wachtrij, met behoud van al gedownloade bestanden.
Dit beïnvloedt wel de volgorde.De Map voor verwerkte downloads mag niet een map in de Tijdelijke download map zijn.Om de RSS-feed automatisch te verwerken, vink het selectievlakje bij de definitie naam aan.
Wanneer een nieuwe feed wordt gedefinieerd, zullen alleen nieuwe items gevonden worden en geen bestaande, behalve wanneer je de op "Forceer download" klikt.Geen hostnaam opgegeven.Het aantal verbindingen dat je provider toestaat.De wachtrij wordt elke 30 seconden opnieuw gesorteerd als de optie % gedownload is gekozen.De server reageerde niet op de 'helo'-begroetingEr zijn geen actieve servers!Er zijn geen verbindingen opgegeven. Er is minimaal één verbinding nodig.Er staan verweesde downloads in de download map.
Je kunt ze verwijderen (inclusief bestanden) of ze terug naar de wachtrij sturen.Met deze sleutel kan een extern programma NZB-bestanden naar SABnzbd sturen.Met deze sleutel heeft een extern programma volledige toegang tot SABnzbd.Deze MaandDit voorkomt extra reparatie pogingen, doordat alle beschikbare par2 files direct worden gedownload.De server staat geen SSL toe op deze poortDeze WeekDeze knop zal SABnzbd herstarten.
Dit kan nuttig zijn wanneer je vermoedt dat het programma niet stabiel is.
Het downloaden zal vóór de herstart gestopt worden en daarna weer doorgaan.Hiermee stuur je een test e-mail.DonderdagTijdslimiet overschredenTijdslimiet overschreden. Probeer met SSL aan of gebruik een andere poort.TijdslimietTitelOm alle waarschuwingen met mogelijke problemen te blokkeren kan de Speciale optie 'helpful_warnings' uitgezet worden.To: %s From: %s Date: %s Subject: SABnzbd meldt een volle harde schijf Hallo, SABnzbd is gestopt met downloaden omdat de harde schrijf bijna vol is. Maak ruimte vrij en laat SABnzbd weer doorgaan. VandaagTe weinig schijfruimte, pauze geforceerdTe veel verbindingen met server %s [%s]Te veel verbindingen, onderbreek het downloaden of probeer later nog eens.BovenTotaalProbleemoplosserProbeer de succes kans van een download van te voren in te schatten (langzamer!)Uitpakpoging met 7zip en wachtwoord '%s'RAR-hernoeming wordt geprobeerdProbeer RAR-verificatieProbeer SFV-verificatieProbeer NZB op te halen van %sPoging de status van niet-bestaande server %s in te stellenUnrar proberen met wachtwoord "%s"DinsdagAfstellingFilterONGEWENSTURL ophalen mislukt; %sURLGRABBER FATALE FOUTKan niet binden aan poort %s van %s. Andere software gebruikt deze poort of SABnzbd is al actief.Geen toegangsrechtenDeblokkerenOnbekende server.Onbekende fout tijdens het decoderen van %sOnbekend SSL protocol: probeer het zonder SSL of probeer een andere poort.Onbekende actie: %sOnbekende authenticatiefout bij de e-mailserverUitpakkenUitpakken van archieven (rar, zip, 7z) binnen archieven toestaanTeveel niveaus om uit te pakken [%s]%s bestanden/mappen uitgepakt in %sUitpakkenUitpakken mislukt, %sUitpakken mislukt, CRC-foutUitpakken mislukt, archief vereist wachtwoordUitplakken mislukt, bestand te groot voor het bestandssysteem (FAT?)Uitpakken mislukt, bestandspad is te langUitpakken mislukt, kan %s niet vindenUitpakken mislukt, schrijffout of schijf vol?Mislukte login poging van %sOnbruikbaar NZB-bestandOnbruikbaar RAR-bestandOngewenste extensie gevonden in %s (%s) De ongewenste extensie zit in RAR-bestand %sOngewenste extensiesUpdate beschikbaar!NZB uploadenUploadenTijd in de luchtGebruik Sorteren om automatisch je voltooide downloads te organiseren en hernoemen.Gebruik een komma en/of spatie om meer dan één URL op te geven.Instellen voor alle sessiesGebruik tijdelijke mapnamen tijdens de nabewerking. Zet dit uit wanneer je systeem daar problemen mee heeft.Gebruik een SOCKS5 proxy server voor alle uitgaande verbindingen.Word uitgevoerd vóór een download aan de wachtrij word toegevoegdGebruikte bufferGebruikersmappenGebrukers sleutelGebrukers sleutel (verplicht)Gebruiker ingelogdGebruiker heeft ingelogdEen gebruikersscript kan een download afkeurenGebruikersnaamWaardenVerificatie m.b.v. SFV-bestanden is geluktControleer certificaten bij beveiligde verbindingen met indexers en RSS-feeds.VerifiërenReparatie controlerenVerificatie...VersieZeer LaagToon Script resultaatWACHT %s secWAARSCHUWING:WachtOntvang 5 dagen voor de verloopdatum een waarschuwing.WaarschuwingMeldingenBewaakte mapBewaakte map verversingsintervalWebinterfaceWebinterface StijlWoensdagAls tijdens het downloaden duidelijk wordt dat te veel data ontbreekt, breek dan de download afWanneer het script een exit code anders dan 0 geeft, zal de download worden afgekeurd.Wanneer een download Opnieuw geprobeerd wordt, staan 'Identieke/Slimme downloaddetectie' en 'Download afbreken als deze zeker niet kan worden voltooid' uit.Als je IP adres veranderd of SABnzbd opnieuw wordt opgestart, zal de sessie verlopen.Welk percentage van de maximale internet snelheid mag SABnzbd gebruiken? B.v. 50Welk script moet uitgevoerd worden voor de notificatie?WhitelistWie zou de email gestuurd moeten hebben?WikiWerkt niet als een categorie-pad naar een andere schijf verwijst.Windows MeldingenjaarJe kunt toegangsrechten instellen voor systemen buiten je lokale netwerk. Je moet eerst een maximumbandbreedte instellen voordat je een limiet kunt instellenDe UNRAR-versie is %s, we adviseren versie %s of hoger te gebruiken.
Je wachtwoordenbestand bevat meer dan 30 wachtwoorden, het testen van al deze wachtwoorden kost heel veel tijd. Zorg ervoor dat je alleen maar nuttige wachtwoorden in dit bestand zet.Persoonlijke Pushbullet API-sleutel (verplicht)[%s] Fout "%s" bij samenvoegen van bestanden[%s] Fout "%s" bij het uitpakken van RAR-bestanden[%s] %s bestanden samengevoegd[%s] Geen par2 groepen[%s] PAR2-opties incorrect, controleer Configuratie=>Instellingen schakelaars[%s] Snelle Controle OK[%s] RAR verificatie niet gelukt: %s[%s] Gerepareerd in %s[%s] Het commando in build_command is ongedefinieerd[%s] %s geverifieerd, alle bestanden zijn goed[%s] Geverifieerd in %s, reparatie is nodigartikelenAanpassen van hoofd- en kleine lettersddagdagenServer uit:Server aan:bestandhuururenovermhandmatigminminuitaanofPaginapar2-programma niet gevonden.eigenschapsecsecondenzie logbestandtekstunrar-programma niet gevonden.week././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993698.9495811 SABnzbd-4.3.2/locale/nb/LC_MESSAGES/SABnzbd.mo0000644000000000000000000015653714625637243017507 0ustar00runnerstaff1o1d12 345'667 37T7t77777771788?8888R9[Y99#99:$%:J: Q:_:'f:':::: : : :: ;;!;'%;M;`;g;y;*; ; ;;;< </< A<M<<<%<#='= @=J=Q=X=== > !>B>]>{>!>6>->!?0?"N?6q?? ??.?'@ /@9@O@e@Sn@ @@@@"@8AVAfA |AAA AAA#A B B 3B*?BjB|B BB3B B B BBBBC C"C 8CYCmC&tC C)CCC4C&D?.DnDDD DD,D,E1I HIUI dI qI~I(I.I)I,J<3J&pJJ'JJJK K AKLK [K hKrKK KKKKK%L!&LHL+hL LL!L*L!M?M'TM"|MM#MM!MN8NQNoNN NNNNNN OO)OABOO'O!OOPPP-P/LP!|P PP&P"P9P6Qav=v v+v ww,ww w>xCxKxQxy" y&.yAUyyy yEyyz+z.Gzvzzzzzzzzzz {J,{w{-{{/{{ | ,|6|K|-g|6|"|#|.}"B}e}w}$}}} }}}b~$g~ ~ ~~~~#~"~ %' M Wdlu   RUG=!ۀEBc+#ҁ) 5JG&'  "&+ :HMOTZ_ahlqux{ уgփx>W% "!.%P v 0 @ \,c%)F$a )'ю #<L[o'ˏ ҏ( "09 Wci8ps2:%I#o  }ɑG#N!r!ђ$ .2;a'(֓;; Ze*n$ Ȕޔ R P[ty+S /6 N \g%–Ֆ -6?/Fv ė ʗח!# E'Ow <ܘ9:$Qv/)ә. ,8J_5x:ɚ 8GL]fl)Л*.=V _l{Ĝ;K^fŝOT X d r ,.-,6H-'ş'!-!O q  Ԡ '2(N$w#) $"A d,%΢"$<'T%|&"ɣ$ ($5Z s}NŤ ,5!b)0ť27)ap/w,9Ԧ%6 < HR Ydm"ѧ. 9 FQ Wet )Ĩ  4&.[  3D5"JmKLԪ!),Bo&$Ϋݫ ))mSЬ߬ /+[jqܭZPiq_, į̯"2Um2sȰϰ Ӱ ݰ   !9>W_ek { ).ױ  1 >L T*^Cg 't6ӳ ! $-R#o  ϴ ڴ +#+3<W i&t  ĵҵ .!Moh$(M*cF;#(%Gm*~Ѹ-( 0 :F Yg$ȹ + 5@IX\m }( Ϻ +=A[ p}q  ˼ռ  ",DSk Mǽ  8 EQo)- 4 >H\ mz׿ #"%1W q| %J[n~ ! &+   8A&Y #8+<?Q:,2#V&i$;5a=0:)2A FP hu  ) (5@v//))9;9u   (!/Q Wdiq   .9V 79.qDSE$13 ep- : B<N l-r)J !P-~9- 5AFOi|(P-(A j-t+ :L#(5# .G'Y %k$Sx "* )(1 Z ft |  )H\_C !&AIEF0%--[vL)+/[#d ! *5;[ SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Complete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGo to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHelpHibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sInvalid server address.Invalid server detailsInvalid stage logging in history for %sIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocation for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLog inLog outLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification Sent!NotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!ProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePushbulletPushoverPython VersionQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...ResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...SubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.Which percentage of the linespeed should SABnzbd use, e.g. 50Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Norwegian Bokmål (https://app.transifex.com/sabnzbd/teams/111101/nb/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: nb Plural-Forms: nplurals=2; plural=(n != 1); SABnzbd kan ikke finne filene for webgrensesnittet i %s.
Vennligst installer programmet på nytt.

SABnzbd oppdaget instillinger fra en annen SABnzbd-versjon
men kan ikke bruke disse.

Kanskje vil du fullføre nedlastingskøen i det gamle programmet først?

Etter det kan du starte dette programmet med "--clean"-parameteren.
Dette vil slette nedlastingskø og historie!
SABnzbd leste filen "%s". SABnzbd oppdaget at filen sqlite3.dll is mangler.

Enkelte antivirus-programmer fjerner denne filen.
Vennligst sjekk ditt antivirusprogram og forsøk å installer SABnzbd på nytt.

SABnzbd trenger en ledig TCP/IP-port for sin interne webserver.
Port %s på %s ble forsøkt brukt, men er utilgjengelig.
Enten er porten allerede i bruk av et annet program, eller så kjører SABnzbd fra før av.

Start SABnzbd på nytt med et annet portnummer. SABnzbd krever en gyldig adresse for sin interne webserver.
Du har spesifisert en ugyldig adresse.
Korrekte verdier er localhost og 0.0.0.0

Vennligst start SABnzbd på ny med en gyldig adresse. SABnzbd kommer HELT UTEN GARANTI. Dette er fri programvare, og du kan redistribuere det under visse vilkår. Det er lisensier under GNU GENERAL PUBLIC LICENSE Versjon 2 eller senere versjoner. %s artikler hadde ulike duplikater%s artikler var korrupte%s artikler manglet%s mappe: %s tilgang mislyktes%s er ikke en korrekt oktal verdi%s er ikke en godkjent e-post-adresse+ Feilsøking+ Info+Fjern+Reparere+Pakker opp.nzb Reservemappe0 er høyeste prioritet, 99 er laveste prioritet7za-binærfil... IKKE funnet!OBS: Mapper kommer til å bli opprettet automatiskt når du Lagrer. Du må angi korrekte søkestier til din mapper for å kunne lagre utenfor standardmappene.Data vil ikke bli flyttet. Krever SABnzbd restart!API (Ingen konfigurasjon)API-nøkkelAPI-nøkkel QR-kodeAPI-nøkkel er feil, bruk API-nøkkel fra Konfigurasjon->Generelt i ditt tredjepartsprogram:API-nøkkel mangler, skriv inn API-nøkkelen fra Konfigurasjon->Generelt i ditt tredjepartsprogram:API-nøkkel for ProwlAvbryt jobber som ikke kan fullføresAvbrutt, kan ikke fullføresAvbrutt, kryptering funnetAvbryt, uønsket forlenging oppdagetAkseptereIngen tilgangHandlingReaksjon når kryptert RAR fil lastes nedHandling når uønsket filtype oppdagetLegg-tilLegg til NZBLegg til NZB filer Legg til nedlastingsplanLegg til serverLa til NZB-filAdministrativ MappePåvirkede kategorierTidAlleAlle filer vil bli lagt til samme mappeOgså nye utgivelserAlltidProgram-tokenProgram-token (påkrevd)Er sikker på at du vil slå av SABnzbd?Er du sikker?ArgumentCachestørrelse for artikklerArtikkel-idMinstHøystGodkjenning mislyktes, kontroller brukernavn og passord.Gjenoppta automatiskAuto-pause når fri plass er nærme grensen.
I bytes, fulgt av K,M,G,T. For eksempel: "800M" eller "8G"TilbakeSikkerhetskopiUkorrekt svar fra Pushbullet (%s): %sUkorrekt svar fra Pushover (%s): %sFeil skjema %s ved %s:%sBåndbreddeBunnBla gjennomLagrer artikler i minnet for å redusere diskaktivitet.
I bytes, fulgt av K,M,G. For eksempel: "64M" eller "128M"AvbrytKunne ikke endre rettigheter på %sKan ikke koble til server %s [%s]Kan ikke sikkerhetskopiere fil %sKan ikke opprette mappe %sKan ikke opprette mappe %sKan ikke lage midlertidig fil for %sKan ikke finne e-post-maler i %sKan ikke finne webmal: %s, prøver standardmalKan ikke starte webserveren, ble sannsynlig vis ikke funnetKan ikke lese %sKan ikke lese den overvåkede mappen %sKan ikke sendes, mangler nødvendig dataKan ikke skrive til historikkdatabase, sjekk filrettigheterKan ikke skrive til INI-fil %sKategorierKategoriEndringer som ikke er lagret vil gå tapt.Endringer krever omstart av SABnzbd!Merk alleSjekk før nedlastingSe etter ny utgaveUndersøkerSjekk intervall (i minutter, minst 15). Ikke aktiv når du bruker nedlastingsplan!Rens listeRensning av %s mislyktesRensNullstill TellereKlikk her for å teste serverinstillingene.SABnzbd kommer ikke til å avsluttes om du lukker vinduet eller fanen i webleseren.Ferdig mappeFerdig mappe-hastighetFerdigFerdig nedlastingsmappeKonfigurasjonKonfig filBekreft Sletting av HistorieBekreft Sletting av KøKontaker %s@%s feilet, feilmelding=%sTilkobling lyktes!Tilkobling mislykket!TilkoblingerKunne ikke koble til (%s)Aktuelle nedlastingsplanerTilpasseDUPLIKATDagligSkadet historikkdatabase, opprettet ny databaseDato sorteringDatoformatDag i månedenTitallStandardStandard base filstiFjernTa bort alleFjern etter nedlastingSlett alt fra køen?Fjerning av %s mislyktes!EnhetEnheten meldingen skal sendes tilEnhet(er)Enhet(er) som meldingen skal sendes tilDeaktiver kvotebegrensningerDeaktivertDeaktiverte HTTPS på grunn av manglende CERT- og KEY-filer.ForkastKople fra usenet serverne når køen er tom eller pauset.Koble fra når køen er tomFull harddisk varslingDiskfeil under opprettelse av fil %sHarddisken er fullDisken er full! Pauser...Utfør ekstra verifisering basert på SFV filerUgyldig autentisering for nyhetsstrøm %sBlirkvoten resatt hver dag, uke, eller måned?NedlastningNedlasting ferdigNedlasting mislyktesLast ned alle par2 filerNedlastning feilet - Finnes ikke på din(e) server(e)Nedlastingsmappe-hastighetNedlasting kan feile, kun %s av kravet på %s tilgjengeligNedlastetHentet filer på %s med gjenomsnitts hastighet på %sB/sEks.F.eks 8 eller 20KRYPTERTFEIL:Endre NZB detaljerE-PostE-Post varsling når nedlasting er ferdigE-post mottakerE-post avsenderMappe for E-post malerE-post adresse til mottaker.E-post sendning lykkesNødssituasjonTomTom NZB-fil %sTom RSS post funnet (%s)AktivereAktiver 7zipHTTPS AktivereAktiver NotifyOSDAktiver Prowl-varslingerAktiver Pushbullet-varslingerAktiver Pushover-varslingerAktiver SFV-baserte sjekkerWindows-varslingerAktiverer tilgangen til webgrensesnittet med HTTPS adresse.Aktiver omdøping av mappeAktiveres for mindre minneforbruk. Deaktiver for å forhindre langsom jobb da køen blokkeres.Aktiver kvotebegrensningerAktiver rekursiv utpakkingAktivertVed å avslutte filstien med en asterisk * vil arbeidsmapper ikke bli opprettetURLEpisodenavnEpisodenummerEpisode.NavnEpisode_NavnFeilFeil "%s" under kjøring av file_join på %sFeil "%s" under kjøring av par2_repair på %sFeil "%s" under kjøring av rar_unpack på %sFeil %s under kjøring av par2_repair på %sFeil %s: Du må oppgi et gyldig brukernavn og passord.Kunne ikke lage SSL-nøkkel eller sertifikat.Kunne ikke importere %sLastingsfeil %s, feilaktig fil oppdagetFeil ved fjerning av %sKunne ikke endre navn fra "%s" til "%s"Kunne ikke legge til %s, tar bortFeil under avslutting av systemetBara ved feilFeil/AdvarselAvslutt SABnzbdendelseEkstern internettilgangEkstra PAR2 parametereTrekker ut...MislyktesKunne ikke logge inn på server %s [%s]Opprettelse av (%s) mislyktesKunne ikke flytte %s til %sAutentisering mot mailserveren mislyktesKunne ikke stenge databasen, se loggKunne ikke stenge e-post-tilkoblingKunne ikke lage regex for søkestreng: %sKunne ikke koble til mailserverDvalemodus feiletKunne ikke importere %s filer fra %sFeilet å starte %s@%s grunnet: %sKunne ikke starte TLS-tilkoblingKlarte ikke å flytte filerKunne ikke endre navn på lik fil: %s til %sKunne ikke hente RSS-kilde fra %s: %sKlarte ikke å sende Prowl meldingKlarte ikke å sende Windows meldingKunne ikke sende e-postKlarte ikke å sende pushbullet-meldingKlarte ikke å sende pushover-meldingKunne ikke sette systemet i ventemodusKunne ikke starte webgrensesnittetKunne ikke starte webgrensesnittet: Feil i tempfil.mkstempKritisk feilKritisk feil ved lagring av tilstandKritisk feil i AssemblerRSS-kildeHentHent NZB fra URLHenterHenter %s blokker...Henter ektra blokk...Fil som inneholder alle passordene som skal forsøkes på krypterte RAR filer.Filsammenslåing av %s mislyktesFilnavn eller søkesti til HTTPS Sertifikat.Filnavn eller sti til HTTPS-lenkeFilnavn eller søkesti til HTTPS Nøkkel.FilsettFilnavnFilterFiltrere ut sample-filer (ex. video samplinger).Mappe som inneholder brukerdefinerte e-post maler.Mappe som automatiskt søkes igjennom etter .nzb filer.Mappe/SøkestiMapperBrukernavn for e-post som krever autentisering.Passord for e-post som krever autentisering.For servere: sørg for at navn er kompatibel med Windows.TvingTving frakoblingTving nedlastingForumLedig plassHyppighetFredagFra SxxEyyFull APIFullt webgrensesnittØvrig hjelp kan du finne på vårGenereltGenerer Ny NøkkelGå til SABnzbdGå til guidenHTTP og HTTPS-portene kan ikke være det sammeHTTPS SertifikatHTTPS-lenke sertificaterHTTPS NyckelHTTPS-portHjelpDvalemodus PCSkjul detaljerSkjul/vis fullførte filerHøyHistorikkHistorikk (10 siste)Historikk-grenseHold shift-tasten for å velge et områdeHjemStartsideAdresseAdressen som SABnzbd skal bruke.Hvor lenge ønsker du å pause? (skriv på engelsk!)Hvor mye can lastes ned denne måneden (K/M/G)UFULLSTENDIGIONice parametereIPv6-adresseLedigOm tom, så vil standardporten bare lytte til HTTPSPrøv et annet nummer hvis du får denne feilmeldingen på nytt.
Ignorer Sample-filerIgnorer alle mapper inne i arkiverIgnorerer duplikatfil "%s"I tilfelle "Pause", så trenger du å sette et passord og gjenoppta jobben.Hvis SABnzbd skulle starte på nytt vil denne skjermen forsvinne automatisk!I mappeUkompatibel nyhetsstrømFeilaktig kø-fil funnet, kan ikke fortsetteUfullstendig mappeUfullstendig sekvens av oppdelte filerFeilaktig RSS-kilde beskrivelse "%s"Feil parameterFeil kodet passord %sUgyldig server-adresse.Ugyldige server-innstillingerUgyldig scenen logging i historien for %sDet er anbefalt at du lagrer denne siden som et bokmerke for å treffe SABnzbd når det kjøres i bakgrunnen.Jobb mislyktesJobb fullførtSlå sammen filerSlår sammen filerSpråkStarter webleseren ved oppstartStarter standard webleser når SABnzbd starter.HastighetsbegrensningListe over filtyper som skal slettes etter nedlasting.
For eksempel: nfo eller nfo, sfvLasterLasting av %s mislyktesLokal IPv4-adresseLokasjon for køadmin og historikkdatabase.
Kan bare endres når køen er tom.Plass for lagrede loggfiler fran SABnzbd.
Krever omstart av SABnzbd!Plass for å lagre bearbeidede og ferdige nedlastinger.
Kan overstyres av brukerdefinerte kategorier.Plass for å lagre ikke bearbeidede nedlastinger.
Kan kun endres når køen er tom.Plass der .nzb filer lagres.LoggmappeLogg påLogg avLoggingMistet tilkobling til SABnzbd..LavSmå bokstaverGjør Windows-kompatibelLikeMaks linje-hastighetMaksimum antall forsøk per serverMaksimum antall forsøkBetyrMinimal fri plass for midlertidig nedlastingsmappeManglende artiklerModererMandagMånedMerFilm NavnFilm.NavnFilm_NavnFlytterFlytter...MultioperasjonerNZB-nøkkelNZB er lagt til i køenNavnNavnserver / DNS oppslagFilnavnAldriNesteNice parametereIngen tilgangIngen e-post-mal funnetIngen mappeIngen mottaker oppgitt, e-post ikke sendtIngen passende autentiseringsmetode ble funnetIngenNormalIngen treffIkke tilgjengeligVarselsenterVarsel sendt!VarslerNotifyOSDSekunder mellom skanninger for .nzb filer.VALGFRITT PassordVALGFRITT BrukernavnAvGammel kø oppdaget. Bruk Status -> Reparer for å konvertere køenNår køen er ferdigPå hvilken dag i måneden eller uken (1=mandag) resetter til nettilbyder kvoten? (Valgfritt med tt:mm)Bara artiklene fra begynnelsen av køenÅpne et terminalvindu og skriv inn linjen (eksempel):Åpne fullført mappeValgfrittAlternativ tilleggs NZBKan velge autentiserings passord.Kan velge autentiserings brukernavn.Valgfritt spesifiser filnavnEller dra og slipp filer i vinduet!SorteringOriginalfilnavnEtterlatte jobberAndre meldingerParametereDelnummerPassordPassordfilPassordet er skjult med ******, prøv igjenPassordSnarveiMønsterHjelp til SorteringsstrengStans midlertidigPause AlltPause nedlasting under etterbehandlingPause forPause 1 timePause 15 minutterPause 3 timerPause 30 minutterPause 5 minutterPause 6 timerPause i...Pause jobber med høy prioritetPause jobber med lav prioritetPause jobber med normal prioritetPause etterbehandlingPausetPauser nedlasting når etterbehandling begynner og gjenopptar nedlasting når etterbehandling er ferdig.Stanser duplikatfil "%s"Prosent av linjehastighetRettigheter for ferdige nedlastingerPersonlig API-nøkkelPersonlig API-nøkkel for Prowl (påkrevd)Persolige notaterHusk at vertsnavnet 0.0.0.0 krever en IPv6-adresse for ekstern tilgangSkriv inn opplysningene om din primære usenet leverandør.PortPorten som SABnzbd skal bruke.Etterbehandling mislyktes for %s (%s)PostprosesseringEtterbehandle kun verifiserte nedlastingerEtterbehandlingEtterbehandling startetFør-kø bruker skriptFor innstillingerTrykk Start+R og skriv inn linjen (eksempel):ForrigePrioritetProblem medProsesser resultatBearbeidingerProgrammet startet ikke!ProwlOffentlig IPv4 adresseFjern Ferdige NZBerFjern Mislykkede NZBerFjern Mislykkede NZBer & Slett FilerSlett historikkSlett NZB-filerSlett NZB & tilhørende filerSlett køPushbulletPushoverPython-versjonKøKø (10 første)Køen er ferdigKø-grenseKøen er ikke tom, kan ikke bytte mappe.Reparer KøHurtigkontroll...HurtigkontrollererAvslutteKvoteGjenværende kvoteKvoteperiodeKvote oppbrukt, setter nedlasting på pauseRSSRSS OppdateringsintervallRSS-kilde %s var tomKjørte i %sSjeldent brukte valg. for å finne forklaring og betydning, klikk på hjelpknappen for å gå til Wiki siden.
Ikke endre på disse uten å sjekke Wiki først, siden noen av dem har alvorlige bieffekter.
Standardverdiene står i parantes.Les alle kilder nåLes kildeLes RSS-kildeLes alle RSS-kanalerLes Wiki Help fer dette!OppdatereOppdateringsfrekvensAvviseRelative mapper er basert påGjenstårHusk megFjern NZBFjern NZB & slett filerTa bort serverFjern alle valgte filerFjern ferdige jobberFjerne mislykkede jobberFjerning av %s mislyktesEndre navnReparererMislykket reparasjon, finner ikke nødvendige reparasjonsblokker (%s mangler)ReparererReparasjon mislyktes, %sReparerer...Gjenta testErstatt mellomrom i mappenavnErstatt punktum i mappenavnErstatt punktum med mellomrom i mappenavnErstatt mellomrom med understrek i mappenavn.KreverKrever en Prowl-kontoKrever en Pushbullet-kontoKrever en Pushover-kontoKreverKatNullstillNullstill kvote nåNullstillingsdagLøs adresseStarte på nyttStart SABnzbd på nyttRestart uten å logge innStarter SABnzbd på nytt...ResultatGjenopptaGjenoppta jobber med høy prioritetGjenoppta jobber med lav prioritetGjenoppta jobber med normal prioritetGjenoppta etterbehandlingGjenopptarTidsrom for liggefristPrøv igjenPrøv alle på nyttPrøv alle mislykkede jobber på nyttKjører skriptKjører skript...Kjør brukerskript %sSABCTools deaktivert: Fant ikke korrekt versjon! (Fant v%s, forventet v%s)SABnzbd %s startetSABnzbd AdresseSABnzbd PassordSABnzbd-portSABnzbd Hurtigstart GuideSABnzbd BrukernavnSABnzbd VersjonSABnzbd WebbserverSABnzbd oppdaget en kritisk feil:SABnzbd er nå avsluttetSABnzbd ble startet med koding %s, dette burde være UTF-8. Forvent problemer med Unicode filer- og katalognavn i nedlastinger.SABnzbd kommer nå å kjøres i bakgrunnen.SMTP-tjenerSQL-kommando mislyktes, se loggSSLLørdagLagreLagre endringerLagring av %s mislyktesLagrer..Sjekk overvåkingsmappeSkjema for ikke eksisterende server %sNedlastingsplanSkriptSkript-avsluttingskode er %sSkriptsSøkSesongnummerVelg språket til Webgrensesnittet.Velges kun om din leverandør tillater SSL-tilkoblinger.Send RSS varslerSend tilbake til køSend e-post nå en RSS feed legger til en nedlasting til køen.Send e-post når harddisken er full og SABnzbd har pauset.Sendte %s til køenSeriesorteringServerServer %s bruker et usikkert HTTP sertifikatServer %s vil bli ignorert i løpet av %s minutterServerinstillingerServeradressen "%s:%s" er ikke gyldig.Krever server-adresseServerbeskrivelseKunne ikke finne servernavnServer krever brukernavn og passord.Serverside-feil (serverkode %s); kunne ikke hente %s på %sServereSett rettigheter for ferdige filer og mapper.
Bruk tall. For eksempel: "755" or "777"Still inn din ISP's server for utgående e-post.Installasjonen er nå ferdig!Skal nedlasting starte på nytt etter at kvoten er resatt?Vis alleVis MislykkedeLoggShow NavnVis aktive tilkoblingerVis detaljerVis grensesnittShow.NavnShow_NavnAvsluttSlå av PCAvslutning av SABnzbdStarter avslutning av SABnzbd..Signal %s mottatt, lagrer og avslutter...StørrelseSome files failed to verify against "%s"Beklager, vi kunne ikke finne ut av det. Prøv igjen.SorteringsstrengSorter etter alder Ny→EldstSorter etter alder Eldst→NySorter etter navn A→ZSorter etter navn Z→ASorter etter størrelse Størst→MinstSorter etter størrelse Minst→StørstSorteringKildeSpesiellHastighetHastighetsgrenseVentemodus PCStart VeiviserStarter reparasjonOppstart/avsluttningStatusStatus og grensesnittalternativerStoppAvslutter...SendSøndagStøtt prosjektet, donèr!Mistenker feil i nedlasterSvitsjerSystemmapperSystemytelse (Pystone)TEKSTFOR STORMidlertidig MappeMidlertidig nedlastingsmappeTest E-postTest varslingenTestserverTester serverinstillinger...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.Avkrysningsboksen ved kildenavnet må aktiveres for at kilden automatiskt skal kontrolleres for nye objekt.
Når en kilde legges til, legges det kun til nye objekt(ikke objekt som allerede finnes). Alle objekter i kilden vises når du klikker på "Tving nedlastning".Du har ikke stilt inn vertsnavn.Antallet tilkoblinger som er tillatt av din leverandørServeren svarte ikke ordentlig til helo hilsenIngen tilkoblinger er aktivert. Du må aktivere minst en tilkobling.Det finnes foreldreløse jobber i nedlastningsmappen.
Du kan velge å slette disse (filene vil også bli slettet) eller sende dem tilbake i nedlastningskøen.Denne nøkkelen vil gi tredjepartsprogrammer lov til å legge til NZBer til SABnzbdDenne nøkkelen vil gi tredjepartsprogrammer full tilgang til SABnzbdDenne månedenDenne serveren tillater ikke SSL på denne portenDenne ukenDette vil starte om SABnzbd.
Brukes når du tror programmet er ustabilt.
Nedlastning vil bli satt på pause før omstarten og gjenoppta etterpå.Dette vil sende en test e-post til din konto.TorsdagTidsavbruddTidsavbrudd: Prøv å aktivere SSL eller bruk en annen port.TidsavbruddTittelTo: %s From: %s Date: %s Subject: SABnzbd rapporterer at disken er full Hei, SABnzbd har stoppet all nedlasting da lagringsdisken nesten er full. Frigjør mer diskplass og gjenoppta nedlasting manuelt. I dagFor lite diskplass, nedlasting satt på pauseFor mange tilkoblinger til server %s [%s]For mange tilkoblinger, sett nedlasting på pause eller prøv igjen senereToppTotaltFeilsøkingPrøve å beregne om ferdigstillelse er mulig før selve nedlastingen (tregere!)Prøver 7zip med password "%s"Prøver SFV-verifiseringForsøker å hente NZB fra %sForsøker å sette status på ikke-eksisterende server %sPrøver unrar med passord "%s"TirsdagJusteringerTypeUØNSKETURL henting mislyktes; %sURLGRABBER KRASJETUautorisert tilgangFjern blokkeringUdefinert server!Ukjent feil oppstod under dekoding av %sUkjent SSL-protokoll: Prøv å deaktivere SSL eller koble til på en annen port.Ukjent handling: %sUkjent godkjenningsfeil i e-postserverenUtpakkingPakk ut arkiver (rar, zip, 7z) inne i arkiverUtpakking nestet for dypt [%s]Utpakket %s filer/mapper på %sUtpakkerUtpakking mislyktes, %sUtpakking mislyktes, CRC-feilUtpakking mislyktes, arkivet krever passordUtpakking feilet, filen er for stor for filsystemet (FAT?)Utpakking feilet, stien er for langUtpakking mislyktes, kunne ikke finne %sUtpakking mislyktes, skrivefeil eller er disken full?Mislykket påloggingsforsøk fra %sFeil, Ubrukelig akrivfilUbrukelig RAR-filUønsket forlenging finnes i rar fil %sUønsket filtyperOppdatering tilgjengeligLast opp NZBOppetidBruk globale grensesnittinnstillingerBruk midlertidige navn under postprosessering. Deaktiver når systemet ditt ikke håndtere dette skikkelig.Brukes før en NZB blir lagt til køBrukt hurtigbufferBrukermapperBrukernøkkelBrukernøkkel (påkrevd)Bruker påloggetBruker logget inn i webgrensesnittBrukerskript kan flagge jobb som mislykketBrukernavnVerdierVerifisering med SFV-filer var vellykketVerifisererVerifserer...VersjonVeldig lavSe skriptloggVENT %s sekADVARSEL:VenterAdvarselAdvarslerOvervåket MappeSkanningsintervall for Overvåkede mapparWebgrensesnittOnsdagAvbryt jobben om det blir klart under nedlasting at for mye data manglerNår brukerskriptet returnerer en ikke-null exit kode, vil jobben bli flagget som mislykket.Hvor mange prosent av linjehastigheten skal SABnzbd bruke, feks. 50Hvem skal vi sende e-posten fra?WikiAktiver Windows-varslingerÅrDu må sette maks båndbredde før du kan sette en båndbreddebegrensningDin Unrar-versjon er %s, vi anbefaler versjon %s eller høyere.
Din personlige Pushbullet API-nøkkel (påkrevd)[%s] Feil "%s" under filsammenslåing[%s] Feil "%s" under utpakking av RAR fil(er)[%s] Slår sammen %s filer[%s] Ingen par2 deler[%s] PAR2 mottok feil kommandoer, undersøk brytere i Konfigurasjon->Brytere[%s] Hurtigkontroll OK[%s] Reparert på %s[%s] Verifiseing tok %s, alle filer er ok[%s] Verifisering tok %s, krever reparasjonartiklerjustert for store og små bokstaverddagdøgnDeaktiver serverAktiver serverfilhtimetimergjenstårmmanueltminuttminutteravpåellersidepar2-binærfil... IKKE funnet!sekundsekunderse loggfiltekstunrar-binærfil... IKKE funnet!uke././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.0008733 SABnzbd-4.3.2/locale/de/LC_MESSAGES/SABnzbd.mo0000644000000000000000000025663514625637243017500 0ustar00runnerstaff>o>dm?@ ABC&D'DE!E :E[E{EE1EME4Fa'Va~a5aa a'ab bb b bbbcc$c>c Nc[c#rcc ccccccd d d$d5dPdpddd4ddS eae|eeeHe f ff &f 3f@f(Ff.of)f,f<f&2gYg'lgggg g hh8h.Vhh h hhhhhi (i6iQiXixii%i!ii+ j 6j#Wj{j!j*j!jk#k>k'Xk"kk#kk!k!l>l^lwlllll mm.mGmamfmlmmmmAmm'n!8nZnznnnn-nn/n!$o FoRo&Zo"o9oBo!p'p8pGpZp `p kpup|p ppp pppGp/7q gq uqqqq'qqq r rr;ro@r rr rrrrss(s ;s\s asksps;s>s- t98t rt}t ttt6tvthluuGXvv"vv<vE+wDqwsw *x5x,Gxtx%x#xxx@yEy<ayz)zzFz9{Q{'h{{{H"|;k|| | ||}| W}b} j}x}}}5} }n} _~i~q~~q~cHlo]%) MX_gdoԁ  $3Xhpx00@qK!Nm DŽ Մ  %-@E])d   م#"++W\ c o}' /(B\;`c"#3W3$ 9EN!h!%ʉ (8G Z eq z* Ê ˊ׊ ݊( +@Rg{ ̋UMrی#Xq%R< GL"kΎj%m-ߏ  1CI]r ؐ <&ci~& őґ  ْ.DK= PZi| ʔ+ 4 > JU o }Ε *.25 hr )ؖ0"3.VΗ  (0@V'l(+ 1Kd ՙH V iv К. ͛ ٛ  ->G#[ ,՜ݜ +\4 43%3Y!Ǟ֞&"-=,k($П! /B&_:oɠ)9c/z3ޡ  " /; J T^ gs '(٢. 13=-q-$ͣ$11I{U !29V [gnu|ͥ  /5 =I c mx `oЧѨ2C5aA>{= M+Q },,Y b>lL"&A LP VEcȮۮ.-\|aį&:BTJt-Ұ/7T t~-6ݱ"#7.[""Ѳ$- ? JTJ[bij<'$d #ʹ"%$LJ  ǵе 208AP j xRUնM+=y0 !:TjAoEB:+¹#)<QJc&º/&-'T|  »ǻͻһԻۻ߻  ".3MNR*'ſ07(#3L(1 $4<Q^   #05 fNU0 +:nJj$;>z-'*0R "7$=O_xr )?W]:b.Hfl& #A\ n yMI) (+6)b 7 dx 9'C,k:,+',5T3O^m00NR;N! PneHC62z" Z+ :E]nv DRJf*"-#-Q ly4I9~,' .= ( 5 B(Lu~ , 9)c&G/I!k7r 0,# ALME i+&*+Q}-;(s;J 0?PL&$F4{ o| 8 ,3G{ &#;(_$%%93Q":ZK`  0;"1^2M9K6j))&9IBZO)'.Gg%%0,!N)n1L-LE:*&07P("0%<+/h-5!02O)-'),$In+ &.)NZx!*$ *Ep 5 897 q};:K?G    31 eob:):L`t2 $$&"%*P`B}  />IM=F+ <Ii:r6MF) AO<E [fF~8%7NVny 7  n L g /   fK L   2  F P   3CK:fv 2@Pi}e~!7 n*   0M eow C"4fOV\dab )3 C MW]o"  (%)0B Q^ },31$+<Me~, 20NZS n>)-hE: $#29 lx   8)buz / $8K^(p!,+  , 7 T & !'3![!y!!#"="jR">""/#*1#\#)l###!##Y$!$$B%Q% Y% d%p% y%%%%%%%)&<& K&Y&$s&& &&&8& ','D'&_'H'''( (*( 2(=(()4*)*_)!))))).)+ ,+7+G+!\+!~+ +++'+ , , (,4, K,X,r,,$,",",- "- /- =-=H- -O- -- ..#-.Q.2q.7.#.// 0/ =/G/a/// //// 00-0E00d010?0!1)1A1 J1)U1"1-1,11 2#222C2$T2y22"2T2%3 :3G3 X3e33331334"4 4 4A4.525G5 O5Y5o555)555516B6 J6X6_6 n6|6 6v6+7;H777%7L7H18&z8"8888929!;9B]9E9(9:%:D:*b::":3:5:-;i4;+;&;F;P8< <<< <<< <= = (=6=>=R=b=3s===7=;>C>>T>8>8>+?+1?;]?<? ????j@k@!@@@@@@ AA$A+A2A6:AqAA AA AAA4ABB*B FB PB^BxB B%BBdCD"E6BE^yE5EFM,FzFUGNoG GdG.0H _HkH%5I [IfIQzIIIaIHJBK.HK'wK^KK L L^"LLL$LL(LB"M$eMMMM M"MMkMYN mNwN%NMNO7O OO8YO$O"O OO$P8&PN_P*P1PF Q!RQtQQ+Q(QQR 'R5RFRCVR.RnRH8SISSSS"T$T$8T8]T TT+TQT 'U4UJUcU kUxU UUU*UU UU'V(V8VOAVqVZWO^WBW W#W"XY'XXXPX^XGQYY-6Z0dZ/ZZZYZ'V[6~[[5[0\11\c\)k\\\\\\\\\\\\\\\\]]]"] 1]=]E]N]n]#s]] SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %f% available of %d requested articles%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address%s is not a valid script%s is not writable at all. This blocks downloads.%s is not writable with special character filenames. This can cause problems.+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!

Use Sorters to automatically organize your completed downloads. For example, put all episodes from a series in a season-specific folder. Or, put movies in a folder named after the movie.

Sorters are tried in order of appearance and can be reordered by dragging and dropping.
The first active sorter that matches both the affected category and job type is applied.

More options are available when Advanced Settings is checked.
Detailed information can be found on the Wiki.

ALTERNATIVEAPI (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedAccount expiration dateActionAction when an unwanted extension is detectedAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdd SorterAdded NZBAdditionally, attempts to set the correct file extension based on the file signature if the extension is not present or meaningless.Adds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup.Administrative FolderAdvancedAffected CategoriesAffected Job TypesAgeAllAll files will go into a single folder.All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings.Allow proper releasesAlso test releasesAlwaysAlways use full screen widthAny propertyApplication TokenApplication token (required)Apply filtersAre you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle availabilityArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically sort jobs in the queue when a new job is added.Automatically sort queueBackBackupBackup FolderBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBlacklistBlocked attempt to create directory %sBottomBrowseBypass smart duplicate detection if PROPER, REAL or REPACK is detected in the download name.Cache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write a long filename to %s. This can cause problems.Cannot write a unicode filename to %s. This can cause problems.Cannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCategory folder cannot be a subfolder of the Temporary Download Folder.Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Certificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfiguration locked, cannot save settingsConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not connect to %s on port %s. It appears that %s operates as a web server (port 80), possibly an indexer, not a usenet server. You have to fill a usenet server.Could not determine connection result (%s)Could not load additional certificates from certifi packageCould not restore backupCreate a backup of the configuration file and databases in the Backup Folder.
If the Backup Folder is not set, the backup will be created in the Completed Download Folder.
Recurring backups can be configured on the Scheduling page.Create backupCurrent SchedulesCurrent umask (%o) might deny SABnzbd access to the files and folders it creates.CustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeobfuscateDeobfuscate corrected the extension of %d file(s)Deobfuscate final filenamesDeobfuscate renamed %d file(s)Deobfuscate skipped due to DVD/Bluray directoriesDetect duplicates based on analysis of the filename.Detect identical downloads based on name or NZB contents.DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDirect UnpackDirect Unpack was automatically enabled.Disable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue.Disconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDisk speedDo an extra verification based on SFV files.Do not have valid authentication for feed %sDo not use a folder in the application folder as your Scripts Folder, it might be emptied during updates.Does the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownload speed limited byDownloadedDownloaded in %s at an average of %sB/sDownloading will automatically resume if the minimum free space is available again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes.Duplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:EditEdit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmergency expireEmergency retryEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Executed after the queue finishes downloading.Executes a custom scriptExit SABnzbdExtensionExternal internet accessExternal process priorityExtra PAR2 ParametersExtra history columnsExtra queue columnsExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to connect: %s %s@%s:%s (%s)Failed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to rename %s to %sFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFatal error in DownloaderFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardGuessIt PropertyGuessIt.PropertyGuessIt_PropertyHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHidden FoldersHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory RetentionHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How many seconds your notification will continue to be retriedHow much can be downloaded this month (K/M/G)How often (in seconds) the same notification will be sentINCOMPLETEIONice ParametersIPv6 addressIdentical download detectionIdleIf empty, the standard port will only listen to HTTPS.If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name.If only the Default category is selected, notifications are enabled for jobs in all categories.If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In case of connection failures, the download queue will be paused for a few minutes instead of skipping this serverIn foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Internet BandwidthInvalid NZB file %s, skipping (error: %s)Invalid backup archiveInvalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job Name as FilenameJob failedJob finishedJobsJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesJoiningKeep all jobsKeyboard shortcutsLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLive ChatLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Location where the backups of the configuration file and databases are stored.
If left empty, the backup will be created in the Completed Download Folder.Log FolderLog inLog outLoggingLogin from too many different IP addresses to server %s [%s] - https://sabnzbd.org/multiple-adressesLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname.Minimum FilesizeMinimum Free Space for Completed Download FolderMinimum Free Space for Temporary Download FolderMissing articlesModerateModern web browsers and other clients will not accept self-signed certificates and will give a warning and/or won't connect at all.MondayMonthMoreMove and rename all episodes in the "tv" category to a show-specific folderMove and rename all movies in the "movies" category to a movie-specific folderMovie NameMovie SortingMovie.NameMovie_NameMoviesMovingMoving...Multi-OperationsMulti-part LabelNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNetwork path "%s" should not be used hereNeverNextNext scan atNice ParametersNo accessNo email templates foundNo foldersNo matching earlier rar file for %sNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly external access requires loginOnly unpack and run scripts on jobs that passed the verification stage. If turned off, all jobs will be marked as Completed even if they are incomplete.Open a Terminal window and type the line (example):Open complete folderOpen folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOriginal Job NameOrphaned jobsOther / UnknownOther MessagesPROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPermissions setting of %s might deny SABnzbd access to the files and folders it creates.Personal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPost-processing was abortedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuick startQuitQuotaQuota for this account, counted from the time it is set. In bytes, optionally follow with K,M,G.
Warn when it reaches 0, checked every few minutes.Quota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!Received a DBus exception %sRefreshRefresh rateRefused connection from:Refused connection with hostname "%s" from:RejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove SorterRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRenaming the job will abort Direct Unpack.RepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.Replace underscores in folder nameReplace underscores with dots in folder names.RequiredRequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorRestore DefaultsRestore backupResultResumeResume high priority jobsResume jobs with categoryResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSOCKS5 ProxySQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSeason folderSecure connection to serverSecuritySelect a mode and list all (un)wanted extensions. For example: exe or exe, comSelect a web interface language.Select only if your provider allows SSL connections.Selected date rangeSend RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeperate multiple URLs by a commaSeriesSeries SortingSeries with air datesServerServer %s has used the specified quotaServer %s is expiring in %s day(s)Server %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Shift+Arrow key: Browse Queue and History pagesShould downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow folderShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSmart duplicate detectionSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by % downloaded Most→LeastSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeed up repairs by installing par2cmdline-turbo, it is available for many platforms.SpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)System loadTEXTTOO LARGETabbed layout
(separate queue and history)Tag jobTemp FolderTemporary Download FolderTest DataTest EmailTest NotificationTest ServerTest downloadTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The Completed Download Folder cannot be the same or a subfolder of the Temporary Download FolderThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe queue will resort every 30 seconds if % downloaded is selected.The server didn't reply properly to the helo greetingThere are no active servers!There are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo prevent all helpful warnings, disable Special setting 'helpful_warnings'.To: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR renamerTrying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse Sorting to automatically organize and rename your completed downloads.Use global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Use the specified SOCKS5 proxy for all outgoing connections.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying repairVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarn 5 days in advance of account expiration date.WarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?WhitelistWho should we say sent the email?WikiWill not work if a category folder is on a different disk.Windows NotificationsYearYou can set access rights for systems outside your local network.You must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] The command in build_command is undefined.[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!propertysecsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Gjelbrim Haskaj, 2024 Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: de Plural-Forms: nplurals=2; plural=(n != 1); SABnzbd kann die Dateien für die Web-Oberfläche in %s nicht finden.
Installieren Sie bitte das Programm erneut.

SABnzbd hat die gespeicherten Daten einer anderen SABnzbd-Version erkannt,
kann diese aber nicht wiederverwenden.

Es wird empfohlen, die ausstehenden Downloads mit der anderen Version fertigzustellen.

Starten Sie dieses Programm danach mit der "--clean"-Option.
Dies löscht die Download-Warteschlange und den Download-Verlauf!
SABnzbd hat die Datei "%s" gelesen. SABnzbd hat erkannt, dass die Datei sqlite3.dll fehlt.

Manche unausgereiften Viren-Scanner löschen diese Datei.
Bitte überprüfen Sie den Viren-Scanner, versuchen Sie eine Neuinstallation von SABnzbd und beschweren Sie sich beim Hersteller des Viren-Scanners.

Für seinen internen Web-Server benötigt SABnzbd einen freien TCP/IP-Port.
Port %s auf %s wurde probiert, ist aber nicht verfügbar.
Entweder verwendet eine andere Software den Port oder SABnzbd läuft bereits.

Starten Sie SABnzbd bitte mit einer anderen Portnummer neu. Für seinen internen Web-Server benötigt SABnzbd eine gültige Rechner-Adresse.
Sie haben eine ungültige Adresse angegeben.
Sichere Werte sind localhost und 0.0.0.0

Starten Sie SABnzbd bitte mit einer gültigen Rechner-Adresse neu. Für SABnzbd besteht KEINERLEI GARANTIE. SABnzbd ist freie Software, die Sie unter bestimmten Bedingungen weitergeben dürfen. Sie steht unter der GNU GENERAL PUBLIC LICENSE Version 2 oder (nach Ihrer Option) jeder späteren Version. %f vorhanden von %d angefragten Artikeln%s Artikel hatten nicht übereinstimmende Duplikate%s Artikel hatten ein ungültiges Format%s Artikel fehltenZugriff auf das Verzeichnis %s fehlgeschlagen: %s%s ist kein gültiger Oktal-Wert%s ist keine gültige E-Mail-Adresse%s ist kein gültiges Script%s ist nicht beschreibbar. Downloads sind dadurch blockiert.Dateinamen mit Umlaute können nicht in %s gespeichert werden. Dies kann zu Problemen führen.+ Fehlersuche+ Info+Löschen+Reparieren+EntpackenNZB-Backup-Ordner0 ist die höchste, 99 die niedrigste Priorität7za-Programmdatei nicht gefunden
Wenn Anmeldung aktiviert ist, müssen sie sich danach noch mal anmelden.HINWEIS: Ordner werden beim Speichern automatisch erstellt. Sie können absolute Pfade angeben, um Ordner ausserhalb der standardmässigen Ordner zu verwenden.Es werden keine Dateien entfernt. Benötigt einen Neustart von SABnzbd!

Benutze die Sortierer, um deine fertigen Downloads zu orgenisieren. Zum Beispiel verschiebe alle Seriendateien in den Serien eigenen Ordner oder Verschiege alle Filme in den Filme eigenen Ordner.

Die Sortierer werden der Reihe nach bearbeitet und könne durch ziehen und ablegen umsortiert werden.
Der erste Aktive Sortierer der sowohl zur Kategorie als auch zum Aufgabentyp passt wird angewendet.

Wenn erweiterte Einstellungen aktiviert sind, sind noch mehr Einstellungen möglich.
Weitere informationen sind in der WIki zu finden.

ALTERNATIVEAPI (ohne Einstellungen)API-SchlüsselAPI-Key OR-CodeAPI-Schlüssel ungültig. Bitte API-Schlüssel aus Einstellungen->Allgemein in die externe Anwendung eingeben:API-Schlüssel fehlt. Bitte API-Schlüssel aus Einstellungen->Allgemein in die externe Anwendung eingeben:API-Schlüssel für ProwlAufträge abbrechen, die nicht abgeschlossen werden können "%s" wurde abgebrochen, da es ein verschlüsseltes RAR Archiv enthält (falls unterstützt, wurden alle Passwörter ausprobiert)Abgebrochen, kann nicht fertiggestellt werdenAbgebrochen, Verschlüsselung vorhandenAbgebrochen, unerwünschte Dateieindung gefundenAkzeptierenZugriff verweigertAccount AblaufdatumAktionAktion bei ungewollter DateiendungAktion wenn eine verschlüsselte RAR Datei geladen wirdAktion bei ungewollter DateienendungHinzufügen einerNZB hinzufügenNZB Dateien hinzufügen Regel hinzufügenServer hinzufügenSortierer hinzufügenHinzugefügte NZBZusätzlich wird versucht, die korrekte Dateierweiterung mithilfe der Dateisignatur zu ermitteln, falls noch keine Dateierweiterung vorhanden, oder sie sinnlos sein sollte.Fügt eine verifizierte NZB-Testdatei mit der angegebenen Dateigröße hinzu. Die Datei ist zufallsgeneriert und dient dem Prüfen der Einstellungen.Administrativer OrdnerErweitertBetroffene KategorienBetroffener AufgabentypAlterAlleAlle Dateien werden in einen einzelnen Ordner gespeichert.Alle Benutzernamen, Passwörter und API-Schlüssel werden automatisch aus dem Log und der darin enthaltenen Kopie deiner Einstellungen entfernt.Erlaube "Proper" ReleasesAuch Test-VeröffentlichungenImmerBenutze die volle FensterbreiteJede EigenschaftAnwendungs-TokenAnwendungs-Token (erforderlich)Filter übernehmenMöchten Sie SABnzbd wirklich beenden?Sind Sie sicher?ArgumenteBegrenzung des Artikel-CachesVerfügbarkeit der ArtikelArtikelbezeichnerMindestensHöchstensAuthentifizierung fehlgeschlagen. Überprüfen Sie Benutzername und Passwort.Automatisch fortsetzenSABnzbd hält automatisch an, wenn der freie Speicherplatz unter diesen Wert fällt.
In Bytes, gefolgt von einem optionalen K, M oder G. Zum Beispiel: "800M" or "8G"Warteschlange automatisch sortieren wenn ein neuer Job hinzugefügt wird.Automatische Sortierung der WarteschlangeZurückSicherheitskopieBackup OrdnerFehlerhafte Antwort von Pushbullet (%s): %sFehlerhafte Antwort von Pushover (%s): %sUngültige Regel %s um %s:%sBandbreiteSperrlisteVersuch das Verzeichnis %s zu erstellen wurde blockiertGanz nach untenDurchsuchenUmgehe intelligente Duplikat-Erkennung, wenn PROPER, REAL oder REPACK im Download-Namen erkannt wirdArtikel werden zwischengespeichert, um die Anzahl der Zugriffe auf die Festplatte zu reduzieren.
In Bytes, gefolgt von einem optionalen K, M oder G. Zum Beispiel: "64M" oder "128M"AbbrechenZugriff auf PID Datei %s nicht möglichRechte von %s konnten nicht geändert werdenVerbindung zum Server %s kann nicht hergestellt werden. %sKann keine Sicherungsdatei erstellen für %sVerzeichnis %s konnte nicht angelegt werdenKonnte Download-Ordner %s nicht anlegenTemporäre Datei für %s konnte nicht angelegt werdenIn %s konnten keine E-Mail-Vorlagen gefunden werdenKonnte Web-Vorlage nicht finden: %s Versuche die Standard-Vorlage zu verwenden.Der Standard-Browser konnte nicht gestartet werden, da er wahrscheinlich nicht gefunden wurde.%s kann nicht gelesen werdenÜberwachter Ordner %s kann nicht gelesen werdenAbsenden nicht möglich, benötigte Daten fehlenKann keinen langen Dateinamen in %s schreiben. Dies kann Probleme verursachen.Kann keinen Dateinamen in Unicode in %s schreiben. Dies kann Probleme verursachen.Kann nicht in die Verlaufsdatenbank schreiben, überprüfe die Zugriffsrechte!Kann INI-Datei %s nicht schreibenKategorienKategorieDer Category-Ordner darf kein Unterordner des Temporärer Download-Ordners sein.Zertifikat ungültig: Der Server-Host ist nicht im angegeben Zertifikat enthalten. Dies ist ein Serverproblem.Zertifikat ist nicht gültig. Dies ist wahrscheinlich ein Serverproblem.Zertifikat überprüfungDie Änderungen wurden nicht gespeichert und werden verloren gehen.Änderungen benötigen einen Neustart von SABnzbd!Alle auswählenVor dem Herunterladen überprüfenAuf neue Version prüfenWird überprüftÜberprüfe zusätzliche DateienÜberprüfungs-Intervall (in Minuten, mindestens 15). Nicht aktive wenn Regeln aktiv sind!Unerwünschte DateienAufräumen von %s fehlgeschlagenLöschenZähler zurücksetzenKlicken um die eingegebenen Informationen zu überprüfen.Das Schliessen des Browser-Fensters oder -Tabs beendet SABnzbd NICHT.Kompaktes LayoutFertige DownloadsZielverzeichnis GeschwindigkeitFertiggestelltOrdner für fertige DownloadsDownload-Ordner %s für abgeschlossene Downloads auf FAT Dateisystem, ist auf maximale Dateigröße von 4GB begrenzt.EinstellungenKonfigurationsdateiKonfiguration ist gesperrt, Einstellungen können nicht gespeichert werdenLöschen von Verlaufeinträgen bestätigenLöschen von Downloads bestätigenFehler beim Verbinden mit %s@%s, Meldung = %sVerbindung erfolgreich hergestellt!Verbindung fehlgeschlagen!VerbindungenDefekte RAR DateiVerbindung zu %s auf Port %s konnte nicht hergestellt werden. Es scheint, als sei %s ein Webserver (Port 80), vielleicht ein Indexer, aber kein Usenet-Server. Trage einen Usenet-Server ein.Die Verbindung konnte nicht überprüft werden. (%s)Konnte weitere Zertifikate vom Paket certifi nicht laden.Backup konnte nicht wiederhergestellt werdenErstelle eine Sicherungskopie der Konfigurationsdatei und der Datenbanken im Backup-Ordner.
Wenn der Backup-Ordner nicht festgelegt ist, wird die Sicherungskopie im Ordner der abgeschlossenen Downloads erstellt.
Wiederkehrende Sicherungen können auf der Seite Planung konfiguriert werden.Backup erstellenAktuelle RegelnDie aktuellen Zugriffseinstellungen (%o) könnte SABnzbd den Zugriff auf die erstellten Dateien und Ordner von SABnzbd verweigern.BenutzerdefiniertDUPLIKATTäglichVerlaufsdatenbank geschädigt, eine leere neue wurde erstelltSortieren nach DatumDatumsformatTag im MonatJahrzehntDecoder Fehler: Nicht genügend SpeicherStandardStandardmässiger Basis-OrdnerLöschenAlle löschenNach dem Download löschenAlle Elemente in der Warteschlange löschen?Löschen von %s fehlgeschlagen!EntschleiernEntschleiern korrigierte die Erweiterung von %d Datei(en)Entschleiere finale DateinamenEntschleiern hat %dDatei(en) umbenanntEntschleiern wird aufgrund von DVD/Blu-ray-Verzeichnissen übersprungenErkenne Duplikate durch Analyse der Dateinamen.Erkenne identische Downloads anhand des Dateinamens oder des NZB-Inhalts.GerätGeräte, welche die Benachrichtigungen empfangen sollenGerät(e)Geräte, welche die Nachrichten empfangen sollenDirekt entpackenDirekt entpacken wurde automatisch aktiviertQuoten-Management ausschaltenDeaktiviertHTTPS wurde wegen ungültigen Zertifikats- und Schlüsseldateien deaktiviertHTTPS wegen fehlenden Zertifikats- und Schlüsseldateien deaktiviert.VerwerfenAlle aktiven Verbindungen zu Usenet-Servern trennen. Verbindungen werden nach ein paar Sekunden wiederhergestellt, falls sich noch Artikel in der Warteschlange befinden.Verbindung zu Usenet-Servern trennen,
wenn die Warteschlange leer ist oder SABnzbd angehalten wurde.Bei leerer Warteschlange Verbindung trennenBenachrichtigung bei voller FestplatteFestplattenfehler beim Anlegen der Datei %sFestplatte vollFestplatte voll! Downloads werden angehalten.FestplattengeschwindigkeitZusätzliche Überprüfung mittels SFV-Dateien durchführenKeine gültige Berechtigung für Feed %sVerwenden Sie keinen Ordner im Anwendungsordner als Ihren Skriptordner, er könnte während Updates geleert werden.Wird das Kontingent jeden Tag, jede Woche oder jeden Monat zurückgesetzt?HerunterladenDownload fertigDownload FehlgeschlagenAlle Par2-Dateien herunterladenDownload fehlgeschlagen - Nicht auf deinem/n Server/n vorhandenZielverzeichnis GeschwindigkeitDownload wahrscheinlich fehlgeschlagen, nur %s von benötigten %s verfügbarDownloadgeschwindigkeit begrenzt durchHeruntergeladenHeruntergeladen in %s mit einer Durchschnittsgeschwindigkeit von %sB/sDas Herunterladen wird automatisch fortgesetzt, wenn der minimale freie Speicherplatz wieder verfügbar ist.
Gilt sowohl für den temporären als auch für den abgeschlossene Downloads-Ordner.
Dies wird alle paar Minuten überprüft.Doppelte NZBZ. B.Z.B. 8 oder 20VERSCHLÜSSELTFEHLER:BearbeitenNZB-Details bearbeitenE-MailEmail-Benachrichtigung beim Fertigstellen von AufträgenE-Mail-EmpfängerE-Mail-AbsenderOrdner mit E-Mail-VorlagenE-Mail-Adresse, an die die E-Mails gesendet werden.E-Mail erfolgreich versendetNotfallNotfall VerfallNotfall WiederanlaufLeerLeere NZB-Datei %sLeerer RSS-Feed gefunden: %sAktivieren7zip aktivierenHTTPS aktivierenNotifyOSD aktivierenProwl-Benachrichtigungen aktivierenPushbullet-Benachrichtigungen aktivierenPushover-Benachrichtungen aktivierenSFV-basierte Überprüfung aktivierenWindows-Benachrichtigungen aktivierenZugriff auf die Oberfläche über HTTPS-Adressen erlaubenOrdner-Umbenennung aktivierenFür geringere Speicher-Verwendung aktivieren.
Deaktivieren, um zu verhindern, dass langsame Aufträge
die anderen Einträge in der Warteschlange blockieren.Aktiviere Benachrichtigungs-SkriptQuoten-Management einschaltenRekursives Entpacken aktivierenAktivEin Sternchen * am Pfad-Ende verhindert die Erzeugung von Auftrags-Ordnern.URLEpisoden-NameEpisoden-NummerEpisoden.NameEpisoden_NameFehlerFehler "%s" beim Ausführen von file_join auf %sFehler "%s" beim Ausführen von par2_repair auf dem Satz %sFehler "%s" beim Ausführen von rar_unpack auf %sFehler "%s" beim Ausführen von par2_repair auf %sFehler %s: Sie müssen einen gültigen Benutzername und ein Passwort angeben.Fehler beim Anlegen des SSL-Schlüssels und -Zertifikats.Fehler beim Importieren von %sFehler beim Laden von %s. Beschädigte Datei gefunden.Fehler beim Entfernen von %sFehler beim Umbenennen von "%s" nach "%s"Fehler beim Hinzufügen von %s. Entferne.Fehler beim Herunterfahren des SystemsNur bei FehlernFehler/WarnungenWichtige Module fehlen, herunterladen kann nicht gestartet werden.Wurde nach Fertigstellung des Downloads der eingereihten Aufträge ausgeführt.Führt ein benutzerdefiniertes Skript ausSABnzbd beendenEndungExterner InternetzugriffPriorität von externem ProzessZusätzliche PAR2-ParameterWeitere Spalten bei der VerlaufslisteWeitere Spalten bei der WarteschlangeWird entpackt …Aufgabe abgebrochen (verschoben in die Historie)FehlgeschlagenAnmelden beim Server fehlgeschlagen. %s [%s]Erstellen von %s fehlgeschlagenVerschieben von %s nach %s fehlgeschlagenAuthentifizierung beim Mail-Server fehlgeschlagenFehler beim Schliessen der Datenbank. Beachten Sie das Nachrichtenprotokoll.Schliessen der Mail-Verbindung fehlgeschlagenKompilieren des regulären Ausdrucks für den Suchbegriff %s fehlgeschlagen.Verbindung zum Mail-Server konnte nicht hergestellt werdenVerbindung fehlgeschlagen: %s %s@%s:%s(%s)Fehler beim Wechsel in den RuhezustandImportieren von %s Dateien von %s fehlgeschlagenFehler %s@%s zu initialisieren, aus folgendem Grund: %sAufbau der TLS-Verbindung fehlgeschlagenDateien verschieben fehlgeschlagenDie Passwortdatei %s konnte nicht gelesen werdenFehler beim umbennenen von %s nach %sUmbenennen der gleichen Datei von %s nach %s fehlgeschlagen.Abrufen des RSS-Feeds von %s fehlgeschlagen: %sProwl-Nachricht konnte nicht versendet werdenWindows Benachrichtigung konnte nicht gesendet werdenSenden des E-Mails fehlgeschlagenSenden von macOS Benachrichtigung fehlgeschlagenPushbullet-Nachricht konnte nicht versendet werdenKonnte Pushover-Nachricht nicht versendenFehler beim Wechsel in den BereitschaftsmodusFehler beim Starten der Weboberfläche.Fehler beim Starten der Web-Oberfläche: Hochladen fehlgeschlagen: %skopieren der NZB "%s" fehlgeschlagenFehler in tempfile.mkstempSchwerwiegender FehlerSchwerer Fehler beim Speichern des ZustandsSchwerer Fehler im AssemblerSchwerer Fehler im DownloaderFeedAbrufenNZB aus URL ladenAbrufen%s Blöcke werden abgerufen …Zusätzliche Blöcke werden abgerufen …Datei mit allen Passwörtern, die bei verschlüsselten RAR-Dateien probiert werden sollen.Fehler beim Zusammenfügen von %sDateiname oder Pfad des HTTPS-Zertifikats.Dateiname oder Pfad zur HTTPS-Kette.Dateiname oder Pfad des HTTPS-Schlüssels.Datei nicht auf dem ServerDateimengeDateinameFilterBeispieldateien herausfiltern (z.B. Videoausschnitte)Ordner enthält Benutzer SkripteOrdner, der benutzerdefinierte E-Mail-Vorlagen enthält.Ordner, der auf neue .nzb Dateien überwacht werden soll.Ordner/PfadOrdnerFür authentifizierte E-Mails wird der Kontoname benötigt.Für authentifizierte E-Mails wird das Passwort benötigt.Für Server: stell sicher, dass die Dateinamen mit Windows kompatibel sind.Für unzuverlässige Server, wird bei Fehlern länger ignoriertErzwingenVerbindung trennenDownload erzwingenErzwinge TrennungForumFreier SpeicherplatzHäufigkeitFreitagVon Show SxxEyyVon SxxEyyGanze APIVolles WebinterfaceWeiterführende Informationen finden Sie in unseremAllgemeinNeuen Schlüssel generierenNeues selbstzertifiziertes Zertifikat und Schlüssel generieren. SABnzbd muss neugestartet werden!Glitter hat ein paar (neue) Feature die du bestimmt magst!SABnzbd anzeigenAssistent öffnenGuessIt EigenschaftGuessIt.EigenschaftGuessIt_EigenschaftHTTP und HTTPS Ports dürfen nicht identisch sein!HTTPS-ZertifikatHTTPS-Kette ZertifikatHTTPS-SchlüsselHTTPS-PortHTTPS Zertifikat ÜberprüfungHilfeHilf uns beim Übersetzen von SABnzbd in deiner Sprache!
Neue Übersetzungen hinzufügen oder bestehende verbessern kannst du hier:Rechner in den Ruhezustand versetzenVersteckte OrdnerDetails verbergenVollendete Dateien anzeigen/versteckenHochVerlaufVerlauf mit den letzten 10 EinträgenVerlaufsgrößeLimit der Objekte im VerlaufShift-Taste gedrückt halten, um einen ganzen Bereich auszuwählenStartseiteStartseiteAdresseHost, auf dem SABnzbd auf Anfragen warten soll.Wie lange oder bis wann möchtest du pausieren? (in Englisch!)Wie viele Sekunden soll versucht werden die Nachricht erneut zu versendenWie viel kann in diesem Monat heruntergeladen werden (K/M/G)?Wie oft dieselbe Benachrichtigung (in Sekunden) geschickt werden soll.UNVOLLSTÄNDIGIONice-ParameterIPv6-AdresseErkennung identischer DownloadsLeerlaufWenn leer, hört der Standard-Port nur auf HTTPS-Anfragen.Dateinamen von (großen) Dateien im Zielordner werden in den Auftragsnamen umbenannt, wenn sie verschleiert oder bedeutungslos aussehen.Wenn nur die Standard-Kategorie ausgewählt ist, werden die Benachrichtigungen für Jobs in allen Kategorien aktiviert. Wenn der SABnzbd Host oder Port im Netz freigegeben ist, lassen die gegenwärtigen Einstellung vollen zugriff auf die SABnzbd Oberfläche zu.Wenn Sie diesen Fehler wieder erhalten, probieren Sie eine andere Nummer.
Beispieldateien ignorierenAlle Ordner innerhalb Archiven ignorierenDoppelte NZB "%s" wird ignoriertUnerwünschter Typ "%s" in RAR Datei. Unerwünschte Datei ist %s Im Fall von "Pause" müssen Sie ein Kennwort setzen und den Aufgabe fortsetzen.Wenn SABnzbd neustartet, wird diese Anzeige automatisch verschwinden!Im Fall von Verbindungsausfällen wird die Download-Warteschlange für ein paar Minuten pausiert, anstatt diesen Server zu überspringenIn OrdnernInkompatibeler RSS-FeedInkompatible Warteschlangen-Datei gefunden. Fortsetzen nicht möglich.Unfertige DownloadUnvollständiger Ablauf beim zusammenführen von DateienUngültige RSS-Feed-Beschreibung "%s"Fehlerhafter ParameterUngültig kodiertes Passwort %sDie Performanz verbessern, indem eine schwächere SSL-Verschlüsselung erzwungen wird.Indexer Kategorien/GruppenIndexer können eine Kategorie innerhalb des NZB liefern, welche SABnzbd versuchen wird, mit den unten definierten Kategorien entsprechen. Darüber hinaus kannst du Begriffe zu "Indexer Kategorien / Gruppen" hinzufügen, um mehreren Kategorien zu entsprechen. Verwende Kommas, um Begriffe zu trennen. Wildcards in den Begriffen werden unterstützt.
Weitere Informationen können im Wiki gefunden werden.Internet BandbreiteUngültige NZB-Datei %s wird übersprungen (Fehler: %s)Invalides Backup ArchivUngültige par2-Dateien oder ungültige PAR2-Parameter, Auftrag konnte nicht überprüft oder repariert werdenUngültige Server-Adresse.Ungültige Server-AngabenUngültiges Stufen-Protokoll im Verlauf für %sProblemeEs ist empfehlenswert, diese Seite mit einem Lesezeichen zu versehen und dieses verwenden, um SABnzbd aufzurufen, wenn es im Hintergrund läuft.Aufgabe "%s" ist wahrscheinlich verschlüsselt, RAR hat den gleichen Namen wie das gepackte RAR-ArchivAufgabe "%s" ist wahrscheinlich verschlüsselt: "Passwort" im Dateiname "%s"Aufgabe Name als OrdnernameAuftrag fehlgeschlagenAuftrag ausgeführtAufträgeAufträge werden bereits während des Download-Vorgangs entpackt, um die Nachbearbeitungszeit zu verkürzen. Nur für Aufträge, die nicht repariert werden müssen.Dateien zusammenfügenZusammenfügenAlle Aufträge behaltenTastaturkürzelSpracheBrowser beim Start öffnenDen Standard-Browser öffnen, wenn SABnzbd gestartet wird.Geschwindigkeit begrenzenListe der Dateiendungen, die nach dem Download gelöscht werden sollen.
Zum Beispiel:nfo or nfo,sfvEchtzeit ChatWird geladen...Fehler beim Laden von %sLokale IPv4-AdresseLokale Speicherung (cookies) sind in ihrem Browser Deaktiviert, Oberflächen Einstellungen gehen Verloren wenn sie den Browser schließen.Ordner, der die für die Warteschlange und den Verlauf verwendeten Datenbanken enthält.
Kann nur geändert werden, wenn die Warteschlange leer ist.Hier werden Protokoll-Dateien von SABnzbd abgelegt.
Benötigt einen Neustart von SABnzbd!Hier werden fertige, verarbeitete Downloads abgelegt.
Kann von benutzerdefinierten Kategorien ausser Kraft gesetzt werden.Hier werden noch nicht verarbeitete Downloads abgelegt.
Kann nur geändert werden wenn die Warteschlange leer ist.Hier werden NZB-Dateien abgelegt.Pfad, an dem die Sicherungen der Konfigurationsdatei und der Datenbanken gespeichert werden.
Wenn diese Option leer bleibt, wird die Sicherung im Ordner der abgeschlossenen Downloads erstellt.Protokoll-OrdnerAnmeldenAbmeldenProtokollVon zu vielen unteschiedlichen IP Adressen beim Server eingeloggt %s[%s] https://sabnzbd.org/multiple-adressesVerbindung zu SABnzbd verloren..GeringKleinschreibungFür Windows kompatibel machenEntsprichtMaximale DownloadgeschwindigkeitMaximale Anzahl wiederholter Versuche pro ServerMaximale WiederholungenBedeutungMinimumMinimum: Wenn SSL aktiviert, prüft die Serveridentität und Benutzung seiner Zertifikate. Strikt: Prüft und stelle sicher das der Hostname stimmt.Minimale DateigrößeMinimaler freier Speicherplatz des abgeschlossene Downloads-OrdnersMinimaler freier Speicherplatz im temporären OrdnerFehlende ArtikelMittelModerne Webbrowser und andere Clients akzeptieren keine selbst signierten Zertifikate und geben eine Warnung aus und/oder stellen gar keine Verbindung her.MontagMonatMehrBennene alle Episodendateien in der Kategorie "tv" um und veschiebe sie in den Serien eigenen OrdnerBennene alle Filmdateien in der Kategorie "filme" um und veschiebe sie in den Filme eigenen OrdnerFilm NameFilm SortierungFilm.NameFilm_NameFilmeVerschiebevorgangWird verschoben …Mehrfach-FunktionenMulti-part KennzeichnungNZB-SchlüsselNZB zur Warteschlange hinzugefügtNameDNS-ServerBenennungNetzwerkpfad "%s" ist hier nicht erlaubtNieWeiterNächster Scan umNice-ParameterKein ZugriffKeine E-Mail-Vorlagen gefundenKeine OrdnerKeine zugehörige frühere RAR-Datei für %sKeine E-Mail gesendet da keine Empfänger angegebenKeine passende Authentifizierungsmethode gefundenNichtsNormalEntspricht nichtNicht verfügbarBenachrichtigungscenterBenachrichtigungs-SkriptBenachrichtigung gesendet!Benachrichtigungsskript "%s" existiert nichtBenachrichtigungenNotifyOSDAnzahl der Sekunden zwischen zwei Überprüfungen.Optionales Konto-PasswortOptionaler Konto-BenutzernameNeinAlte Warteschlangen-Version erkannt, über Status->Reparieren ins neue Format konvertierenWenn fertigAn welchem Tag des Monats oder der Woche (1=Montag) setzt Ihr ISP das Kontingent zurück (optional mit hh:mm)?Nur Artikel für obersten Warteschlangen-Eintrag herunterladenNur externer Zugriff benötigt eine AnmeldungEntpacken und starten von Skripten nur bei verifizierten Jobs. Wenn ausgeschaltet, werden alle Jobs als vollständig markiert, selbst wenn sie unvollständig sind.Öffnen Sie ein Terminal und geben Sie folgende Zeile ein (Beispiel):Öffne ZielverzeichnisOrdner öffnenOptionalOptionale ergänzende NZB-DateiOptionale Anmeldung mit PasswortOptionale Anmeldung mit BenutzernameWahlweise einen Dateinamen angeben:Oder Dateien per Drag-und-Drop ins Fenster ziehen!ReihenfolgeUrsprünglicher DateinameUrsprünglicher Aufgabe NameVerwaiste AufträgeAndere / UnbekannteAndere NachrichtenAUSBREITUNG %s minParameterTeilnummerPasswortPasswortdateiPasswort ist als ****** maskiert. Bitte erneut eingeben.passwortgeschütztPfadMusterMuster-SchlüsselAnhaltenAlle anhaltenDownloads während der Nachbearbeitung anhaltenAnhalten fürEine Stunde anhalten15 Minuten anhalten3 Stunden anhalten30 Minuten anhalten5 Minuten anhalten6 Stunden anhaltenAnhalten für …Aufträge mit hoher Priorität pausierenAufträge mit Kategorie pausierenAufträge mit niedriger Priorität pausierenAufträge mit normaler Priorität pausierenNachbearbeiten anhaltenAngehalten"%s" wurde angehalten, da es ein verschlüsseltes RAR Archiv enthält (falls unterstützt, wurden alle Passwörter ausprobiert)Hält die Downloads zu Beginn der Nachbearbeitung an
und setzt sie danach fort.Doppelt vorhandene NZB "%s" angehaltenProzentsatz der DownloadgeschwindigkeitRechte für fertige DownloadsDie aktuellen Zugriffseinstellungen (%s) könnte SABnzbd den Zugriff auf die erstellten Dateien und Ordner von SABnzbd verweigern.Persönlicher API-SchlüsselDein API-Key für Prowl (benötigt)Persönliche NotizenBitte beachten Sie, dass der 0.0.0.0-Hostname eine IPv6-Adresse benötigen wird für den externen Zugriff.Geben Sie bitte die Informationen zu Ihrem Usenet-Provider an.PortPort, auf dem SABnzbd auf Anfragen warten soll.Nachbearbeitung von %s fehlgeschlagen (%s)NachbearbeitungNur überprüfte Aufträge nachbearbeitenNachbearbeitungNachbearbeitung gestartetNachbearbeitung wurde abgebrochenArtikel werden angehalten bis sie mindestens das gewählte alter erreicht haben. Ändern der Job Priorität auf Erzwingen wird die Verzögerung überspringen.Das Vorwarteschlangen (pre-queue) Skript hat die Downloadaufgabe als gescheitert markiertBenutzer-Skript vor WarteschlangeVoreinstellungenDrücken Sie Start+R und geben Sie folgenden Zeile ein (Beispiel):ZurückPrioritätProblem mitErgebnisVerarbeitenProgramm wurde nicht gestartet!AusbreitungsverzögerungProwlÖffentliche IPv4-AdresseFertige NZBs löschenFehlgeschlagene NZBs löschenFehlgeschlagene NZBs und Dateien löschenVerlauf leerenNZBs löschenNZBs und Dateien löschenLösche NZBs auf der aktuellen SeiteWarteschlange leerenPushbulletPushoverPython VersionDem Pythonskript "%s" fehlen die Ausführungsrechte (+x)WarteschlangeWarteschlange mit den 10 obersten EinträgenWarteschlange abgearbeitetLimit der Objekte in der WarteschlangeOrdner kann nicht geändert werden, da die Warteschlange nicht leer ist.Reparatur der WarteschlangeSchnelle Überprüfung …Schnelle ÜberprüfungSchnellstartBeendenKontingentKontingent für dieses Konto, gezählt ab dem Zeitpunkt, an dem es festgelegt wird. In Bytes, optional gefolgt von K, M, G.
Warne, wenn es 0 erreicht, wird alle paar Minuten überprüft.Verbleibendes KontingentKontingents-PeriodeKontingent aufgebraucht, Downloads werden angehaltenRAR-Datei konnten nicht überprüft werdenRAR-Datei erfolgreich überprüftRSSRSS-ÜberprüfungRSS-Feed %s war leer%s ausgeführtSelten genutzte Funktionen. Bedeutung und Erklärungen finden Sie per klick auf den Hilfe-Button um auf die Wiki-Seite zu gelangen.
Änder nichts ohne vorher das Wiki gelesen zu haben, da sonst schwerwiegende Nebeneffekte auftreten können.
Die Ursprungswerte stehen zwischen den runden Klammern.Jetzt alle Feeds lesenFeed lesenRSS-Feeds lesenAlle RSS-Feeds lesenLesen Sie dazu die Hilfe im Wiki!DBus-Ausnahmefehler empfangen %s Neu ladenAktualisierungsrateAbgelehnte Verbindung von:Verbindung vom Host "%s" abgelehnt von:VerwerfenRelative Ordner basieren aufVerbleibendAutomatische AnmeldungNZB löschenNZBs und Dateien löschenServer entfernenSortierer entfernenAlle ausgewählten Dateien entfernenAbgeschlossene Aufträge entfernenEntferne fehlgeschlagene AufträgeEntfernen von %s fehlgeschlagenEntferne JobEntferne JobsUmbenennenDas Umbenennen des Jobs wird das direkte entpacken abbrechen.ReparierenReparatur fehlgeschlagen. Nicht genug Reparatur-Blöcke vorhanden (%s zu wenig)ReparierenReparatur fehlgeschlagen. %sWird repariert …Test wiederholenLeerzeichen in Ordnernamen ersetzenPunkte in Ordner-Namen ersetzenPunkte in Ordner-Namen durch Leerzeichen ersetzen.Leerzeichen in Ordnernamen durch Unterstriche ersetzen.Ersetze Unterstriche in OrdnernamenErsetze Unterstriche mit Punkte in Ordnernamen.ErforderlichBenötigtErfordert ein Prowl-KontoErfordert ein Pushbullet-KontoBenötigt einen Pushover-KontoBenötigt KategorieZurücksetzenKontingent jetzt zurücksetzenTag zurücksetzenAdresse wird aufgelöst …Neu startenSABnzbd neustartenNeustart ohne AnmeldungSABnzbd wird neu gestartet …Neustart aufgrund eines abgestürzten AssemblersNeustart aufgrund eines abgestürzten DownloadersNeustart aufgrund eines abgestürzten NachbearbeitungsprozessesWerkseinstellung wiederherstellenBackup wiederherstellenResultatFortsetzenAufträge mit hoher Priorität fortsetzenAufträge mit Kategorie fortsetzenAufträge mit niedriger Priorität fortsetzenAufträge mit normaler Priorität fortsetzenNachbearbeiten fortsetzenFortgesetztRückhaltezeitErneut versuchenAlle wiederholenFehlgeschlagene Aufträge neustartenAusführen des SkriptsSkripts wird ausgeführt …Ausführen des Benutzer-Skripts %sSABCTools deaktiviert: Keine korrekte Version gefunden! (Gefunden v%s, Erwartet v%s)SABnzbd %s gestartetSABnzbd-HostSABnzbd-PasswortSABnzbd-PortSABnzbd-EinrichtungsassistentSABnzbd-BenutzernameSABnzbd-VersionSABnzbd-WebserverSABnzbd hat einen schwerwiegenden Fehler erkannt:SABnzbd wurde beendetSABnzbd wurde mit Encoder/Zeichensatz %s gestartet, Dieser sollte UTF-8 sein. Es werden Probleme mit Unicode codierten Dateien und Ordnerbezeichnungen in Downloads erwartet.SABnzbd läuft nun im Hintergrund.SMTP-ServerSOCKS5 ProxySQL-Befehl fehlgeschlagen. Beachten Sie das Nachrichtenprotokoll.SSLSSL-VerschlüsselungSamstagSpeichernÄnderungen speichernFehler beim Speichern von %sSpeichervorgang …Überwachter Ordner lesenRegel für nicht existierenden Server %s.PlanungSkriptExit-Code des Skripts ist %sSkript gab Fehlercode %s und Ausgabe "%s" zurückSkripteSkript OrdnerSuchenStaffel-NummerStaffelordnerSichere Verbindung zum ServerSicherheitModus auswählen, und alle (nicht-)erwünschten Erweiterungen auflisten. Zum Beispiel: exe oder exe, comWählen Sie die Sprache der Weboberfläche.Nur auswählen, wenn der Provider SSL-Verbindungen erlaubt.Ausgewählter DatumsbereichRSS-Benachrichtigungen sendenZurück in die Warteschlange schickenE-Mail senden, wenn ein RSS-Feed einen Auftrag zur Warteschlange hinzufügt.E-Mail senden, wenn die Festplatte voll ist und SABnzbd angehalten wird.%s wurde an die Warteschlange gesendetTrenne verschiedene URLs mit KommaSerienSortieren von TV-SerienSerien mit AusstrahlungsdatumServerServer %s hat das angegebene Kontingent verbrauchtServer %s läuft in %s Tag(en) abDer Server %s nutzt ein nicht vertrauenswürdiges HTTPS-ZertifikatDer Server %s verwendet ein nicht vertrauenswürdiges Zertifikat [%s]Server %s wird für %s Minuten ignoriertServer-DetailsServer-Adresse "%s:%s" ist ungültig.Server-Adresse wird benötigtServer konnte nicht vollständig antwortenServerbeschreibungKonnte Servernamen nicht auflösenServer benötigt ein Benutzername und ein Passwort.Server-Fehler (Code %s); konnte %s von %s nicht ladenServerRechte für Dateien und Ordner festlegen.
In oktaler Notation. Zum Beispiel: "755" oder "777"ISP-Server für ausgehende E-Mails angeben.Die Einrichtung ist nun abgeschlossen.Shift+Pfeil-Taste: Durchsuche eingereihte Aufträge und VerlaufsseitenSoll wieder Heruntergeladen werden, nachdem das Kontingent zurückgesetzt wurde?Alle anzeigenNur FehlgeschlageneProtokoll anzeigenSendungs NameAktive Verbindungen anzeigenDetails anzeigenZeige OrdnerInterface anzeigenSendungs.NameSendungs_NameBeendenRechner ausschaltenSABnzbd beendenWird beendet …Signal %s erkannt. Wird gespeichert und beendet …GrösseIntelligente Duplikat ErkennungÜberprüfung einiger Dateien mittels %s fehlgeschlagenSorry, damit konnten wir nichts anfangen. Versuchs nochmal.SortieranweisungSortiere nach % heruntergeladen Viel→WenigSortieren nach Alter Neuste→ÄltesteSortieren nach Alter Älteste→NeusteSortieren nach Name A→ZSortieren nach Name Z→ASortieren nach Grösse Grösste→KleisteSortieren nach Grösse Kleinste→GrössteSortierungQuelleSpezialGeschwindigkeitErhöhe Reparaturgeschwindigkeit durch installation von Multicore Par2, verfügbar auf vielen Plattformen.GeschwindigkeitsbegrenzungRechner in Bereitschaft versetzenAssistenten startenBeginn der ReparaturStarten/BeendenStatusStatus und Interface-OptionenAbbrechenWird angehalten …StriktSendenSonntagBitte unterstützen Sie das Projekt durch eine Spende!Vermute Fehler im DownloaderSchalterSystem-OrdnerSystem PerformanceSystemlastTEXTZU GROSSTab Layout
(separate Warteschlange und Verlauf)Markiere AuftragTemporärer OrdnerTemporärer Download-OrdnerTestdatenE-Mail testenBenachrichtigungen testenServer überprüfenTest DownloadServer-Angaben werden überprüft …Ein Klick auf den Knopf "Reparieren" startet SABnzbd neu
und baut die Warteschlange neu auf, wobei bereits
heruntergeladene Dateien bestehen bleiben. Die Reihenfolge
der Warteschlange wird dabei verändert.Der "Abgeschlossene Downloads"-Ordner darf kein Unterordner des "Temporäre Downloads"-Ordners sein.Aktivieren Sie das Feld neben dem Feed-Namen, wenn automatisch auf neue Einträge geprüft werden soll.
Wenn ein Feed hinzugefügt wird, werden nur neue Einträge verarbeitet und nicht diejenigen, die bereits im RSS-Feed enthalten waren, ausser Sie klicken "Download erzwingen".Der Hostname wurde nicht angegebenDie Anzahl der Verbindungen, die der Provider erlaubt.Die Warteschlange wird alle 30 Sekunden neu sortiert, wenn % heruntergeladen, ausgewählt ist.Keine korrekte Server-Antwort auf den HELO/EHLO-CheckEs gibt keine aktiven Server!Keine Verbindungen angegeben. Bitte geben Sie mindestens eine Verbindung ein.Der Download-Ordner enthält verwaiste Aufträge.
Diese können gelöscht (zusammen mit den Dateien) oder zurück in die Warteschlange verschoben werden.Dieser Schlüssel erlaubt Drittprogrammen das Hinzufügen von NZB-Dateien zu SABnzbd.Dieser Schlüssel gibt Drittprogrammen uneingeschränkten Zugriff auf SABnzbd.Dieser MonatDies verhindert mehrfache Reparaturversuche, durch herunterladen aller par2 Dateien, wenn notwendig.Dieser Server erlaubt kein SSL auf diesem PortDiese WocheEin Klick auf den Knopf \"Neu starten\" startet SABnzbd neu.
Benutzen Sie ihn, falls ein Stabilitätsproblem vorliegt.
Die Downloads werden vor dem Neustart angehalten und danach fortgesetzt.Sendet eine Test-E-Mail an Ihr Konto.DonnerstagZeitüberschreitungZeitüberschreitung: Versuche es mit eingeschalteten SSL oder einen anderen Port.ZeitüberschreitungTitelUm alle hilfreichen Warnungen zu verbergen, deaktiviere die extra Einstellung 'helpful_warnings'.To: %s From: %s Date: %s Subject: SABnzbd meldet eine volle Festplatte Hallo, SABnzbd hat mit dem Herunterladen aufgehört, da die Festplatte fast voll " ist. Bitte geben Sie manuell Speicherplatz frei und setzen Sie die Downloads " danach fort. HeuteAngehalten wegen zu wenig freiem SpeicherplatzZu viele Verbindungen zu Server %s [%s]Zu viele Verbindungen. Bitte halten Sie die Downloads an oder versuchen Sie es später erneut.Ganz nach obenGesamtFehler suchenVersuche die erfolgreiche Fertigstellung noch vor dem Herunterladen vorherzusagen (langsamer!)Versuche 7zip mit Passwort "%s"Versuche RAR-UmbenennerRAR-basierte Überprüfung versuchenVersuche SFV-ÜberprüfungNZB-Datei wird versucht von %s abzurufenStatus für nicht vorhandenen Server wird versucht %s einzustellenVersuche entpacken mit Passwort "%s"DienstagFeinabstimmungTypUNERWÜNSCHTAbrufen der URL fehlgeschlagen; %sURLGRABBER abgestürztKonnte nicht an Port %s auf %s starten. Eine andere Software nutzt diesen Port oder SABnzbd läuft bereits.Unerlaubter ZugriffFreigebenUndefinierter Server!Unbekannter Fehler %s beim DekodierenUnbekanntes SSL-Protokoll: SSL deaktivieren oder alternativen Port versuchen.Unbekannte Aktion: %sUnbekannter Authentifizierungsfehler des E-Mail-ServersEntpackenArchive (rar, zip, 7z) innerhalb von Archiven entpacken.Entpacken zu tief verschachtelt [%s]%s Datei(en)/Ordner entpackt in %sEntpackenEntpacken fehlgeschlagen. %sEntpacken fehlgeschlagen. CRC-FehlerEntpacken fehlgeschlagen. Archiv benötigt ein Passwort.Entpacken fehlgeschlagen - Datei zu groß für Dateisystem (Formatierung FAT?)Entpacken fehlgeschlagen, Pfad ist zu langEntpacken fehlgeschlagen. Konnte %s nicht finden.Entpacken fehlgeschlagen. Fehler beim Schreiben oder volle Festplatte?Fehlerhafter Login Versuch von %sUngültige NZB-Datei.RAR-Datei beschädigtUngewollte Dateiendung in der Datei %s (%s)Unerwünschter Dateityp im RAR-Archiv %sUngewollte DateiendungenNeue Version verfügbar!NZB hochladenWird hochgeladenZeit seit StartBenutze Sortieren um deine Dateien zu orgenisieren und umzubennenendie globalen Interface-Einstellungen verwendenTemporäre Namen während der Nachbearbeitung verwenden. Deaktivieren, wenn das System nicht damit klar kommt.Benutze den angegebenen SOCKS5 Proxy für alle ausgehenden Verbindungen.Wird verwendet, bevor eine NZB-Datei zur Warteschlange hinzugefügt wird.Verwendeter CacheBenutzer-OrdnerBenutzer-SchlüsselBenutzer-Schlüssel (erforderlich)Benutzer angemeldetBenutzer im Web-Interface angemeldetBenutzerskript kann Auftrag als fehlgeschlagen markierenBenutzernameWerteÜberprüfung mit SFV-Datei(en) erfolgreichÜberprüfe Zertifikate bei Verbindungen zu Indexern und RSS-Quellen über HTTPS.ÜberprüfenÜberprüfe ReparaturÜberprüfung läuft …VersionSehr niedrigSkript-Protokoll anzeigenWARTE %s SekWARNUNG:Warten5 Tage vor dem Ablauf des Accounts warnen.AchtungWarnungenÜberwachter OrdnerGeschwindigkeit der Ordner-ÜberwachungWeb-OberflächeMittwochJob abbrechen falls während des Downloads klar wird, dass zuviele Daten fehlenWenn das Benutzerskript einen Exit-Code ausgibt, der nicht "0" ist, wird der Auftrag als fehlgeschlagen markiert.Falls sich deine IP Adresse ändert oder SABnzbd neu startet, wird deine Session ungültigWelchen Prozentsatz deiner Downloadgeschwindigkeit SABnzbd nutzen soll, z.B. 50Welches Skript sollte für die Benachrichtigung ausgeführt werdenErlaubtlisteWer soll die E-Mail versandt haben?WikiFunktioniert nicht, wenn sich der Kategorie-Ordner auf einer anderen Festplatte befindet.Windows-BenachrichtigungenJahrEs können Zugriffsrechte für Systeme außerhalb des Netzwerkes gesetzt werden.Bevor ein Bandbreitenlimit gesetzt werden kann, muss die maximale Bandbreite festgelegt werdenDeine UNRAR-Version ist %s, wir empfehlen Version %s oder höher.
Ihre Passwort-Datei enthält mehr als 30 Passwörter, das Testen aller Passwörter dauert sehr lange. Versuchen Sie, nur nützliche Passwörter aufzulisten.Dein Pushbullet API-Schlüssel (erforderlich)[%s] Fehler "%s" beim Zusammenfügen der Dateien[%s] Fehler "%s" beim Entpacken der RAR-Dateien[%s] %s Dateien zusammengefügt[%s] Keine PAR2-Sätze[%s] Ungültige PAR2-Optionen. Überprüfen Sie die Angaben in Einstellungen -> Schalter.[%s] Schnelle Überprüfung erfolgreich[%s] RAR-basierte Überprüfung ist fehlgeschlagen: %s[%s] Repariert in %s[%s] Der Befehl in build_command ist nicht definiert.[%s] Überprüft in %s. Alle Dateien fehlerfrei.[%s] Überprüft in %s. Reparatur wird benötigt.ArtikelGroß- / Kleinschreibung berücksichtigentTagTageServer deaktivierenServer aktivierenDateihStundeStundenrestmManuellMinutenMinutenAusAnoderSeitepar2-Programmdatei nicht gefunden!EigenschaftSekundeSekundenBeachten Sie die Protokolldateitextunrar-Programmdatei nicht gefunden!Woche././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.2511988 SABnzbd-4.3.2/locale/fi/LC_MESSAGES/SABnzbd.mo0000644000000000000000000017610414625637243017476 0ustar00runnerstaff5l3om3d3B5 <6I7=8''9O9j9 9999999: :1:P:Ai::?0;p;;;R;[;G<#Y<}<<$<< <<'<' =H=L=T= c= p= {====='==== >*(> S> a>k>>>>/> >>c?h?%o?#?? ????k@r@ @ @@@ A!,A6NA-AAA"A6B:B VBaBjB.B'B BBBCSC mCzCCC"C8CDD D 6D@DZD aDmDD#DDD DD* E5EGE NEXE3^E E E EEEEE EE F$F8F&?F fF)pFFF4FF?F9GSGkG GG,G,G1H9HBHUHeH'}HH5H H'H$I )I 6I@IGIXI$^II II#II III J(J /J ;JHJYJtJJJJ4JKS1KKKKKHK $L .L;L JL WLdL(jL.L)L,L<M&VM}M'MMMM N 'N2NAN ZN gNqNN NNNNN%N!%OGO+gO OO!O*O!P>P'SP"{PP#PP!PQ7QPQnQQ QQQQQQ RR(RAARR'R!RRSS S)S-0S/^S!S SS&S"S9THTNT_TnTT T TT TTT TTTGU/MU }U U'UUU U UUVo#V V VVVVVV VW #W-W2W;QW-W WW WW6WG!XiX"xXXEXDX BYMY,_YY%Y#YYY@Z]Z<yZ[['[ \\ \ \ \\\\5\ #]n/]]]]q]c=^H^o^]Z_)_ ____`!` %`0`H`P`$c```0`````` ` a aa %a/a@aHa[a`axaaaa aa a"a+abb #b /b=bQbeb'xb b b/bbcc; c\cclc"c#c3dKd`did!d!dd%d ee #e1e@e Se ^eje se*e eee ee e(e ff$f9fKf`ftf ffffffMfJgeg#~gg%ggRg<;hxh}h"hhhhhjiii-iii ii i j j2j8jLjaj sj j jjj j jjkkk0k?k&Pk wkkkkk k k kkl!l%l;lQlXlJm ]mgmvmmm mmm m m mn n(nBnXnkn ~n nnn2n nn n oo/o)Jo0tooooo p pp #p-p?pGpWpmppppppppqq q &q0qFqUqgq~q qq qqqqq r+rEr.r rss !s-s6s ;sHsYsbs#vs sss,sss s t4.tctzt3t3ttuu-u,Ju(wuu$uuuu&v:Cv~vov)v w37wkw tw w ww ww w ww ww x'x;x(@x.ix x-x-x$y$%y1Jy1|yyyyy y y yyyzz3z 8zDzKzRzYzvzzzzz z/z {{ ,{7{ I{U{o{ |!}2:}5m}A}}>j~=~ ~+~ (, > LTZ"&7A^ E:R.nł̂тڂ!3JS-߃/3 S]r-"#߄.2D$V{ bۅ$> c n{#"ˆ%L$ q { Ƈ·ׇ RUkM=0M!~EB+I#u)Ê؊J5&Ip&'Ӌ ܋ $)+26;?BEJdh p|]p(@\ t2&ܔ#(6_gpx3ҕVDX@ S]yr}j,z'Ę0&:"C2f ęԙ  %*,Wjo~. ɚ ך!  %:0k6 ?,M*z'͜Ԝٜߜ8'1%30Y,<<1$C8hF$ "0:4kɠ ޠXDS r|*@% AM akz+آ5)_ s~ F %1 8E LZ$u $/?INZ" 9 Z#h>'˦9-3DX)tB/.4CKR h/uܨ/'@IPgΩ" &0WCw(*$ī MC R ^ l x,,-*:=-x6.#6$Z Ԯݮ $/3"c2&/,.=+l2)˰0&&MAm,#ܱ)#*(N&w5/Բ2"7 Z"g  γس#Ym-%&% 4A/I?y/ @9??y ٶ   ( 6A^v~]I5 H,U ʸx ep&$529B&KCr3 4DT"!̻YSH //&-T#k?ϽVFf. -:?uN"|ox+  ! )@GB[&8  (2; C Q _ mz    1;>6z  & ? K+W$G0"+*1JY%s,"/ $? O\ p {0 )ARe()'*Q| Z&%+Co0Y15g&n/+. =  %2:O^ x0  +!Ln } #. +<MTc3 (- F,R  % 0 ; HSk{ -B4 w #01'Y`s ),%V|$%& + 5CT1l +F^m!%l $ %/)Hrz3%0MfIE&9;B:~#-9)K.uE y2o=  +9Ul  3 0:B}77//18a8  &9N%S y  %) 0C< &-.28ae$U8(9:7?IO  n0x&G 'D61{%%<0R   "LB341-Gu~"1.%:D!0 $ 1?-R,F\r7=:J3Pa  6 H R\ eq Id NrI( *4_dxU~R3'+[*N3-Iw:. !$ ,6Rktv|    = SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdministrative FolderAffected CategoriesAgeAllAll files will go into a single folder.Also test releasesAlwaysApplication TokenApplication token (required)Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"BackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCertificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderConfigConfig FileConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not determine connection result (%s)Current SchedulesCustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDisable quota managementDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningExecutes a custom scriptExit SABnzbdExtensionExternal internet accessExtra PAR2 ParametersExtracting...FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.ForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How much can be downloaded this month (K/M/G)INCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Invalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job failedJob finishedJoin filesJoiningLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLog inLog outLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly external access requires loginOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOrphaned jobsOther MessagesPROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause low priority jobsPause normal priority jobsPause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!RefreshRefresh rateRejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restore DefaultsResultResumeResume high priority jobsResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsSearchSeason NumberSelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETabbed layout
(separate queue and history)Temp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: fi Plural-Forms: nplurals=2; plural=(n != 1); SABnzbd ei löydä sen web-käyttöliittymän tiedostoja polusta %s.
Ole hyvä ja asenna ohjelma uudelleen.

SABnzbd havaitsi tallennettua tietoa toisesta SABnzbd versiosta
mutta ei voi uudelleenkäyttää tietoja toisesta ohjelmasta.

Haluat ehkä ladata jonon loppuun toisella ohjelmallasi.

Tämän jälkeen, käynnistä ohjelma "--clean" muuttujalla.
Tämä tyhjentää nykyisen jonon ja historiasi!
SABnzbd luki tiedostoa "%s". SABnzbd havaitsi, että tiedosto sqlite3.dll puuttuu.

Jotkin huonosti suunnitellut viruksentorjunta ohjelmistot poistavat tämän tiedoston.
Tarkista virustorjunta ohjelmistosi, yritä asentaa SABnzbd uudelleen ja valita virustorjunta ohjelmistosi valmistajalle.

SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
Porttia %s kohteessa %s yritettiin käyttää , mutta se ei ollut vapaana.
Jokin toinen ohjelmisto käyttää porttia tai SABnzbd on jo käynnissä.

Ole hyvä ja uudelleenkäynnistä SABnzbd toisella porttinumerolla. SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
Olet määritellyt epäkelvon osoitteen.
Turvalliset arvot ovat localhost ja 0.0.0.0

Ole hyvä ja uudelleenkäynnistä SABnzbd kunnollisella isäntäosoitteella. SABnzbd ohjelmalla EI OLE MINKÄÄNLAISTA TAKUUTA. Tämä on ilmainen ohjelma ja olet vapaa levittämään sitä tiettyjen ehtojen ollessa voimassa. Se on lisensoitu GNU GENERAL PUBLIC LICENSE Versio 2 alaiseksi ja (oman valinnan mukaan) myös myöhempien versioiden. %s artikkelissa oli ei-vastaavia kaksoiskappaleita%s artikkelia oli väärin muotoiltuja%s artikkelia puuttui%s kansio: %s virhe käytettäessä%s ei ole oikea oktaalinen arvo%s ei ole kelvollinen sähköpostiosoite+ Debug+ Tiedot+Poista+Korjaa+Pura.nzb varmuuskopiokansio0 on suurin prioriteetti, 99 on pienin prioriteetti7za-ohjelmaa... EI löydy!
Jos tunnistautuminen on käytössä, sinun täytyy kirjautua sisään uudestaan.HUOM: Kansiot luodaan automaattisesti tallennuksen yhteydessä. Voit käyttää täydellisiä polkuja jos haluat tallentaa oletuskansioiden ulkopuolelle.Tiedostoja ei tulla siirtämään. Vaatii SABnzbd uudelleenkäynnistyksen!API (ei asetuksia)API avainAPI avaimen QR-koodiAPI avain virheellinen, käytä Asetukset->Yleiset löytyvää api avainta käyttämääsi kolmannen osapuolen ohjelmaan:API avain puuttuu, ole hyvä ja syötä Asetukset->Yleiset löytyvä api avain käyttämääsi kolmannen osapuolen ohjelmaan:Prowl API avainPeruuta lataukset jotka eivät voi valmistuaPeruutettu, ei voi valmistuaPeruutettu, salattu arkisto tunnistettuPeruutettu, ei toivottu tiedostopääte havaittuHyväksyEi käyttöoikeuttaToimintoToiminto kun salattu RAR havaitaanToiminto kun havaitaan ei toivottu tiedostopääteLisääLisää NZBLisää NZB tiedostot Lisää ajastusLisää palvelinLisätty NZBHallinnollinen kansioKategoriat joita koskeeIkäKaikkiKaikki tiedostot menevät yhteen kansioon.Myös testiversiotAinaOhjelman tokenOhjelman token (pakollinen)Oletko varma, että haluat sammuttaa SABnzbdn?Oletko varma?ParametritVälimuistirajoitus artikkeleilleArtikkelin tunnisteVähintäänEnintäänVarmennus epäonnistui, tarkista käyttäjänimi/salasana.Jatka automaattisestiKeskeytä automaattisesti kun vapaan tilan määrä on vähemmän kuin tämä arvo.
Tavuina, mutta voit laittaa perään K,M,G,T kirjaimen. Esimerkiksi: "800M" tai "8G"TakaisinVarmuuskopioiVirheellinen vastaus Pushbulletilta (%s): %sVirheellinen vastaus Pushoverilta (%s): %sVirheellinen ajastus %s kohteessa %s:%sKaistaAlinSelaaVälimuistita artikkelit muistissa levytapahtumien vähentämiseksi.
Tavuina, vaihtoehtoisesti lisää pääte K,M,G. Esimerkiksi: "64M" tai "128M"PeruutaKäyttöoikeuksien muuttaminen epäonnistui kohteelle %sPalvelimeen %s ei voida yhdistää [%s]Ei voitu luoda varmuuskopiotiedostoa kohteelle %sEi voi luoda kansiota %sEi voitu luoda lopullista kansiota %sVäliaikaistiedostoa ei voida luoda kohteelle %sSähköpostipohjia ei löydy hakemistosta %sWeb-mallia %s ei löydy, yritetään käyttää oletusmalliaSelainta ei voida käynnistää, todennäköisesti ei löydyEi voida lukea %sVahdittua kansiota %s ei voida lukeaEi voida lähettää, vaaditut tiedot ovat puutteellisetHistorian tietokantaan ei voida kirjoittaa, tarkista käyttöoikeudet!Ei voitu kirjoittaa INI tiedostoa %sKategoriatKategoriaSertifikaatin varmennusMuutoksia ei ole tallennettu ja ne menetetään.Muutokset vaativat SABnzbdn uudelleenkäynnistyksen!Valitse kaikkiTarkista ennen lataamistaTarkista uusi versioTarkistetaanTarkistusväli (minuutteina, vähintään 15). Ei ole aktiivinen jos käytät Ajastinta!Puhdistuslista%s puhdistaminen epäonnistui.TyhjennäNollaa laskuritKlikkaa testataksesi syötettyjä tietoja.Selaimen tai sen välilehtien sulkeminen EI sammuta SABnzbd:tä.Tiivis käyttöliittymäValmistuneet-kansioValmistuneet-kansion nopeusValmistunutValmistuneet kansioAsetuksetAsetustiedostoVarmista historian poistotVarmista jonon poistotYhdistäminen %s@%s epäonnistui, viesti=%sYhdistäminen onnistui!Yhteys epäonnistui!YhteydetKorruptoitunut RAR arkistoYhteystestin lopputulosta ei voitu määrittää (%s)Nykyiset ajastuksetMukautettuKAKSOISKAPPALEPäivittäinHistorian tietokanta on vahingoittunut, luotiin uusi tyhjä tietokantaPäivämäärän lajitteluPäivämäärän muotoKuukauden päiväVuosikymmenOletusOletuskansioPoistaPoista kaikkiPoista lataamisen jälkeenPoistetaanko kaikki kohteet jonosta?Kohteen %s poisto epäonnistui!LaiteLaite johon viesti lähetetäänLaitteetLaitteet joihin viesti lähetetäänOta latausrajoituksen hallinta pois käytöstäEi käytössäHTTPS on poistettu käytöstä puuttuvien CERT- ja KEY-tiedostojen vuoksiHylkääKatkaise yhteys Usenet palvelimeen/palvelimiin kun jono on tyhjä tai tila on keskeytetty.Katkaise yhteys kun jono on tyhjäLevy täynnä ilmoituksetLevyvirhe luotaessa tiedostoa %sLevy täynnäLevy täynnä! Pakotetaan keskeytysSuorittaa ylimääräisen varmennuksen SFV tiedostojen avulla.Ei ole käyttöoikeutta syötteeseen %sResetoidaanko rajoitus joka päivä, viikko vai kuukausi?LataaLataus valmistuiLataus epäonnistuiLataa kaikki par2 tiedostotLataus epäonnistui - Ei ole palvelimillaLatauskansion nopeusLataaminen saattaa epäonnistua, vain %s osaa %s osasta saatavillaLadattuLadattiin ajassa %s keskilatausnopeudella %sB/sEsim.Esim. 8 tai 20SALATTUVIRHE:NZB tietojen muokkausSähköpostiSähköposti-ilmoitus onnistuneesta latauksestaSähköpostin vastaanottajaSähköpostin lähettäjäSähköpostipohjien kansioSähköpostiosoite johon viestit lähetetään.Sähköpostitus onnistuiHälytysTyhjäTyhjä NZB tiedosto %sTyhjä RSS kohde löytyi (%s)Ota käyttöön7zip käytössäHTTPS käytössäNotifyOSD käytössäProwl ilmoitukset käytössäPushbullet ilmoitukset käytössäPushover ilmoitukset käytössäSFV-pohjaiset tarkistukset käytössäWindows-ilmoitukset käytössäOta käyttöön käyttöliittymän käyttäminen HTTPS-osoitteesta.Kansion uudelleennimeäminen käytössäLaita päälle jos haluat ohjelman käyttävän vähemmän muistia. Ota pois päältä jos haluat estää hitaiden latauksien aiheuttavan ruuhkaa jonossa.Ilmoitusskripti päälläOta latausrajoituksen hallinta käyttöönRekursiivinen purkaminen käytössäKäytössäPolun päättäminen tähteen * estää latauskohtaisten kansioiden luomisen.Syötä osoiteJakson nimiJakson numeroJakson.nimiJakson_nimiVirheVirhe "%s" ajettaessa file_join kohteelle %sVirhe "%s" ajettaessa par2_repair setille %sVirhe "%s" ajettaessa rar_unpack kohteelle %sVirhe %s ajettaessa par2_repair setille %sVirhe %s: Syötä kelvollinen käyttäjänimi ja salasana.Virhe luotaessa SSL avainta ja sertifikaattiaVirhe tuotaessa %sVirhe ladattaessa %s, korruptoitunut tiedosto havaittuVirhe poistettaessa %sVirhe uudelleennimettäessä "%s" nimelle "%s"Virhe lisättäessä %s, poistetaanVirhe sammutettaessa järjestelmääVain virheetVirheet/varoituksetSuorittaa käyttäjän skriptinPoistu SABnzbd:stäTunnisteUlkoinen ohjelman käyttöYlimääräiset PAR2 parametritPuretaan...EpäonnistunutKirjautuminen palvelimelle %s epäonnistui [%s]Kohteen (%s) luominen epäonnistuiKohteen %s siirtäminen kohteeseen %s epäonnistuiPostipalvelimen varmennus epäonnistuiTietokannan sulkeminen epäonnistui, katso lokiSähköpostiyhteyden sulkeminen epäonnistuiRegex käännös epäonnistui hakutermille: %sPostipalvelimeen yhdistäminen epäonnistuiJärjestelmän lepotilaan laittaminen epäonnistuiVirhe tuotaessa %s tiedostoa kohteesta %sAlustaminen epäonnistui kohteessa %s@%s syy: %sTLS yhteyden aloittaminen epäonnistuiTiedostojen siirto epäonnistuiSamankaltaisen tiedoston uudelleennimeäminen epäonnistui: %s %sRSS noutaminen epäonnistui kohteesta %s: %sProwl viestin lähetys epäonnistuiWindows-ilmoituksen lähetys epäonnistuiSähköpostin lähetys epäonnistuiPushbullet viestin lähetys epäonnistuiPushover viestin lähetys epäonnistuiJärjestelmän valmiustilaan laittaminen epäonnistuiWeb-käyttöliittymän käynnistys epäonnistuiWeb-käyttöliittymän käynnistys epäonnistui : Virhe tiedostossa tempfile.mkstempVakava virheVakava virhe tallennettaessa tilaaVakava virhe kohteessa AssemblerSyöteNoudaNouda NZB osoitteestaNoudetaanNoudetaan %s lohkoa...Noudetaan ylimääräiset lohkot...Tiedosto joka sisältää kaikki salasanat joita kokeillaan salattuihin RAR tiedostoihin.Tiedostoliitos %s epäonnistuiTiedostonimi tai polku HTTPS sertifikaattiin.Tiedostonimi tai polku HTTPS ketjuun.Tiedostonimi tai polku HTTPS avaimeen.Tiedostoa ei ole palvelimellaTiedostojoukkoTiedostonimiSuodataOhittaa näytetiedostot (esim. videonäytteet).Kansio joka sisältää käyttäjän luomat sähköpostipohjat.Kansio jota vahditaan .nzb tiedostojen varalta.Kansio/PolkuKansiotKirjautumisen vaativalle sähköpostille, tilin käyttäjänimi.Kirjautumisen vaativalle sähköpostille, tilin salasana.Palvelimille: varmistaa että nimet ovat Windows yhteensopivia.PakotaPakota yhteyden katkaisuPakota latausPakotetaan yhteyden katkaisuFoorumiVapaa tilaToistoPerjantaiAlkaen SxxExxTäysi APITäysi Web-käyttöliittymäLisää ohjeita löytyyYleisetLuo uusi avainLuo uusi itse allekirjoitettu sertifikaatti ja avain. Vaatii SABnzbd uudelleenkäynnistyksen!Glitter-teemassa on muutamia (uusia) ominaisuuksia joista saatat pitää!Siirry SABnzbd:henMene velhoonHTTP- ja HTTPS-portit eivät voi olla samojaHTTPS sertifikaattiHTTPS ketjun sertifikaatitHTTPS avainHTTPS porttiHTTPS sertfikaatin varmennusOhjeAuta meitä kääntämään SABnzbd sinun kielellesi!
Käännä tai muokkaa olemassaolevia käännöksiä täällä:HorrostilaPiilota yksityiskohdatPiilota/näytä valmistuneet tiedostotKorkeaHistoriaVie viimeiset 10 kohdetta historiaanHistorian pituusrajoitusPaina vaihto-näppäintä pohjassa valitaksesi alueenAlkuunKotisivuIsäntäOsoite jota SABnzbdn tulisi kuunnella.Kuinka pitkään tai mihin asti haluat keskeyttää? (englanniksi!)Kuinka paljon voidaan ladata tässä kuussa (K/M/G)KESKENERÄINENIONice muuttujatIPv6 osoiteToimetonJos tyhjä, oletusportti kuuntelee ainoastaan HTTPS.Jos saat tämän virhesanoman uudestaan, kokeile toista numeroa.
Ohita näytteetOhita kansiot arkistojen sisälläOhitetaan kaksoiskappale NZB "%s"Jos valitsit "Keskeytä", sinun täytyy antaa salasana ja jatkaa sen jälkeen lataamista.Mikäli SABnzbd käynnistetään uudelleen, tämä ruutu häviää automaattisesti!KansioissaPuutteellinen syöteEi-tuettu jonotiedosto löytyi, ei voida jatkaaLataukset-kansioPuutteellinen joukko yhdistettäviä tiedostojaVirheellinen RSS syötteen kuvaus "%s"Virheellinen parametriVirheellisesti koodattu salasana %sLisää suorituskykyä pakottamalla alhaisempi SSL-suojaustaso.Indeksoijan kategoriat / ryhmäIndeksoijat voivat tarjota kategorian NZB tiedoston sisällä jonka SABnzbd yrittää vastata johonkin esimääriteltyyn kategoriaan. Voit lisäksi lisätä sanoja "Indeksoijan kategoriat / ryhmä" -kohtaan vastaamaan useampia kategorioita. Käytä pilkkuja sanojen erottamiseen. Jokerimerkit ovat tuettuna.
Lisätietoja löytyy Wikistä.Virheellinen palvelimen osoite.Virheelliset palvelimen tiedotVirheellinen tila lokihistoriassa kohteelle %sOngelmatOn suositeltavaa, että painat linkistä hiiren oikealla ja lisäät sen kirjanmerkkeihin. Sitten voit käyttää kirjanmerkkiä kun haluat käyttää SABnzbd ohjelmaa sen ollessa käynnissä taustalla.Lataus epäonnistuiLataus valmistunutYhdistä tiedostotYhdistetäänKieliKäynnistä selain käynnistyksen yhteydessäKäynnistää oletusselaimen kun SABnzbd käynnistetään.NopeusrajoitusLista tiedostopäätteistä jotka poistetaan latauksen valmistuttua.
Esimerkiksi: nfo tai nfo, sfvLadataanKohteen %s lataaminen epäonnistuiPaikallinen IPv4 osoiteLocalStorage (evästeet) on pois käytöstä selaimen asetuksista. Käyttöliittymän asetukset menetetään kun selain suljetaan!Sijainti jonne tallennetaan jonon hallinnan ja historian tietokannat.
Voidaan muuttaa vain jonon ollessa tyhjä.Sijainti jonne SABnzbd ohjelman lokitiedostot tallennetaan.
Vaatii SABnzbd uudelleenkäynnistyksen!Sijainti jonne tallennetaan valmistuneet ja täysin käsitellyt ladatut kohteet.
Käyttäjän asettamat kategoriat voivat kumota tämän.Sijainti jonne tallennetaan latauksessa olevat kohteet ennen käsittelyä.
Voidaan muuttaa vain kun jono on tyhjä.Sijainti jonne .nzb tiedostot tallennetaan.LokikansioKirjaudu sisäänKirjaudu ulosLokiinkirjausMenetettiin yhteys SABnzbd:hen...MatalaPienaakkosetWindows yhteensopivuusVastaaSuurin latausnopeusEnimmäismäärä uudelleenyrityksiä yksittäiselle palvelimelle.Enimmäismäärä uudelleenyrityksilleMerkitysPienin vapaan tilan määrä väliaikaisille latauksillePuuttuvat artikkelitKohtalainenMaanantaiKuukausiLisääElokuvan nimiElokuvan.nimiElokuvan_nimiSiirretäänSiirretään...MonioperaatiotNZB avainNZB lisätty jonoonNimiNimipalvelin / DNS-selvitysNimeäminenEi koskaanSeuraavaNice muuttujatEi pääsyäSähköpostipohjia ei löydyEi kansioitaVastaanottajaa ei määritelty, sähköpostia ei lähetettyYhteensopivan varmennustavan löytäminen epäonnistuiEi mitäänNormaaliEi vastaavuuttaEi saatavillaIlmoituskeskusIlmoitusskriptiIlmoitus lähetetty!Ilmoitusskriptiä "%s" ei ole olemassaIlmoituksetIlmoitusOSDSkannausväli sekunteina .nzb tiedostoille.VAIHTOEHTOINEN tilin salasanaVAIHTOEHTOINEN tilin käyttäjänimiEi käytössäVanhan version jono havaittiin, käytä Tila->Korjaa muuntaaksesi jononKun jono on tyhjäMinä päivänä kuusta tai viikosta (1=Maanantai) palveluntarjoajasi resetoi rajoituksen? (Voit syöttää kellonajan perään hh:mm)Hae artikkelit vain jonon huipultaVain ulkoinen käyttö vaatii kirjautumisenAvaa pääte ja kirjoita rivi (esimerkki):Avaa valmistuneet-kansioVaihtoehtoinenVaihtoehtoinen täyte-NZBVaihtoehtoinen salasana todennukseen.Vaihtoehtoinen käyttäjänimi todennukseen.Vaihtoehtoisesti anna tiedostonimiTai vedä ja pudota tiedostot tähän ikkunaan!JärjestysAlkuperäinen tiedostonimiOrvot latauksetMuut viestitLEVITETÄÄN %s minParametritOsan numeroSalasanaSalasanatiedostoSalasana on piilotettu ******, syötä uudelleenSalasanasuojattuPolkuMalliMallin avainKeskeytäKeskeytä kaikkiKeskeytä lataus jälkikäsittelyn ajaksiKeskeytä ajaksiKeskeytä tunniksiKeskeytä 15:ksi minuutiksiKeskeytä 3:ksi tunniksiKeskeytä 30:ksi minuutiksiKeskeytä 5:ksi minuutiksiKeskeytä 6:ksi tunniksiKeskeytä ajaksi...Keskeytä korkean prioriteetin latauksetKeskeytä alhaisen prioriteetin latauksetKeskeytä normaalin prioriteetin latauksetKeskeytä jälkikäsittelyKeskeytettyKeskeyttää lataamisen kun jälkikäsittely alkaa ja jatkaa lataamista kun se lopetetaan.Keskeytetään kaksoiskappale NZB "%s"Latausnopeuden prosenttiosuusKäyttöoikeudet valmistuneille latauksilleHenkilökohtainen API avainProwlin henkilökohtainen API avain (pakollinen)Henkilökohtaiset huomautuksetHuomioithan, että 0.0.0.0 isäntänimi vaatii IPv6 osoitteen jotta pääset ulkoverkkoonSyötä pääasiallisen usenet tarjoajasi tiedot.PorttiPortti jota SABnzbdn tulisi kuunnella.Jälkikäsittely epäonnistui kohteelle %s (%s)JälkikäsittelyJälkikäsittele vain onnistuneet latauksetJälkikäsittelyJälkikäsittely aloitettuLähetykset tauotetaan kunnes ne ovat vähintään näin vanhoja. Prioriteetin asettaminen pakottamiselle ohittaa asetetun viiveen.Esijonon käyttäjän skriptiEsiasetuksetPaina Windows-nappia+R ja kirjoita seuraava rivi (esimerkki):EdellinenPrioriteettiOngelmaKäsitellyt tuloksetKäsitelläänOhjelma ei käynnistynyt!LevitysviiveProwlJulkinen IPv4 osoitePuhdista valmistuneet NZBtPuhdista epäonnistuneet NZBtPuhdista epäonnistuneet NZBt & poista tiedostotTyhjennä historiaPuhdista NZBtPuhdista NZBt & poista tiedostotPuhdista NZBt nykyiseltä sivultaTyhjennä jonoPushbulletPushoverPython versioJonoVie ensimmäiset 10 kohdetta jonoonJono valmistunutJonon pituusrajoitusJono ei ole tyhjä, kansiota ei voida vaihtaa.Jonon korjausPikatarkistus...PikatarkistetaanLopetaLatausrajoitusLatausrajoitusta jäljelläLatausrajoituksen pituusLatausrajoitus saavutettu, keskeytetään latauksetRAR arkistoja ei voitu varmentaaRAR arkistot varmennettiin onnistuneestiRSSRSS tarkistusväliRSS syöte %s oli tyhjäAjettiin %sHarvoin käytetyt asetukset. Paina Ohje-painiketta Wiki-sivustolle päästäksesi, jotta saat tietää näiden tarkoituksen ja ohjeet käyttöön.
Älä muuta ennen Wikin lukemista, koska näiden muuttamisella voi olla vakavia sivuvaikutuksia.
Oletusarvot ovat kirjoitettuna sulkeiden sisään.Lue kaikki syötteet nytLue syöteLue RSS syötteetLue kaikki RSS syötteetLue Wikin ohjeet tähän!PäivitäPäivitysväliHylkääSuhteelliset kansiot jotka perustuvatJäljelläMuista minutPoista NZBPoista NZB ja tiedostotPoista palvelinPoista kaikki valitut tiedostotPoista valmistuneet latauksetPoista epäonnistuneet lataukset%s poistaminen epäonnistuiPoistetaan latausPoistetaan latauksetUudelleennimeäKorjaaKorjaaminen epäonnistui, ei tarpeeksi korjauslohkoja (%s puuttuu)KorjataanKorjaus epäonnistui, %sKorjataan...Toista testiKorvaa välilyönnit kansionimessäKorvaa pisteet kansionimessäKorvaa pisteet välilyönneillä kansionimissä.Korvaa välilyönnit alaviivoilla kansionimissä.VaatiiVaatii Prowl-tilinVaatii Pushbullet tilinVaatii Pushover tilinVaadittuCatNollaaResetoi latausrajoitus nytResetointipäiväSelvitetään osoitettaKäynnistä uudelleenUudelleenkäynnistä SABnzbdKäynnistä uudelleen ilman kirjautumistaKäynnistetään SABnzbd uudelleen...Palauta oletusasetuksetTulosJatkaJatka korkean prioriteetin latauksetJatka alhaisen prioriteetin latauksetJatka normaalin prioriteetin latauksetJatka jälkikäsittelyäJatketaanSäilytysaikaYritä uudelleenYritä uudelleen kaikkiYritä uudelleen kaikki epäonnistuneet latauksetAjetaan skriptiAjetaan skripti...Ajetaan käyttäjän skripti %sSABnzbd %s käynnistettySABnzbd isäntäSABnzbd salasanaSABnzbd porttiSABnzbd pika-aloitus velhoSABnzbd käyttäjänimiSABnzbd versioSABnzbd web-palvelinSABnzbd havaitsi vakavan virheen:SABnzbd sammutus valmisSABnzbd käynnistettiin %s merkistökoodauksella. Tämän pitäisi olla UTF-8. Unicode-merkkejä tiedosto- ja kansionimissä sisältävät lataukset voivat aiheuttaa ongelmia.SABnzbd on nyt käynnissä taustalla.SMTP-palvelinSQL komento epäonnistui, katso lokiSSLSSL-salausLauantaiTallennaTallenna muutoksetKohteen %s tallentaminen epäonnistuiTallennetaan...Tarkista vahdittu kansioAjastettu tuntemattomalle palvelimelle %sAjastusSkriptiSkriptin lopetuskoodi on %sSkripti palautti lopetuskoodin %s ja tulosteen "%s"SkriptitEtsiTuotantokauden numeroValitse web-käyttöliittymän kieli.Valitse vain jos tarjoajasi sallii SSL yhteydet.Lähetä RSS ilmoituksetLähetä takaisin jonoonLähetä sähköpostia kun RSS syötteestä lisätään latauksia jonoon.Lähetä sähköposti kun levy on täynnä ja SABnzbd on keskeytetty.Lähetettiin %s jonoonSarjojen lajitteluPalvelinPalvelin %s käyttää epäluotettavaa HTTPS sertifikaattiaPalvelin %s käyttää epäluotettavaa sertifikaattia [%s]Palvelin %s ohitetaan %s minuutiksiPalvelimen tiedotPalvelimen osoite "%s:%s" ei ole kelvollinen.Palvelimen osoite vaaditaanPalvelimen kuvausPalvelimen osoitetta ei voitu selvittääPalvelin vaatii käyttäjänimen ja salasanan.Palvelinpään virhe (virhekoodi %s); ei voitu noutaa %s kohteesta %sPalvelimetAseta käyttöoikeusmalli valmistuneille tiedostoille/kansioille.
Oktaalilukuna. Esimerkiksi: "755" tai "777"Sähköpostin lähtevän postin palvelimen osoite.Asennus on nyt valmis!Pitäisikö latauksia jatkaa kun latausrajoitus on resetoitu?Näytä kaikkiNäytä epäonnistuneetNäytä lokiOhjelman nimiNäytä aktiiviset yhteydetNäytä yksityiskohdatNäytä käyttöliittymäOhjelman.nimiOhjelman_nimiSammutaSammuta tietokoneSammuta SABnzbdSammutetaanSignaali %s kaapattu, tallennetaan ja lopetetaan...KokoJotkin tiedostot eivät varmentuneet "%s" kanssaValitettavasti emme ymmärtäneet tuota. Yritä uudelleen.LajittelumerkkijonoJärjestä iän mukaan Uusin→VanhinJärjestä iän mukaan Vanhin→UusinJärjestä nimen mukaan A→ZJärjestä nimen mukaan Z→AJärjestä koon mukaan Suurin→PieninJärjestä koon mukaan Pienin→SuurinLajitteluLähdeErikoisasetuksetNopeusNopeusrajoitusLepotilaKäynnistä velhoAloitetaan korjausKäynnistys/SammutusTilaTilan ja käyttöliittymän asetuksetPysäytäPysäytetään...TiukkaLähetäSunnuntaiTue projektia, lahjoita!Mahdollinen virhe lataajassaMuuttujatJärjestelmäkansioJärjestelmän suorituskyky (Pystone)TEKSTILIIAN SUURIVälilehditetty käyttöliittymä
(erillinen jono ja historia)VäliaikaiskansioVäliaikaiset lataukset kansioTestaa sähköpostiaTestaa ilmoitustaTestaa palvelintaTestataan pavelimen tietoja..."Korjaa" painike käynnistää SABnzbd uudelleen ja luo jonon
sisällön täydellisesti uudelleen, säilyttäen jo ladatut tiedostot.
Tämä muuttaa jonon järjestystä.Valintaruutu syötteen nimen vieressä täytyy olla valittuna jotta syöte on päällä ja uusia kohteita tarkistetaan automaattisesti.
Kun syöte lisätään, siitä lisätään vain uusia kohteita eikä niitä jotka ovat jo julkaistu syötteessä ellet paina "Pakota lataus" -painiketta.Isäntänimeä ei ole asetettu.Tarjoajasi sallimien yhteyksien lukumäärä.Palvelin ei vastannut oikein hello-pyyntöön.Yhteyksiä ei ole asetettu. Aktivoi ainakin yksi yhteys.Latauskansiossa on orpoja latauksia.
Voit valita niiden poistamisen (sisältäen tiedostot) tai voit lähettää ne takaisin jonoon.Tämä avain antaa kolmannen osapuolen ohjelmille oikeudet lisätä NZB-tiedostoja SABnzbd-ohjelmaan.Tämä avain antaa kolmannen osapuolen ohjelmille täyden pääsyn SABnzbd-ohjelmaan.Tässä kuussaTämä palvelin ei salli SSL yhteyksiä tähän porttiinTällä viikollaTämä uudelleenkäynnistää SABnzbdn.
Käytä sitä kun luulet ohjelman toimivan epävakaasti.
Lataaminen keskeytyy uudelleenkäynnistyksen ajaksi ja jatkuu ohjelman käynnistyttyä.Tämä lähettää testiviestin sähköpostiosoitteeseesi.TorstaiAikakatkaistiinAikakatkaistu: Yritä laittaa SSL päälle tai yhdistä toiseen porttiin.AikakatkaisuNimiTo: %s From: %s Date: %s Subject: SABnzbd raportoi levy täynnä Hei, SABnzbd on lopettanut lataamasta, koska levy on lähes täynnä. Ole hyvä ja tee lisää tilaa ja jatka SABnzbd käsin. TänäänLevytilaa ei ole tarpeeksi, pakotetaan KESKEYTYSLiikaa yhteyksiä palvelimelle %s [%s]Liikaa yhteyksiä, keskeytä lataaminen tai yritä myöhemmin uudelleenYlinYhteensäVianmääritysYritä ennustaa latauksen valmistuminen ennen lataamista (hitaampi!)Yritetään purkaa 7zip arkistoa salasanalla "%s"Yritetään RAR-pohjaista varmennustaYritetään SFV varmennustaYritetään noutaa NZB osoitteesta %sYritettiin asettaa tila ei olemassa olevalle palvelimelle %sYritetään purkaa rar arkistoa salasanalla "%s"TiistaiHienosäätöTyyppiEI TOIVOTTUOsoitteen nouto epäonnistui; %sOSOITTEENNOUTAJA KAATUILuvaton käyttöPoista estoMäärittämätön palvelin!Tuntematon virhe dekoodattaessa %sTuntematon SSL protokolla: Kokeile ottaa SSL käytöstä tai vaihda porttia.Tuntematon toiminto: %sTuntematon varmennusvirhe sähköpostipalvelimelta.PuraPurkaa arkistot (rar, zip, 7z) arkistojen sisältä.Purkaessa havaittiin liikaa pakkauskerroksia [%s]Purettiin %s tiedostoa/kansiota kohteeseen %sPuretaanPurkaminen epäonnistui, %sPurkaminen epäonnistui, CRC virhePurkaminen epäonnistui, arkisto vaatii salasananPurkaminen epäonnistui, polku on liian pitkäPurkaminen epäonnistui, %s ei löydyPurkaminen epäonnistui, kirjoitusvirhe tai levy täynnä?NZB tiedostoa ei voida käyttääKäyttökelvoton RAR arkistoEi toivottu tiedostopääte on rar arkistossa %sEi toivotut tiedostopäätteetPäivitys saatavilla!Lähetä NZBLähetetäänKäynnissäoloaikaKäytä yleisiä käyttöliittymän asetuksiaKäyttää väliaikaisia nimiä kun jälkikäsittely on käynnissä. Poista käytöstä jos järjestelmäsi ei toimi oikein asetuksen ollessa päällä.Käytetään ennen NZB lisäämistä jonoon.Käytetty välimuistiKäyttäjähakemistotKäyttäjän avainKäyttäjän avain (pakollinen)Käyttäjä kirjautui sisäänKäyttäjä kirjautui sisään web-käyttöliittymäänKäyttäjän skripti voi merkitä latauksen epäonnistuneeksiKäyttäjänimiArvotVarmennettiin onnistuneesti SFV tiedostojen avulla.Varmenna sertifikaatit yhdistettäessä indeksoijiin ja RSS-lähteisiin HTTPS protokollan avulla.VarmennetaanVarmennetaan...VersioErittäin vähäinenNäytä skriptien lokiODOTA %s sekuntiaVAROITUS:OdotetaanVaroitusVaroituksetVahdittu kansioVahditun kansion tarkistusväliWeb-käyttöliittymäKeskiviikkoPeruutetaan lataus, jos ladattaessa huomataan liikaa tiedostoja puuttuvanKun käyttäjän skripti palauttaa nollasta poikkeavan koodin, lataus merkitään epäonnistuneeksi.Istunto vanhenee kun IP-osoite vaihtuu tai SABnzbd käynnistetään uudelleen.Kuinka monta prosenttia latausnopeudesta SABnzbd saa käyttää, esim. 50Mikä skripti suoritetaan ilmoitukselle?Kuka näytetään viestin lähettäjänä?WikiWindows-ilmoituksetVuosiSinun täytyy määrittää enimmäiskaista ennen kaistarajoituksen käyttöönottoa.UNRAR-versiosi on %s, suosittelemme käyttämään versiota %s tai uudempaa.
Henkilökohtainen Pushbullet API avain (pakollinen)[%s] Virhe "%s" yhdistettäessä tiedostoja[%s] Virhe "%s" purettaessa RAR tiedostoja[%s] Liitetty %s tiedostoa[%s] Ei par2 arkistoja[%s] PAR2 vastaanotti vääränlaiset asetukset, tarkista Asetukset->Muuttujat[%s] Pikatarkistus OK[%s] RAR-pohjainen varmennus epäonnistui: %s[%s] Korjattiin ajassa %s[%s] Varmennettiin ajassa %s, kaikki tiedostot kelvollisia[%s] Varmennetiin ajassa %s, vaatii korjauksenartikkeleitakirjainkokoa säätäväpvpäiväpäivääpoista palvelin käytöstäota palvelin käyttööntiedostottuntituntiajäljellämkäsikäyttöinenminuuttiminuuttiaei käytössäkäytössätaisivupar2 ohjelmaa... EI löydy!sekuntisekuntiakatso lokitiedostotekstiunrar-ohjelmaa... EI löydy!viikko././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993698.4908547 SABnzbd-4.3.2/locale/fr/LC_MESSAGES/SABnzbd.mo0000644000000000000000000027013714625637242017507 0ustar00runnerstaff\ @o@d ArB lCyDmE&WF'~FFF FFG;G1TGMG5G HHH!H)H1H1DHvHAHH?VII KKKKRK[LmL#LLVLM-M$JMoM vMMM-M'M'M!N%N-N jej'xjjjj j kk8)k.bkk k kkkk l l 4lBl]ldlll%l!ll+m Bm#cmm!m*m!mn#&nJn'dn"nn0nn#o@o!Vo0xo!ooop"pBp\pwp ppppppp qq+qADqq'q!qqrr#r,r-3rar/r!r rr&r"s91sBkssssss s st t t&t/t BtctktG|t/t t uu u1u'Buju|u u uuuou =vJv Yvfvvvvvv vv vvv;w>Xw-w9w w x x)xFx6KxvxhxbyGy-z"~h~F~~~'~$H;4 I Ta}f  !5; qn} q#cHoB]): ڄda~ $00͆"KчN7lH  # *4EV^qv)ʼn ʉ׉  #"9+\ Š֊'  /)Ys;͋݋c-X"#͌3f č!ލ!"%@fl~ L  (4 =*K v  ( ӏݏ*> P]vؐUߐM5!#ّXV%gR<,1"Ps˓j%Rx-Ĕ͔ ֔ (.BW i ȕ <SYn}& –і  ɗ4;- @JYl +ә $ . :E _ m{ њ ޚ*2% Xb w )ț0"#.Fu~ ڜ  0F'\(+ٝ!;Tp ŞԞHF Yf wӟ . ɠ֠  .7#K oz,š͡ܡ \$ 4ע33IC}!ң  &'"N-q,(̤$)!Acv&:o)m/3ަ  ( 4 AK c p|   ŧ'ӧ(.C r3~--$$31X1ĩ˩өU٩ / : ERbsz ڪ +7 </Fv ~  ˫ ׫`2+C^5خA7>= 9MD+ Ȱ,m >LG"&$AK E :R.nŴ̴Ѵڴag{J-A/Hx Զ-6"U#x."˷"$5Zn J7b=<$ݹ  #7#F"j%Lú  +8@I Yen2vɻ  RUbcM=j0 ٽ!: E[A`EB++#߿)-BJT&/&'Em v  $>C|P6Qb)S-}'% FGdu:"]e l w'GQo[*z  (1hBe7%]y{!-6dm|7.29 AMg D-2-7e*0/9i)2,F Xb}A P'#*2(H'q" 1 s!')-Q-5"(2/2bg@>+T2UX ^b+ ejKPBl<  <+Jev'.9Fh' E*/B,r ;S%G=m^ 9G OHY  + + FP!_'4Z`9:)+,=X>O%1. `8l; D$GiSj2!3 GTqC9C $9?yR( '!I % 3 =KT\eC=Sqy& ! "0B$b"!5=!V${ 4D5MBM;"P;s#()#&J]MtA % 5?W!v&+6=)F#p)597.@f,)"0!=R.$/64*k!9(;*Y;'%'**R#}! &$5Zck-W+D-p6*"#:I@P+B/0 ?4L5NSZax    6* akaH2 C X i z 7     ! ) .    '   ! #, P !m 4    6 C 6\ 0 F    * +7  c 7n  6ZO#6XOwJ?/!'Qy"C#4"N<;  iR+U ht&=2 O>| 2 qPo u ( DD ^ q z "!(!-!72!dj!a!L1"`~" " ""# # ##7#H#^# g### #8####$ $'$D$2T$3$@$$% %%+%B%Y%.q% % %]%#&:& S&b_&&&p&:l'@'2'(=())H) Z)d)2)7)1)1*Q*W*o****l**+ =+I+ Y+f+6~++++++ ,=,X,a,", ,",!, -+-.C-0r-/-0-".'.{0.Y.!/%(//N/:~/l/&0-;0i0l|0>0(1!-1&O1v1+111%12D2)23=(3 f3 r3|333 333344254h4{4 4'4#44 455S#5w5155*5C5@6[6s66666 ]7k7,}7/7$778#8 >8%K8q9999=9: :,:F::]::1::: :):%;:;*N;y;;;;;<6< G<GS<<<<<.<-$=<R=I=0=B > M> Y>e>>>>>"> > ? $?0?D?#b?.?0?0?!@9@ Q@ [@(e@*@)@*@A+AEEE>eEEE EEE E Fs!F%FHFG"G@GK`GTGbH!dH*HHHHH,H&IHEI3I-II/J4J*OJzJ'J6JIJ:KCK3KKILRhL LLLL MM;MQMeM |M MMMMM>MN$N4:N?oNN8N=O<DO%O%O:O:PCPJPQPZPobPPPPQ#Q5Q Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %f% available of %d requested articles%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address%s is not a valid script%s is not writable at all. This blocks downloads.%s is not writable with special character filenames. This can cause problems.%s@%s: Received unknown status code %s for article %s+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!

Use Sorters to automatically organize your completed downloads. For example, put all episodes from a series in a season-specific folder. Or, put movies in a folder named after the movie.

Sorters are tried in order of appearance and can be reordered by dragging and dropping.
The first active sorter that matches both the affected category and job type is applied.

More options are available when Advanced Settings is checked.
Detailed information can be found on the Wiki.

ALTERNATIVEAPI (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAbort post-processingAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedAccount expiration dateActionAction when an unwanted extension is detectedAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdd SorterAdded NZBAdditionally, attempts to set the correct file extension based on the file signature if the extension is not present or meaningless.Adds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup.Administrative FolderAdvancedAffected CategoriesAffected Job TypesAgeAllAll files will go into a single folder.All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings.Allow proper releasesAlso test releasesAlwaysAlways use full screen widthAny propertyApplication TokenApplication token (required)Apply filtersArchiveAre you sure you want to remove these jobs?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle availabilityArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically sort jobs in the queue when a new job is added.Automatically sort queueBackBackupBackup FolderBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBlacklistBlocked attempt to create directory %sBottomBrowseBypass smart duplicate detection if PROPER, REAL or REPACK is detected in the download name.Cache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write a long filename to %s. This can cause problems.Cannot write a unicode filename to %s. This can cause problems.Cannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCategory folder cannot be a subfolder of the Temporary Download Folder.Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Certificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a theme.Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfiguration locked, cannot save settingsConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not connect to %s on port %s. It appears that %s operates as a web server (port 80), possibly an indexer, not a usenet server. You have to fill a usenet server.Could not determine connection result (%s)Could not load additional certificates from certifi packageCould not restore backupCreate a backup of the configuration file and databases in the Backup Folder.
If the Backup Folder is not set, the backup will be created in the Completed Download Folder.
Recurring backups can be configured on the Scheduling page.Create backupCurrent SchedulesCurrent umask (%o) might deny SABnzbd access to the files and folders it creates.CustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Apprise URLsDefault Base FolderDeleteDelete AllDelete after downloadDelete all completed jobsDelete all items from the queue?Delete jobs from the history and archive after specified number of daysDelete jobs if the history and archive exceeds specified number of jobsDeleting %s failed!DeobfuscateDeobfuscate corrected the extension of %d file(s)Deobfuscate final filenamesDeobfuscate renamed %d file(s)Deobfuscate skipped due to DVD/Bluray directoriesDetect duplicates based on analysis of the filename.Detect identical downloads based on name or NZB contents.DeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDirect UnpackDirect Unpack was automatically enabled.Disable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue.Disconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDisk speedDo an extra verification based on SFV files.Do not have valid authentication for feed %sDo not use a folder in the application folder as your Scripts Folder, it might be emptied during updates.Does the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownload speed limited byDownloadedDownloaded in %s at an average of %sB/sDownloading will automatically resume if the minimum free space is available again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes.Duplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:EditEdit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmergency expireEmergency retryEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable Apprise notificationsEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Executed after the queue finishes downloading.Executes a custom scriptExit SABnzbdExtensionExternal internet accessExternal process priorityExtra PAR2 ParametersExtra history columnsExtra queue columnsExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to connect: %s %s@%s:%s (%s)Failed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to rename %s to %sFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Apprise messageFailed to send Apprise message - no URLs definedFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send one or more Apprise NotificationsFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFatal error in DownloaderFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardGuessIt PropertyGuessIt.PropertyGuessIt_PropertyHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHidden FoldersHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory RetentionHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How many seconds your notification will continue to be retriedHow much can be downloaded this month (K/M/G)How often (in seconds) the same notification will be sentINCOMPLETEIONice ParametersIPv6 addressIdentical download detectionIdleIf empty, the standard port will only listen to HTTPS.If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name.If only the Default category is selected, notifications are enabled for jobs in all categories.If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In case of connection failures, the download queue will be paused for a few minutes instead of skipping this serverIn foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Internet BandwidthInvalid NZB file %s, skipping (error: %s)Invalid backup archiveInvalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job Name as FilenameJob failedJob finishedJobsJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesJoiningKeep all jobsKeyboard shortcutsLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLive ChatLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Location where the backups of the configuration file and databases are stored.
If left empty, the backup will be created in the Completed Download Folder.Log FolderLog inLog outLoggingLogin from too many different IP addresses to server %s [%s] - https://sabnzbd.org/multiple-adressesLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname.Minimum FilesizeMinimum Free Space for Completed Download FolderMinimum Free Space for Temporary Download FolderMissing articlesModerateModern web browsers and other clients will not accept self-signed certificates and will give a warning and/or won't connect at all.MondayMonthMoreMove all completed jobs to archiveMove and rename all episodes in the "tv" category to a show-specific folderMove and rename all movies in the "movies" category to a movie-specific folderMove jobs to the archive after specified number of daysMove jobs to the archive if the history exceeds specified number of jobsMovie NameMovie SortingMovie.NameMovie_NameMoviesMovingMoving...Multi-OperationsMulti-part LabelNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNetwork path "%s" should not be used hereNeverNextNext scan atNice ParametersNo accessNo email templates foundNo foldersNo matching earlier rar file for %sNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn queue finish scriptOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)One or more Apprise URLs could not be loaded.Only Get Articles for Top of QueueOnly external access requires loginOnly unpack and run scripts on jobs that passed the verification stage. If turned off, all jobs will be marked as Completed even if they are incomplete.Open a Terminal window and type the line (example):Open complete folderOpen folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOriginal Job NameOrphaned jobsOther / UnknownOther MessagesOverride the default URLs for specific notification types below, if desired.PROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermanently delete (skip archive)Permissions for completed downloadsPermissions setting of %s might deny SABnzbd access to the files and folders it creates.Personal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPost-processing was abortedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge LogsPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuick startQuitQuotaQuota for this account, counted from the time it is set. In bytes, optionally follow with K,M,G.
Warn when it reaches 0, checked every few minutes.Quota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!Received a DBus exception %sRefreshRefresh rateRefused connection from:Refused connection with hostname "%s" from:RejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove SorterRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRenaming the job will abort Direct Unpack.RepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.Replace underscores in folder nameReplace underscores with dots in folder names.RequiredRequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorRestore DefaultsRestore backupResultResumeResume high priority jobsResume jobs with categoryResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSOCKS5 ProxySQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSeason folderSecure connection to serverSecuritySelect a mode and list all (un)wanted extensions. For example: exe or exe, comSelect a web interface language.Select only if your provider allows SSL connections.Selected date rangeSend RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send notifications using Apprise to almost any notification serviceSent %s to queueSeperate multiple URLs by a commaSeriesSeries SortingSeries with air datesServerServer %s has used the specified quotaServer %s is expiring in %s day(s)Server %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Shift+Arrow key: Browse Queue and History pagesShould downloading resume after the quota is reset?Show AllShow ArchiveShow FailedShow LoggingShow NameShow active connectionsShow detailsShow folderShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSmart duplicate detectionSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by % downloaded Most→LeastSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeed up repairs by installing par2cmdline-turbo, it is available for many platforms.SpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)System loadTEXTTOO LARGETabbed layout
(separate queue and history)Tag jobTemp FolderTemporary Download FolderTest DataTest EmailTest NotificationTest ServerTest downloadTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The Completed Download Folder cannot be the same or a subfolder of the Temporary Download FolderThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe queue will resort every 30 seconds if % downloaded is selected.The server didn't reply properly to the helo greetingThere are no active servers!There are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo prevent all helpful warnings, disable Special setting 'helpful_warnings'.To: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR renamerTrying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse Sorting to automatically organize and rename your completed downloads.Use a comma and/or space to identify more than one URL.Use global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Use the specified SOCKS5 proxy for all outgoing connections.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying repairVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarn 5 days in advance of account expiration date.WarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb Interface ThemeWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be completed' are disabled.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?WhitelistWho should we say sent the email?WikiWill not work if a category folder is on a different disk.Windows NotificationsYearYou can set access rights for systems outside your local network.You must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] The command in build_command is undefined.[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!propertysecsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.2RC1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Fred L <88com88@gmail.com>, 2024 Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: fr Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2; SABnzbd ne peut pas trouver ses fichiers d'interface web dans %s.
Veuillez réinstaller le programme.

SABnzbd a détecté des données sauvegardées avec une autre version de SABnzbd
mais ne peut réutiliser les données de l'autre programme.

Vous voudrez peut-être terminer votre première file d'attente avec l'autre programme.

Après cela, lancez ce programme avec l'option "--clean".
Cette opération effacera la file d'attente actuelle et l'historique !
SABnzbd a lu le fichier "%s". SABnzbd a détecté que le fichier sqlite3.dll est manquant.

Certains antivirus mal conçu peuvent supprimer ce fichier.
S'il vous plaît vérifier votre antivirus, essayez de ré-installer SABnzbd et plaignez vous à l'éditeur de l'antivirus.

SABnzbd a besoin d'un port tcp/ip libre pour le serveur Web interne.
La plage de ports %s à %s a été essayée mais elle n'est pas disponible.
Un autre logiciel utilise ce port ou SABnzbd est déjà en cours d'exécution.

Veuillez redémarrer SABnzbd avec un port différent. SABnzbd a besoin d'une adresse hôte valide pour son serveur Web interne.
Vous avez spécifié une adresse non valide.
Les valeurs sûres sont localhost et 0.0.0.0

Veuillez redémarrer SABnzbd avec une adresse hôte correcte. SABnzbd est fourni sans AUCUNE GARANTIE. Ce logiciel est gratuit, et vous êtes invité à le redistribuer sous certaines conditions. Il est distribué sous licence GNU GENERAL PUBLIC LICENSE Version 2 ou toute autre version ultérieure. %f% disponibles sur %d articles demandés%s articles avec doublons sans correspondance%s articles malformés%s articles manquants%s dossier : %s erreur d'accès%s n'est pas une valeur octale correcte%s n'est pas une adresse email valide%s n'est pas un script valide%s n'est pas du tout inscriptible. Les téléchargements sont bloqués.Le fichier %s n'est pas inscriptible à cause des caractères spéciaux dans le nom. Cela peut causer des problèmes.%s@%s a reçu le code d'état inconnu %s pour l'article %s+ Debug+ Info+Supprimer+Réparer+DécompresserDossier de sauvegarde des fichiers .nzb0 est la priorité la plus élevée, 99 est la priorité la plus faibleBinaire 7za ... Introuvable!
Si l'authentification est activée, vous devrez vous identifier à nouveau.NOTE: Les dossiers seront créés automatiquement lors de l'enregistrement. Il est possible d'utiliser des chemins absolus pour sauvegarder en dehors du répertoire par défaut.Les données ne seront pas déplacées. Requiert un redémarrage de SABnzbd !

Utilisez les trieurs pour organiser automatiquement vos téléchargements terminés. Par exemple, placez tous les épisodes d'une série dans un dossier spécifique à la saison. Ou encore, placez les films dans un dossier portant le nom du film.

Les trieurs sont essayés par ordre d'apparition et peuvent être réorganisés par glisser-déposer.
Le premier trieur actif qui correspond à la fois à la catégorie et au type de tâche concernée est appliqué.

D'autres options sont disponibles lorsque l'option Paramètres avancés est cochée.
Des informations détaillées sont disponibles sur le Wiki.

ALTERNATIVEAPI (aucune configuration)Clé APIClé API code QRClé API incorrecte, utilisez la clé API de la configuration générale dans votre application tierce :Clé API manquante, entrez la clé API de la configuration générale dans votre application tierce :Clé API pour ProwlInterrompre les tâches qui ne peuvent être terminéesAbandonner le post-traitementLa tâche "%s" a été abandonnée à cause d'un fichier RAR chiffré (tous les mots de passe fournis ont été essayés)Interrompu, ne peut être achevéInterrompu, cryptage détectéInterrompu, extension indésirable détectéeAccepterAccès refuséDate d'expiration du compteActionAction lorsqu'une extension indésirable est détectéeAction quand un RAR chiffré est téléchargéAction si une extension indésirable est détectéAjouterAjouter NZBAjouter des fichiers NZB Ajouter une planificationAjouter un serveurAjouter un trieurNZB ajoutéTente par ailleurs de trouver l'extension du fichier en se basant sur sa signature si l'extension n'est pas présente ou si elle n'a pas de sens.Ajoute un fichier test NZB, de la taille spécifiée, rempli de données aléatoires. Peut être utilisé pour vérifier votre configuration.Dossier administrateurOptions avancéesCatégories affectéesTypes de tâche concernéeÂgeTousTous les fichiers iront dans un seul dossier.Tous les noms d'utilisateur, mots de passe et clés API sont automatiquement supprimés du journal et de la copie de vos réglages.Autoriser les versions corrigées (proper)Versions de test égalementToujoursToujours utiliser la largeur totale de l'écranN'importe quel attributJeton (token) d'applicationJeton (token) d'application (obligatoire)Appliquer les filtresArchivesÊtes-vous sûr de vouloir supprimer ces tâches ?Etes-vous sûr de vouloir arrêter SABnzbd ?Êtes-vous sûr ?ArgumentsLimite du cache d'articlesDisponibilité de l'articleIdentifiant de l'articleAu moinsAu plusEchec d'authentification, vérifiez les identifiant/mot de passe.Reprise autoMettre en pause lorsque l'espace libre est en-dessous de cette valeur.
En octets, peut être suivi de O,M,G,T. Par exemple : "800M" ou "8G"Trier automatiquement la file d'attente lorsqu'une nouvelle tâche est ajoutée.Trier automatiquement la file d'attenteRetourSecoursDossier de sauvegardeMauvaise réponse de Pusbullet (%s) : %sMauvaise réponse de Pushover (%s) : %sMauvaise planification %s à %s:%sBande passanteListe noireTentative bloquée de création du répertoire %sTout en basParcourirContourner la détection des doublons si PROPER, REAL ou REPACK est détecté dans l'intitulé du téléchargement.Mettre les articles en cache pour réduire les accès disque.
En Octets, peut être suivi de K,M,G. Par exemple : "64M" ou "128M"AnnulerImpossible d'accéder au fichier PID %sImpossible de changer les permissions pour %sImpossible de se connecter au serveur %s [%s]Impossible de créer le fichier de sauvegarde pour %sImpossible de créer le dossier %sImpossible de créer le dossier final %sImpossible de créer le fichier temporaire pour %sImpossible de trouver les modèles d'email dans %sImpossible de trouver le template de l'interface web : %s, nouvelle tentative avec le template standardImpossible de lancer le navigateur web, probablement pas trouvéImpossible de lire %sImpossible de lire le dossier surveillé %sImpossible d'envoyer, données requises manquantesImpossible d'écrire un nom de fichier long dans %s. Cela peut causer des problèmes.Impossible d'écrire un nom de fichier unicode dans %s. Cela peut causer des problèmes.Impossible d'écrire dans la base de données de l'historique, vérifier les droits d'accès !Impossible d'écrire dans le fichier INI %sCatégoriesCatégorieLe dossier de catégorie ne peut pas être un sous-dossier du dossier de téléchargement temporaire.Incompatibilité du nom d'hôte du certificat : le nom d'hôte du serveur n'est pas répertorié dans le certificat. Il s'agit d'un problème de serveur.Le certificat n'est pas valide. C'est probablement un problème de serveur.Vérification du certificatLes modifications n'ont pas été enregistrées et seront perdues.Les modifications nécessiteront un redémarrage de SABnzbd!Tout sélectionnerVérifiez avant de téléchargerVérifier les mises à jourVérificationVérification des fichiers supplémentairesIntervalle de vérification (en minutes, au moins 15). Inactif quand vous utilisez le Planificateur !Choisissez un thème.Nettoyer la listeÉchec du nettoyage de %s.EffacerRAZ des compteursCliquez pour tester les informations entrées.Fermer la fenêtre/onglet de votre navigateur NE QUITTERA PAS SABnzbd.Affichage compactDossier completVitesse du dossier "Complete"TerminéDossier des téléchargements terminésLe système de fichiers du dossier des téléchargements terminés %s est au format FAT, limitant la taille maximale d'un fichier à 4 GoConfigurationFichier de configurationConfiguration verrouillée, impossible de sauvegarder les paramètresConfirmer les suppressions de l'historiqueConfirmer les suppressions de la file d'attenteLa connexion à %s@%s a échoué, message=%sConnexion réussie!Echec de connexion !ConnectionsFichier RAR corrompuImpossible de se connecter à %s sur le port %s. Il semble que %s fonctionne comme un serveur web (port 80), peut-être un indexeur, et non comme un serveur Usenet. Vous devez spécifier un serveur Usenet.Impossible de déterminer le résultat de la connexion (%s)Impossible de charger les certificats supplémentaires à partir du package certifiImpossible de restaurer la sauvegardeCréer une sauvegarde du fichier de configuration et des bases de données dans le Dossier de sauvegarde.
Si le Dossier de sauvegarde n'est pas défini, la sauvegarde sera créée dans le Dossier des téléchargements terminés.
Les sauvegardes récurrentes peuvent être configurées sur la page Planification.Créer une sauvegardePlanifications actuellesL'umask actuel (%o) pourrait refuser à SABnzbd l'accès aux fichiers et dossiers qu'il crée.PersonnaliséDOUBLONQuotidienBase de données d'historique endommagée, création d'une nouvelle baseTri par dateFormat de la dateJour du moisDécennieÉchec du décodeur : mémoire insuffisantePar défautURLs par défaut d'AppriseDossier racine par défautSupprimerTout supprimerSupprimer après téléchargementSupprimer toutes les tâches terminéesSupprimer tous les éléments de la file d'attente ?Supprimer les tâches de l'historique et des archives après le nombre de jours spécifiéSupprimer les tâches si l'historique et les archives dépassent le nombre de tâches spécifiéImpossible de supprimer %s !DésobfuscationLa désobfuscation a corrigé l'extension de %d fichier(s)Désobfusquer les noms de fichiers finauxLa désobfuscation a renommé %d fichier(s)Désobfuscation ignorée à cause des répertoires DVD/BlurayDétecter les doublons basés sur l'analyse du nom de fichier.Détecter les téléchargements identiques basés sur le nom ou le contenu NZB.AppareilAppareil sur lequel le message doit être envoyéAppareil(s)Appareil(s) auxquels doivent être envoyés les messagesDécompression DirecteLa Décompression Directe a été activée automatiquement.Désactiver la gestion de quotaDésactivéHTTPS a été désactivé à cause de fichiers CERT et KEY invalidesHTTPS désactivé car le certificat et la clé n'ont pas été trouvésRejeterDéconnecte toutes les connexions actives aux serveurs Usenet. Les connexions seront rouvertes après quelques secondes si des éléments sont présents dans la file d'attente.Se déconnecter du serveur(s) Usenet lorsque la file d'attente est vide ou en pauseSe déconnecter lorsque la file d'attente est videNotifications de disque dur pleinErreur de disque lors de la création du fichier %sDisque pleinDisque plein ! Pause forcéeVitesse du disqueFait une vérification supplémentaire basée sur les fichiers SFV.Vous n'avez pas d'authentification valide pour ce flux %sN'utilisez pas un dossier à l'intérieur du dossier de l'application pour y stocker les scripts, il pourrait être vidé lors des mises à jour.Est-ce que le quota se réinitialise chaque jour, semaine ou mois ?TéléchargerTéléchargement terminéÉchec du téléchargementTélécharger tous les fichiers par2Le téléchargement a échoué - absent de vos serveur(s)Vitesse du dossier "Download"Le téléchargement pourrait échouer, seulement %s des %s requis sont disponiblesVitesse de téléchargement limitée parTéléchargéTéléchargé en %s à %sB/s de moyenneLe téléchargement reprendra automatiquement si l'espace libre minimum est à nouveau disponible.
S'applique aux dossiers des téléchargements temporaires et terminés.
Vérifié toutes les quelques minutes.Dupliquer NZBPar ex. :Ex. : 8 ou 20CHIFFRÉERREUR:ModifierÉditer les détails du NZBEmailNotification par email lorsque des téléchargements sont terminésEmail du destinataireEmail de l'expéditeurDossier des modèles d'emailAdresse email à laquelle seront envoyées les notifications.L'envoi de l'e-mail a réussiUrgenceExpiration d'urgenceNouvelle tentative d'urgenceVideFichier NZB %s videEntrée vide de flux RSS trouvée (%s)ActiverActiver 7zipActiver les notifications AppriseActiver HTTPSActiver NotifyOSDActiver les notifications ProwlActiver les notifications PushbulletActiver les notifications PushoverActiver les contrôles SFVActiver les notifications WindowsActive l'accès à l'interface via une adresse HTTPS.Activer le renommage du dossierActiver pour moins d'utilisation de la RAM. Désactiver pour éviter que les téléchargements lents bloquent la file d'attente.Activer le script de notificationActiver la gestion de quotaActiver l'extraction récursiveActivéTerminer le chemin avec une étoile * empêche la création des dossiers de la tâche.Saisir une URLNom de l'épisodeNuméro de l'épisodeNom.ÉpisodeNom_ÉpisodeErreurErreur "%s" lors de l'exécution de file_join sur %sErreur "%s" lors de l'exécution de par2_repair sur la collection %sErreur "%s" lors de l'exécution de rar_unpack sur %sErreur %s lors de l'exécution de par2_repair sur la collection %sErreur %s: vous devez fournir un nom d'utilisateur et un mot de passe valide.Erreur lors de la création de la clé et du certificat SSLErreur lors de l'importation de %sErreur lors du chargement de %s, fichier corrompu détectéErreur lors de la suppression de %sErreur lors du renommage de "%s" en "%s"Erreur lors de l'ajout de %s, suppressionErreur lors de l'arrêt du systèmeErreurs uniquementErreurs/AvertissementsDes modules essentiels sont manquants, le téléchargement ne peut démarrer.Exécuté après la fin du téléchargement de la file d'attente.Exécute un script personnaliséQuitter SABnzbdExtensionAccès Internet externePriorité de processus externeParamètres PAR2 supplémentairesColonnes d'historique supplémentairesColonnes de file d'attente supplémentairesDécompression en cours...Faire échouer la tâche (déplacer vers l'historique)ÉchouéÉchec de la connexion au serveur %s [%s]Échec lors de la création de (%s)Échec lors du déplacement de %s vers %sÉchec de l'authentification au serveur de messagerieImpossible de fermer la base de données, voir le journalÉchec de la fermeture de la connexion à la messagerieEchec de la compilation de regex pour la recherche du terme : %sÉchec de connexion au serveur de messagerieÉchec de la connexion : %s %s@%s:%s (%s)Échec de la mise en hibernatationEchec de l'importation des fichiers %s depuis %sÉchec d'initialisation de %s@%s pour la raison suivante : %sÉchec de l'initialisation de la connexion TLSImpossible de déplacer les fichiersÉchec de lecture du fichier de mot de passe %sÉchec du renommage de %s en %sImpossible de renommer le fichier similaire : %s en %sÉchec de la récupération RSS de %s : %sÉchec d'envoi du message AppriseÉchec d'envoi du message Apprise - aucune URLs définiesÉchec d'envoi du message ProwlEchec d'envoi de la notification WindowsÉchec de l'envoi de l'e-mailÉchec de l'envoi de la notification macOSÉchec de l'envoi d'une ou plusieurs notifications Apprise.Échec de l'envoi du message PushbulletÉchec de l'envoi du message PushoverÉchec de la mise en veilleImpossible de démarrer l'interface webImpossible de démarrer l'interface web : Échec de l'upload du fichier : %sÉchec de duplication du NZB "%s"Échec dans tempfile.mkstempErreur fataleErreur fatale lors de l'enregistrementErreur fatale dans l'assembleurErreur fatale dans le TéléchargeurFlux RSSChargerImporter le NZB depuis l'URLRécupération en coursRécupération de %s blocs...Récupération des blocs supplémentaires ...Le fichier contenant tous les mots de passe sera testé sur les fichiers RAR chiffrés.La concaténation du fichiers %s a échouéNom du fichier ou chemin du certificat HTTPS.Nom du fichier ou chemin d'accès de la chaîne HTTPS.Nom du fichier ou chemin de la clé HTTPS.Fichier introuvable sur le serveurCollection de fichiersNom de fichierFiltreExclure les fichiers échantillons (par ex. les samples vidéo).Dossier contenant les scripts utilisateurs.Dossier contenant les modèles d'email définis par l'utilisateur.Dossier d'import automatique des fichiers .nzb.Dossier/CheminRépertoiresIdentifiant du compte pour les envois authentifiés.Mot de passe du compte pour les envois authentifiés.Pour les serveurs : assurez-vous que les noms soient compatibles avec Windows.Pour les serveurs non fiables, sera ignorée plus longtemps en cas de défaillancesForcerForcer la déconnexionForcer le téléchargementDéconnexion forcée en coursForumEspace libreFréquenceVendrediÀ partir de la Série SxxEyyDepuis SxxEyyAPI complèteInterface Web complèteUne aide supplémentaire peut être trouvée sur notreGénéralGénérer une nouvelle cléGénérer à nouveau les certificat et clé auto-signés. Nécessite le redémarrage de SABnzbd !Glitter a des (nouvelles) fonctionnalités que vous devriez apprécier !Aller à SABnzbdAller à l'assistantAttribut GuessItAttribut.GuessitAttribut_GuessitLes ports HTTP et HTTPS ne peuvent pas être identiquesCertificat HTTPSCertificats de chaîne HTTPSClé HTTPSPort HTTPSVérification du certificat HTTPSAideAidez-nous à traduire SABnzbd dans votre langue !
Améliorez les traductions existantes ou ajoutez celles qui manquent ici :Mettre le PC en hibernationDossiers cachésMasquer les détailsAfficher/masquer les fichiers terminésHauteHistoriqueHistorique des 10 derniers articlesConservation de l'historiqueLimite des éléments historisésMaintenez la touche Maj pour sélectionner une plageAccueilPage d'accueilHôteHôte sur lequel SABnzbd doit attendre les connexions.Combien de temps ou jusqu'à quand souhaitez-vous mettre en pause ?Réessayer la notification pendant combien de secondesCombien peut-être télécharger ce mois (K/M/G)À quelle fréquence la même notification sera envoyée (en secondes)INCOMPLETParamètres 'IONice'Adresse IPv6Détection des téléchargements identiquesA l'arrêtSi vide, le port standard écoutera seulement le HTTPS.Si les noms de fichiers (volumineux) dans le dossier final semblent obscurs ou dénués de sens, ils seront renommés avec le nom de la tâche.Si seule la catégorie Défaut est sélectionnée, les notifications seront activées pour les tâches de toutes les catégories.Vos paramètres actuels permettent un accès externe complet à l'interface SABnzbd si l'hôte ou le port SABnzbd est ouvert vers l'internet.Si vous obtenez ce message d'erreur à nouveau, veuillez essayer un nombre différent.
Ignorer les échantillons (Samples)Ignorer tous les dossiers à l'intérieur des archivesDoublon NZB ignoré "%s"Le fichier RAR "%s" contient une extension indésirable. Le fichier indésirable est %s En cas de "Pause", vous devrez mettre un mot de passe pour reprendre la tâche.En cas de redémarrage de SABnzbd cet écran disparaîtra automatiquement!En cas d'échecs de connexion, la file d'attente des téléchargements sera mise en pause pendant quelques minutes au lieu de passer au serveur suivant.Dans les dossiersFlux incompatibleFichier de file d'attente incompatible, impossible de continuerDossier incompletSéquence incomplète des fichiers à fusionnerDescription du flux RSS incorrecte "%s"Paramètre incorrectEncodage mot de passe incorrect %sAugmenter les performances en forçant un cryptage SSL plus faible.Catégories de l'indexeur / GroupesLes indexeurs peuvent fournir une catégorie à l'intérieur du NZB que SABnzbd tentera de faire correspondre aux catégories définies ci-dessous. En outre, vous pouvez ajouter des termes à "Catégories de l'indexeur / Groupes" pour faire correspondre plus de catégories. Utilisez des virgules pour séparer les termes. Les caractères génériques sont pris en charge.
Plus d'informations peuvent être trouvées sur le Wiki.Bande passante InternetFichier NZB %s invalide, sera ignoré (erreur : %s)Archives de sauvegarde non validesParamètres ou fichiers PAR2 non valides, impossible de vérifier ou réparer.Adresse du serveur erronéeParamètres serveur incorrectsÉtape de journalisation invalide dans l'historique pour %sIncidentsIl est recommandé de faire un clic-droit et d'ajouter cette page à vos favoris pour accéder à SABnzbd quand il tourne en arrière plan.La tâche "%s" est probablement chiffrée en raison d'un RAR ayant le même nom à l'intérieur de ce RARLa tâche "%s" est probablement chiffrée : "password" dans le nom de fichier "%s"Nom de la tâche en tant que nom de fichierLa tâche a échouéTâche terminéTâchesLes tâches seront décompréssées pendant le téléchargement pour réduire le temps de post-traitement. Fonctionne uniquement pour les tâches qui ne nécessitent aucune réparation.ConcaténerConcaténationConserver toutes les tâchesRaccourcis clavierLangueLancer le navigateur web au démarrageLance le navigateur web par défaut au démarrage de SABnzbd.Limiter la vitesseListe des extensions de fichiers qui doivent être supprimés après le téléchargement.
nfo ou nfo, sfvChat en directChargementEchec du chargement de %sAdresse IPv4 localeLe stockage des données locales (cookies) est désactivé dans votre navigateur, les réglages de l'interface seront perdus lorsque vous fermerez votre navigateur !Emplacement de la file d'attente et de la base de données d'historique.
Ne peut être changé que lorsque la file d'attente est vide.Emplacement des fichiers journaux de SABnzbd.
Redémarrage requis !Emplacement des téléchargements terminés et post-traités.
Peut être outrepassé par les catégories définies par l'utilisateur.Emplacement de stockage des téléchargements non-traités.
Modifiable uniquement si la file d'attente est vide.Emplacement où les fichier .nzb seront archivés.Emplacement où sont stockées les sauvegardes du fichier de configuration et des bases de données.
Si laissé vide, la sauvegarde sera créée dans le Dossier des téléchargements terminés.Dossier du fichier journalSe connecterSe déconnecterJournalisationConnexion au serveur %s [%s] à partir de trop d'adresses IP différentes - https://sabnzbd.org/multiple-adressesConnexion à SABnzbd perdue...BasseMinusculeRendre Windows compatibleCorrespondVitesse maximale de la ligneNombre maximal de tentatives par serveurNombre de tentatives maximumSignificationMinimalMinimal: lorsque SSL est activé, vérifier l'identité du serveur à l'aide de ses certificats. Strict: vérifier et imposer le nom d'hôte correspondant.Taille minimale du fichierEspace libre minimum pour le dossier des téléchargements terminésEspace disque minimum pour le dossier de téléchargement temporaireArticles manquantsModéréLes navigateurs web modernes et les autres clients n'accepteront pas les certificats auto-signés et donneront un avertissement et / ou ne se connecteront pas du tout.LundiMoisPlusDéplacer tous les tâches terminées vers les archivesDéplacer et renommer tous les épisodes de la catégorie "tv" vers un dossier de série spécifiqueDéplacer et renommer tous les films de la catégorie "films" vers un dossier de film spécifiqueDéplacer les tâches vers les archives après le nombre de jours spécifiéDéplacez les tâches vers les archives si l'historique dépasse le nombre de tâches spécifiéNom du filmTri des filmsNom.FilmNom_FilmFilmsDéplacementDéplacement en cours...Multi-OperationsÉtiquette multi-blocClé NZBNZB ajouté à la file d'attenteNomNameserver / DNS LookupAppellationLe chemin réseau "%s" ne devrait pas être utilisé iciJamaisSuiv.Prochain scan àParamètres 'Nice'Aucun accèsAucun modèle email trouvésPas de dossiersAucun fichier rar antérieur correspondant pour %sAucun destinataire déterminé, aucun email envoyéAucune méthode d'authentification appropriée n'a été trouvéAucunNormaleNe correspond pasNon disponibleCentre de notificationScript de notificationNotification envoyée !Le script de notification "%s" est introuvableNotificationsNotifyOSDNombre de secondes entre chaque scan du dossier pour vérifier la présence de fichiers .nzb.Mot de passe du compte (facultatif)Identifiant (facultatif)DésactivéAncienne file d'attente détectée, utiliser Statut-> Réparation pour convertir la file d'attenteEn fin de file d'attenteScript de fin de file d'attenteA quel jour du mois ou de la semaine (1=lundi) votre fournisseur réinitialise le quota ? (Optionnel avec hh:mm)Une ou plusieurs URL Apprise n'ont pas pu être chargées.Télécharger uniquement les articles en tête de file d'attenteSeul l'accès extérieur nécessite un identifiantDécompresser et lancer les scripts uniquement sur les tâches qui ont passé l'étape de vérification. Si désactivé, toutes les tâches seront marquées comme Terminées même si elles sont incomplètes.Ouvrez une fenêtre de Terminal et tapez la ligne (exemple) :Ouvrir le dossier des completsOuvrir le dossierOptionnelNZB supplémentaire optionnelMot de passe pour l'authentification (facultatif).Nom d'utilisateur pour l'authentification (facultatif).Vous pouvez également indiquer un nom de fichierOu glissez-déposez des fichiers sur la fenêtre!OrdreNom de fichier originelNom d'origine de la tâcheTâches orphelinesAutre / InconnuAutres messagesRemplacez les URL par défaut pour les types de notifications spécifiques ci-dessous, si vous le souhaitez.PROPAGATION %s minParamètresNuméro de blocMot de passeFichier de mot de passeMot de passe masqué en ******, veuillez le ressaisir.Protégé par un mot de passeChemin d'accèsModèleModèle de cléMettre en pauseSuspendre toutMettre en pause les téléchargements lors du post-traitementPause deMettre en pause pendant 1 heureMettre en pause pendant 15 minutesMettre en pause pendant 3 heuresMettre en pause pendant 30 minutesMettre en pause pendant 5 minutesMettre en pause pendant 6 heuresMettre en pause pour…Mettre en pause les tâches de priorité hauteMettre en pause les tâches ayant une catégorieMettre en pause les tâches de priorité faibleMettre en pause les tâches de priorité normaleMettre en pause le post-traitementEn pauseLa tâche "%s" a été mise en pause à cause d'un fichier RAR chiffré (tous les mots de passe fournis ont été essayés)Met en pause les téléchargements au début du post-traitement et les reprend à la fin.Mise en pause du doublon NZB "%s"Pourcentage de la vitesse de la ligneSupprimer définitivement (ignorer l'archivage)Permissions pour le dossier de téléchargements terminésLe réglage des permissions de %s pourrait refuser à SABnzbd l'accès aux fichiers et dossiers qu'il crée.Clé API personnelleClé API personnelle pour Prowl (obligatoire)Notes personnellesS'il vous plaît soyez conscient que l'Hôte 0.0.0.0 aura besoin d'une adresse IPv6 pour les accès externesEntrez les informations de votre principal fournisseur usenet.PortPort que SABnzbd doit surveiller.Échec du post-traitement pour %s (%s)Post-traitementNe post-traiter que les tâches vérifiéesPost-traitementPost-traitement démarréLe post-traitement a été interrompuLes publications seront mises en pause jusqu'à ce qu'elles aient au moins cet âge. La tâche commence immédiatement si elle est passée en priorité Forcée.Le script de pré-file d'attente a marqué la tâche comme échouéeScript utilisateur de pré-file d'attenteModèles prédéfinisAppuyez sur la touche Drapeau+R et tapez la ligne (exemple) :PrécédentPrioritéProblème avecRésultat traitéTraitement en coursLe programme n'a pas démarré !Délai de propagationProwlAdresse IPv4 publiqueVider les NZB terminésPurger les NZB échouésPurger les NZBs échoués & supprimer les fichiersVider l'historiquePurger les logsVider les NZBPurger les NZB & supprimer les fichiersPurger les NZBs de la page en coursVider la file d'attentePushbulletPushoverVersion de PythonLe script Python "%s" n'est pas configuré avec les permissions d’exécution (+x)File d'attenteMettre en file d'attente les 10 premiers articlesFile d'attente terminéeLimite des éléments de la file d'attenteLa file d'attente n'est pas vide, impossible de changer de dossier.Réparer la file d'attenteVérification rapide...Contrôle rapideDémarrage rapideQuitterQuotaQuota pour ce compte calculé à partir du moment où il est défini. En octets, éventuellement suivi de K,M,G.
Avertir quand il atteint 0, vérifié toutes les quelques minutes.Quota restantPériode du quotaQuota atteint, téléchargement mis en pauseEchec lors de la vérification des fichiers RARFichiers RAR vérifiés avec succèsRSSInvervalle de vérification RSSLe flux RSS %s était vide%s exécutéOptions rarement utilisées. Pour leur sens et leur explication, cliquez sur le bouton Aide pour accéder à la page Wiki.
Ne pas les modifier sans consulter le wiki en premier, car certaines ont de graves effets secondaires.
Les valeurs par défaut sont indiquées entre parenthèses.Lire tous les flux maintenantLire le flux RSSLire les flux RSSLire tous les flux RSSConsultez le Wiki pour plus d'info à ce sujet (en anglais) !Exception DBus reçue %sRafraîchirTaux de rafraîchissementConnexion refusée de:Connexion refusée avec le nom d'hôte "%s" à partir de :RejeterLes chemins relatifs des dossiers sont basés surRestantSe souvenir de moiSupprimer NZBSupprimer le NZB & supprimer les fichiersSupprimer le serveurSupprimer le trieurSupprimer tous les fichiers sélectionnésEffacer les tâches terminéesRetirer les tâches échouéesÉchec de la suppression de %sSuppression de la tâcheSuppression des tâchesRenommerRenommer la tâche annulera la Décompression Directe.RéparationÉchec de la réparation, pas assez de blocs de réparation (manque %s)Réparation en coursÉchec de la réparation, %sRéparation en cours...Refaire le testRemplacer les espaces dans les noms de dossierRemplacer les points dans les noms de dossierRemplace les points par des espaces dans les noms de dossierRemplace les espaces par des underscores ( _ ) dans les noms de dossiers.Remplacer les underscores dans le nom du dossierRemplacer les underscores par des points dans les noms de dossiersObligatoireObligatoireNécessite un compte ProwlNécessite un compte PushbulletNécessite un compte PushoverCatObligatoireRéinitialiserRéinitialiser le quota maintenantJour de RAZRésolution de l'adresseRedémarrerRedémarrer SABnzbdRedémarrer sans se connecterRedémarrage de SABnzbd en cours...Redémarrage suite au plantage de l'assembleurRedémarrage suite au plantage du téléchargeurRedémarrage suite au plantage du postprocesseurRétablir les valeurs par défautRestaurer la sauvegardeRésultatReprendreReprendre les tâches de priorité hauteReprendre les tâches ayant une catégorieReprendre les tâches de priorité faibleReprendre les tâches de priorité normaleReprendre le post-traitementReprise en coursDélai de rétentionRéessayerRéessayer tousRéessayez toutes les tâches échouéesExécution du scriptExécution de script en cours...Exécution du script utilisateur %sSABCTools désactivé: aucune version correcte n'a été trouvée ! (v%s trouvée, v%s attendue)SABnzbd %s démarréHôte SABnzbdMot de passe SABnzbdPort SABnzbdAssistant de configuration SABnzbdIdentifiant SABnzbdVersion de SABnzbdServeur web SABnzbdSABnzbd a détecté une erreur fatale :Arrêt de SABnzbd terminéSABnzbd a été démarré avec l'encodage %s, celui-ci devrait être UTF-8. Attendez-vous à des problèmes avec les noms de fichiers et de répertoires Unicode dans les téléchargements.SABnzbd fonctionnera dorénavant en arrière plan.Serveur SMTPProxy SOCKS5Echec de la commande SQL, voir le journalSSLChiffrements SSLSamediEnregistrerEnregistrer les modificationsL'enregistrement de %s a échouéEnregistrement..Analyser le dossier surveilléPlanification pour un serveur non existant %sPlanificationScriptLe code script de sortie est %sLe script a renvoyé le code de sortie %s et le résultat "%s"ScriptsDossier des scriptsRechercherNuméro de la saisonDossier de la saisonConnexion sécurisée au serveurSécuritéSélectionnez un mode et listez toutes les extensions (non) souhaitées. Par exemple: exe ou exe, comChoisir la langue de l'interface web.Cochez uniquement si votre fournisseur usenet permet les connexions SSL.Plage de dates sélectionnéeEnvoyer les notifications RSSRenvoyer dans la file d'attenteEnvoie un email quand un flux RSS ajoute un fichier dans la file d'attente.Envoie un email lorsque le disque dur est plein et que SABnzbd a été mis en pause.Envoyer des notifications en utilisant Apprise vers presque n'importe quel service de notification%s envoyé dans la file d'attenteSéparez les URL multiples par une virguleSériesTri des sériesSéries avec dates de diffusionServeurLe serveur %s a utilisé le quota spécifiéLe serveur %s expirera dans %s jour(s)Le serveur %s utilise un certificat de sécurité HTTPS non authentifiéLe serveur %s utilise un certificat peu fiable [%s]Le serveur %s sera ignoré pendant %s minutesDétails du serveurL' adresse du serveur "%s:%s" n'est pas valide.Adresse du serveur requiseLe serveur n'a pas pu terminer la requêteDescription du serveurResolution du nom de serveur impossibleLe serveur requiert un identifiant et un mot de passe.Erreur du côté serveur (code serveur %s) ; n'a pas pu obtenir %s sur %sServeursAppliquer ce modèle de permissions aux fichiers/dossiers téléchargés.
En notation octale. Par exemple : "755" ou "777"Entrez le serveur de courrier sortant de votre FAI.La configuration est terminée!Maj+flèche : parcourir les pages de la file d'attente et de l'historiqueLe téléchargement devrait-il reprendre après que le quota soit réinitialisé ?Afficher ToutAfficher les archivesAfficher les échouésAfficher le journalNom de la sérieAfficher les connexions activesAfficher les détailsAfficher le dossierAfficher l’interfaceNom.SérieNom_SérieArrêterÉteindre le PCArrêter SABnzbdArrêt en cours...Signal %s intercepté, enregistrement et fermeture en cours...TailleDétection intelligente des doublonsCertains fichiers n'ont pas pu être vérifiés "%s"Désolé, nous n'avons pas pu interpréter ça. Essayez encore.Chaîne de caractères de triTrier par % téléchargé Most→LeastTrier par âge Plus récent→Moins récentTrier par Age Moins récent→Plus récentTrier par nom A→ZTrier par nom Z→ATrier par taille Plus grand→Plus petitTrier par taille Plus petit→Plus grandTriageSourceSpécialVitesseAccélérez les réparations en installant par2cmdline-turbo, il est disponible pour de nombreuses plateformes.Limite de vitesseMettre le PC en veilleLancer l'assistantRéparation en coursDémarrage/ArrêtStatutOptions de statut et d'interfaceArrêterArrêt en cours...StrictSoumettreDimancheSoutenez le projet, faites un don !Erreur suspecte dans le téléchargeurSwitchesDossiers systèmePerformance du système ( Pystone )Charge du systèmeTEXTETROP VOLUMINEUXMise en page par onglets
(file d'attente et historique séparés)Taguer la tâcheDossier temporaireDossier temporaire de téléchargementDonnées de testEmail de testTest de NotificationTester le serveurTester le téléchargementTest des détails du serveur en cours...Ceci redémarre SABnzbd et fait une complète reconstruction
de la file d'attente, tout en conservant les fichiers déjà téléchargés.
Ceci modifiera l'ordre de la file d'attente.Le dossier des téléchargements terminés ne peut pas être le même dossier que les téléchargements temporaires, ni être l'un de ses sous-dossiersLa case à cocher à coté du nom du flux doit être cochée pour que le flux soit activé et qu'il soit pris en compte dans la vérification des nouveaux téléchargements.
Quant un flux est ajouté, seuls les nouveaux téléchargements seront pris en compte à moins de cliquer sur "Forcer téléchargements".Le nom d'hôte n'est pas défini.Le nombre de connexions autorisées par votre fournisseur usenetLa file d'attente sera triée toutes les 30 secondes si le % de téléchargement est sélectionné.Le serveur n'a pas répondu correctement au protocole d'identification "hello"Il n'y a aucun serveur actif !Aucune connexion n'est configurée. Veuillez définir au moins une connexion.Il y a des dossiers orphelins dans le répertoire de téléchargement.
Vous pouvez choisir de les supprimer (y compris les fichiers) ou de les renvoyer dans la file d'attente.Cette clé permettra aux programmes tiers de pouvoir ajouter des NZB à SABnzbd.Cette clé permettra aux programmes tiers d'avoir un accès complet à SABnzbd.Ce moisCeci évite les réparations multiples en téléchargeant tous les fichiers par2 nécessaires.Ce serveur n'authorise pas de connexion SSL sur ce portCette semaineCeci redémarrera SABnzbd.
Utilisez cette fonction si vous pensez avoir un problème de stabilité.
Les téléchargements en cours seront mis en pause puis repris.Ceci enverra un email de test sur votre compte.JeudiDélai dépasséDélai dépassé : essayez d'activer SSL ou de vous connecter sur un port différent.Délai d'expirationTitrePour éviter tous les avertissements utiles, désactivez le paramètre spécial 'helpful_warnings'.A : %s De : %s Date : %s Sujet : Alerte SABnzbd : disque plein Salut, SABnzbd a arrêté le téléchargement car le disque est presque plein. Merci de faire de la place avant de reprendre manuellement le téléchargement sous SABnzbd. Aujourd'huiEspace disque faible, PAUSE forcéeTrop de connexions au serveur %s [%s]Trop de connexions, veuillez mettre en pause le téléchargement ou essayer plus tardTout en hautTotalRésoudre les problèmesTente de prédire la réussite de la tâche avant le téléchargement complet (plus lent !)Tentative 7zip avec le mot de passe "%s"Essai avec le renommeur RARTentative de vérification RAREssai vérification SFVEssai de récupération du NZB depuis %sTest de l'état du serveur inexistant %sTentative d'extraction avec le mot de passe "%s"MardiRéglagesTypeINDÉSIRABLEÉchec de récupération de l'URL ; %sL'URLGRABBER A PLANTÉImpossible de lier le port %s sur %s. Un autre logiciel utilise le port ou SABnzbd est déjà en cours d'exécution.Accès non autoriséDébloquerServeur non défini !Erreur inconnue lors du décodage de %sProtocole SSL inconnu: essayez de désactiver SSL ou de vous connecter sur un autre port.Action inconnue : %sÉchec d'authentification inconnu dans le serveur de messagerieDécompresserDécompresser les archives (rar, zip, 7z) à l'intérieur des archives.Arborescence trop profonde dans le fichier compressé [%s]%s fichiers/dossiers extraits dans %sExtractionÉchec de l'extraction, %sÉchec de l'extraction, erreur CRCÉchec de l'extraction, l'archive nécessite un mot de passeLa décompression a échoué, le fichier est trop volumineux pour le système de fichiers (FAT ?)Extraction échoué, le chemin est trop longÉchec de l'extraction, %s n'a pas été trouvéÉchec de l'extraction, erreur d'écriture ou espace disque insuffisant ?Echec de la tentative de connexion de %sFichier NZB inutilisableFichier RAR inutilisableExtension non souhaitée dans le fichier %s (%s)L'extension indésirable est dans le fichier rar %sExtensions indésirablesMise à Jour disponible!Uploader le NZBUpload en coursTemps de fonctionnementUtilisez le tri pour organiser et renommer automatiquement vos téléchargements terminés.Utilisez une virgule et/ou un espace pour identifier plusieurs URL.Utiliser les paramètres globaux de l'interfaceUtiliser des noms temporaires pendant le post-traitement. Désactiver lorsque votre système ne le gère pas correctement.Utiliser le proxy SOCKS5 spécifié pour toutes les connexions sortantes.Utilisé avant qu'un NZB n'entre dans la file d'attente.Cache utiliséDossiers utilisateurClé utilisateurClé utilisateur (obligatoire)Utilisateur connectéUtilisateur connecté à l'interface webLe script utilisateur peut signaler la tâche comme échouéeNom d'utilisateurValeursVérifié avec succès en utilisant des fichiers SFVVérifier les certificats lors de la connexion aux indexeurs et sources RSS utilisant HTTPS.Vérification en coursVérification de la réparationVérification...VersionTrès basAfficher le journal des scriptsPATIENTER %s secAVERTISSEMENT :En attenteAvertir 5 jours avant la date d'expiration du compte.AvertissementAvertissementsDossier à surveillerIntervalle de scanInterface WebThème de l'interface webMercrediS'il apparait clairement pendant le téléchargement qu'il manque trop de données, annuler la tâcheLorsque le script de l'utilisateur renvoie un code de sortie "non-zéro", la tâche sera signalée comme échouée.Lorsque vous réessayez une tâche, la "Détection des doublons" et "Abandonner les travaux qui ne peuvent pas être terminés" sont désactivés.La session expirera quand votre adresse IP changera ou quand SABnzbd sera redémarré.Quel est le pourcentage de la vitesse de la ligne que SABnzbd doive utiliser, par exemple 50Quel script devons-nous utiliser pour les notifications ?Liste blancheQui doit-on indiquer comme expéditeur de l'email ?WikiNe fonctionnera pas si un dossier de catégorie se trouve sur un autre disque.Notifications WindowsAnnéeVous pouvez définir des droits d'accès pour les systèmes en dehors de votre réseau local.Vous devez définir une bande passante maximale avant de pouvoir définir une limite de bande passanteVotre version de UNRAR est %s, nous recommandons la version %s ou plus.
Votre fichier de mot de passe contient plus de 30 mots de passe. Tester tous ces mots de passe prend beaucoup de temps. Essayez de n'y lister que les mots de passe utiles.Votre clé API Pushbullet personnelle (obligatoire)[%s] Erreur "%s" lors de la concaténation des fichiers[%s] Erreur "%s" lors de l'extraction des fichiers RAR[%s] %s fichiers fusionnés[%s] Pas de fichiers par2[%s] PAR2 a reçu des paramètres incorrects, vérifiez dans Configuration-> Paramètres Switches[%s] Contrôle rapide OK[%s] La vérification RAR a échoué: %s[%s] Réparé(s) dans %s[%s] La commande dans build_command n'est pas définie.[%s] Vérifié dans %s, tous les fichiers sont corrects[%s] Vérifié dans %s, réparation nécessairearticlesLettre Capitalejjourjoursdésactiver le serveuractiver le serveurfichierhheureheuresrestantmmanuelminminsnonouioupagebinaire par2... Introuvable!attributsecsecondesvoir le journaltextebinaire unrar... Introuvable!semaine././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993698.8996089 SABnzbd-4.3.2/locale/es/LC_MESSAGES/SABnzbd.mo0000644000000000000000000022250114625637243017500 0ustar00runnerstaffT8o8d8b: \;i<]='G>o>> >>>? ???#?+?1>?p?A???P@@@@R@[ AgA#yAVAAB$.BSB ZBhB'oB'BBBB B B BjBgC}CCCC'CtC?DUDhDoDD D*D D DDEEE/'E WEcE=E%F>FCF%JF#pFF FFFFFGMGgG G GGGH!!H6CH-zHHH"H6H/I KIVIG_IlI<JQJ.jJ'J JJJJKSK iKvKKK"K8KK LL 2Ldc-c9c dd (d5d6:dvqddGkee"ee<fE>fDf ff,fg%%g#Kgogg@gg<h=i)PiFziii'ijjHj;j/k Dk Ok\k}ak kk kl l5#l YlnellllqmcsmHmo n]n)n o#o*o2o:oWo [ofo~oo$ooooo0dpppppp p p p pp pqqq-q2qJqQqWq\q lqvq q#q"q+q rr r %r3rGr[r'nr r r/rrrs;sRscbs"s#s3 tAtVt_t!yt!tt%tuuu +u9uHu [u furu {u*u uuu uu u(u vv,vAvSvhv|v vvvvvwwUwMswww#wx%*xPxR_x<xxx"y6yFyfyvyjy%yz5z-=zkztz }zz zzzzzzz { 1{ ?{J{d{ { {{{<{{{ ||&*| Q|^|m|||| | | |||||}+}2}$~ 7~A~P~c~~~ ~+~~~   # =Ke{  2   )5R)m0Ȁр $06 FPbjz'(΁+#4;B\v‚˂ڂ !H8  ڃ.H.Ʉ  $09 >K\e#y ,ƅ ; D4e3Ć3,!=_n-u,(Ї$-!Egz&:o)q3  *7 F PZ co '(. --M${$1ŋ1)18@ F Q \iy ƌ͌Ԍ %B G/Q   ̍ ؍2ˏ5A4v>=: xM+ё ,ْ >+39"&A= Eܔ1.M|ѕaFZbtJߖ- /'Wt -ϗ6"4#W.{"͘ߘ"$9M _ jt{b$ ! ,9BV#e"%L /9 JW_h x ϛ ݛRU:M=ޜ0!MotEB՝+#̞)/JA&ǟ/۟& '2Z cqsw|  Ơɠ̠Ѡ "'w-J -#9$V {7 ԩ  6'!^EƪMS g׫[?,~۬!Z|G.+1] eq ?]f|.Fe"$ϰ 0K T>a SQ"Ȳϲ%#(,Udlu%&4.[3!#-.2PaF& $4XY& ٶ \MT@/^( ø߸ Zu/˹@<M^ y#u&?8$x!. )7>Hv`ۼ < I SK_ ν۽' 6 ?M*e& Ͼ$۾*:<T H< CMI#+O%m 76#, PZn!1 A 8%C iv ~ # != W ep !2T$t8#n% G>Pe{&2*2;An,$)Hh A  !;Y p!~)/3-(a-)&,&'S{*.#%+7%c&*( ""Cf  $0JNg+8/7)gE;EB3 LF%QlT.>U Z hs{ &R>S 4 %!2TZ $ 2 7 Abz;+1>I/G  .;7s f,+X_uOO%uG'+D)ZJn0Z#9:X zaXz,!( A#ew"(~>zW8n%1(; @L iw* A6I\ e q & 3<6L,> 2J)c B $Q,~c;208c.54jp  2L\aiq x* !1S!s#|KY!# <fMB'&E(T} SF ;   4?\v|# #' K XclU~! 6* an+- 9=Vt 1% BM;j# )1[y S .8 Vc.t$?FOX"s  .M-d-/ #!!E#g%  0 ;Mbr 0&Biy$3 ' #/ S%`+&N>F\c{ *8 ?:Oz5!AW*3&/5e*+a 8|C6!> Xe z     , F 0N I  ; ; *P *{ A A  * 7 >  G Q  f s          ) % D M #e   A    # 3 K [ #n  Yq/6C;QK#otx+ %*BUu}E(I-rKS%e) 7/+[bj ozu' <H-`YJ K<XF*1AN_.-LM-+@"c{ "qAQ#6"Yk6sN "1:C[j q { +  Q}?FU 6Z -    ` GA!!1." `","""Y"<#2T##3#3#*$ .$9$P$R$W$]$s$$$$$$$$$$ $$$$$$$%%%:% SABnzbd cannot find its web interface files in %s.
Please install the program again.

SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s is not a correct octal value%s is not a valid email address+ Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder0 is highest priority, 100 is the lowest priority7za binary... NOT found!
If authentication is enabled, you will need to login again.NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!API (no Config)API KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:API key for ProwlAbort jobs that cannot be completedAborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Aborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccess deniedActionAction when encrypted RAR is downloadedAction when unwanted extension detectedAddAdd NZBAdd NZB files Add ScheduleAdd ServerAdded NZBAdds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup.Administrative FolderAdvancedAffected CategoriesAgeAllAll files will go into a single folder.All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings.Allow proper releasesAlso test releasesAlwaysApplication TokenApplication token (required)Apply filtersAre you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAt leastAt mostAuthentication failed, check username/password.Auto resumeAuto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically sort jobs in the queue when a new job is added.Automatically sort queueBackBackupBad response from Pushbullet (%s): %sBad response from Pushover (%s): %sBad schedule %s at %s:%sBandwidthBottomBrowseCache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"CancelCannot access PID file %sCannot change permissions of %sCannot connect to server %s [%s]Cannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot read %sCannot read Watched Folder %sCannot send, missing required dataCannot write to History database, check access rights!Cannot write to INI file %sCategoriesCategoryCategory folder cannot be a subfolder of the Temporary Download Folder.Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue.Certificate not valid. This is most probably a server issue.Certificate verificationChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check allCheck before downloadCheck for New ReleaseCheckingChecking extra filesChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Cleanup ListCleanup of %s failed.ClearClear CountersClick to test the entered details.Closing any browser windows/tabs will NOT close SABnzbd.Compact layoutComplete FolderComplete folder speedCompletedCompleted Download FolderCompleted Download Folder %s is on FAT file system, limiting maximum file size to 4GBConfigConfig FileConfiguration locked, cannot save settingsConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s failed, message=%sConnection Successful!Connection failed!ConnectionsCorrupt RAR fileCould not determine connection result (%s)Could not load additional certificates from certifi packageCurrent SchedulesCurrent umask (%o) might deny SABnzbd access to the files and folders it creates.CustomDUPLICATEDailyDamaged History database, created empty replacementDate SortingDate formatDay of monthDecadeDecoder failure: Out of memoryDefaultDefault Base FolderDeleteDelete AllDelete after downloadDelete all items from the queue?Deleting %s failed!Deobfuscate final filenamesDeviceDevice to which message should be sentDevice(s)Device(s) to which message should be sentDirect UnpackDirect Unpack was automatically enabled.Disable quota managementDisabledDisabled HTTPS because of invalid CERT and KEY filesDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue.Disconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk fullDisk full! Forcing PauseDo an extra verification based on SFV files.Do not have valid authentication for feed %sDoes the quota get reset each day, week or month?DownloadDownload CompletedDownload FailedDownload all par2 filesDownload failed - Not on your server(s)Download folder speedDownload might fail, only %s of required %s availableDownloadedDownloaded in %s at an average of %sB/sDuplicate NZBE.g.E.g. 8 or 20ENCRYPTEDERROR:Edit NZB DetailsEmailEmail Notification On Job CompletionEmail RecipientEmail SenderEmail Templates FolderEmail address to send the email to.Email succeededEmergencyEmergency expireEmergency retryEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable 7zipEnable HTTPSEnable NotifyOSDEnable Prowl notificationsEnable Pushbullet notificationsEnable Pushover notificationsEnable SFV-based checksEnable Windows NotificationsEnable accessing the interface from a HTTPS address.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable notification scriptEnable quota managementEnable recursive unpackingEnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameErrorError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error creating SSL key and certificateError importing %sError loading %s, corrupt file detectedError removing %sError renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyErrors/WarningEssential modules are missing, downloading cannot start.Executes a custom scriptExit SABnzbdExtensionExternal internet accessExternal process priorityExtra PAR2 ParametersExtracting...Fail job (move to History)FailedFailed login for server %s [%s]Failed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s with reason: %sFailed to initiate TLS connectionFailed to move filesFailed to read the password file %sFailed to rename similar file: %s to %sFailed to retrieve RSS from %s: %sFailed to send Prowl messageFailed to send Windows notificationFailed to send e-mailFailed to send macOS notificationFailed to send pushbullet messageFailed to send pushover messageFailed to standby systemFailed to start web-interfaceFailed to start web-interface: Failed to upload file: %sFailing duplicate NZB "%s"Failure in tempfile.mkstempFatal errorFatal error at saving stateFatal error in AssemblerFeedFetchFetch NZB from URLFetchingFetching %s blocks...Fetching extra blocks...File containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File not on serverFile setFilenameFilterFilter out sample files (e.g. video samples).Folder containing user scripts.Folder containing user-defined email templates.Folder to monitor for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.For servers: make sure names are compatible with Windows.For unreliable servers, will be ignored longer in case of failuresForceForce DisconnectForce DownloadForcing disconnectForumFree SpaceFrequencyFridayFrom Show SxxEyyFrom SxxEyyFull APIFull Web interfaceFurther help can be found on ourGeneralGenerate New KeyGenerate new self-signed certificate and key. Requires SABnzbd restart!Glitter has some (new) features you might like!Go to SABnzbdGo to wizardHTTP and HTTPS ports cannot be the sameHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS certificate verificationHelpHelp us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:Hibernate PCHide detailsHide/show completed filesHighHistoryHistory Last 10 ItemsHistory RetentionHistory item limitHold shift key to select a rangeHomeHome pageHostHost SABnzbd should listen on.How long or untill when do you want to pause? (in English!)How many seconds your notification will continue to be retriedHow much can be downloaded this month (K/M/G)How often (in seconds) the same notification will be sentINCOMPLETEIONice ParametersIPv6 addressIdleIf empty, the standard port will only listen to HTTPS.If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name.If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface.If you get this error message again, please try a different number.
Ignore SamplesIgnore any folders inside archivesIgnoring duplicate NZB "%s"In "%s" unwanted extension in RAR file. Unwanted file is %s In case of "Pause", you'll need to set a password and resume the job.In case of SABnzbd restart this screen will disappear automatically!In foldersIncompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrectly encoded password %sIncrease performance by forcing a lower SSL encryption strength.Indexer Categories / GroupsIndexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.Internet BandwidthInvalid NZB file %s, skipping (error: %s)Invalid par2 files or invalid PAR2 parameters, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sIssuesIt is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" is probably encrypted due to RAR with same name inside this RARJob "%s" is probably encrypted: "password" in filename "%s"Job Name as FilenameJob failedJob finishedJobsJobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair.Join filesJoiningKeep all jobsLanguageLaunch Browser on StartupLaunch the default web browser when starting SABnzbd.Limit SpeedList of file extensions that should be deleted after download.
For example: nfo or nfo, sfvLoadingLoading %s failedLocal IPv4 addressLocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!Location for queue admin and history database.
Can only be changed when queue is empty.Location of log files for SABnzbd.
Requires SABnzbd restart!Location to store finished, fully processed downloads.
Can be overruled by user-defined categories.Location to store unprocessed downloads.
Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLog inLog outLoggingLost connection to SABnzbd..LowLower CaseMake Windows compatibleMatchedMaximum line speedMaximum number of retries per serverMaximum retriesMeaningMinimalMinimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname.Minimum Free Space for Temporary Download FolderMissing articlesModerateMondayMonthMoreMovie NameMovie SortingMovie.NameMovie_NameMovingMoving...Multi-OperationsNZB KeyNZB added to queueNameNameserver / DNS LookupNamingNeverNextNice ParametersNo accessNo email templates foundNo foldersNo matching earlier rar file for %sNo recipients given, no email sentNo suitable authentication method was foundNoneNormalNot MatchedNot availableNotification CenterNotification ScriptNotification Sent!Notification script "%s" does not existNotificationsNotifyOSDNumber of seconds between scans for .nzb files.OPTIONAL Account PasswordOPTIONAL Account UsernameOffOld queue detected, use Status->Repair to convert the queueOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly external access requires loginOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optionally specify a filenameOr drag and drop files in the window!OrderOriginal FilenameOriginal Job NameOrphaned jobsOther MessagesPROPAGATING %s minParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause forPause for 1 hourPause for 15 minutesPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for...Pause high priority jobsPause jobs with categoryPause low priority jobsPause normal priority jobsPause post-processingPausedPaused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)Pauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Percentage of line speedPermissions for completed downloadsPersonal API keyPersonal API key for Prowl (required)Personal notesPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter in the details of your primary usenet provider.PortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-processingPost-processing startedPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue script marked job as failedPre-queue user scriptPresetsPress Startkey+R and type the line (example):PreviousPriorityProblem withProcessed ResultProcessingProgram did not start!Propagation delayProwlPublic IPv4 addressPurge Completed NZBsPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge NZBs on the current pagePurge QueuePushbulletPushoverPython VersionPython script "%s" does not have execute (+x) permission setQueueQueue First 10 ItemsQueue finishedQueue item limitQueue not empty, cannot change folder.Queue repairQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRAR files failed to verifyRAR files verified successfullyRSSRSS Checking IntervalRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead all RSS feedsRead the Wiki Help on this!Received a DBus exception %sRefreshRefresh rateRefused connection with hostname "%s" from:RejectRelative folders are based onRemainingRemember meRemove NZBRemove NZB & Delete FilesRemove ServerRemove all selected filesRemove completed jobsRemove failed jobsRemoving %s failedRemoving jobRemoving jobsRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Repeat testReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace spaces with underscores in folder names.RequiresRequires a Prowl accountRequires a Pushbullet accountRequires a Pushover accountRequiresCatResetReset Quota nowReset dayResolving addressRestartRestart SABnzbdRestart without loginRestarting SABnzbd...Restarting because of crashed assemblerRestarting because of crashed downloaderRestarting because of crashed postprocessorRestore DefaultsResultResumeResume high priority jobsResume jobs with categoryResume low priority jobsResume normal priority jobsResume post-processingResumingRetention timeRetryRetry allRetry all failed jobsRunning scriptRunning script...Running user script %sSABCTools disabled: no correct version found! (Found v%s, expecting v%s)SABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.SABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSSLSSL CiphersSaturdaySaveSave ChangesSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScriptScript exit code is %sScript returned exit code %s and output "%s"ScriptsScripts FolderSearchSeason NumberSecure connection to serverSecuritySelect a web interface language.Select only if your provider allows SSL connections.Send RSS notificationsSend back to queueSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Sent %s to queueSeperate multiple URLs by a commaSeries SortingServerServer %s uses an untrusted HTTPS certificateServer %s uses an untrusted certificate [%s]Server %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer could not complete requestServer descriptionServer name does not resolveServer requires username and password.Server side error (server code %s); could not get %s on %sServersSet permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"Set your ISP's server for outgoing email.Setup is now complete!Should downloading resume after the quota is reset?Show AllShow FailedShow LoggingShow NameShow active connectionsShow detailsShow interfaceShow.NameShow_NameShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSome files failed to verify against "%s"Sorry, we could not interpret that. Try again.Sort StringSort by Age Newest→OldestSort by Age Oldest→NewestSort by Name A→ZSort by Name Z→ASort by Size Largest→SmallestSort by Size Smallest→LargestSortingSourceSpecialSpeedSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStatus and interface optionsStopStopping...StrictSubmitSundaySupport the project, Donate!Suspect error in downloaderSwitchesSystem FoldersSystem Performance (Pystone)TEXTTOO LARGETabbed layout
(separate queue and history)Tag jobTemp FolderTemporary Download FolderTest EmailTest NotificationTest ServerTest downloadTesting server details...The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThe server didn't reply properly to the helo greetingThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis prevents multiple repair runs by downloading all par2 files when needed.This server does not allow SSL on this portThis weekThis will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToo little diskspace forcing PAUSEToo many connections to server %s [%s]Too many connections, please pause downloading or try again laterTopTotalTroubleshootTry to predict successful completion before actual download (slower!)Trying 7zip with password "%s"Trying RAR-based verificationTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUNWANTEDURL Fetching failed; %sURLGRABBER CRASHEDUnable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.Unauthorized accessUnblockUndefined server!Unknown Error while decoding %sUnknown SSL protocol: Try disabling SSL or connecting on a different port.Unknown action: %sUnknown authentication failure in mail serverUnpackUnpack archives (rar, zip, 7z) within archives.Unpack nesting too deep [%s]Unpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, archive requires a passwordUnpacking failed, file too large for filesystem (FAT?)Unpacking failed, path is too longUnpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unsuccessful login attempt from %sUnusable NZB fileUnusable RAR fileUnwanted Extension in file %s (%s)Unwanted extension is in rar file %sUnwanted extensionsUpdate Available!Upload NZBUploadingUptimeUse global interface settingsUse temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUser FoldersUser KeyUser Key (required)User logged inUser logged in to the web interfaceUser script can flag job as failedUsernameValuesVerified successfully using SFV filesVerify certificates when connecting to indexers and RSS-sources using HTTPS.VerifyingVerifying repairVerifying...VersionVery LowView Script LogWAIT %s secWARNING:WaitingWarningWarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWednesdayWhen during download it becomes clear that too much data is missing, abort the jobWhen the user script returns a non-zero exit code, the job will be flagged as failed.When your IP address changes or SABnzbd is restarted the session will expire.Which percentage of the linespeed should SABnzbd use, e.g. 50Which script should we execute for notification?Who should we say sent the email?WikiWindows NotificationsYearYou must set a maximum bandwidth before you can set a bandwidth limitYour UNRAR version is %s, we recommend version %s or higher.
Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords.Your personal Pushbullet API key (required)[%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] RAR-based verification failed: %s[%s] Repaired in %s[%s] The command in build_command is undefined.[%s] Verified in %s, all files correct[%s] Verified in %s, repair is requiredarticlescase-adjustedddaydaysdisable serverenable serverfilehhourhoursleftmmanualminminsoffonorpagepar2 binary... NOT found!secsecondssee logfiletextunrar binary... NOT foundweekProject-Id-Version: SABnzbd-4.3.1 PO-Revision-Date: 2020-06-27 15:49+0000 Last-Translator: Safihre , 2023 Language-Team: Spanish (https://app.transifex.com/sabnzbd/teams/111101/es/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: es Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2; SABnzbd no puede encontrar sus ficheros de la interfaz web en %s.
Por favor instala el programa de nuevo.

SABnzbd ha detectado información guardada de otra versión de SABnzbd
pero no puede ser reutilizada por la otra versión.

Tal vez quieras finalizar primero tu cola actual con la otra versión.

Tras ello, ejecuta este programa con la opción "--clean".
Esto eliminará la cola e historial actuales!.
SABnzbd leer el archivo "%s" SABnzbd ha detectado que el fichero sqlite3.dll no existe.

Algunos virus de de pésima calidad eliminan este fichero.
Por favor revisa la configuración de tu antivirus y quéjate a tu proveedor del AntiVirus. Tras ello reinstala SABnzbd.

SABnzbd necesita un puerto tcp/ip libre para su servidor web interno.
Se ha intentado en el puerto %s en %s, pero no está disponible.
Puede que otro software ya esté utilizando este puerto, o que SABnzbd ya esté en ejecución.

Por favor reinicia SABnzbd indicando un número de puerto diferente. SABnzbd necesita una dirección IP para su servidor web interno.
Has especificado una dirección inválida.
Valores seguros son localhost y 0.0.0.0

Por favor reinicia SABnzbd con una dirección o nombre de host correctos. SABnzbd se entrega SIN NINGUNA GARANTÍA. Este es un software libre, y eres bienvenido a redistribuirlo bajo determinadas condiciones. Está licenciado bajo la versión 2 ó posterior de GNU GENERAL PUBLIC LICENSE. %s artículos contenían duplicados inconexos%s artículos estaban mal formados.%s artículos no encontradosDirectorio %s: Error al acceder a %s%s no es un valor octal correcto%s no es una dirección de correo electrónico válida.+Depuración+Info+Eliminar+Reparar+DescomprimirDirectorio de Backups de .nzbs0 El prioridad más alta, 99 es la prioridad más bajaNo se encontró el binario de 7zaSi la autenticación esta activada, tendrás que conectarte de nuevo.NOTA: Los directorios se crean automáticamente al guardar. Puedes usar una ruta absoluta, exterior a los directorios predefinidos.Los datos no se moverán. Requiere queu SABnzbd sea reiniciado!API (sin Config)Clave APICódigo QR de la clave APIClave de API erróneo, favor ingresar la clave correcta desde Config->General en tu aplicacion externa:Falta clave de API, favor ingresar la clave desde Config->General en tu aplicacion externa:Clave API de ProwlTrabajos abortados no pueden ser completadosSe ha cancelado la tarea "%s" debido al archivo codificado RAR (se han probado todas las contraseñas, si se han suministrado)Abortado, No puede ser completadoAbortado, detectamos cifradosSe interrumpió la acción porque se detectó una extensión no deseadaAceptarAcceso denegadoAcciónAccion cuando un archivo RAR cifrado es bajadoAcción al detectar extensiones no deseadasAñadirAñadir NZBAñadir archivos NZB Añadir planificaciónAñadir servidorNZB añadidoAñade una prueba verificada NZB del tamaño especificado con datos aleatorios. Puede utilizarse para verificar su configuración.Directorio de administraciónAvanzadoCategorías AfectadasEdadTodosTodos los archivos irán en una sola carpeta .Todos los nombres de usuarios, contraseñas y llaves-API se eliminan automáticamente del registro y se incluye una copia de su configuración.Permitir comunicados adecuadosTambién libera de pruebaSiempreToken de aplicaciónToken de aplicación (obligatorio)Aplicar filtros¿Seguro que deseas detener SABnzbd?¿Estás seguro?ArgumentosLímite de cacheo de artículosIdentificador de artículoAl menosComo máximoAutenticación fallida, compruebe el usuario o la contraseña.Auto reanudarParar automáticamente cuando el espacio libre esté por debajo de este valor.
En bytes, opcionalmente seguido de K,M,G,T. Por ejemplo: "800M" ó "8G"Clasifique tareas de forma automática en la cola cuando se añade una tarea nueva.Cola de clasificación automáticaAtrásCopia de seguridadMala respuesta de Pushbullet (%s): %sMala respuesta de Pushover (%s): %sPlanificación incorrecta %s a las %s:%sAncho de BandaÚltimoExaminarCachear artículos en memoria para reducir el acceso a disco.
En bytes, opcionalmente seguido de K,M,G. Por ejemplo: "64M" o "128M"CancelarNo se puede acceder al archivo PID %sNo se puede cambiar los permisos de %sError en inicio de conexion a servidor %s [%s]No se puede crear copia de seguridad del archivo %sNo se pudo crear el directorio %sImposible crear directorio final %sNo se puede crear el archivo temporal para %sNo se pudo encontrar plantillas de email en %sNo se puede encontrar la plantilla web: %s, intentando con la plantilla estandarImposible iniciar el navegador, probablemente no se le haya encontradoNo se puede leer %sDirectorio Watched %s no se puede leerNo se ha podido enviar, faltan datosNo se puede escribir en la base de datos de historia, compruebe los derechos de acceso !No se puede escribir al archivo INI %sCategoríasCategoríaEl directorio Categoría no puede ser un subdirectorio del directorio de descargas temporal.Desajuste del certificado de nombre de equipo: el nombre de equipo del servido no está en la lista del certificado. Se trata de un problema con el servidor.El certificado no es válido. Probablemente se trate de un problema con el servidor.Verificación del certificadoNo se han guardado los cambios, y se perderán.Los cambios requieren reiniciar SABnzbd!Marcar todoChequear antes de descargarBuscar Nva VersiónVerificandoComprobando archivos extraIntervalo de Chequeo (en minutos, mínimo 15). No toma efecto si utilizas el Planificador!Lista de elementos a limpiarHa fallado la limpieza de %sLimpiarResetear contadoresHaz clic para probar los detalles introducidos.Si cierras las pestañas o el navegador, SABnzbd NO se cerrará.Diseño compactoCarpeta CompletaVelocidad completa carpetaCompletadoDirectorio de descargas completadasDirectorio de descargas completo %s está en el sistema de archivos FAT, y limita el tamaño de archivo máximo a 4GBConfig.Fichero de ConfigConfiguración bloqueada, no se puede guardar la configuraciónConfirmar eliminación del historialConfirmar eliminación de la colaHa fallado la conexión a %s@%s, el mensaje=%s¡Conexión exitosa!¡Ha fallado la conexión!ConexionesFichero RAR corruptoNo se pudo determinar el resultado de la conexión (%s)No se han podido cargar los certificados adicionales del paquete certifiTareas Programadas ActualesLa umask actual (%o) podría denegarle acceso a SABnzbd a los archivos y carpetas que este crea.PersonalizarDUPLICADODiariamenteLa base de datos del Historial está dañada, se ha reemplazado vaciándolaOrdenar por fechaFormato de fechaDía del mesDécadaFallo del decodificador: no hay memoriaPredeterminadoDirectorio base por defectoEliminarEliminar todoEliminar tras descargar¿Eliminar todos los elementos de la cola?¡Error al eliminar %s!Deobfuscar nombres de archivos finalesDispositivoDispositivo al que enviar el mensajeDispositivo(s)Dispositivo(s) a los que enviar el mensajeDescomprimir directamenteDescomprimir directamente se ha habilitado automáticamente.Gestión de cuotas DesactivarDeshabilitadoHTTPS deshabilitado debido a que los archivos CERT y KEY no son válidosHTTPS deshabilitado debido a la falta de archivos CERT y KEYDescartarDesconectar todas las conexiones activas a los servidores usenet. La conexiones volverán a abrirse tras unos segundos si hay elementos en la cola.Desconecta del servidor de Usenet cuando la cola está vacía, o pausada.Desconectar si la cola está vacíaNotificaciones de Disco LlenoError de disco al crear el archivo %sDisco llenoDisco lleno! Pausando la colaRealiza una verificación extra basada en ficheros SFV.No se encontró autenticación válida para el feed %s¿Cada cuánto se resetea la cuota?DescargarDescarga CompletadaLa descarga fallóDescargar todos los archivos PAR2Descarga fallida - No está en tu(s) servidor(es)La velocidad de descarga carpetaLa descarga fallo, solo %s de los %s requeridos estan disponiblesDescargadoDescargado en %s a una media de %sB/sDuplicar NZBPor ej.P.ej. 8 ó 20ENCRIPTADOERROR:Editar Detalles de NZBCorreoNotificación por email al terminarDestinatarioRemitenteDirectorio de plantillas de EmailDirección de correo electrónico a la que enviar el mensaje.Email exitosoEmergenciaExpiración de emergenciaReintento de emergenciaVacíaFichero NZB vacío: %sEntrada RSS vacía (%s)HabilitarHabilitar 7zipHabilitar HTTPSHabilitar NotifyOSDActivar notificaciones ProwlActivar notificaciones PushbulletActivar notificaciones PushoverHabilitar verificacion basada en SFVActivar notificaciones WindowsHabilia el acceso a la interfaz con una dirección HTTPSHabilitar renombrado de directoriosHabilitar para usar menos memoria. Deshabilitar para prevenir que trabajos que se ralentizen bloqueen la cola.Activar script de notificaciónHabilitar la administración de cuotaActivar descompresión recursivaHabilitadoTerminar la ruta con un * previene que se creen directorios de trabajo.Introduzca la URLNombre del capítuloNúmero del capítuloNombre.capítuloNombre_capítuloSe ha producido un errorError "%s" al ejecutar file_join en %sError %s al ejecutar par2_repair en el conjunto %sError "%s" al ejecutar rar_unpack sobre %sError %s al ejecutar par2_repair en el conjunto %sError %s: Necesitas introducir un usuario y contraseña válidos.Error al crear la llave SSL y el certificadoError importando %sError al cargar %s, archivo corruptoError al quitar %sError al renombrar "%s" a "%s"Error al añadir %s, eliminandoError al apagarel sistemaSólo ErroresErrores/AdvertenciasFaltan módulos imprescindibles, no se puede iniciar la descarga.Ejecutar un script personalizadoSalir SABnzbdExtensiónAcceso a internet externaPrioridad del proceso externoParámetros PAR2 extraExtrayendo...Tarea fallida (mover a historial)FallidoRegistraccion fallo para servidor %s [%s]Error al crear (%s)Error al mover %s a %sNo se pudo autenticar con el servidor de correoNo se pudo cerrar el base de datos, vea el registroNo se pudo cerrar la conexión de correoCompilación de regex para término fallo: %sNo se pudo conectar al servidor de correoError al hibernar el sistemaError al importar %s ficheros desde %sError al inicializar %s@%s con la razón: %sNo se pudo inicializar la conexión TLSError al mover ficherosError al leer el archivo de contraseña %sError al renombrar ficheros similares: %s a %sError al recuperar RSS desde %s: %sNo se pudo enviar el mensaje de ProwlFallo al mandar la notificación de WindowsNo se pudo enviar correo electrónicoFallo al enviar la notificación macOSNo se updo enviar el mensaje de PushbulletNo se pudo enviar el mensaje de PushoverError al suspender el sistemaError al iniciar la interfaz webError al iniciar la interfaz web: Error al subir archivo: %sFallo al duplicar NZB "%s"Fallo en tempfile.mkstempError graveError grave al guardar estadoError grave en el ensambladorCanalObtenerDescargar NZB desde URLRecuperandoRecuperando %s bloques...Recuperando bloques extra...Fichero que contiene todas las contraseñas a usar en ficheros RAR protegidos.Error al unir el fichero %sNombre de archivo o ruta al Certificado SSLNombre de archivo o ruta de acceso a la cadena de HTTPS.Nombre de archivo o ruta a la clave privada SSLEl fichero no se encuentra en el servidorConjunto de ficherosNombre de archivoFiltrarFiltra la descarga de ficheros de ejemplo (e.g. un sample de vídeo).Directorio que contiene secuencias de comandos del usuario.Directorio que contiene plantillas de email definidas por el usuario.Directorio a monitorizar en busca de ficheros .nzb.Directorio/RutaDirectoriosPara correos electrónicos con autentificación, poner el nombre de usuario.Para correos electrónicos con autentificación, poner la contraseña.Para los servidores : asegúrese de que los nombres son compatibles con Windows .Para los servidores poco fiables, se ignorará durante más tiempo en caso de fallosForzarForzar desconexiónForzar DescargaForzar la desconexiónForoEspacio libreFrecuenciaViernesDesde mostrar SxxEyyDe SxxEyyAPI completaInterfaz web completaPuedes encontrar más ayuda en nuestroGeneralGenerar nueva claveGenere un certificado autofirmado nuevo y una llave. ¡Requiere reiniciar SABnzbd!¡Glitter tiene alguna nueva funcionalidad que puede gustarte!Ir a SABnzbdIr al AsistenteLos puertos de HTTP y de HTTPS no pueden ser igualesCertificado HTTPSCadena de Certificados HTTPSClave privada SSLPuerto HTTPSValidación del certificado HTTPSAyuda¡Ayúdanos a traducir SABnzbd en tu idioma!
Traduce textos que aun no tienen ninguna traducción o mejora los que ya lo están traducidos aquí:Hibernar PCOcultar detallesOcultar/Mostrar ficheros completadosAltaHistorialHistórico últimos 10 elementosHistorial de retenciónLímite del historialMantén presionada la tecla shift para seleccionar un rangoInicioPagina principalEquipoDónde debería escuchar el Host de SABnzbd¿Durante cuánto tiempo quieres dejarlo pausado?Cuántos segundos continuará reintentándose su notificaciónCantidad de descarga permitida este mes (K/M/G)Con cuánta frecuencia (en segundos) se enviará la misma notificaciónINCOMPLETOParámetros IONiceDirección IPv6InactivoSi se deja vacío, el puerto estándar escuchará por HTTPSSi los nombres de archivo de archivos (grandes) en el directorio final están demasiado encriptadas o no tienen sentido, se volverán a renombrar con el nombre de la tarea.Si el host de SABnzbd o el puerto está expuesto al internet, su configuración actual le permitirá acceso externo total a la interfaz de SABnzbd.Si obtiene este mensaje de error consecutivamente, por favor inténtelo de nuevo con otro número.
Ignorar SamplesIgnorar cualquier carpeta dentro de archivosIgnorando NZB Duplicado "%s"Se ha encontrado una extensión no deseada en el fichero RAR "%s". El fichero no deseado es %s In caso de PAUSA, necesitara escribir una contrasena para continuar el trabajo.Esta ventana desaparecerá automáticamente una vez SABnzbd se haya reiniciado.En directoriosCanal IncorrectoSe ha encontrado un fichero de cola incompatible, no se puede continuarCarpeta IncompletaSecuencia incompleta de archivos a uniriaDescripción de canal RSS incorrecta "%s"Parámetro incorrectoContraseña incorrectamente codificado %sMejora el rendimiento forzando un cifrado SSL con una intensidad inferior.Categorías Indexer / GruposLos Indexer pueden suministrar una categoría dentro de NZB, que SABnzbd intentará emparejar con las categorías que se definen a continuación. Además, puede añadir términos a "Categorías Indexer / Grupos" para emparejar más categorías. Utilice comas para separar los términos. Se permite el uso de comodines en los términos.
Puede encontrar más información en la Wiki.Ancho de banda de internetFichero NBZ inválido: %s, omitiendo (razón=%s)Archivos par2 no válidos o parámetros PAR2 no válidos, no se puede verificar ni repararDirección del servidor no válida.Detalles de servidor invalidosRegistro de etapa invalido para transferencia terminada %sProblemasSe recomienda que guardes esta ubicación como favorito y la añadas a tu navegador para acceder a SABnzbd cuando quieras.La tarea "%s" está codificada probablemente debido al RAR con el mismo nombre dentro de este RARLa tarea "%s" está probablemente codificada: "contraseña" en el nombre de archivo "%s"Nombre de la tarea para el nombre de archivoTrabajo fallidoTarea finalizadaTareasLas tareas comenzarán a descomprimirse durante la descarga para reducir el tiempo de procesamiento posterior. Solamente para las tareas que no necesitan reparación.Unir ficherosUniendoMantener todas las tareasIdiomaLanzar navegador al ArrancarEjecuta el navegador por defecto del sistema al arrancar SABnzbd.Limitar VelocidadLista de extensiones de archivo que se deben eliminar después de la descarga
Por ejemplo : . nfo o nfo, sfv < /b>CargandoCargar de %s no se pudo completar.Dirección IPv4 localTu buscador de internet tiene las cookies desactivadas, la configuración de la interfaz se perderá si cierras el explorador.Ubicación de la base de datos de historial y administración.
Sólo se puede cambiar si la cola está vacía.Ubicación de los ficheros de log para SABnzbd.
Requiere reiniciar SABnzbd!Ubicación donde guardar descargas finalizadas, totalmente procesaddas.
Puede ser obviado debido a categorías definidas por el usuario.Localización donde guardar descargas incompletas.
Sólo se puede cambiar si la cola est&aa; vacíUbicación donde se guardarán los ficheros .nzb.Directorio de HistorialIniciar sesiónCerrar sesiónRegistros de sucesosSe ha perdido la conexión con SABnzbd..BajaMinúsculasHacer compatible con WindowsEncontrado(s)Velocidad máxima de líneaMáximo número de reintentos por servidorReintentos máximosSignificadoMínimoMínimo: cuando se habilita el SSL, verifica la identidad del servidor utilizando sus certificados. Estricto: verifica y obliga a que el nombre de equipo sea equivalente.Espacio libre mínimo para el directorio de descargas temporalesArtículos no encontradosModeradaLunesMesMásNombre de PelículaClasificación de películasNombre.de.peliculaNombre_de_peliculaMoviendoMoviendo...Op.MúltiplesClave NZBNZB añadido a la colaNombreNombre del servidor / Búsqueda de DNSNombradoNuncaSiguienteParámetros NiceAcceso denegadoNo se encontraron plantillas de correo electrónicoSin DirectoriosNo hay un archivo rar anterior correspondiente para %sSin destinatarios no se pudo enviar el emailNo se ha encontrado ningún método de autenticación adecuadoNingunoNormalNo encontradoNo disponibleCentro de NotificaciónScript de notificación¡Notificación enviada!El script de notificación "%s" no existeNotificacionesNotifyOSDNúmero de segundos entre pasadas en busca de ficheros .nzb.Contraseña de usuario OPCIONALNombre de usuario OPCIONALApagadoSe ha encontrado una cola antigua, utilice Estado->Reparar para convertir la colaAl finalizar colaEn qué día del mes o semana (1=Lunes) resetea tu proveedor la cuota mensual? (Opcional con hh:mm)Sólo obtener artículos para el primer elemento de la ColaSolo acceso externo requieren conexión de usuarioApre una ventana de Consola y teclea la línea (ejemplo)Abrir todo el folderOpcionalNZB Suplementario OpcionalContraseña opcionalNombre de usuario opcionalOpcionalmente especificar un nombre de fichero¡ó arrastra y suelta ficheros en la propia ventana!OrdenNombre fichero originalNombre de la tarea originalTrabajos descolgadosOtros mensajesPROPAGANDO %s minParametrosNumero de ParteContraseñaArchivo de contraseñasContraseña protejido por ******, favor reingresarCon contraseñaRutaPatrónPatrónPausarPausar todoPausar Descargas Durante el Post-ProcesadoPausar durantePausar 1 horaPausar 15 minutosPausar 3 horasPausar 30 minutosPausar 5 minutosPausar 6 horasPausar durante...Pausar trabajos de prioridad altaPausar tareas con la categoríaPausar trabajos de prioridad bajaPausar trabajos de prioridad normalPausar post-procesamientoEn pausaSe ha pausado la tarea "%s" debido al archivo codificado RAR (se han probado todas las contraseñas, si se han suministrado)Pausa las descargas al principio del post-procesado, y reanuda al terminar.Pausando NZB duplicados "%s"Porcentaje de velocidad de líneaPermisos para descargas completadasClave API personalClave privada de la API de ProwlNotas personalesTenga en cuenta que el nombre de equipo 0.0.0.0 necesitará una dirección IPv6 para el acceso externoPor favor introduce los datos de tu proveedor principal de Usenet.PuertoPuerto en que SABnzbd debería escucharError al post-procesar %s (%s)Post procesadoPost-procesar sólo trabajos verificadosPost-ProcesadoProcesamiento posterior empezadoLos mensajes serán pausados hasta que alcancen al menos esta edad. Esta espera puede evitarse si se le da el valor Forzar a la prioridad de la tarea.La secuencia de comandos de la cola preestablecida ha marcado la tarea como fallidaScript de usuario Pre-colaPreajustesPresiona la Tecla de Windows+R y teclea la línea (ejemplo)AnteriorPrioridadProblema conResultado del procesadoEn procesoEl programa no ha arrancado!Demora de la propagaciónProwlDirección IPv4 públicaPurgar NZBs completadosPurgar los NZBs fallidosPurgar NZBs fallidos y sus ficherosPurgar historialPurgar NZBsPurgar NZBs y Eliminar FicherosPurgar los NZB en la página actualLimpiar ColaPushbulletPushoverVersion de PythonLa secuencia de comandos Python "%s" no tiene configurado el permiso de ejecutar (+x)ColaEncolar los primeros 10 elementosCola terminadaLímite de elementos encolablesCola no esta vacía, no se puede cambiar el directorioReparar colaChequeo Rápido...Chequeo RápidoSalirCuotaQuota disponiblePeriodo de la cuotaQuota gastado, pausando colaNo se han podido verificar los archivos RARLos archivos RAR se han verificado con éxitoRSSIntervalo de chequeo RSSEl canal RSS %s estaba vacíoSe ejecutó %sOpciones usadas raramente. Para su significado y explicación, haga clic en el botón de Ayuda para ir al Wiki.
No cambie esto sin chequear primero en la wiki,ya que algunos ajustes tienen severas consecuencias.
Los valores por defecto se muestran entre paréntesis.Leer todas las fuentes ahoraLeer FuenteLeer entradas RSSLeer todos los canales RSSLee la ayuda en la Wiki (inglés) acerca de esto!Se ha recibido una excepción DBus %sActualizarFrecuencia de actualizaciónSe deniega la conexión con el nombre de equipo "%s" desde:RechazarLos directorios relativos, lo son aRestanteMantenerme conectadoEliminar NZBEliminar NZB y Eliminar FicherosEliminar servidorEliminar todos los ficheros seleccionadosEliminar trabajos completadosEliminar trabajos fallidosError al eliminar %sEliminar tareaEliminar tareasRenombrarRepararHa fallado la reparación, no existen bloques de reparación suficientes (%s short)ReparandoLa reparación ha fallado, %sReparando...Repita la pruebaReemplazar espacios en el nombre de directorioReemplazar puntos en los directoriosReemplaza los puntos con espacios en los nombres de directorio.Reemplaza los espacios con guiones bajos en los nombres de directorio.NecesitaNecesitas una cuenta ProwlNecesitas una cuenta en PushbulletNecesitas una cuenta PushoverRequiereCatReiniciarReinicializar Quota ahoraDía de reinicio del conteoResolviendo sitioReiniciarReiniciar SABnzbdReiniciar sin sesión iniciadaReiniciando SABnzbd...Reiniciando debido al cuelgue del ensambladorReiniciando debido al cuelgue del descargadorReiniciando a causa de un posprocesador colgadoRestaurar valores por defectoResultadoReanudarReanudar trabajos de prioridad altaReanudar tareas con la categoríaReanudar trabajos de prioridad bajaReanudar trabajos de prioridad normalReanudar post-procesamientoReanudandoPeriodo de retenciónReintentarRe-intentar todoVuelva a intentar todos los trabajos con erroresEjecutando scriptEjecutando script...Ejecutando script de usuario %sSABCTools deshabilitado: ¡no se ha encontrado la versión correcta! (Se ha encontrado la v%s, se esperaba la v%s)SABnzbd %s comenzóHost de SABnzbdContraseña de SABnzbdPuerto de SABnzbdAsistente de Configuración de SABnzbdUsuario SABnzbdVersión de SABnzbdServidor web de SABnzbdSABnzbd ha detectado un error grave:Cierre de SABnzbd terminadoSe ha iniciado SABnzbd con codificación %s, la codificación debería ser UTF-8. Habrá problemas con el archivo en Unicode y con los nombres de directorio en las descargas.SABnzbd ahora quedará ejecutando en segundo plano.Servidor SMTPComando SQL ha fallado, vea el registroSSLCifrado SSLSábadoGuardarGuardar cambiosGuardar de %s no se pudo completar.Guardando...Escanear directorio bajo observaciónPlanificación para servidor %s inexistentePlanificaciónScriptEl código de retorno del Script es %sLa secuencia de comandos ha devuelto el código de salida %s y ha emitido "%s"ScriptsDirectorio de ScriptsBuscarNúmero de la temporadaConexión segura al servidorSeguridadSelecciona un idioma para la interfaz web.Selecciona sólo si tu proveedor permite conexiones SSL.Enviar notificaciones RSSEnviar de nuevo a la colaEnviar email cuando una fuente RSS añade un trabajo a la cola.Envía un email cuando el disco se ha llenado y SABnzbd se ha tenido que parar.Enviado(s) %s a la colaSeparar varias URL con una comaOrdenación de SeriesServidorEl servidor %s utiliza un certificado HTTPS no fiableEl servidor %s utiliza un certificado que no es de confianza [%s]El servidor %s se ignorará por %s minutosDetalles del servidorLa dirección del servidor «%s:%s» no es válida.Se necesita la dirección del servidorEl servidor no ha podido completar la solicitudDescripción del servidorNo se puede resolver el nombre de servidorEl servidor necesita usuario y contraseña.Error del lado servidor (código enviado por el servidor: %s); no se ha podido conseguir %s en %sServidoresAjustar patrón de permisos para ficheros/directorios completados.
En notación ocal. Por ejemplo:"755" ó "777"Indica los ajustes de tu correo electrónico saliente.¡La configuración ha terminado!¿Deberían las descargas resumirse tras reiniciarse la cuota?Mostrar TodoMostrar los FallidosVer LoggingNombre de la SerieMostrar conexiones activasMostrar detallesMostrar interfazNombre.serieNombre_serieApagarApagar PCApagar SABnzbdApagandoSeñal %s capturado, guardando y saliendo...TamañoHan fallado algunos ficheros al verificarse "%s"Lo siento, no hemos podido interpretar eso. Vuelve a intentarlo de nuevo.Ordenar cadenaOrdenar por Fecha Más nuevo→Más viejoOrdenar por Fecha Más viejo→Más nuevoOrdenar por nombre A→ZOrdenar por nombre Z→AOrdenar por Tamaño Más grande→Más pequeñoOrdenar por Tamaño Más pequeño→Más grandeOrdenaciónFuenteEspecialVelocidadLímite de VelocidadSuspender PCIniciar AsistenteIniciando reparaciónInicio/ApagadoEstadoOpciones de estado e interfazPararDeteniendo...EstrictoEnviarDomingo¡Apoye el proyecto, haga una donación!Error sospechoso en downloaderSwitchesDirectorios del sistemaRendimiento del sistema ( Pystone )TEXTODEMASIADO GRANDEDiseño de pestañas
(separa la cola de espera y la historia)Etiquetar tareaCarpeta temporalDirectorio de descarga temporalEmail de pruebaNotificación de pruebaProbar ServidorDescarga de pruebaTesteando información del servidorEl botón "Reparar" reiniciará SABnzbd y hará una reconstrucción
completa del contenido de la cola, preservando las descargas ya terminadas.
Esto modificará el orden de la cola.La casilla junto al nombre de la fuente debería marcarse para habilitar la fuente y que se marquen automáticamente los nuevos elementos.
Cuando una fuente se añade, sólo se cogerán los elementos nuevos y nada de lo que ya exista, salvo que presiones "Forzar Descarga".El hostname no está definido.Número de conexiones permitidas a tu proveedorEl servidor no respondió adecuadamente al saludo heloNo se han configurado conexiones. Configure al menos una conexión.Existen trabajos huérfanos en la carpeta de descarga.
Puedes escoger por eliminarlos (incluyendo los ficheros) o enviarlos de nuevo a la cola.Esta clave permitirá acceso a programas de terceros para añadir NZBs a SABnzbd.Esta clave le permitirá a programas de terceros acceso completo a SABnzbd.Este mesEsto evita que se ejecuten varias reparaciones mediante la descarga de todos los archivos par2 cuando sea necesario.Este servidor no permite SSL en este puertoEsta semanaEsto reiniciará SABnzbd.
Usalo cuando creas que el programa está colgado.
Las descargas se pausarán antes de reiniciar, y se reanudarán a continuación.Se enviará un email de prueba a tu cuentaJuevesTiempo agotadoTiempo agotado: Trate conectar en puerto diferente o encender SSL.Expiración del plazo (Timeout)TítuloPara: %s De: %s Fecha: %s Asunto: SABnzbd informa de un disco lleno Hola: SABnzbd ha detenido las descargas porque casi se ha llenado el disco. Haga algo de espacio y reanude SABnzbd manualmente. HoyMuy poco espacio en disco forzando PAUSADemasiadas conexiones con el servidor %s [%s]Demasiadas conexiones; pause las descargas o inténtelo de nuevo más tardeSuperiorTotalResolver un problemaIntenta predecir si la descarga actual se completará con éxito (ojo, esto tarda!)Tratando 7zip con la contraseña "%s"Intentando la verificación basada en RARIntentando verificación por SFVTratando de buscar NZB de %sIntentando cambiar el estado de servidor inexistente %sIntentado descomprimir rar con contraseña "%s"MartesAjustesTipoNO DESEADOError al recuperar la URL; %sEL URLGRABBER HA FALLADONo es posible vincular al puerto %s en %s. Otro software está utilizando el puerto o SABnzbd ya se está ejecutando.Acceso no autorizadoDesbloquear¡Servidor no definido!Error inespecifico mientras descodificando %sProtocolo SSL desconocido: intente desabilitar el SSL o conectarse a un puerto diferente.Acción desconocida: %sSe produjo un fallo de autenticación desconocido en el servidor de correoDescomprimirDescomprimir archivos (rar,zip,7z) dentro de otros archivos.El anidamiento de descompresiones ha resultado demasiado profundo [%s]Descompresos %s archivos/directorios en %sDescomprimiendoError al descomprimir, %sError de CRC al descomprimirError al descomprimir; El archivo está protegido por contraseñaLa descompresión ha fallado, el archivo es demasiado grande para el sistema de archivos (FAT?)Aperture de archivo fallo, la via es muy largaError al descomprimir; Imposible encontrar %sError al descomprimir; ¿Error de escritura, o tal vez el disco está lleno?Intento fallido de inicio de sesión desde %sArchivo NZB inusableArchivo RAR inutilizableExtensión no deseada en el archivo %s (%s)Se ha encontrado una extensión desconocida en el fichero rar %sextensiones no deseadas¡Actualización Disponible!Subir NZBSubiendoTiempo en ActivoUsar ajustes de la interfaz globalUsa nombres temporales durante el procesado. Deshabilitalo si tu sistema se vuelve inestable con ello habilitado.Se usa precediendo a la entrada de un NZB en la cola del sistema.Caché utilizadaDirectorios del usuarioClave de usuarioClave de usuario (obligatoria)Usuario conectadoUsuario conectado a la interfaz webScript de usuario puede marcar un trabajo como falladoNombre de usuarioValoresSe ha verificado correctamente utilizando ficheros SFVVerificar certificados al conectarse a indexadores y fuentes RSS usando HTTPS.VerificandoReparación de verificaciónVerificando...VersiónMuy bajaVer bitacora de ScriptsESPERAR %s segAVISO:En esperaAdvertenciaAdvertenciasDirectorio a vigilarVelocidad de escaneo de la carpeta vigiladaInterfaz webMiércolesCuando este bajando, si es claro que mucha data esta faltando, aborte el trabajo.Cuando la secuencia de comandos de usuario devuelve un código de salida distinto de cero, el trabajo se marca como fallido .Cuando tu dirección IP cambie o reinicies SABnzbd, la sesión caduca.Porcentaje de la velocidad de la línea que SABnzbd debería utilizar, por ejemplo 50¿Que script deberíamos ejecutar para notificaciones?¿Quién quieres que aparezca como remitente?WikiNotificaciones WindowsAñoDebe establecer un ancho de banda máximo antes de poder establecer un límite de ancho de bandaSu versión UnRAR es %s, recomendamos la versión %s o superior.
Su archivo de contraseña contiene más de 30 contraseñas, probar todas estas contraseñas conlleva mucho tiempo. Intente registrar solamente contraseñas útiles.Tu clave API personal de Pushbullet (obligatoria)[%s] Error "%s" al unir archivos[%s] Error "%s" al descomprimir ficheros RAR[%s] %s ficheros unidos.[%s] No hay conjuntos par2[%s] PAR2 ha recibido opciones incorrectas, chequea tus ajustes en Preferencias->Switches[%s] Chequeo Rápido OK[%s] La verificación basada en RAR ha fallado: %s[%s] Reparado en %s[%s] El comando en build_command no está definido.[%s] Verificado en %s, todos los archivos correctos[%s] Verificado en %s, se necesita repararartículosajustado a mayus-minusddíadíasdeshabilitar servidorhabilitar servidorarchivohhorahorasRestantemmanualmínminsdesactivadoactivadoopáginapar2 binario... NO encontrado!segsegundosver fichero de logtextounrar binario... NO encontradosemana././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993698.6382246 SABnzbd-4.3.2/locale/en/LC_MESSAGES/SABnzbd.mo0000644000000000000000000000742614625637243017502 0ustar00runnerstaff%Dlm1 R>[(-Es;65Mjh!;Tp,!5 @"I lUz ;C 0 R [g     4' \ :u :    6 iQ      9 U 9f #   6 5-? m`{ 
SABnzbd shutdown finished.
Wait for about 5 second and then click the button below.

Refresh
0 is highest priority, 100 is the lowest priorityAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AdvancedConfirm History DeletionsConfirm Queue DeletionsDownloads will not unpacked.Filter out sample files (e.g. video samples).HTTPS Chain CertifcatesHow long or untill when do you want to pause? (in English!)If empty, the standard port will only listen to HTTPS.Optionally specify a filenamePause high prioirty jobsPause low prioirty jobsPause normal prioirty jobsPosts will be paused untill they are at least this age. Setting job priority to Force will skip the delay.Pre-queue user scriptReplace Spaces in FoldernameReplace dots in FoldernameResume high prioirty jobsResume low prioirty jobsResume normal prioirty jobsRetry all failedScript returned exit code %s and output "%s"Seperate multiple URLs by a commaSupport the project, Donate!System Performance (Pystone)The server didn't reply properly to the helo greetingTimeleftUser script can flag job as failedWeb InterfaceWhen the user script returns a non-zero exit code, the job will be flagged as failed.disable serverenable serverunrar binary... NOT foundProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2015-07-04 10:12+0000 PO-Revision-Date: 2015-07-04 12:26+0000 Last-Translator: shypike Language-Team: Dutch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit  
SABnzbd shutdown finished.
Wait for about 5 seconds and then click the button below.

Refresh
0 is highest priority, 99 is the lowest priorityAPI key incorrect, Use the API key from Config->General in your 3rd party program:API key missing, please enter the API key from Config->General into your 3rd party program:Advanced SettingsConfirm history deletionsConfirm queue deletionsDownloads will not be unpacked.Filter out sample files (e.g. video samples/proofs).HTTPS Chain CertificatesHow long or until when do you want to pause? (in English!)If empty, the SABnzbd Port set above will listen to HTTPS.Optionally specify a namePause high priority jobsPause low priority jobsPause normal priority jobsPosts will be paused until they are at least this age. Setting job priority to Force will skip the delay.Pre-queue scriptReplace spaces in folder nameReplace dots in folder nameResume high priority jobsResume low priority jobsResume normal priority jobsRetry All FailedNotification script returned exit code %s and output "%s"Separate multiple URLs with a commaSupport the project, donate!System performance (Pystone)The server didn't reply properly to the hello greetingTime leftPost-processing script can flag job as failedWeb interfaceWhen the post-processing script returns a non-zero exit code, the job will be flagged as failed.Disable server:Enable server:unrar binary... NOT found!././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4390585 SABnzbd-4.3.2/licenses/License-pybonjour.txt0000644000000000000000000000040614625637243020200 0ustar00runnerstaffThe module pybonjour is (C) Christopher Stawarz Version: 1.1.1 May 8, 2008 Home of the module: http://pseudogreen.org/bzr/pybonjour/ It is covered by the following license: "pybonjour is free software, distributed under the MIT license." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4391356 SABnzbd-4.3.2/licenses/License-Python.txt0000644000000000000000000003244714625637243017444 0ustar00runnerstaffA. HISTORY OF THE SOFTWARE ========================== Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others. In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software. In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. Release Derived Year Owner GPL- from compatible? (1) 0.9.0 thru 1.2 1991-1995 CWI yes 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes 1.6 1.5.2 2000 CNRI no 2.0 1.6 2000 BeOpen.com no 1.6.1 1.6 2001 CNRI yes (2) 2.1 2.0+1.6.1 2001 PSF no 2.0.1 2.0+1.6.1 2001 PSF yes 2.1.1 2.1+2.0.1 2001 PSF yes 2.2 2.1.1 2001 PSF yes 2.1.2 2.1.1 2002 PSF yes 2.1.3 2.1.2 2002 PSF yes 2.2.1 2.2 2002 PSF yes 2.2.2 2.2.1 2002 PSF yes 2.2.3 2.2.2 2003 PSF yes 2.3 2.2.2 2002-2003 PSF yes 2.3.1 2.3 2002-2003 PSF yes 2.3.2 2.3.1 2002-2003 PSF yes 2.3.3 2.3.2 2002-2003 PSF yes 2.3.4 2.3.3 2004 PSF yes 2.3.5 2.3.4 2005 PSF yes 2.4 2.3 2004 PSF yes 2.4.1 2.4 2005 PSF yes 2.4.2 2.4.1 2005 PSF yes 2.4.3 2.4.2 2006 PSF yes 2.5 2.4 2006 PSF yes 2.7 2.6 2010 PSF yes Footnotes: (1) GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't. (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, because its license has a choice of law clause. According to CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 is "not incompatible" with the GPL. Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible. B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON =============================================================== PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 ------------------------------------------- BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software"). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 --------------------------------------- 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013". 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 -------------------------------------------------- Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.439213 SABnzbd-4.3.2/licenses/License-PythonParts.txt0000644000000000000000000000027114625637243020444 0ustar00runnerstaffpystone.py and msgfmt.py have been copied from the Python sourcecode. They are covered by the same license as Python itself, that license is contained in the file "License_Python.txt". ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.439286 SABnzbd-4.3.2/licenses/License-systrayicon.txt0000644000000000000000000000051614625637243020542 0ustar00runnerstaffOn http://www.brunningonline.net/simon/blog/archives/001835.html, the author licensed SysTrayIcon.py under a variant of the WTFPL: > Any road up, help yourself. Consider SysTrayIcon.py to be under an > "Aleister Crowley" style license - "Do what thou wilt shall be the > only law". > > Err, but don't sue me if it doesn't work. ;-) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.439466 SABnzbd-4.3.2/licenses/License-kronos.txt0000644000000000000000000000350314625637243017465 0ustar00runnerstaffKronos.py is written by Irmen de Jong. Retrieved from: http://www.razorvine.net/download/kronos.py Quote from the module: """ This version has been extracted from the Turbogears source repository and slightly changed to be completely stand-alone again. Also some fixes have been made to make it work on Python 2.6 (sched module changes). The version in Turbogears is based on the original stand-alone Kronos. """ It is covered by the following license. http://www.opensource.org/licenses/mit-license.php -------------------------------------------------------------------------------------------- The MIT License Kronos.py is Copyright (c) Irmen de Jong. 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. --------------------------------------------------------------------------------------------././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4395413 SABnzbd-4.3.2/licenses/License-pynewsleecher.txt0000644000000000000000000000057314625637243021033 0ustar00runnerstaffThe original author of SABnzbd based his work on Pynewsleecher by Freddy@madcowdesease.org. Few parts of Pynewsleecher have survived the generations of SABnzbd in a recognizable form. Still, we wish to thank Freddy for his inspiration. The home of the Pynewsleecher project: http://www.madcowdisease.org/mcd/pynewsleecher The software does not carry any license information. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4397552 SABnzbd-4.3.2/licenses/License-rarfile.txt0000644000000000000000000000171014625637243017574 0ustar00runnerstaffThe module rarfile.py is written by Marko Kreen. Home of the module: http://grue.l-t.ee/~marko/src/rarfile/ It is covered by the following license. ------------------------------------------------------------------------- Copyright (c) 2005 Marko Kreen Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4398856 SABnzbd-4.3.2/tests/test_par2file.py0000644000000000000000000001322714625637243016507 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ Testing SABnzbd par2 parsing """ from sabnzbd.par2file import * from tests.testhelper import * # TODO: Add testing for edge cases, such as non-unique md5of16k or broken par files class TestPar2Parsing: def test_parse_par2_file(self, caplog): # To capture the par2-creator, we need to capture the logging with caplog.at_level(logging.DEBUG): # These files are all <16k so the MD5 of the whole file is the same as the 16k one assert ( "7e926efb97172cbcff9a5b32a6a4df55", { "random.bin": FilePar2Info( filename="random.bin", hash16k=b"\xbf\xe0\xe4\x10\xa2#\xf5\xbeN\x7f2\xe5\x9e\xdd\t\x03", filehash=787459617, filesize=5120, ) }, ) == parse_par2_file(os.path.join(SAB_DATA_DIR, "deobfuscate_filenames", "rename.par2"), {}) assert "Par2-creator of rename.par2 is: QuickPar 0.9" in caplog.text caplog.clear() assert ( "6f9d1d2e7466f09f1db010084bb4ca89", { "frènch_german_demö.rar": FilePar2Info( filename="frènch_german_demö.rar", hash16k=b"C\t\x1d\xbd\xdf\x8c\xb5w \xcco\xbf~L)\xc2", filehash=1320056373, filesize=132, ) }, ) == parse_par2_file( os.path.join(SAB_DATA_DIR, "test_win_unicode", "frènch_german_demö.rar.vol0+1.par2"), {} ) assert "Par2-creator of frènch_german_demö.rar.vol0+1.par2 is: QuickPar 0.9" in caplog.text caplog.clear() assert ( "a96d3f9c00d63653d8e2cc171e8c5384", { "我喜欢编程.part3.rar": FilePar2Info( filename="我喜欢编程.part3.rar", hash16k=b"\xe0\xab\xe9\x96\xfa\xdc\xba\x07?\xb1\xd4w\t2\xe5\x96", filehash=2849562011, filesize=20480, ), "我喜欢编程.part6.rar": FilePar2Info( filename="我喜欢编程.part6.rar", hash16k=b"\xb4\x86t\xf7B\x0bW+\xee-\xfd4z\x03\x05\xd2", filehash=251711255, filesize=1191, ), "我喜欢编程.part2.rar": FilePar2Info( filename="我喜欢编程.part2.rar", hash16k=b"\x1f\n\xc8\xf09@A&n\x17ah\xa4\x1dEi", filehash=1866884676, filesize=20480, ), "我喜欢编程.part1.rar": FilePar2Info( filename="我喜欢编程.part1.rar", hash16k=b"\x9b\x9cm\xd63\x15\x16\x923\xc9\xd7\x1c\x94\xd8\xd9#", filehash=3178523720, filesize=20480, ), "我喜欢编程.part5.rar": FilePar2Info( filename="我喜欢编程.part5.rar", hash16k=b"\x89fu\xd8\x10a\x01Ze\xcb\x04\x0b\ndjr", filehash=4287933540, filesize=20480, ), "我喜欢编程.part4.rar": FilePar2Info( filename="我喜欢编程.part4.rar", hash16k=b"8TA\x83\xeb\xc8\xbe\xf58\x95g\x87\n\xa2A\xa1", filehash=3954002734, filesize=20480, ), }, ) == parse_par2_file(os.path.join(SAB_DATA_DIR, "unicode_rar", "我喜欢编程.par2"), {}) assert "Par2-creator of 我喜欢编程.par2 is: Created by par2cmdline version 0.8.1" in caplog.text caplog.clear() def test_parse_par2_file_16k(self, caplog): # Capture logging of the par2-creator with caplog.at_level(logging.DEBUG): # This file is 18k, so it's md5 of the first 16k is actually different md5of16k = {} assert ( "69af2273e8fa0b4d811b56d02a9c4b59", { "rss_feed_test.xml": FilePar2Info( filename="rss_feed_test.xml", hash16k=b"'ky\xd7\xd1\xd3wF\xed\x9c\xf7\x9b\x90\x93\x106", filehash=1157097199, filesize=17803, ) }, ) == parse_par2_file(os.path.join(SAB_DATA_DIR, "par2file", "basic_16k.par2"), md5of16k) assert md5of16k == {b"'ky\xd7\xd1\xd3wF\xed\x9c\xf7\x9b\x90\x93\x106": "rss_feed_test.xml"} assert "Par2-creator of basic_16k.par2 is: QuickPar 0.9" in caplog.text caplog.clear() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4400141 SABnzbd-4.3.2/tests/test_deobfuscate_filenames.py0000644000000000000000000004325014625637243021311 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ Testing SABnzbd deobfuscate module """ import random import shutil import zipfile from sabnzbd.deobfuscate_filenames import * from tests.testhelper import * def create_big_file(filename): with open(filename, "wb") as myfile: # must be above MIN_SIZE, so ... 15MB myfile.truncate(15 * 1024 * 1024) def create_small_file(filename): with open(filename, "wb") as myfile: myfile.truncate(1024) @pytest.mark.usefixtures("clean_cache_dir") class TestDeobfuscateFinalResult: def test_is_probably_obfuscated(self): # Test the base function test_is_probably_obfuscated(), which gives a boolean as RC # obfuscated names assert is_probably_obfuscated("599c1c9e2bdfb5114044bf25152b7eaa.mkv") assert is_probably_obfuscated("/my/blabla/directory/stuff/599c1c9e2bdfb5114044bf25152b7eaa.mkv") assert is_probably_obfuscated( "/my/blabla/directory/A Directory Should Not Count 2020/599c1c9e2bdfb5114044bf25152b7eaa.mkv" ) assert is_probably_obfuscated("/my/blabla/directory/stuff/afgm.avi") assert is_probably_obfuscated("/my/blabla/directory/stuff/afgm2020.avi") assert is_probably_obfuscated("MUGNjK3zi65TtN.mkv") assert is_probably_obfuscated("T306077.avi") assert is_probably_obfuscated("bar10nmbkkjjdfr.mkv") assert is_probably_obfuscated("4rFF-fdtd480p.bin") assert is_probably_obfuscated("e0nFmxBNTprpbQiVQ44WeEwSrBkLlJ7IgaSj3uzFu455FVYG3q.bin") assert is_probably_obfuscated("e0nFmxBNTprpbQiVQ44WeEwSrBkLlJ7IgaSj3uzFu455FVYG3q") # no ext assert is_probably_obfuscated("greatdistro.iso") assert is_probably_obfuscated("my.download.2020") assert is_probably_obfuscated("abc.xyz.a4c567edbcbf27.BLA") # by definition assert is_probably_obfuscated("abc.xyz.iso") # lazy brother assert is_probably_obfuscated("0675e29e9abfd2.f7d069dab0b853283cc1b069a25f82.6547") assert is_probably_obfuscated("[BlaBla] something [More] something b2.bef89a622e4a23f07b0d3757ad5e8a.a0 [Brrr]") # non-obfuscated names: assert not is_probably_obfuscated("/my/blabla/directory/stuff/My Favorite Distro S03E04.iso") assert not is_probably_obfuscated("/my/blabla/directory/stuff/Great Distro (2020).iso") assert not is_probably_obfuscated("ubuntu.2004.iso") assert not is_probably_obfuscated("/my/blabla/directory/stuff/GreatDistro2020.iso") assert not is_probably_obfuscated("Catullus.avi") assert not is_probably_obfuscated("Der.Mechaniker.HDRip.XviD-SG.avi") assert not is_probably_obfuscated("Bonjour.1969.FRENCH.BRRiP.XviD.AC3-HuSh.avi") assert not is_probably_obfuscated("Bonjour.1969.avi") assert not is_probably_obfuscated("This That S01E11") assert not is_probably_obfuscated("This_That_S01E11") assert not is_probably_obfuscated("this_that_S01E11") assert not is_probably_obfuscated("My.Download.2020") assert not is_probably_obfuscated("this_that_there_here.avi") assert not is_probably_obfuscated("Lorem Ipsum.avi") assert not is_probably_obfuscated("Lorem Ipsum") # no ext @staticmethod def deobfuscate_wrapper(filelist, jobname): """Wrapper to avoid the need for NZO""" nzo = mock.Mock() nzo.set_unpack_info = mock.Mock() deobfuscate(nzo, filelist, jobname) def test_deobfuscate_filelist_lite(self): # lightweight test of deobfuscating: with just one file # Create directory (with a random directory name) dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) # Create a big file with a useless, obfuscated filename output_file1 = os.path.join(dirname, "111c1c9e2bdfb5114044bf25152b7eab.bin") create_big_file(output_file1) assert os.path.isfile(output_file1) # create the filelist, with just the above file myfilelist = [output_file1] # and now unleash the magic on that filelist, with a more useful jobname: jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Check original files: assert not os.path.isfile(output_file1) # original filename should not be there anymore # Check the renaming assert os.path.isfile(os.path.join(dirname, jobname + ".bin")) # ... it should be renamed to the jobname # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_deobfuscate_big_file_small_accompanying_files(self): # input: myiso.iso, with accompanying files (.srt and -sample files) # test that the accompanying files (with same basename) are renamed accordingly to the big ISO # Note: this is the most typical usage of deobfuscation # Create directory (with a random directory name) dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) # Create a big enough file with a useless filename isofile = os.path.join(dirname, "myiso.iso") create_big_file(isofile) assert os.path.isfile(isofile) # and a srt file srtfile = os.path.join(dirname, "myiso.srt") create_small_file(srtfile) assert os.path.isfile(srtfile) # and a sample file samplefile = os.path.join(dirname, "myiso-sample.iso") create_small_file(samplefile) assert os.path.isfile(samplefile) # and a non-related file txtfile = os.path.join(dirname, "something.txt") create_small_file(txtfile) assert os.path.isfile(txtfile) # create the filelist, with just the above files myfilelist = [isofile, srtfile, samplefile, txtfile] # and now unleash the magic on that filelist, with a more useful jobname: jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Check original files: assert not os.path.isfile(isofile) # original iso not be there anymore assert not os.path.isfile(srtfile) # ... and accompanying file neither assert not os.path.isfile(samplefile) # ... and this one neither assert os.path.isfile(txtfile) # should still be there: not accompanying # Check the renaming assert os.path.isfile(os.path.join(dirname, jobname + ".iso")) # ... should be renamed to the jobname assert os.path.isfile(os.path.join(dirname, jobname + ".srt")) # ... should be renamed to the jobname assert os.path.isfile(os.path.join(dirname, jobname + "-sample.iso")) # ... should be renamed to the jobname # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_deobfuscate_filelist_full(self): # Full test, with a combinantion of files: Test that deobfuscate() works and renames correctly # ... but only the files that are in the filelist # Create directory (with a random directory name) dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) # Create a big enough file with a useless filename output_file1 = os.path.join(dirname, "111c1c9e2bdfb5114044bf25152b7eaa.bin") create_big_file(output_file1) assert os.path.isfile(output_file1) # create a small file. Obfuscated, but should not get renamed output_file2 = os.path.join(dirname, "222c1c9e2bdfb5114044bf25152b7eaa.bin") create_small_file(output_file2) assert os.path.isfile(output_file2) # create the filelist, with just the above files myfilelist = [output_file1, output_file2] # Create some extra files ... that will not be in the list output_file3 = os.path.join(dirname, "333c1c9e2bdfb5114044bf25152b7eaa.bin") create_big_file(output_file3) assert os.path.isfile(output_file3) output_file4 = os.path.join(dirname, "This Great Download 2020.bin") create_big_file(output_file4) assert os.path.isfile(output_file4) # and now unleash the magic on that filelist, with a more useful jobname: jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Check original files: assert not os.path.isfile(output_file1) # original filename should not be there anymore assert os.path.isfile(output_file2) # original smaller file should still be there assert os.path.isfile(output_file3) # but this one should still be there assert os.path.isfile(output_file4) # and this one too # Check the renaming assert os.path.isfile(os.path.join(dirname, jobname + ".bin")) # ... it should be renamed to the jobname # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_deobfuscate_one_small_file(self): # Test of deobfuscating: with just one small file # Create directory (with a random directory name) dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) # Create a small file with a useless, obfuscated filename output_file1 = os.path.join(dirname, "blabla.txt") create_small_file(output_file1) assert os.path.isfile(output_file1) # create the filelist, with just the above file myfilelist = [output_file1] # and now unleash the magic on that filelist, with a more useful jobname: jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Check original files: assert not os.path.isfile(output_file1) # original filename should not be there anymore # Check the renaming assert os.path.isfile(os.path.join(dirname, jobname + ".txt")) # ... it should be renamed to the jobname # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_deobfuscate_filelist_subdir(self): # test of deobfuscating with sub directories # Create directory with subdirs dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) subdirname = os.path.join(dirname, "testdir" + str(random.randint(10000, 99999))) os.mkdir(subdirname) subsubdirname = os.path.join(subdirname, "testdir" + str(random.randint(10000, 99999))) os.mkdir(subsubdirname) # Create a big enough file with a useless, obfuscated filename output_file1 = os.path.join(subsubdirname, "111c1c9e2bdfb5114044bf25152b7eab.bin") create_big_file(output_file1) assert os.path.isfile(output_file1) # create the filelist, with just the above file myfilelist = [output_file1] # and now unleash the magic on that filelist, with a more useful jobname: jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Check original files: assert not os.path.isfile(output_file1) # original filename should not be there anymore # Check the renaming assert os.path.isfile(os.path.join(subsubdirname, jobname + ".bin")) # ... it should be renamed to the jobname # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_no_deobfuscate_DVD_dir(self): # test of typical DVD directory structure ... no deobfuscating should happen # Create a working directory, with a VIDEO_TS subdirectory dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) subdirname = os.path.join(dirname, "VIDEO_TS") os.mkdir(subdirname) # Create a big file with a useless, obfuscated filename (which normally should get renamed) output_file1 = os.path.join(subdirname, "111c1c9e2bdfb5114044bf25152b7eab.bin") create_big_file(output_file1) assert os.path.isfile(output_file1) # create the filelist, with just the above file myfilelist = [output_file1] # and now unleash deobfuscate() on that filelist, with a useful jobname: jobname = "My DVD 2021" self.deobfuscate_wrapper(myfilelist, jobname) # ... but because inside "VIDEO_TS" directory, the file should not be touched / renamed: assert os.path.isfile(output_file1) # should still be there # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_deobfuscate_collection_with_same_size(self): # input: a collection of a few files with about the same size # test that there is no renaming # Create directory (with a random directory name) dirname = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) # Create big enough files with a useless filenames, all with same extension file1 = os.path.join(dirname, "file1.bin") create_big_file(file1) assert os.path.isfile(file1) file2 = os.path.join(dirname, "file2.bin") create_big_file(file2) assert os.path.isfile(file2) file3 = os.path.join(dirname, "file3.bin") create_big_file(file3) assert os.path.isfile(file3) file4 = os.path.join(dirname, "file4.bin") create_big_file(file4) assert os.path.isfile(file4) # create the filelist, with the above files myfilelist = [file1, file2, file3, file4] # and now unleash the magic on that filelist, with a more useful jobname: jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Check original files: # the collection with same extension should still be there: assert os.path.isfile(file1) # still there assert os.path.isfile(file2) # still there assert os.path.isfile(file3) # still there assert os.path.isfile(file4) # still there # Done. Remove (non-empty) directory shutil.rmtree(dirname) def test_deobfuscate_filelist_nasty_tests(self): # check no problems occur with nasty use cases # non existing file myfilelist = ["/bla/bla/notthere.bin"] jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) # Create directory with a directory name that could be renamed, but should not dirname = os.path.join(SAB_CACHE_DIR, "333c1c9e2bdfb5114044bf25152b7eaa.bin") os.mkdir(dirname) myfilelist = [dirname] jobname = "My Important Download 2020" self.deobfuscate_wrapper(myfilelist, jobname) assert os.path.exists(dirname) shutil.rmtree(dirname) def test_deobfuscate_par2(self): # Simple test to see if the par2 file is picked up test_dir = os.path.join(SAB_DATA_DIR, "deobfuscate_filenames") test_input = os.path.join(test_dir, "E0CcYdGDFbeCAsT3LoID") test_output = os.path.join(test_dir, "random.bin") # Check if it is there assert os.path.exists(test_input) list_of_files = [] for dirpath, dirnames, filenames in os.walk(test_dir): list_of_files += [os.path.join(dirpath, file) for file in filenames] # Run deobfuscate recover_par2_names(list_of_files) # Should now be renamed to the filename in the par2 file assert not os.path.exists(test_input) assert os.path.exists(test_output) # Rename back os.rename(test_output, test_input) assert os.path.exists(test_input) def test_deobfuscate_par2_plus_deobfuscate(self): # test for first par2 based renaming, then deobfuscate obfuscated names work_dir = os.path.join(SAB_CACHE_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(work_dir) source_zip_file = os.path.join(SAB_DATA_DIR, "deobfuscate_par2_based", "20mb_with_par2_package.zip") with zipfile.ZipFile(source_zip_file, "r") as zip_ref: zip_ref.extractall(work_dir) assert os.path.isfile(os.path.join(work_dir, "rename.par2")) # the par2 that will do renaming assert os.path.isfile(os.path.join(work_dir, "aaaaaaaaaaa")) # a 20MB no-name file ... list_of_files = [] for dirpath, dirnames, filenames in os.walk(work_dir): list_of_files += [os.path.join(dirpath, file) for file in filenames] # deobfuscate will do: # first par2 based renaming aaaaaaaaaaa to twentymb.bin, # then deobfuscate twentymb.bin to the job name (with same extension) list_of_files = recover_par2_names(list_of_files) print(list_of_files) assert os.path.isfile(os.path.join(work_dir, "twentymb.bin")) # should exist self.deobfuscate_wrapper(list_of_files, "My Great Download") assert os.path.isfile(os.path.join(work_dir, "My Great Download.bin")) # the twentymb.bin should be renamed assert not os.path.isfile(os.path.join(work_dir, "twentymb.bin")) # should now be gone shutil.rmtree(work_dir) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.440108 SABnzbd-4.3.2/tests/test_internetspeed.py0000644000000000000000000000217614625637243017655 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_internetspeed - Testing SABnzbd internetspeed """ import pytest from sabnzbd.internetspeed import internetspeed @pytest.mark.usefixtures("clean_cache_dir") class TestInternetSpeed: def test_internet_speed(self): curr_speed_mbps = internetspeed() assert isinstance(curr_speed_mbps, float) assert curr_speed_mbps > 0 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.440276 SABnzbd-4.3.2/tests/test_nzbparser.py0000644000000000000000000000525514625637243017013 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_nzbparser - Tests of basic NZB parsing """ from tests.testhelper import * import sabnzbd.nzbparser as nzbparser from sabnzbd import nzbstuff from sabnzbd.filesystem import save_compressed @pytest.mark.usefixtures("clean_cache_dir") class TestNzbParser: @set_config({"download_dir": SAB_CACHE_DIR}) def test_nzbparser(self): nzo = nzbstuff.NzbObject("test_basic") # Create test file metadata = {"category": "test", "password": "testpass"} nzb_fp = create_and_read_nzb_fp("..", metadata=metadata) # Create folder and save compressed NZB like SABnzbd would do save_compressed(SAB_CACHE_DIR, "test", nzb_fp) nzb_file = os.path.join(SAB_CACHE_DIR, "test.nzb.gz") assert os.path.exists(nzb_file) # Files we expect test_dir = os.path.normpath(os.path.join(SAB_DATA_DIR, "..")) expected_files = [fl for fl in os.listdir(test_dir) if os.path.isfile(os.path.join(test_dir, fl))] expected_files.sort() assert expected_files # Parse the file nzbparser.nzbfile_parser(nzb_file, nzo) # Compare filenames resulting_files = [nzf.filename for nzf in nzo.files] resulting_files.sort() assert resulting_files == expected_files # Compare sizes expected_sizes = [os.path.getsize(os.path.join(test_dir, fl)) for fl in expected_files] expected_sizes.sort() resulting_sizes = [nzf.bytes for nzf in nzo.files] resulting_sizes.sort() assert resulting_sizes == expected_sizes # Check meta-data for field in metadata: assert [metadata[field]] == nzo.meta[field] @pytest.mark.xfail(reason="These tests should be added") def test_nzbparser_bad_stuff(self): # TODO: Add tests for: # Duplicate parts # Strange articles sizes # Correct parsing of dates assert False ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4403837 SABnzbd-4.3.2/tests/test_consistency.py0000644000000000000000000000772314625637243017350 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_consistency - Keep things consistent """ import re import sabnzbd import lxml.html from sabnzbd.skintext import SKIN_TEXT from tests.testhelper import * class TestVersion: def test_sabctools_version_match(self): with open("requirements.txt", "r") as reqs: assert f"sabctools=={sabnzbd.constants.SABCTOOLS_VERSION_REQUIRED}" in reqs.read() class TestSkintext: def test_skintext(self): # Make one giant string of all the text for semi-efficient search combined_files = "" for dirname, dirnames, filenames in os.walk("interfaces"): for filename in filenames: # Only .tmpl and .htm(l) files if ".tmpl" in filename or ".htm" in filename: with open(os.path.join(dirname, filename), "r") as myfile: data = myfile.read().replace("\n", "") combined_files = combined_files + data # Items to ignore, we might use them in the future! to_ignore = ("sch-", "hours", "removeNZB", "purgeNZBs", "purgeQueue", "menu-home") # Search for translation function not_found = [] for key in SKIN_TEXT: if "T('" + key not in combined_files and 'T("' + key not in combined_files: if not key.startswith(to_ignore): not_found.append(key) # If anything shows up, the translation string is no longer used and should be removed! assert not not_found # @pytest.mark.skipif(os.environ.get("GITHUB_REF_NAME", "") != "develop", reason="Only check on develop branch") @pytest.mark.usefixtures("run_sabnzbd") class TestWiki: def test_added_wiki_entries(self): """Test that every option has a Wiki entry, and removed options are removed from the wiki""" wiki_diff = {} config_diff = {} for url in ("general", "switches", "special"): config_tree = lxml.html.fromstring( requests.get("http://%s:%s/config/%s/" % (SAB_HOST, SAB_PORT, url)).content ) # Have to remove some decorating stuff and empty values config_labels = [ label.lower().strip().strip(" ()") for label in config_tree.xpath("//fieldset//label/text()") ] config_labels = [label for label in config_labels if label] # Parse the version info to get the right Wiki version version = re.search(r"(\d+\.\d+)\.(\d+)([a-zA-Z]*)(\d*)", sabnzbd.__version__).group(1) wiki_tree = lxml.html.fromstring( requests.get("https://sabnzbd.org/wiki/configuration/%s/%s" % (version, url)).content ) # Special-page needs different label locator label_element = "code" if "special" in url else "strong" wiki_labels = [label.lower() for label in wiki_tree.xpath("//tbody/tr/td[1]/%s/text()" % label_element)] wiki_diff[url] = set(config_labels) - set(wiki_labels) assert not wiki_diff[url] # There can be a difference, for example Windows-only options are not shown on macOS config_diff[url] = set(wiki_labels) - set(config_labels) # Add print() to see this difference ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4405718 SABnzbd-4.3.2/tests/conftest.py0000644000000000000000000001524114625637243015567 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.conftest - Setup pytest fixtures These have to be separate otherwise SABnzbd is started multiple times! """ import shutil import subprocess import sys from selenium import webdriver from selenium.webdriver.chrome.options import Options as ChromeOptions from warnings import warn from sabnzbd.constants import DEF_INI_FILE from tests.testhelper import * @pytest.fixture(scope="module") def clean_cache_dir(request): # Remove cache if already there try: if os.path.isdir(SAB_CACHE_DIR): shutil.rmtree(SAB_CACHE_DIR) # Create an empty placeholder os.makedirs(SAB_CACHE_DIR) except Exception: pytest.fail("Failed to freshen up cache dir %s" % SAB_CACHE_DIR) yield request # Remove cache dir with retries in case it's still running for x in range(10): try: time.sleep(1) shutil.rmtree(SAB_CACHE_DIR) break except OSError: print("Unable to remove cache dir (try %d)" % x) time.sleep(1) @pytest.fixture(scope="module") def run_sabnzbd(clean_cache_dir, request): """Start SABnzbd (with translations). A number of key configuration parameters are defined in testhelper.py (SAB_* variables). Scope is set to 'module' to prevent configuration changes made during functional tests from causing failures in unrelated tests.""" def shutdown_sabnzbd(): # Shutdown SABnzbd try: get_url_result("shutdown", SAB_HOST, SAB_PORT) except requests.ConnectionError: sabnzbd_process.kill() sabnzbd_process.communicate(timeout=30) except Exception as err: warn("Failed to shutdown the sabnzbd process: %s" % err) # Allow the test file to specify what ini to load; if none given, use the basic one by default ini_file = getattr(request.module, "INI_FILE", "sabnzbd.basic.ini") # Copy basic config file with API key shutil.copyfile(os.path.join(SAB_DATA_DIR, ini_file), os.path.join(SAB_CACHE_DIR, DEF_INI_FILE)) # Check if we have language files locale_dir = os.path.join(SAB_BASE_DIR, "..", "locale") if not os.path.isdir(locale_dir): try: # Language files missing; let make_mo do its thing make_mo = subprocess.Popen([sys.executable, os.path.join(SAB_BASE_DIR, "..", "tools", "make_mo.py")]) make_mo.communicate(timeout=30) # Check the dir again, should exist now if not os.path.isdir(locale_dir): raise FileNotFoundError except Exception: pytest.fail("Failed to compile language files in %s" % locale_dir) # Start SABnzbd and continue sabnzbd_process = subprocess.Popen( [ sys.executable, os.path.join(SAB_BASE_DIR, "..", "SABnzbd.py"), "--new", "--server", "%s:%s" % (SAB_HOST, str(SAB_PORT)), "--browser", "0", "--logging", "2", "--config", SAB_CACHE_DIR, ] ) # Wait for SAB to respond for _ in range(30): try: get_url_result() # Woohoo, we're up! break except requests.ConnectionError: time.sleep(1) else: # Make sure we clean up shutdown_sabnzbd() raise requests.ConnectionError() yield shutdown_sabnzbd() @pytest.fixture(scope="session") def run_sabnews_and_selenium(request): """Start SABNews and Selenium/Chromedriver, shared across the pytest session.""" # We only try Chrome for consistent results driver_options = ChromeOptions() # Headless during CI testing if "CI" in os.environ: driver_options.add_argument("--headless") driver_options.add_argument("--no-sandbox") # Useful for stability on Linux/macOS, doesn't work on Windows if not sys.platform.startswith("win"): driver_options.add_argument("--single-process") # Start the driver and pass it on to all the classes driver = webdriver.Chrome(options=driver_options) SABnzbdBaseTest.driver = driver # Start SABNews sabnews_process = subprocess.Popen([sys.executable, os.path.join(SAB_BASE_DIR, "sabnews.py")]) # Now we run the tests yield # Shutdown SABNews try: sabnews_process.kill() sabnews_process.communicate(timeout=10) except Exception as err: warn("Failed to shutdown the sabnews process: %s" % err) # Shutdown Selenium/Chrome try: driver.close() driver.quit() except Exception as err: # If something else fails, this can cause very non-informative long tracebacks warn("Failed to shutdown the selenium/chromedriver process: %s" % err) @pytest.fixture(scope="class") def generate_fake_history(request): """Add fake entries to the history db""" history_size = randint(42, 81) try: history_db = os.path.join(SAB_CACHE_DIR, DEF_ADMIN_DIR, DB_HISTORY_NAME) with FakeHistoryDB(history_db) as fake_history: fake_history.add_fake_history_jobs(history_size) # Make history parameters available to the test class request.cls.history_category_options = fake_history.category_options request.cls.history_distro_names = fake_history.distro_names request.cls.history_size = history_size except Exception: pytest.fail("Failed to add fake entries to history db %s" % history_db) return @pytest.fixture(scope="function") def update_history_specs(request): """Update the history size at the start of every test""" if request.function.__name__.startswith("test_"): json = get_api_result( "history", SAB_HOST, SAB_PORT, extra_arguments={"limit": request.cls.history_size}, ) request.cls.history_size = len(json["history"]["slots"]) # Test o'clock return ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4406495 SABnzbd-4.3.2/tests/test_notifier.py0000644000000000000000000001656314625637243016630 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_notifier - Testing notification functionality """ import re from sabnzbd.notifier import send_notification, send_apprise, NOTIFICATION_TYPES from unittest import mock, TestCase import sabnzbd.cfg as cfg from sabnzbd.config import Option from importlib import reload class TestNotifier(TestCase): @classmethod def setUpClass(self): # hack since test_misc uses @set_config decorator eliminating all of the default configuration # We wnat to test with the default configuration in place; This safely resets all fields and # replaces them correctly in memory reload(cfg) # capture state of config so we can reverse it self._saved_cfg = {} for attr in dir(cfg): if isinstance(getattr(cfg, attr), Option): # Backup configuration as it was before entering this test object self._saved_cfg[attr] = getattr(cfg, attr).get() # Set our value to be a default getattr(cfg, attr).set(getattr(cfg, attr).default) @classmethod def setUp(self): # Enforce our default values associated with the class for attr in dir(cfg): if isinstance(getattr(cfg, attr), Option): getattr(cfg, attr).set(getattr(cfg, attr).default) @classmethod def tearDownClass(self): # rollback our assignments to be as they were for k, v in self._saved_cfg.items(): getattr(cfg, k).set(v) @mock.patch("sabnzbd.DIR_PROG") @mock.patch("apprise.Apprise.notify") @mock.patch("apprise.Apprise.add") def test_send_apprise_notification(self, mock_add, mock_notify, mock_sabdir): """ Test send_apprise() outside of threading call to verify it handles requests properly """ # # Mocks below pertain to testing # # Asset just needs to be anything at all mock_sabdir.return_value = "/tmp" cfg.apprise_enable.set(True) urls = ", ".join( [ "json://localhost", "xml://localhost", "pbul://credentials", ] ) cfg.apprise_urls.set(urls) mock_notify.return_value = True # Startup is disabled by default assert send_apprise("title", "body", "startup") == "" assert mock_notify.call_count == 0 mock_notify.reset_mock() mock_add.reset_mock() cfg.apprise_target_startup_enable.set(True) assert send_apprise("title", "body", "startup") == "" assert mock_notify.call_count == 1 mock_add.assert_called_once_with(urls) mock_notify.reset_mock() mock_add.reset_mock() for attr in dir(cfg): # Enable all of our apprise attributes if isinstance(getattr(cfg, attr), Option) and re.match("^apprise_target_.+_enable$", attr): getattr(cfg, attr).set(True) for t in NOTIFICATION_TYPES.keys(): mock_notify.reset_mock() mock_add.reset_mock() assert send_apprise("title", "body", t) == "" assert mock_notify.call_count == 1 assert mock_add.call_count == 1 mock_add.assert_called_once_with(urls) # Garbage in, get's garbage out mock_notify.reset_mock() mock_add.reset_mock() assert send_apprise("title", "body", "garbage_type") == "" # Nothing sent assert mock_notify.call_count == 0 assert mock_add.call_count == 0 # No URLs defined cfg.apprise_urls.set("") mock_notify.reset_mock() mock_add.reset_mock() assert send_apprise("title", "body", "other") == "" assert mock_notify.call_count == 0 assert mock_add.call_count == 0 # Special Targets mock_notify.reset_mock() mock_add.reset_mock() cfg.apprise_target_other.set("xml://custom/other") assert send_apprise("title", "body", "other") == "" assert mock_notify.call_count == 1 assert mock_add.call_count == 1 # Target value over-rides; this tests that a user can provide # over-rides to the Apprise URLs mock_add.assert_called_once_with("xml://custom/other") # Over-ride is still set even if general URLS are provided cfg.apprise_urls.set(urls) mock_notify.reset_mock() mock_add.reset_mock() assert send_apprise("title", "body", "other") == "" assert mock_notify.call_count == 1 assert mock_add.call_count == 1 # Target value over-rides; this tests that a user can provide # over-rides to the Apprise URLs mock_add.assert_called_once_with("xml://custom/other") # Test case where notify() fails mock_notify.return_value = False mock_notify.reset_mock() mock_add.reset_mock() # A non-string is returned assert send_apprise("title", "body", "other") != "" assert mock_notify.call_count == 1 assert mock_add.call_count == 1 # Test other exception handlings mock_notify.return_value = None mock_notify.side_effect = AttributeError mock_notify.reset_mock() mock_add.reset_mock() # A non-string is returned assert send_apprise("title", "body", "other") != "" assert mock_notify.call_count == 1 assert mock_add.call_count == 1 # Test Mode # Return the status to being a proper return value mock_notify.return_value = True mock_notify.side_effect = None mock_notify.reset_mock() mock_add.reset_mock() # Download is enabled by default; set Test flag assert send_apprise("title", "body", "download", test={"apprise_urls": urls}) == "" assert mock_notify.call_count == 1 assert mock_add.call_count == 1 mock_add.assert_called_once_with(urls) @mock.patch("threading.Thread.start") def test_send_notification_as_apprise(self, mock_thread): """ Test send_apprise() inside it's threaded check environment """ # Set up our config the way we want it cfg.apprise_enable.set(True) cfg.apprise_urls.set("okay://") # startup is disabled by default assert not cfg.apprise_target_startup_enable.get() send_notification("title", "body", "startup") assert mock_thread.call_count == 0 mock_thread.reset_mock() cfg.apprise_target_startup_enable.set(True) assert cfg.apprise_target_startup_enable.get() send_notification("title", "body", "startup") assert mock_thread.call_count == 1 mock_thread.reset_mock() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.440724 SABnzbd-4.3.2/tests/test_dirscanner.py0000644000000000000000000000763614625637243017142 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_dirscanner - Testing functions in dirscanner.py """ import asyncio import pyfakefs.fake_filesystem_unittest as ffs from sabnzbd.constants import AddNzbFileResult from tests.testhelper import * # Set the global uid for fake filesystems to a non-root user; # by default this depends on the user running pytest. global_uid = 1000 ffs.set_uid(global_uid) @pytest.fixture def create_mock_coroutine(mocker, monkeypatch): def _create_mock_patch_coro(to_patch=None): mock = mocker.Mock() async def coroutine(*args, **kwargs): return mock(*args, **kwargs) if to_patch: monkeypatch.setattr(to_patch, coroutine) return mock return _create_mock_patch_coro @pytest.fixture def mock_sleep(create_mock_coroutine): return create_mock_coroutine(to_patch="asyncio.sleep") class TestDirScanner: @pytest.mark.asyncio @pytest.mark.parametrize( "path, catdir", [ ("file.zip", None), ("file.rar", None), ("file.7z", None), ("file.nzb", None), ("file.gz", None), ("file.bz2", None), ("file.zip", "movies"), ("file.rar", "tv"), ("file.7z", "audio"), ("file.nzb", "software"), ("file.gz", "movies"), ("file.bz2", "tv"), ], ) async def test_adds_valid_nzbs(self, mock_sleep, fs, mocker, path, catdir): mocker.patch("sabnzbd.nzbparser.add_nzbfile", return_value=(AddNzbFileResult.ERROR, [])) mocker.patch("sabnzbd.config.save_config", return_value=True) fs.create_file(os.path.join(catdir or "", path), contents="FAKEFILE") scanner = sabnzbd.dirscanner.DirScanner() await scanner.scan_async("") sabnzbd.nzbparser.add_nzbfile.assert_any_call( os.path.join(sabnzbd.cfg.dirscan_dir.get_path(), catdir or "", path), catdir=catdir, keep=False ) @pytest.mark.asyncio @pytest.mark.parametrize( "path", [ "file.zip", "file.rar", "file.7z", "file.nzb", "file.gz", "file.bz2", ], ) async def test_ignores_empty_files(self, mock_sleep, fs, mocker, path): mocker.patch("sabnzbd.nzbparser.add_nzbfile", return_value=(AddNzbFileResult.ERROR, [])) mocker.patch("sabnzbd.config.save_config", return_value=True) fs.create_file(path) scanner = sabnzbd.dirscanner.DirScanner() await scanner.scan_async("") sabnzbd.nzbparser.add_nzbfile.assert_not_called() @pytest.mark.asyncio @pytest.mark.parametrize( "path", [ "file.doc", "filenzb", ], ) async def test_ignores_non_nzbs(self, mock_sleep, fs, mocker, path): mocker.patch("sabnzbd.nzbparser.add_nzbfile", return_value=(AddNzbFileResult.ERROR, [])) mocker.patch("sabnzbd.config.save_config", return_value=True) fs.create_file(path, contents="FAKEFILE") scanner = sabnzbd.dirscanner.DirScanner() await scanner.scan_async("") sabnzbd.nzbparser.add_nzbfile.assert_not_called() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4408376 SABnzbd-4.3.2/tests/test_functional_config.py0000644000000000000000000003033014625637243020464 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_config - Basic testing if Config pages work """ from selenium.common.exceptions import NoSuchElementException, UnexpectedAlertPresentException, NoAlertPresentException from selenium.webdriver.common.by import By from pytest_httpserver import HTTPServer from tests.testhelper import * class TestBasicPages(SABnzbdBaseTest): def test_base_pages(self): # Quick-check of all Config pages test_urls = ["config", "config/server", "config/categories", "config/scheduling", "config/rss"] for test_url in test_urls: self.open_page("http://%s:%s/%s" % (SAB_HOST, SAB_PORT, test_url)) def test_base_submit_pages(self): test_urls_with_submit = [ "config/general", "config/folders", "config/switches", "config/notify", "config/special", ] for test_url in test_urls_with_submit: self.open_page("http://%s:%s/%s" % (SAB_HOST, SAB_PORT, test_url)) # Can only click the visible buttons submit_btns = self.selenium_wrapper(self.driver.find_elements, By.CLASS_NAME, "saveButton") for submit_btn in submit_btns: if submit_btn.is_displayed(): break else: raise NoSuchElementException # Click the right button submit_btn.click() try: self.wait_for_ajax() except UnexpectedAlertPresentException: try: # Ignore restart-request due to empty sabnzbd.ini in tests self.driver.switch_to.alert.dismiss() except NoAlertPresentException: pass # For Specials page we get redirected after save, so check for no crash if "special" in test_url: self.no_page_crash() else: # For others if all is fine, button will be back to normal in 1 second time.sleep(1.5) assert submit_btn.text == "Save Changes" class TestConfigLogin(SABnzbdBaseTest): def test_login(self): # Test if base page works self.open_page("http://%s:%s/sabnzbd/config/general" % (SAB_HOST, SAB_PORT)) # Set the username and password username_imp = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[data-hide='username']") username_imp.clear() username_imp.send_keys("test_username") pass_inp = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[data-hide='password']") pass_inp.clear() pass_inp.send_keys("test_password") # Submit and ignore alert self.selenium_wrapper(self.driver.find_element, By.CLASS_NAME, "saveButton").click() try: self.wait_for_ajax() except UnexpectedAlertPresentException: try: # Ignore restart-request self.driver.switch_to.alert.dismiss() except NoAlertPresentException: pass # Open any page and check if we get redirected self.open_page("http://%s:%s/sabnzbd/general" % (SAB_HOST, SAB_PORT)) assert "/login/" in self.driver.current_url # Fill nonsense and submit username_login = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[name='username']") username_login.clear() username_login.send_keys("nonsense") pass_login = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[name='password']") pass_login.clear() pass_login.send_keys("nonsense") self.driver.find_element(By.TAG_NAME, "button").click() # Check if we were denied assert ( "Authentication failed" in self.selenium_wrapper(self.driver.find_element, By.CLASS_NAME, "alert-danger").text ) # Fill right stuff username_login = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[name='username']") username_login.clear() username_login.send_keys("test_username") pass_login = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[name='password']") pass_login.clear() pass_login.send_keys("test_password") self.driver.find_element(By.TAG_NAME, "button").click() # Can we now go to the page and empty the settings again? self.open_page("http://%s:%s/sabnzbd/config/general" % (SAB_HOST, SAB_PORT)) assert "/login/" not in self.driver.current_url # Set the username and password username_imp = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[data-hide='username']") username_imp.clear() pass_inp = self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "input[data-hide='password']") pass_inp.clear() # Submit and ignore alert self.selenium_wrapper(self.driver.find_element, By.CLASS_NAME, "saveButton").click() try: self.wait_for_ajax() except UnexpectedAlertPresentException: try: # Ignore restart-request self.driver.switch_to.alert.dismiss() except NoAlertPresentException: pass # Open any page and check if we get redirected self.open_page("http://%s:%s/sabnzbd/general" % (SAB_HOST, SAB_PORT)) assert "/login/" not in self.driver.current_url class TestConfigCategories(SABnzbdBaseTest): category_name = "testCat" def test_page(self): # Test if base page works self.open_page("http://%s:%s/sabnzbd/config/categories" % (SAB_HOST, SAB_PORT)) # Add new category self.driver.find_elements(By.NAME, "newname")[1].send_keys("testCat") self.selenium_wrapper( self.driver.find_element, By.XPATH, "//button/text()[normalize-space(.)='Add']/parent::*" ).click() self.no_page_crash() assert self.category_name not in self.driver.page_source class TestConfigRSS(SABnzbdBaseTest): rss_name = "_SeleniumFeed" def test_rss_basic_flow(self, httpserver: HTTPServer): # Setup the response for the NZB nzb_fp = create_and_read_nzb_fp("basic_rar5") httpserver.expect_request("/test_nzb.nzb").respond_with_data(nzb_fp.read()) nzb_url = httpserver.url_for("/test_nzb.nzb") # Set the response for the RSS-feed, replacing the URL to the NZB with open(os.path.join(SAB_DATA_DIR, "rss_feed_test.xml")) as rss_file: rss_data = rss_file.read() rss_data = rss_data.replace("NZB_URL", nzb_url) httpserver.expect_request("/rss_feed.xml").respond_with_data(rss_data) rss_url = httpserver.url_for("/rss_feed.xml") # Test if base page works self.open_page("http://%s:%s/sabnzbd/config/rss" % (SAB_HOST, SAB_PORT)) # Uncheck enabled-checkbox for new feeds self.selenium_wrapper( self.driver.find_element, By.XPATH, '//form[@action="add_rss_feed"]//input[@name="enable"]' ).click() input_name = self.selenium_wrapper( self.driver.find_element, By.XPATH, '//form[@action="add_rss_feed"]//input[@name="feed"]' ) input_name.clear() input_name.send_keys(self.rss_name) self.selenium_wrapper( self.driver.find_element, By.XPATH, '//form[@action="add_rss_feed"]//input[@name="uri"]' ).send_keys(rss_url) self.selenium_wrapper(self.driver.find_element, By.XPATH, '//form[@action="add_rss_feed"]//button').click() # Check if we have results tab_results = int( self.selenium_wrapper(self.driver.find_element, By.XPATH, '//a[@href="#rss-tab-matched"]/span').text ) assert tab_results > 0 # Check if it matches the number of rows tab_table_results = len(self.driver.find_elements(By.XPATH, '//div[@id="rss-tab-matched"]/table/tbody/tr')) assert tab_table_results == tab_results # Pause the queue do we don't download stuff assert get_api_result("pause") == {"status": True} # Download something download_btn = self.selenium_wrapper( self.driver.find_element, By.XPATH, '//div[@id="rss-tab-matched"]/table/tbody//button' ) download_btn.click() self.wait_for_ajax() # Does the page think it's a success? assert "Added NZB" in download_btn.text # Wait 2 seconds for the fetch time.sleep(2) # Let's check the queue for _ in range(10): queue_result_slots = get_api_result("queue")["queue"]["slots"] # Check if the fetch-request was added to the queue if queue_result_slots: break time.sleep(1) else: # The loop never stopped, so we fail pytest.fail("Did not find the RSS job in the queue") return # Let's remove this thing get_api_result("queue", extra_arguments={"name": "delete", "value": "all"}) assert len(get_api_result("queue")["queue"]["slots"]) == 0 # Unpause assert get_api_result("resume") == {"status": True} class TestConfigServers(SABnzbdBaseTest): server_name = "_SeleniumServer" def open_config_servers(self): # Test if base page works self.open_page("http://%s:%s/sabnzbd/config/server" % (SAB_HOST, SAB_PORT)) self.scroll_to_top() # Show advanced options advanced_btn = self.selenium_wrapper(self.driver.find_element, By.NAME, "advanced-settings-button") if not advanced_btn.get_attribute("checked"): advanced_btn.click() def add_test_server(self): # Add server self.selenium_wrapper(self.driver.find_element, By.ID, "addServerButton").click() host_inp = self.selenium_wrapper(self.driver.find_element, By.NAME, "host") host_inp.clear() host_inp.send_keys(SAB_NEWSSERVER_HOST) # Change port port_inp = self.selenium_wrapper(self.driver.find_element, By.NAME, "port") port_inp.clear() port_inp.send_keys(SAB_NEWSSERVER_PORT) # Disable SSL for testing self.selenium_wrapper(self.driver.find_element, By.NAME, "ssl").click() # Test server-check self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "#addServerContent .testServer").click() self.wait_for_ajax() check_result = self.selenium_wrapper( self.driver.find_element, By.CSS_SELECTOR, "#addServerContent .result-box" ).text assert "Connection Successful" in check_result # Set test-servername self.selenium_wrapper(self.driver.find_element, By.ID, "displayname").send_keys(self.server_name) # Add and show details port_inp.send_keys(Keys.RETURN) time.sleep(1) if not self.selenium_wrapper(self.driver.find_element, By.ID, "host0").is_displayed(): self.selenium_wrapper(self.driver.find_element, By.CLASS_NAME, "showserver").click() def remove_server(self): # Remove the first server and accept the confirmation self.selenium_wrapper(self.driver.find_element, By.CLASS_NAME, "delServer").click() self.driver.switch_to.alert.accept() # Check that it's gone time.sleep(2) assert self.server_name not in self.driver.page_source def test_add_and_remove_server(self): self.open_config_servers() self.add_test_server() self.remove_server() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.440916 SABnzbd-4.3.2/tests/test_misc.py0000644000000000000000000010757214625637243015745 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_misc - Testing functions in misc.py """ import datetime import subprocess import sys import tempfile from random import randint, sample from sabnzbd import lang from sabnzbd import misc from sabnzbd import newsunpack from sabnzbd.config import ConfigCat, get_sorters, save_config from sabnzbd.constants import HIGH_PRIORITY, FORCE_PRIORITY, DEFAULT_PRIORITY, NORMAL_PRIORITY, GUESSIT_SORT_TYPES from tests.testhelper import * class TestMisc: @staticmethod def assertTime(offset, age): assert offset == misc.calc_age(age, trans=True) assert offset == misc.calc_age(age, trans=False) def test_timeformat24h(self): assert "%H:%M:%S" == misc.time_format("%H:%M:%S") assert "%H:%M" == misc.time_format("%H:%M") @set_config({"ampm": True}) def test_timeformatampm(self): misc.HAVE_AMPM = True assert "%I:%M:%S %p" == misc.time_format("%H:%M:%S") assert "%I:%M %p" == misc.time_format("%H:%M") def test_calc_age(self): date = datetime.datetime.now() m = date - datetime.timedelta(minutes=1) h = date - datetime.timedelta(hours=1) d = date - datetime.timedelta(days=1) self.assertTime("1m", m) self.assertTime("1h", h) self.assertTime("1d", d) def test_safe_lower(self): assert "all caps" == misc.safe_lower("ALL CAPS") assert "" == misc.safe_lower(None) def test_is_none(self): assert misc.is_none(None) is True assert misc.is_none(0) is True assert misc.is_none(False) is True assert misc.is_none("None") is True assert misc.is_none("nOne") is True assert misc.is_none(True) is False assert misc.is_none(1) is False assert misc.is_none(True) is False assert misc.is_none("Not None") is False def test_clean_comma_separated_list(self): assert misc.clean_comma_separated_list("") == [] assert misc.clean_comma_separated_list(None) == [] assert misc.clean_comma_separated_list(123) == [] assert misc.clean_comma_separated_list("a,b") == ["a", "b"] assert misc.clean_comma_separated_list(",b") == ["b"] assert misc.clean_comma_separated_list(" a , b ") == ["a", "b"] assert misc.clean_comma_separated_list(["a ", " b", ""]) == ["a", "b"] def test_cmp(self): assert misc.cmp(1, 2) < 0 assert misc.cmp(2, 1) > 0 assert misc.cmp(1, 1) == 0 def test_cat_to_opts(self): # Need to create the Default category, as we would in normal instance # Otherwise it will try to save the config ConfigCat("*", {"pp": 3, "script": "None", "priority": NORMAL_PRIORITY}) assert ("*", 3, "None", NORMAL_PRIORITY) == misc.cat_to_opts("*") assert ("*", 3, "None", NORMAL_PRIORITY) == misc.cat_to_opts("Nonsense") assert ("*", 1, "None", NORMAL_PRIORITY) == misc.cat_to_opts("*", pp=1) assert ("*", 1, "test.py", NORMAL_PRIORITY) == misc.cat_to_opts("*", pp=1, script="test.py") ConfigCat("movies", {"priority": HIGH_PRIORITY, "script": "test.py"}) assert ("movies", 3, "test.py", HIGH_PRIORITY) == misc.cat_to_opts("movies") assert ("movies", 1, "test.py", HIGH_PRIORITY) == misc.cat_to_opts("movies", pp=1) assert ("movies", 1, "not_test.py", HIGH_PRIORITY) == misc.cat_to_opts("movies", pp=1, script="not_test.py") assert ("movies", 3, "test.py", FORCE_PRIORITY) == misc.cat_to_opts("movies", priority=FORCE_PRIORITY) # If the category has DEFAULT_PRIORITY, it should use the priority of the *-category (NORMAL_PRIORITY) # If the script-name is Default for a category, it should use the script of the *-category (None) ConfigCat("software", {"priority": DEFAULT_PRIORITY, "script": "Default"}) assert ("software", 3, "None", NORMAL_PRIORITY) == misc.cat_to_opts("software") assert ("software", 3, "None", FORCE_PRIORITY) == misc.cat_to_opts("software", priority=FORCE_PRIORITY) def test_wildcard_to_re(self): assert "\\\\\\^\\$\\.\\[" == misc.wildcard_to_re("\\^$.[") assert "\\]\\(\\)\\+.\\|\\{\\}.*" == misc.wildcard_to_re("]()+?|{}*") def test_cat_convert(self): # TODO: Make test pass def test_convert_version(self): assert (3010099, False) == misc.convert_version("3.1.0") assert (3010099, False) == misc.convert_version("3.1.0BlaBla") assert (3010001, True) == misc.convert_version("3.1.0Alpha1") assert (3010041, True) == misc.convert_version("3.1.0Beta1") assert (3010081, True) == misc.convert_version("3.1.0RC1") assert (3010194, True) == misc.convert_version("3.1.1RC14") def test_from_units(self): assert -1.0 == misc.from_units("-1") assert 100.0 == misc.from_units("100") assert 1024.0 == misc.from_units("1KB") assert 1048576.0 == misc.from_units("1024KB") assert 1048576.0 == misc.from_units("1024Kb") assert 1048576.0 == misc.from_units("1024kB") assert 1048576.0 == misc.from_units("1MB") assert 1073741824.0 == misc.from_units("1GB") assert 1125899906842624.0 == misc.from_units("1P") def test_to_units(self): assert "" == misc.to_units("foobar") assert "1 K" == misc.to_units(1024) assert "1 KBla" == misc.to_units(1024, postfix="Bla") assert "1.0 M" == misc.to_units(1024 * 1024) assert "1.0 M" == misc.to_units(1024 * 1024 + 10) assert "-1.0 M" == misc.to_units(-1024 * 1024) assert "10.0 M" == misc.to_units(1024 * 1024 * 10) assert "100.0 M" == misc.to_units(1024 * 1024 * 100) assert "9.8 G" == misc.to_units(1024 * 1024 * 10000) assert "1024.0 P" == misc.to_units(1024**6) def test_unit_back_and_forth(self): assert 100 == misc.from_units(misc.to_units(100)) assert 1024 == misc.from_units(misc.to_units(1024)) assert 1024**3 == misc.from_units(misc.to_units(1024**3)) # Negative numbers are not supported assert 100 == misc.from_units(misc.to_units(-100)) def test_caller_name(self): @set_config({"log_level": 0}) def test_wrapper(skip): return misc.caller_name(skip=skip) @set_config({"log_level": 2}) def test_wrapper_2(skip): return misc.caller_name(skip=skip) # No logging on lower-level assert "N/A" == test_wrapper(1) assert "N/A" == test_wrapper(2) assert "N/A" == test_wrapper(3) # Wrappers originate from the set_config-wrapper assert "test_wrapper_2" in test_wrapper_2(1) assert "wrapper_func" in test_wrapper_2(2) def test_split_host(self): assert (None, None) == misc.split_host(None) assert (None, None) == misc.split_host("") assert ("sabnzbd.org", 123) == misc.split_host("sabnzbd.org:123") assert ("sabnzbd.org", None) == misc.split_host("sabnzbd.org") assert ("127.0.0.1", 566) == misc.split_host("127.0.0.1:566") assert ("[::1]", 1234) == misc.split_host("[::1]:1234") assert ("[2001:db8::8080]", None) == misc.split_host("[2001:db8::8080]") @set_config({"cleanup_list": [".exe", ".nzb"]}) def test_on_cleanup_list(self): assert misc.on_cleanup_list("test.exe") assert misc.on_cleanup_list("TEST.EXE") assert misc.on_cleanup_list("longExeFIlanam.EXe") assert not misc.on_cleanup_list("testexe") assert misc.on_cleanup_list("test.nzb") assert not misc.on_cleanup_list("test.nzb", skip_nzb=True) assert not misc.on_cleanup_list("test.exe.lnk") def test_format_time_string(self): assert "0 seconds" == misc.format_time_string(None) assert "0 seconds" == misc.format_time_string("Test") assert "0 seconds" == misc.format_time_string(0) assert "1 sec" == misc.format_time_string(1) assert "10 seconds" == misc.format_time_string(10) assert "1 min" == misc.format_time_string(60) assert "1 hour 1 min 1 sec" == misc.format_time_string(60 * 60 + 60 + 1) assert "1 day 59 seconds" == misc.format_time_string(86400 + 59) assert "2 days 2 hours 2 seconds" == misc.format_time_string(2 * 86400 + 2 * 60 * 60 + 2) def test_format_time_string_locale(self): # Have to set the languages, if it was compiled locale_dir = os.path.join(SAB_BASE_DIR, "..", sabnzbd.constants.DEF_LANGUAGE) if not os.path.exists(locale_dir): pytest.mark.skip("No language files compiled") lang.set_locale_info("SABnzbd", locale_dir) lang.set_language("de") assert "1 Sekunde" == misc.format_time_string(1) assert "10 Sekunden" == misc.format_time_string(10) assert "1 Minuten" == misc.format_time_string(60) assert "1 Stunde 1 Minuten 1 Sekunde" == misc.format_time_string(60 * 60 + 60 + 1) assert "1 Tag 59 Sekunden" == misc.format_time_string(86400 + 59) assert "2 Tage 2 Stunden 2 Sekunden" == misc.format_time_string(2 * 86400 + 2 * 60 * 60 + 2) # Reset language lang.set_language() def test_format_time_left(self): assert "0:00:00" == misc.format_time_left(0) assert "0:00:00" == misc.format_time_left(-1) assert "0:00:01" == misc.format_time_left(1) assert "0:01:01" == misc.format_time_left(60 + 1) assert "0:11:10" == misc.format_time_left(60 * 11 + 10) assert "3:11:10" == misc.format_time_left(60 * 60 * 3 + 60 * 11 + 10) assert "13:11:10" == misc.format_time_left(60 * 60 * 13 + 60 * 11 + 10) assert "1:09:11:10" == misc.format_time_left(60 * 60 * 33 + 60 * 11 + 10) def test_format_time_left_short(self): assert "0:00" == misc.format_time_left(0, short_format=True) assert "0:01" == misc.format_time_left(1, short_format=True) assert "1:01" == misc.format_time_left(60 + 1, short_format=True) assert "11:10" == misc.format_time_left(60 * 11 + 10, short_format=True) assert "3:11:10" == misc.format_time_left(60 * 60 * 3 + 60 * 11 + 10, short_format=True) assert "13:11:10" == misc.format_time_left(60 * 60 * 13 + 60 * 11 + 10, short_format=True) assert "1:09:11:10" == misc.format_time_left(60 * 60 * 33 + 60 * 11 + 10, short_format=True) def test_int_conv(self): assert 0 == misc.int_conv("0") assert 10 == misc.int_conv("10") assert 10 == misc.int_conv(10) assert 10 == misc.int_conv(10.0) assert 0 == misc.int_conv(None) assert 1 == misc.int_conv(True) assert 0 == misc.int_conv(object) def test_create_https_certificates(self): cert_file = "test.cert" key_file = "test.key" assert misc.create_https_certificates(cert_file, key_file) assert os.path.exists(cert_file) assert os.path.exists(key_file) # Remove files os.unlink("test.cert") os.unlink("test.key") @pytest.mark.parametrize( "name, result", [ ("Free.Open.Source.Movie.2001.1080p.WEB-DL.DD5.1.H264-FOSS", False), # Not samples ("Setup.exe", False), ("23.123.hdtv-rofl", False), ("Something.1080p.WEB-DL.DD5.1.H264-EMRG-sample", True), # Samples ("Something.1080p.WEB-DL.DD5.1.H264-EMRG-sample.ogg", True), ("Sumtin_Else_1080p_WEB-DL_DD5.1_H264_proof-EMRG", True), ("Wot.Eva.540i.WEB-DL.aac.H264-Groupie sample.mp4", True), ("file-sample.mkv", True), ("PROOF.JPG", True), ("Bla.s01e02.title.1080p.aac-sample proof.mkv", True), ("Bla.s01e02.title.1080p.aac-proof.mkv", True), ("Bla.s01e02.title.1080p.aac sample proof.mkv", True), ("Bla.s01e02.title.1080p.aac proof.mkv", True), ("Lwtn.s08e26.1080p.web.h264-glhf-sample.par2", True), ("Lwtn.s08e26.1080p.web.h264-glhf-sample.vol001-002.par2", True), ("Look at That 2011 540i WEB-DL.H265-NoSample", False), ], ) def test_is_sample(self, name, result): assert misc.is_sample(name) == result @pytest.mark.parametrize( "name, result", [ ("Not Death Proof (2022) 1080p x264 (DD5.1) BE Subs", False), # Try to trigger some false positives ("Proof.of.Everything.(2042).4320p.x266-4U", False), ("Crime_Scene_S01E13_Free_Sample_For_Sale_480p-OhDear", False), ("Sample That 2011 480p WEB-DL.H265-aMiGo", False), ("NOT A SAMPLE.JPG", False), ], ) def test_is_sample_known_false_positives(self, name, result): """We know these fail, but don't have a better solution for them at the moment.""" assert misc.is_sample(name) != result @pytest.mark.parametrize( "test_input, expected_output", [ (["cmd1", 9, "cmd3"], '"cmd1" "9" "cmd3"'), # sending all commands as valid string (["", "cmd1", "5"], '"" "cmd1" "5"'), # sending blank string (["cmd1", None, "cmd3", "tail -f"], '"cmd1" "" "cmd3" "tail -f"'), # sending None in command (["cmd1", 0, "ps ux"], '"cmd1" "" "ps ux"'), # sending 0 (['pass"word', "command"], '"pass""word" "command"'), # special escaping of unrar ], ) def test_list2cmdline_unrar(self, test_input, expected_output): """Test to convert list to a cmd.exe-compatible command string""" res = misc.list2cmdline_unrar(test_input) # Make sure the output is cmd.exe-compatible assert res == expected_output def test_recursive_html_escape(self): """Very basic test if the recursive clean-up works""" input_test = { "foo": "?ar'\"", "test_list": ["test&1", 'test"2'], "test_nested_list": [["test&1", 'test"2', 4]], "test_dict": {"test": ["test<>1", "#"]}, } # Dict is updated in-place misc.recursive_html_escape(input_test) # Have to check them by hand assert input_test["foo"] == "<b>?ar'"" assert input_test["test_list"] == ["test&1", "test"2"] assert input_test["test_nested_list"] == [["test&1", "test"2", 4]] assert input_test["test_dict"]["test"] == ["test<>1", "#"] @pytest.mark.parametrize( "value, result", [ ("1.2.3.4", True), ("255.255.255.255", True), ("0.0.0.0", True), ("10.11.12.13", True), ("127.0.0.1", True), ("400.500.600.700", False), ("blabla", False), ("2001::1", False), ("::1", False), ("::", False), ("example.org", False), (None, False), ("", False), ("3.2.0", False), (-42, False), ("::ffff:192.168.1.100", False), ], ) def test_is_ipv4_addr(self, value, result): assert misc.is_ipv4_addr(value) is result @pytest.mark.parametrize( "value, result", [ ("2001::1", True), ("::1", True), ("[2001::1]", True), ("fdd6:5a2d:3f20:0:14b0:d8f4:ccb9:fab6", True), ("::", True), ("a::b", True), ("1.2.3.4", False), ("255.255.255.255", False), ("0.0.0.0", False), ("10.11.12.13", False), ("127.0.0.1", False), ("400.500.600.700", False), ("blabla", False), (666, False), ("example.org", False), (None, False), ("", False), ("[1.2.3.4]", False), ("2001:1", False), ("2001::[2001::1]", False), ("::ffff:192.168.1.100", True), ], ) def test_is_ipv6_addr(self, value, result): assert misc.is_ipv6_addr(value) is result @pytest.mark.parametrize( "value, result", [ ("::1", True), ("[::1]", True), ("127.0.0.1", True), ("127.255.0.0", True), ("127.1.2.7", True), ("fdd6:5a2d:3f20:0:14b0:d8f4:ccb9:fab6", False), ("::", False), ("a::b", False), ("1.2.3.4", False), ("255.255.255.255", False), ("0.0.0.0", False), ("10.11.12.13", False), ("400.500.600.700", False), ("localhost", False), (-666, False), ("example.org", False), (None, False), ("", False), ("[127.6.6.6]", False), ("2001:1", False), ("2001::[2001::1]", False), ("::ffff:192.168.1.100", False), ("::ffff:1.1.1.1", False), ("::ffff:127.0.0.1", True), ], ) def test_is_loopback_addr(self, value, result): assert misc.is_loopback_addr(value) is result @pytest.mark.parametrize( "value, result", [ ("localhost", True), ("::1", True), ("[::1]", True), ("localhost", True), ("127.0.0.1", True), ("127.255.0.0", True), ("127.1.2.7", True), (".local", False), ("test.local", False), ("fdd6:5a2d:3f20:0:14b0:d8f4:ccb9:fab6", False), ("::", False), ("a::b", False), ("1.2.3.4", False), ("255.255.255.255", False), ("0.0.0.0", False), ("10.11.12.13", False), ("400.500.600.700", False), (-1984, False), ("example.org", False), (None, False), ("", False), ("[127.6.6.6]", False), ("2001:1", False), ("2001::[2001::1]", False), ("::ffff:192.168.1.100", False), ("::ffff:1.1.1.1", False), ("::ffff:127.0.0.1", True), ], ) def test_is_localhost(self, value, result): assert misc.is_localhost(value) is result @pytest.mark.parametrize( "value, result", [ ("10.11.12.13", True), ("172.16.2.81", True), ("192.168.255.255", True), ("169.254.42.42", True), # Link-local ("fd00::ffff", True), # Part of fc00::/7, IPv6 "Unique Local Addresses" ("fe80::a1", True), # IPv6 Link-local ("::1", False), ("localhost", False), ("127.0.0.1", False), ("2001:1337:babe::", False), ("172.32.32.32", False), # Near but not part of 172.16.0.0/12 ("100.64.0.1", False), # Test net ("[2001::1]", False), ("::", False), ("::a:b:c", False), ("1.2.3.4", False), ("255.255.255.255", False), ("0.0.0.0", False), ("127.0.0.1", False), ("400.500.600.700", False), ("blabla", False), (-666, False), ("example.org", False), (None, False), ("", False), ("[1.2.3.4]", False), ("2001:1", False), ("2001::[2001::1]", False), ("::ffff:192.168.1.100", True), ("::ffff:1.1.1.1", False), ("::ffff:127.0.0.1", False), ], ) def test_is_lan_addr(self, value, result): assert misc.is_lan_addr(value) is result @pytest.mark.parametrize( "value, local_ranges, result", [ ("10.11.12.13", None, True), ("172.16.2.81", None, True), ("192.168.255.255", None, True), ("169.254.42.42", None, True), # Link-local ("fd00::ffff", None, True), # Part of fc00::/7, IPv6 "Unique Local Addresses" ("fe80::a1", None, True), # IPv6 Link-local ("::1", None, False), ("localhost", None, False), ("127.0.0.1", None, False), ("2001:1337:babe::", None, False), ("172.32.32.32", None, False), # Near but not part of 172.16.0.0/12 ("100.64.0.1", None, False), # Test net ("[2001::1]", None, False), ("::", None, False), ("::a:b:c", None, False), ("1.2.3.4", None, False), ("255.255.255.255", None, False), ("0.0.0.0", None, False), ("127.0.0.1", None, False), ("400.500.600.700", None, False), ("blabla", None, False), (-666, None, False), ("example.org", None, False), (None, None, False), ("", None, False), ("[1.2.3.4]", None, False), ("2001:1", None, False), ("2001::[2001::1]", None, False), ("::ffff:192.168.1.100", None, True), ("::ffff:1.1.1.1", None, False), ("::ffff:127.0.0.1", None, False), ("10.11.12.13", "10.0.0.0/8", True), ("10.11.12.13", "12.34.56.78, 10.0.0.0/8", True), ("10.11.12.13", "10.0.0.0/24", False), ("172.16.2.81", "10.0.0.0/24", False), ("192.168.255.255", "2001::/64", False), ("2001:1337:babe::42", "2001:1337:babe::/48", True), ("2001:1337:babe::11", "1002:1337:babe::/48", False), ("2001:1337:babe::", "2001:1337:babe::/16", False), # Invalid local range ("2001:1337:babe::", "1002:1337:babe::/8", False), # Idem ("2001::1", "2001::/2", False), ("::", "1.2.3.0/26, 9.8.7.6", False), ("::a:b:c", "1.2.3.0/26, 9.8.7.6", False), ("1.2.3.4", "1.2.3.0/24, 9.8.7.6", True), ("1.2.3.4", "1.2.3.4/32, 9.8.7.6", True), ("1.2.3.4", "9.8.7.6, 1.2.3.4/32", True), ("1.2.3.4", "ffff:1234::/128, 1.2.3.4/32, 9.8.7.6", True), ("ffff:1234::0", "ffff:1234::/128, 1.2.3.4/32, 9.8.7.6", True), ("EEEE::ccc", "ffff:1234::/128, 1.2.3.4/32, 9.8.7.6", False), ("FFFFFFFF:1234::0", "ffff:1234::/128, 1.2.3.4/32, 9.8.7.6", False), ("1.2.3.4", "1.2.3.3/32, 9.8.7.6", False), ("1.2.3.4", "1.2.3.5/32, 9.8.7.6", False), ], ) def test_is_local_addr(self, value, local_ranges, result): @set_config({"local_ranges": local_ranges}) def _func(): assert misc.is_local_addr(value) is result _func() @pytest.mark.parametrize( "ip, subnet, result", [ ("2001:c0f:fee::1", "2001:c0f:fee", True), # Old-style range setting ("2001:c0f:fee::1", "2001:c0f:FEE:", True), ("2001:c0f:fee::1", "2001:c0FF:ffee", False), ("2001:c0f:fee::1", "2001:c0ff:ffee:", False), ("2001:C0F:FEE::1", "2001:c0f:fee::/48", True), ("2001:c0f:fee::1", "2001:c0f:fee::/112", True), ("2001:c0f:fee::1", "::/0", True), # Subnet equals the entire IPv6 address space ("2001:c0f:fee::1", "2001:c0:ffee::/48", False), ("2001:c0f:fee::1", "2001:c0ff:ee::/112", False), ("2001:c0f:fEE::1", "2001:c0f:fee:eeee::/48", False), # Invalid subnet ("2001:c0f:Fee::1", "2001:c0f:fee:/64", False), ("2001:c0f:fee::1", "2001:c0f:fee:eeee:3:2:1:0/112", False), ("2001:c0f:fee::1", "2001:c0f:fee::1", True), # Single-IP subnet ("2001:c0f:fee::1", "2001:c0f:fee::1/128", True), ("2001:c0f:fee::1", "2001:c0f:fee::2", False), ("2001:c0f:fee::1", "2001:c0f:fee::2/128", False), ("::1", "::/127", True), ("::1", "2021::/64", False), # Localhost not in subnet ("192.168.43.21", "192.168.43", True), # Old-style subnet setting ("192.168.43.21", "192.168.43.", True), ("192.168.43.21", "192.168.4", False), ("192.168.43.21", "192.168.4.", False), ("10.11.12.13", "10", True), # Bad old-style setting (allowed 100.0.0.0/6, 104.0.0.0/6 and 108.0.0.0/7) ("10.11.12.13", "10.", True), # Correct version of the same (10.0.0.0/8 only) ("108.1.2.3", "10", False), # This used to be allowed with the bad setting! ("108.1.2.3", "10.", False), ("192.168.43.21", "192.168.0.0/16", True), ("192.168.43.21", "192.168.0.0/255.255.255.0", True), ("::ffff:192.168.43.21", "192.168.43.0/24", True), # IPv4-mapped IPv6 ("dual-stack") notation ("::FFff:192.168.43.21", "192.168.43.0/24", True), ("::ffff:192.168.12.34", "192.168.43.0/24", False), ("::ffFF:192.168.12.34", "192.168.43.0/24", False), ("192.168.43.21", "192.168.43.0/26", True), ("200.100.50.25", "0.0.0.0/0", True), # Subnet equals the entire IPv4 address space ("192.168.43.21", "10.0.0.0/8", False), ("192.168.43.21", "192.168.1.0/22", False), ("192.168.43.21", "192.168.43.21/24", False), # Invalid subnet ("192.168.43.21", "192.168.43/24", False), ("192.168.43.21", "192.168.43.0/16", False), ("192.168.43.21", "192.168.43.0/255.252.0.0", False), ("192.168.43.21", "192.168.43.21", True), # Single-IP subnet ("192.168.43.21", "192.168.43.21/32", True), ("192.168.43.21", "192.168.43.21/255.255.255.255", True), ("192.168.43.21", "192.168.43.12", False), ("192.168.43.21", "192.168.43.0/32", False), ("192.168.43.21", "43.21.168.192/255.255.255.255", False), ("127.0.0.1", "127.0.0.0/31", True), ("127.0.1.1", "127.0.0.0/24", False), # Localhost not in subnet ("111.222.33.44", "111:222:33::/96", False), # IPv4/IPv6 mixup ("111:222:33::44", "111.222.0.0/24", False), ("aaaa::1:2:3:4", "f:g:h:i:43:21::/112", False), # Invalid subnet ("4.3.2.1", "654.3.2.1.0/24", False), (None, "1.2.3.4/32", False), # Missing input ("1:a:2:b::", None, False), (None, None, False), ], ) def test_ip_in_subnet(self, ip, subnet, result): misc.ip_in_subnet(ip, subnet) is result @pytest.mark.parametrize( "ip, result", [ ("::ffff:127.0.0.1", "127.0.0.1"), ("::FFFF:127.0.0.1", "127.0.0.1"), ("::ffff:192.168.1.255", "192.168.1.255"), ("::ffff:8.8.8.8", "8.8.8.8"), ("2007::2021", "2007::2021"), ("::ffff:2007:2021", "::ffff:2007:2021"), ("2007::ffff:2021", "2007::ffff:2021"), ("12.34.56.78", "12.34.56.78"), ("foobar", "foobar"), ("0:0:0:0:0:ffff:8.8.4.4", "8.8.4.4"), ("0000:0000:0000:0000:0000:ffff:1.0.0.1", "1.0.0.1"), ("0000::0:ffff:1.1.1.1", "1.1.1.1"), ], ) def test_strip_ipv4_mapped_notation(self, ip, result): misc.strip_ipv4_mapped_notation(ip) == result def test_sort_to_opts(self): for result, sort_type in GUESSIT_SORT_TYPES.items(): assert misc.sort_to_opts(sort_type) == result @pytest.mark.parametrize( "sort_type, result", [ ("", 0), ("foobar", 0), (False, 0), (666, 0), ], ) def test_sort_to_opts_edge_cases(self, sort_type, result): assert misc.sort_to_opts(sort_type) == result @pytest.mark.parametrize("movie_limit", ["", "42M"]) @pytest.mark.parametrize("episode_limit", ["", "13M"]) @pytest.mark.parametrize("movie_sort_extra", ["", "disc%1"]) @pytest.mark.parametrize("tv_enabled", [True, False]) @pytest.mark.parametrize("tv_str", ["", "foobar tv"]) @pytest.mark.parametrize("tv_cats", [sample(["tv", "sports"], randint(0, 2))]) @pytest.mark.parametrize("date_enabled", [True, False]) @pytest.mark.parametrize("date_str", ["", "foobar date"]) @pytest.mark.parametrize("date_cats", [sample(["date"], randint(0, 1))]) @pytest.mark.parametrize("movie_enabled", [True, False]) @pytest.mark.parametrize("movie_str", ["", "foobar movie"]) @pytest.mark.parametrize("movie_cats", [[], ["movie"], ["movie", "horror", "docu"]]) def test_convert_sorter_settings( self, movie_limit, episode_limit, movie_sort_extra, tv_enabled, tv_str, tv_cats, date_enabled, date_str, date_cats, movie_enabled, movie_str, movie_cats, ): @set_config( { "movie_rename_limit": movie_limit, "episode_rename_limit": episode_limit, "movie_sort_extra": movie_sort_extra, "enable_tv_sorting": tv_enabled, "tv_sort_string": tv_str, "tv_categories": tv_cats, "enable_movie_sorting": movie_enabled, "movie_sort_string": movie_str, "movie_categories": movie_cats, "enable_date_sorting": date_enabled, "date_sort_string": date_str, "date_categories": date_cats, "language": "en", # Avoid translated sorter names in the test } ) def _func(): # Delete any leftover/pre-defined new-style sorters if existing_sorters := get_sorters(): for config in list(existing_sorters.keys()): try: existing_sorters[config].delete() except NameError as error: if "CFG_OBJ" in str(error): # Ignore failure to save the config to file in this very barebones test environment pass assert not get_sorters() # Run conversion misc.convert_sorter_settings() try: save_config() except NameError as error: if "CFG_OBJ" in str(error): # Once again, ignore failure to save the config pass # Verify the resulting config new_sorters = get_sorters() new_sorter_count = 0 for old_sorter_type, old_name, old_str, old_cats, old_enabled in ( ("tv", "Series Sorting", tv_str, tv_cats, tv_enabled), ("date", "Date Sorting", date_str, date_cats, date_enabled), ("movie", "Movie Sorting", movie_str, movie_cats, movie_enabled), ): if not old_str or not old_cats or not old_enabled: # Without these two essential variables, no new sorter config should be generated assert old_name not in new_sorters.keys() continue # Run basic checks on the new sorter assert new_sorters[old_name] new_sorter = new_sorters[old_name].get_dict() assert len(new_sorter) == 8 # Handle the old, movie-specific sorting features size_limit = movie_limit if old_sorter_type == "movie" else episode_limit part_label = movie_sort_extra if old_sorter_type == "movie" else "" # Verify the entire new sorter config for key, value in ( ("name", old_name), ("order", new_sorter_count), ("min_size", size_limit), ("multipart_label", part_label), ("sort_string", old_str), ("sort_cats", old_cats), ("sort_type", [misc.sort_to_opts(old_sorter_type)]), ("is_active", int(old_enabled)), ): assert (new_sorter[key]) == value # Update counter new_sorter_count += 1 # Verify no extra sorters appeared out of nowhere assert new_sorter_count == len(new_sorters) _func() class TestBuildAndRunCommand: # Path should exist script_path = os.path.join(SAB_BASE_DIR, "test_misc.py") def test_none_check(self): with pytest.raises(IOError): misc.build_and_run_command([None]) @mock.patch("subprocess.Popen") @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows tests") def test_win(self, mock_subproc_popen): # Needed for priority and startupinfo check import win32process import win32con misc.build_and_run_command(["test.cmd", "input 1"]) assert mock_subproc_popen.call_args[0][0] == ["test.cmd", "input 1"] assert mock_subproc_popen.call_args[1]["creationflags"] == win32process.NORMAL_PRIORITY_CLASS assert mock_subproc_popen.call_args[1]["startupinfo"].dwFlags == win32process.STARTF_USESHOWWINDOW assert mock_subproc_popen.call_args[1]["startupinfo"].wShowWindow == win32con.SW_HIDE misc.build_and_run_command(["test.py", "input 1"]) assert mock_subproc_popen.call_args[0][0] == ["python.exe", "test.py", "input 1"] assert mock_subproc_popen.call_args[1]["creationflags"] == win32process.NORMAL_PRIORITY_CLASS assert mock_subproc_popen.call_args[1]["startupinfo"].dwFlags == win32process.STARTF_USESHOWWINDOW assert mock_subproc_popen.call_args[1]["startupinfo"].wShowWindow == win32con.SW_HIDE # See: https://github.com/sabnzbd/sabnzbd/issues/1043 misc.build_and_run_command(["UnRar.exe", "\\\\?\\C:\\path\\"]) assert mock_subproc_popen.call_args[0][0] == ["UnRar.exe", "\\\\?\\C:\\path\\"] misc.build_and_run_command(["UnRar.exe", "\\\\?\\C:\\path\\", "pass'\"word"], windows_unrar_command=True) assert mock_subproc_popen.call_args[0][0] == '"UnRar.exe" "\\\\?\\C:\\path\\" "pass\'""word"' @mock.patch("sabnzbd.misc.userxbit") @mock.patch("subprocess.Popen") def test_std_override(self, mock_subproc_popen, userxbit): userxbit.return_value = True misc.build_and_run_command([self.script_path], stderr=subprocess.DEVNULL) assert mock_subproc_popen.call_args[1]["stderr"] == subprocess.DEVNULL @set_platform("linux") @set_config({"nice": "--adjustment=-7", "ionice": "-t -n9 -c7"}) @mock.patch("sabnzbd.misc.userxbit") @mock.patch("subprocess.Popen") def test_linux_features(self, mock_subproc_popen, userxbit): # Should break on no-execute permissions userxbit.return_value = False with pytest.raises(IOError): misc.build_and_run_command([self.script_path, "input 1"]) userxbit.return_value = True # Check if python-call is added if not supplied by shebang temp_file_fd, temp_file_path = tempfile.mkstemp(suffix=".py") os.close(temp_file_fd) misc.build_and_run_command([temp_file_path, "input 1"]) assert mock_subproc_popen.call_args[0][0] == [ sys.executable if sys.executable else "python", temp_file_path, "input 1", ] os.remove(temp_file_path) # Make sure Windows UnRar patching stays on Windows test_cmd = ["unrar", "/home/", "pass'\"word"] misc.build_and_run_command(test_cmd, windows_unrar_command=True) assert mock_subproc_popen.call_args[0][0] == test_cmd # Have to fake these for it to work newsunpack.IONICE_COMMAND = "ionice" newsunpack.NICE_COMMAND = "nice" userxbit.return_value = True misc.build_and_run_command([self.script_path, "input 1"]) assert mock_subproc_popen.call_args[0][0] == [ "nice", "--adjustment=-7", "ionice", "-t", "-n9", "-c7", self.script_path, "input 1", ] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4410005 SABnzbd-4.3.2/tests/test_newswrapper.py0000644000000000000000000001233714625637243017361 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_newswrapper - Tests of various functions in newswrapper """ import logging import os.path import socket import tempfile import threading import ssl import time import warnings from typing import Optional import portend from flaky import flaky from tests.testhelper import * from sabnzbd import misc from sabnzbd import newswrapper from sabnzbd.happyeyeballs import AddrInfo TEST_HOST = "127.0.0.1" TEST_PORT = portend.find_available_local_port() TEST_DATA = b"connection_test" def socket_test_server(ssl_context: ssl.SSLContext): """Support function that starts a mini-server""" # Allow reuse of the address, because our CI is too fast for the socket closing server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: server_socket.bind((TEST_HOST, TEST_PORT)) server_socket.listen(1) server_socket.settimeout(1.0) conn, _ = server_socket.accept() with ssl_context.wrap_socket(sock=conn, server_side=True) as wrapped_socket: wrapped_socket.write(TEST_DATA) except Exception as e: # Skip SSL errors logging.info("Error in server: %s", e) pass finally: # Make sure to close the socket server_socket.close() @flaky class TestNewsWrapper: cert_file = os.path.join(tempfile.mkdtemp(), "test.cert") key_file = os.path.join(tempfile.mkdtemp(), "test.key") @pytest.mark.parametrize( "server_tls, expected_client_tls, client_cipher, can_connect", [ (None, "TLSv1.3", None, True), # Default, highest (ssl.TLSVersion.TLSv1_2, "TLSv1.2", None, True), # Server with just TLSv1.2 (ssl.TLSVersion.SSLv3, None, None, False), # No connection for old TLS/SSL (ssl.TLSVersion.TLSv1, None, None, False), (ssl.TLSVersion.TLSv1_1, None, None, False), (None, None, "RC4-MD5", False), # No connection for old cipher (None, "TLSv1.2", "AES256-SHA", True), # Forced to TLSv1.2 if ciphers set (None, None, "TLS_AES_128_CCM_SHA256", False), # Cannot force use of TLSv1.3 cipher ], ) def test_newswrapper( self, server_tls: Optional[ssl.TLSVersion], expected_client_tls: Optional[str], client_cipher: Optional[str], can_connect: bool, ): # We need at least some certificates for the server to work if not os.path.exists(self.cert_file) or not os.path.exists(self.key_file): misc.create_https_certificates(self.cert_file, self.key_file) # Create the server context server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_context.load_cert_chain(self.cert_file, self.key_file) server_context.set_ciphers("HIGH") # Set the options if server_tls: # Ignore DeprecationWarning about old SSL/TLS settings with warnings.catch_warnings(): warnings.simplefilter("ignore") server_context.maximum_version = server_tls server_thread = threading.Thread(target=socket_test_server, args=(server_context,), daemon=True) server_thread.start() # Create the NNTP, mocking the required values # We disable certificate validation, as we use self-signed certificates nw = mock.Mock() nw.blocking = True nw.thrdnum = 1 nw.server = mock.Mock() nw.server.host = TEST_HOST nw.server.port = TEST_PORT nw.server.info = AddrInfo(*socket.getaddrinfo(TEST_HOST, TEST_PORT, 0, socket.SOCK_STREAM)[0]) nw.server.timeout = 10 nw.server.ssl = True nw.server.ssl_context = None nw.server.ssl_verify = 0 nw.server.ssl_ciphers = client_cipher # Do we expect failure to connect? if not can_connect: with pytest.raises(OSError): newswrapper.NNTP(nw, nw.server.info) else: nntp = newswrapper.NNTP(nw, nw.server.info) assert nntp.sock.recv(len(TEST_DATA)) == TEST_DATA # Assert SSL data assert nntp.sock.version() == expected_client_tls if client_cipher: assert nntp.sock.cipher()[0] == client_cipher # Wait for server to close server_thread.join(timeout=1.5) if server_thread.is_alive(): raise RuntimeError("Test server was not stopped") time.sleep(1.0) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4410713 SABnzbd-4.3.2/tests/test_decoder.py0000644000000000000000000001776514625637243016423 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_decoder- Testing functions in decoder.py """ import binascii import os import pytest from random import randint from unittest import mock import sabnzbd.decoder as decoder from sabnzbd.nzbstuff import Article def uu(data: bytes): """Uuencode data and insert a period if necessary""" line = binascii.b2a_uu(data).rstrip(b"\n") # Dot stuffing if line.startswith(b"."): return b"." + line return line LINES_DATA = [os.urandom(45) for _ in range(32)] VALID_UU_LINES = [uu(data) for data in LINES_DATA] END_DATA = os.urandom(randint(1, 45)) VALID_UU_END = [ uu(END_DATA), b"`", b"end", ] class TestUuDecoder: def _generate_msg_part( self, part: str, insert_empty_line: bool = True, insert_excess_empty_lines: bool = False, insert_headers: bool = False, insert_end: bool = True, insert_dot_stuffing_line: bool = False, begin_line: bytes = b"begin 644 My Favorite Open Source Movie.mkv", ): """Generate message parts. Part may be one of 'begin', 'middle', or 'end' for multipart messages, or 'single' for a singlepart message. All uu payload is taken from VALID_UU_*. Returns Article with a random id and lowest_partnum correctly set, socket-style raw data, and the expected result of uu decoding for the generated message. """ article_id = "test@host" + os.urandom(8).hex() + ".sab" article = Article(article_id, randint(4321, 54321), None) article.lowest_partnum = True if part in ("begin", "single") else False # Mock an nzf so results from hashing and filename handling can be stored article.nzf = mock.Mock() # Store the message data and the expected decoding result data = [] result = [] # Always start with the response code line data.append(b"222 0 <" + bytes(article_id, encoding="ascii") + b">") if insert_empty_line: # Only insert other headers if there's an empty line if insert_headers: data.extend([b"x-hoop: is uitgestelde teleurstelling", b"Another-Header: Sure"]) # Insert the empty line between response code and body data.append(b"") if insert_excess_empty_lines: data.extend([b"", b""]) # Insert uu data into the body if part in ("begin", "single"): data.append(begin_line) if part in ("begin", "middle", "single"): size = randint(4, len(VALID_UU_LINES) - 1) data.extend(VALID_UU_LINES[:size]) result.extend(LINES_DATA[:size]) if insert_dot_stuffing_line: data.append(uu(b"\0" * 14)) result.append(b"\0" * 14) if part in ("end", "single"): if insert_end: data.extend(VALID_UU_END) result.append(END_DATA) # Signal the end of the message with a dot on a line of its own data.append(b".") # Join the data with \r\n line endings, just like we get from socket reads data = b"\r\n".join(data) # Concatenate expected result result = b"".join(result) return article, bytearray(data), result def test_no_data(self): with pytest.raises(decoder.BadUu): assert decoder.decode_uu(None, None) @pytest.mark.parametrize( "raw_data", [ b"", b"\r\n\r\n", b"foobar\r\n", # Plenty of list items, but (too) few actual lines b"222 0 \r\nX-Too-Short: yup\r\n", ], ) def test_short_data(self, raw_data): with pytest.raises(decoder.BadUu): assert decoder.decode_uu(None, bytearray(raw_data)) @pytest.mark.parametrize( "raw_data", [ b"222 0 \r\n\r\n", # Missing altogether b"222 0 \r\n\r\nbeing\r\n", # Typo in 'begin' b"222 0 \r\n\r\nx-header: begin 644 foobar\r\n", # Not at start of the line b"666 0 \r\nbegin\r\n", # No empty line + wrong response code b"OMG 0 \r\nbegin\r\n", # No empty line + invalid response code b"222 0 \r\nbegin\r\n", # No perms b"222 0 \r\nbegin ABC DEF\r\n", # Permissions not octal b"222 0 \r\nbegin 755\r\n", # No filename b"222 0 \r\nbegin 644 \t \t\r\n", # Filename empty after stripping ], ) def test_missing_uu_begin(self, raw_data): article = Article("foo@bar", 1234, None) article.lowest_partnum = True filler = b"\r\n" * 4 with pytest.raises(decoder.BadUu): raw_data = bytearray(raw_data) raw_data.extend(filler) assert decoder.decode_uu(article, raw_data) @pytest.mark.parametrize("insert_empty_line", [True, False]) @pytest.mark.parametrize("insert_excess_empty_lines", [True, False]) @pytest.mark.parametrize("insert_headers", [True, False]) @pytest.mark.parametrize("insert_end", [True, False]) @pytest.mark.parametrize("insert_dot_stuffing_line", [True, False]) @pytest.mark.parametrize( "begin_line", [ b"begin 644 nospace.bin", b"begin 444 filename with spaces.txt", b"BEGIN 644 foobar", b"begin 0755 shell.sh", ], ) def test_singlepart( self, insert_empty_line, insert_excess_empty_lines, insert_headers, insert_end, insert_dot_stuffing_line, begin_line, ): """Test variations of a sane single part nzf with proper uu-encoded data""" # Generate a singlepart message article, raw_data, expected_result = self._generate_msg_part( "single", insert_empty_line, insert_excess_empty_lines, insert_headers, insert_end, insert_dot_stuffing_line, begin_line, ) assert decoder.decode_uu(article, raw_data) == expected_result assert article.nzf.filename_checked @pytest.mark.parametrize("insert_empty_line", [True, False]) def test_multipart(self, insert_empty_line): """Test a simple multipart nzf""" # Generate and process a multipart msg decoded_data = expected_data = b"" for part in ("begin", "middle", "middle", "end"): article, data, result = self._generate_msg_part(part, insert_empty_line, False, False, True) decoded_data += decoder.decode_uu(article, data) expected_data += result # Verify results assert decoded_data == expected_data assert article.nzf.filename_checked @pytest.mark.parametrize( "bad_data", [ VALID_UU_LINES[-1][:10] + bytes("ваше здоровье", encoding="utf8") + VALID_UU_LINES[-1][-10:], # Non-ascii ], ) def test_broken_uu(self, bad_data): article = Article("foo@bar", 4321, None) article.lowest_partnum = False filler = b"\r\n".join(VALID_UU_LINES[:4]) + b"\r\n" with pytest.raises(decoder.BadData): assert decoder.decode_uu(article, bytearray(b"222 0 \r\n" + filler + bad_data + b"\r\n")) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4411387 SABnzbd-4.3.2/tests/requirements.txt0000644000000000000000000000040514625637243016650 0ustar00runnerstaff# Testing requirements pytest==7.4.4 setuptools selenium requests pyfakefs<5.4.0 werkzeug<2.1.0 # Breaks httpbin in newer versions pytest-httpbin pytest-httpserver flaky xmltodict tavern flask tavalidate importlib_metadata lxml black pytest-mock pytest-asyncio ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4412034 SABnzbd-4.3.2/tests/test_lang.py0000644000000000000000000000205114625637243015715 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_lang - Test stuff in sabnzbd/lang.py """ from sabnzbd.lang import * def test_is_rtl(): # Test if a language is right-to-left assert not is_rtl("en") assert is_rtl("he") # edge cases assert not is_rtl("blabla") assert not is_rtl(None) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4413488 SABnzbd-4.3.2/tests/test_functional_sorting.py0000644000000000000000000001103514625637243020705 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_sorting - Test downloads with season sorting and sequential files """ import os from tests.testhelper import * from flaky import flaky import sabnzbd.config as config # Use an ini file with a valid, old style series and movie sorting configuration # that also serves to verify conversion to the new sorter settings is performed INI_FILE = "sabnzbd.sorting.ini" @flaky @pytest.mark.usefixtures("run_sabnzbd") class TestDownloadSorting(DownloadFlowBasics): def test_sorter_settings_conversion(self): """Read the ini file after the sabnzbd test instance completed startup and verify all defined sorters were converted to the new format""" return_status, return_msg = config._read_config(os.path.join(SAB_CACHE_DIR, DEF_INI_FILE), try_backup=False) assert return_status assert not return_msg assert config.CFG_OBJ["sorters"] assert len(config.CFG_OBJ["sorters"]) == 2 # The ini file only has Series and Movie sorting @pytest.mark.parametrize( "test_data_dir, result", [ ( "sea_sort_s01_4k_uhd-SABnzbd", ["Sea.Sort.S01E0" + str(n) + ".data" for n in (1, 2, 3, 5)], ), # Data files with season and episode markers, one episode number intentionally missing ( "sea_sort_s02_4k_uhd-SABnzbd", ["Sea.Sort.S02E0" + str(n) + ".data" for n in (4, 6, 7, 9)], ), # Data files with episode markers only, one episode number intentionally missing ], ) def test_download_season_sorting(self, test_data_dir, result): """Test season pack sorting""" self.download_nzb(os.path.join("sorting", test_data_dir), result, True) @pytest.mark.parametrize( "test_data_dir, result", [ ( "Long_live_CDs_2023_576i_mono-SABnzbd", ["Movie_DVD_" + str(n) + ".disc" for n in (1, 2, 3)], ), # Data files with "CD n" sequence markers ( "Its_all_about_parts_2023_576i_mono-SABnzbd", ["Movie_DVD_" + str(n) + ".disc" for n in (6, 7, 8)], ), # Data file with "Part n" sequence markers ], ) def test_download_sequential(self, test_data_dir, result): """Test sequential file handling""" self.download_nzb(os.path.join("sorting", test_data_dir), result, True) @pytest.mark.parametrize( "test_data_dir, result", [ ( "SINGLE_sort_s23e06_480i-SABnzbd", ["Single.Sort.S23E06.mov"], ), # Single episode, no other files ( "SINGLE_sort_s23e06_480i-SABnzbd", ["Single.Sort.S23E06.1.mov"], ), # Repeat to verify a unique filename is applied pytest.param( "single-ep_sort_s06e66_4k_uhd-SABnzbd", ["Single-Ep.Sort.S06E66." + ext for ext in ("avi", "srt")], marks=pytest.mark.xfail( sabnzbd.MACOS or sabnzbd.WIN32, reason="Unreliable on macOS and Windows", ), ), # Single episode with associated smaller file pytest.param( "single-ep_sort_s06e66_4k_uhd-SABnzbd", ["Single-Ep.Sort.S06E66.1." + ext for ext in ("avi", "srt")], marks=pytest.mark.xfail( sabnzbd.MACOS or sabnzbd.WIN32, reason="Unreliable on macOS and Windows", ), ), # Repeat to verify unique filenames are applied ], ) def test_download_sorting_single(self, test_data_dir, result): """Test single episode file handling""" self.download_nzb(os.path.join("sorting", test_data_dir), result, True) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4414334 SABnzbd-4.3.2/tests/test_win_utils.py0000644000000000000000000000312114625637243017010 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_win_utils - Testing Windows utils """ import sys import pytest if not sys.platform.startswith("win"): pytest.skip("Skipping Windows-only tests", allow_module_level=True) import sabnzbd.utils.apireg as ar class TestAPIReg: def test_set_get_connection_info_user(self): """Test the saving of the URL in USER-registery We can't test the SYSTEM one. """ test_url = "sab_test:8080" ar.set_connection_info(test_url, True) assert ar.get_connection_info(True) == test_url assert not ar.get_connection_info(False) # Remove and check if gone ar.del_connection_info(True) assert not ar.get_connection_info(True) def test_get_install_lng(self): """Not much to test yet..""" assert ar.get_install_lng() == "en" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4415147 SABnzbd-4.3.2/tests/test_sorting.py0000644000000000000000000017020314625637243016466 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_sorting - Testing functions in sorting.py """ import os import pyfakefs import re import shutil import sys import datetime from random import choice, choices, randint, sample from string import ascii_letters from unittest import mock from sabnzbd import sorting from sabnzbd.constants import IGNORED_MOVIE_FOLDERS, GUESSIT_PART_INDICATORS from sabnzbd.filesystem import globber, get_ext from sabnzbd.misc import sort_to_opts from tests.testhelper import * class TestSortingFunctions: @pytest.mark.parametrize( "name, result", [ ( "2147.Confinement.2015.1080p.WEB-DL.DD5.1.H264-EMRG", {"type": "movie", "title": "2147 Confinement"}, ), # Digit at the start ( "2146.Confinement.1080p.WEB-DL.DD5.1.H264-EMRG", {"type": "movie", "title": "2146 Confinement"}, ), # No year, guessit sets type to episode ("Setup.exe", {"type": "unknown", "title": "Setup exe"}), # Guessit uses 'movie' as its default type ( "25.817.hdtv-rofl", {"type": "episode", "title": "25", "season": 8, "episode": 17}, ), # Guessit comes up with bad episode info: [25, 17] ( "The.Wonders.of.Usenet.E08.2160p-SABnzbd", {"type": "episode", "season": 1, "episode": 8}, ), # Episode without season ( "Glade Runner 2094 2022.avi", {"type": "movie", "title": "Glade Runner 2094", "year": 2022}, ), # Double year ("Micro.Maffia.s01.web.aac.x265-Tfoe{{Wollah}}", {"release_group": "Tfoe"}), # Password in jobname ("No.Choking.Part.2.2008.360i-NotLOL", {"part": None, "title": "No Choking Part 2"}), # Part property ( "John.Hamburger.III.US.S01E01.OMG.WTF.BBQ.4320p.WEB.H265-HeliUM.mkv", { "type": "episode", "episode_title": "OMG WTF BBQ", "screen_size": "4320p", "title": "John Hamburger III", "country": "US", }, ), ("Test Movie 720p HDTV AAC x265 MYgroup-Sample", {"release_group": "MYgroup", "other": "Sample"}), ("Test Date Detection 22.07.14", {"date": datetime.date(2022, 7, 14)}), (None, None), # Jobname missing ("", None), ], ) def test_guess_what(self, name, result): """Test guessing quirks""" if not result: # Bad input with pytest.raises(ValueError): guess = sorting.guess_what(name) else: guess = sorting.guess_what(name) for key, value in result.items(): if value is None: # Property should not exist in the guess assert key not in guess else: assert guess[key] == value @pytest.mark.parametrize("platform", ["linux", "macos", "win32"]) @pytest.mark.parametrize( "path, result_unix, result_win", [ ("/tmp/test.file", True, True), ("/boot", True, True), ("/y.e.p", True, True), ("/ok/", True, True), ("/this.is.a/full.path", True, True), ("f:\\e.txt", False, True), ("\\\\relative.path", False, True), ("Z:\\some\\thing", False, True), ("Bitte ein Bit", False, False), ("this/is/not/an/abs.path", False, False), ("this\\is\\not\\an\\abs.path", False, False), ("AAA", False, False), ("", False, False), ], ) def test_is_full_path(self, platform, path, result_unix, result_win): @set_platform(platform) def _func(): result = result_win if sabnzbd.WIN32 else result_unix assert sorting.is_full_path(path) == result _func() @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows tests") @pytest.mark.parametrize( "path, result", [ ("P:\\foo\\bar", "P:\\foo\\bar"), ("FOO\\bar\\", "FOO\\bar"), ("foo\\_bar_", "foo\\bar"), ("foo\\__bar", "foo\\bar"), ("foo\\bar__", "foo\\bar"), ("foo\\ bar ", "foo\\bar"), ("foo\\ bar", "foo\\bar"), ("E:\\foo\\bar _", "E:\\foo\\bar"), ("E:\\foo_\\_bar", "E:\\foo\\bar"), ("E:\\foo._\\bar", "E:\\foo\\bar"), (".foo\\bar", "foo\\bar"), # Dots ("E:\\\\foo\\bar\\...", "E:\\foo\\bar"), ("E:\\\\foo\\bar\\...", "E:\\foo\\bar"), ("E:\\foo_\\bar\\...", "E:\\foo\\bar"), ("\\\\some.path.\\foo\\_bar_", "\\\\some.path\\foo\\bar"), # UNC ("\\\\some.path.\\foo\\_bar_", "\\\\some.path\\foo\\bar"), (r"\\?\UNC\SRVR\SHR\__File.txt__", r"\\SRVR\SHR\File.txt"), ("F:\\.path.\\ more\\foo bar ", "F:\\path\\more\\foo bar"), # Drive letter ("c:\\.path.\\ more\\foo bar \\ ", "c:\\path\\more\\foo bar"), ("c:\\foo_.\\bar", "c:\\foo\\bar"), # The remainder are all regression tests ("c:\\foo_ _\\bar", "c:\\foo\\bar"), ("c:\\foo. _\\bar", "c:\\foo\\bar"), ("c:\\foo. .\\bar", "c:\\foo\\bar"), ("c:\\foo. _\\bar", "c:\\foo\\bar"), ("c:\\foo. .\\bar", "c:\\foo\\bar"), ("c:\\__\\foo\\bar", "c:\\foo\\bar"), # No double \\\\ when an entire element is stripped ("c:\\...\\foobar", "c:\\foobar"), ], ) def test_strip_path_elements_win(self, path, result): def _func(): assert sorting.strip_path_elements(path) == result _func() @pytest.mark.skipif(sys.platform.startswith("win"), reason="Unix tests") @pytest.mark.parametrize( "path, result", [ ("/foo/bar", "/foo/bar"), ("FOO/bar/", "FOO/bar"), ("foo/_bar_", "foo/bar"), ("foo/__bar", "foo/bar"), ("foo/bar__", "foo/bar"), ("foo/ bar ", "foo/bar"), ("foo/ bar", "foo/bar"), ("/foo/bar _", "/foo/bar"), ("/foo_/_bar", "/foo/bar"), ("/foo._/bar", "/foo./bar"), (".foo/bar", ".foo/bar"), # Dots ("/foo/bar/...", "/foo/bar/..."), ("foo_\\bar\\...", "foo_\\bar\\..."), ("foo_./bar", "foo_./bar"), # The remainder are all regression tests ("foo_ _/bar", "foo/bar"), ("foo. _/bar", "foo./bar"), ("foo. ./bar", "foo. ./bar"), ("foo. _/bar", "foo./bar"), ("/foo. ./bar", "/foo. ./bar"), ("/__/foo/bar", "/foo/bar"), # No double // when an entire element is stripped ], ) def test_strip_path_elements_unix(self, path, result): def _func(): assert sorting.strip_path_elements(path) == result _func() @pytest.mark.parametrize( "path, result", [ ("/Foo/Bar", "/Foo/Bar"), # Nothing to do ("/{Foo}/Bar", "/foo/Bar"), ("{/Foo/B}ar", "/foo/bar"), ("/{F}oo/B{AR}", "/foo/Bar"), # Multiple ("/F{{O}O/{B}A}R", "/Foo/baR"), # Multiple, overlapping ("/F}oo/B{ar", "/Foo/Bar"), # Wrong order, no lowercasing should be done but { and } removed still ("", ""), ], ) def test_to_lowercase(self, path, result): assert sorting.to_lowercase(path) == result @pytest.mark.parametrize( "path, result", [ ("/Foo/Bar", False), ("", False), ("%fn", True), (".%ext", True), ("%fn.%ext", True), ("{%fn}", True), # A single closing lowercase marker is allowed ("{.%ext}", True), ("%fn{}", False), # But not the opening lowercase marker (".%ext{}", False), ("%fn}}", False), # Nor multiple closing lowercase markers (".%ext}}", False), ("%ext.%fn", True), ("%ext", False), # Missing dot ("%fn.ext", False), (".ext", False), (".fn", False), ("", False), ], ) def test_ends_in_file(self, path, result): assert sorting.ends_in_file(path) is result assert sorting.ends_in_file(os.path.join("/tmp", path)) is result # Prepending makes no difference assert sorting.ends_in_file("foo.bar-" + path) is result assert sorting.ends_in_file(path + "-foo.bar") is False # Appending does, obviously assert sorting.ends_in_file(os.path.join("/tmp", path + "-foo.bar")) is False @pytest.mark.parametrize("extra_file", [None, "Setup.exe", "cd1cd2cd3.cda"]) @pytest.mark.parametrize("indicator", ["", "cd", "cd ", " cd", " cd ", "CD", "part", "diskette", "floppy "]) @pytest.mark.parametrize( "files, result", [ ([], None), # Empty input (["foo.bar"], None), # Single file (["foo", "bar"], None), # No multipart files, without extension (["foo.txt", "bar.txt"], None), # No multipart files, with extension (["foobar.txt", "foobar.ini"], None), # No multipart files, same basename, different extension (["INDICATOR1.txt", "INDICATOR1.ini"], None), # No multipart files, same basename, different extension (["INDICATOR.txt1", "INDICATOR.txt2"], None), # No multipart files, same basename, sequential extension ( ["INDICATOR1.txt", "INDICATOR2.txt", "INDICATOR3.txt"], {"1": "INDICATOR1.txt", "2": "INDICATOR2.txt", "3": "INDICATOR3.txt"}, ), # Sequential basename, same extension ( ["INDICATOR1.txt1", "INDICATOR2.txt2", "INDICATOR3.txt3"], {"1": "INDICATOR1.txt1", "2": "INDICATOR2.txt2", "3": "INDICATOR3.txt3"}, ), # Sequential basename, sequential extension ( ["INDICATOR1.foo", "INDICATOR2.bar", "INDICATOR3.!!!"], {"1": "INDICATOR1.foo", "2": "INDICATOR2.bar", "3": "INDICATOR3.!!!"}, ), # Sequential basename, different extension ( ["foo-INDICATOR1.txt", "foo-INDICATOR2.txt"], {"1": "foo-INDICATOR1.txt", "2": "foo-INDICATOR2.txt"}, ), # Appended multipart indicator (["foo-INDICATOR1.txt1", "foo-INDICATOR2.txt2"], {"1": "foo-INDICATOR1.txt1", "2": "foo-INDICATOR2.txt2"}), (["foo-INDICATOR1.foo", "foo-INDICATOR2.bar"], {"1": "foo-INDICATOR1.foo", "2": "foo-INDICATOR2.bar"}), ( ["INDICATOR1-bar.txt", "INDICATOR2-bar.txt"], {"1": "INDICATOR1-bar.txt", "2": "INDICATOR2-bar.txt"}, ), # Prepended multipart indicator (["INDICATOR1-bar.txt1", "INDICATOR2-bar.txt2"], {"1": "INDICATOR1-bar.txt1", "2": "INDICATOR2-bar.txt2"}), (["INDICATOR1-bar.foo", "INDICATOR2-bar.bar"], {"1": "INDICATOR1-bar.foo", "2": "INDICATOR2-bar.bar"}), (["foo-INDICATOR1.txt", "foo-INDICATOR1.txt"], None), # Appended multipart indicator, duplicate key (["foo-INDICATOR1.txt1", "foo-INDICATOR1.txt2"], None), (["foo-INDICATOR1.foo", "foo-INDICATOR1.bar"], None), (["INDICATOR1-bar.txt", "INDICATOR1-bar.txt"], None), # Prepended multipart indicator, duplicate key (["INDICATOR1-bar.txt1", "INDICATOR1-bar.txt2"], None), (["INDICATOR1-bar.foo", "INDICATOR1-bar.bar"], None), (["foo-INDICATOR1.txt", "foo-INDICATOR3.txt"], None), # Appended multipart indicator, non-sequential keys (["foo-INDICATOR4.txt1", "foo-INDICATOR1.txt2"], None), (["foo-INDICATOR5.foo", "foo-INDICATOR8.bar"], None), (["INDICATOR4-bar.txt", "INDICATOR1-bar.txt"], None), # Prepended multipart indicator, non-sequential keys (["INDICATOR7-bar.txt1", "INDICATOR1-bar.txt2"], None), (["INDICATOR9-bar.foo", "INDICATOR1-bar.bar"], None), ], ) def test_check_for_multiple(self, extra_file, indicator, files, result): # Replace indicators in both function input and expected result if files: files = [f.replace("INDICATOR", indicator) for f in files] if result: result = {k: v.replace("INDICATOR", indicator) for k, v in result.items()} # Insert noise if extra_file: if len(files) > 0: # Never insert at the start as that can have decisive influence on the test result files.insert(randint(1, len(files)), extra_file) else: files.append(extra_file) # Only expect a result for known indicators if indicator.strip().lower() not in GUESSIT_PART_INDICATORS: result = None assert sorting.check_for_multiple(files) == result @pytest.mark.parametrize( "sort_string, job_name, multipart_label, result", [ ("", "", "", None), # Empty sort_string and job_name ("AAA", "", "", None), # Empty job_name ("", "BBB", "", None), # Empty sort_string ("%y/%r/%sn", "SABnzbd.ftw.2023.divx.480i-Team", "", "2023/480i/Sabnzbd Ftw/"), ("%y/%r/%sn.%ext", "SABnzbd.ftw.2023.divx.480i-Team", "", "2023/480i/Sabnzbd Ftw.ext"), ("{%s.n.%y.%r}-%GI", "SABnzbd.ftw.2023.divx.480i-Team", "", "sabnzbd.ftw.2023.480i-Team/"), ( "%s_n_%y_%r_%GI_%1.%ext", "SABnzbd.ftw.2023.divx.480i-Team", "cd%1", "Sabnzbd_Ftw_2023_480i_Team_cd1.ext", ), ( "{%s.n.%y.%r}-%GI/%fn", "SABnzbd.ftw.2023.divx.480i-Team", "", "sabnzbd.ftw.2023.480i-Team/Original Filename.ext", ), ("%dn_%1.%ext", "SABnzbd.ftw.2023.divx.480i-Team", "cd%1", "SABnzbd.ftw.2023.divx.480i-Team_cd1.ext"), ], ) def test_eval_sort(self, sort_string, job_name, multipart_label, result): if sabnzbd.WIN32 and result: result = result.replace("/", "\\") assert sorting.eval_sort(sort_string, job_name, multipart_label) == result @pytest.mark.skipif(sys.platform.startswith("win"), reason="Unix tests") def test_move_to_parent_directory_unix(self): # Standard files/dirs with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: pyfakefs.fake_filesystem_unittest.set_uid(0) # Create a fake filesystem with some file content in a random base directory base_dir = "/" + os.urandom(4).hex() + "/" + os.urandom(2).hex() for test_dir in ["dir/2", "TEST/DIR2"]: ffs.fs.create_dir(base_dir + "/" + test_dir, perm_bits=755) assert os.path.exists(base_dir + "/" + test_dir) is True for test_file in ["dir/some.file", "TEST/DIR/FILE"]: ffs.fs.create_file(base_dir + "/" + test_file, int("0644", 8)) assert os.path.exists(base_dir + "/" + test_file) is True return_path, return_status = sorting.move_to_parent_directory(base_dir + "/TEST") # Affected by move assert not os.path.exists(base_dir + "/TEST/DIR/FILE") # Moved to subdir assert not os.path.exists(base_dir + "/TEST/DIR2") # Deleted empty directory assert not os.path.exists(base_dir + "/DIR2") # Dirs don't get moved, only their file content assert os.path.exists(base_dir + "/DIR/FILE") # Moved file # Not moved assert not os.path.exists(base_dir + "/some.file") assert not os.path.exists(base_dir + "/2") assert os.path.exists(base_dir + "/dir/some.file") assert os.path.exists(base_dir + "/dir/2") # Function return values assert (return_path) == base_dir assert (return_status) is True # Exception for DVD directories with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: pyfakefs.fake_filesystem_unittest.set_uid(0) # Create a fake filesystem in a random base directory, and included a typical DVD directory base_dir = "/" + os.urandom(4).hex() + "/" + os.urandom(2).hex() dvd = choice(IGNORED_MOVIE_FOLDERS) for test_dir in ["dir/2", "TEST/DIR2"]: ffs.fs.create_dir(base_dir + "/" + test_dir, perm_bits=755) assert os.path.exists(base_dir + "/" + test_dir) is True for test_file in ["dir/some.file", "TEST/" + dvd + "/FILE"]: ffs.fs.create_file(base_dir + "/" + test_file, int("0644", 8)) assert os.path.exists(base_dir + "/" + test_file) is True return_path, return_status = sorting.move_to_parent_directory(base_dir + "/TEST") # Nothing should move in the presence of a DVD directory structure assert os.path.exists(base_dir + "/TEST/" + dvd + "/FILE") assert os.path.exists(base_dir + "/TEST/DIR2") assert not os.path.exists(base_dir + "/DIR2") assert not os.path.exists(base_dir + "/DIR/FILE") assert not os.path.exists(base_dir + "/some.file") assert not os.path.exists(base_dir + "/2") assert os.path.exists(base_dir + "/dir/some.file") assert os.path.exists(base_dir + "/dir/2") # Function return values assert (return_path) == base_dir + "/TEST" assert (return_status) is True @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows tests") def test_move_to_parent_directory_win(self): # Standard files/dirs with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: pyfakefs.fake_filesystem_unittest.set_uid(0) # Create a fake filesystem with some file content in a random base directory base_dir = "Z:\\" + os.urandom(4).hex() + "\\" + os.urandom(2).hex() for test_dir in ["dir\\2", "TEST\\DIR2"]: ffs.fs.create_dir(base_dir + "\\" + test_dir, perm_bits=755) assert os.path.exists(base_dir + "\\" + test_dir) is True for test_file in ["dir\\some.file", "TEST\\DIR\\FILE"]: ffs.fs.create_file(base_dir + "\\" + test_file, int("0644", 8)) assert os.path.exists(base_dir + "\\" + test_file) is True return_path, return_status = sorting.move_to_parent_directory(base_dir + "\\TEST") # Affected by move assert not os.path.exists(base_dir + "\\TEST\\DIR\\FILE") # Moved to subdir assert not os.path.exists(base_dir + "\\TEST\\DIR2") # Deleted empty directory assert not os.path.exists(base_dir + "\\DIR2") # Dirs don't get moved, only their file content assert os.path.exists(base_dir + "\\DIR\\FILE") # Moved file # Not moved assert not os.path.exists(base_dir + "\\some.file") assert not os.path.exists(base_dir + "\\2") assert os.path.exists(base_dir + "\\dir\\some.file") assert os.path.exists(base_dir + "\\dir\\2") # Function return values assert (return_path) == base_dir assert (return_status) is True # Exception for DVD directories with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: pyfakefs.fake_filesystem_unittest.set_uid(0) # Create a fake filesystem in a random base directory, and included a typical DVD directory base_dir = "D:\\" + os.urandom(4).hex() + "\\" + os.urandom(2).hex() dvd = choice(IGNORED_MOVIE_FOLDERS) for test_dir in ["dir\\2", "TEST\\DIR2"]: ffs.fs.create_dir(base_dir + "\\" + test_dir, perm_bits=755) assert os.path.exists(base_dir + "\\" + test_dir) is True for test_file in ["dir\\some.file", "TEST\\" + dvd + "\\FILE"]: ffs.fs.create_file(base_dir + "\\" + test_file, int("0644", 8)) assert os.path.exists(base_dir + "\\" + test_file) is True return_path, return_status = sorting.move_to_parent_directory(base_dir + "\\TEST") # Nothing should move in the presence of a DVD directory structure assert os.path.exists(base_dir + "\\TEST\\" + dvd + "\\FILE") assert os.path.exists(base_dir + "\\TEST\\DIR2") assert not os.path.exists(base_dir + "\\DIR2") assert not os.path.exists(base_dir + "\\DIR\\FILE") assert not os.path.exists(base_dir + "\\some.file") assert not os.path.exists(base_dir + "\\2") assert os.path.exists(base_dir + "\\dir\\some.file") assert os.path.exists(base_dir + "\\dir\\2") # Function return values assert (return_path) == base_dir + "\\TEST" assert (return_status) is True @pytest.mark.usefixtures("clean_cache_dir") class TestSortingSorter: @pytest.mark.parametrize( "s_class, jobname, sort_string, result_path, result_setname", [ ( "date", "My.EveryDay.Show.20210203.Great.Success.1080p.aac.hdtv-mygrp.mkv", "%y-%0m/%t - %y-%0m-%0d - %desc.%ext", "2021-02", "My EveryDay Show - 2021-02-03 - Great Success", ), ( "date", "My.EveryDay.Show.20210606.Greater.Successes.2160p.dts.bluray-mygrp.mkv", "%y-%m/%t - %y-%m-%d - %desc.%ext", "2021-6", "My EveryDay Show - 2021-6-6 - Greater Successes", ), ( "date", "ME!.1999.12.31.720p.hd-tv", "{%t}/%0decade_%r/%t - %y-%0m-%0d.%ext", "me!/1990_720p", "ME! - 1999-12-31", ), ( "date", "2000 A.D. 28-01-2000 360i dvd-r.avi", "%y/%0m/%0d/%r.%dn.%ext", "2000/01/28", "360i.2000 A.D. 28-01-2000 360i dvd-r.avi", ), ("date", "Allo_Allo_07-SEP-1984", "%y/%0m/%0d/%.t.%ext", "1984/09/07", "Allo.Allo"), ( "date", "www.example.org Allo_Allo_07-SEP-1984", "%GI/%GI/%y/%0m/%0d/%.t%GI.%ext", "www.example.org/1984/09/07", "Allo.Allo", ), ( "tv", "onslow.goes.to.university.s06e66-grp.mkv", "%sn/Season %s/%sn - %sx%0e - %en.%ext", "Onslow Goes To University/Season 6", "Onslow Goes To University - 6x66 - grp", ), ( "tv", "rose's_BEAUTY_parlour", "%sn/S%0sE%0e - %en/%sn - S%0sE%0e - %en.%ext", "Rose's Beauty Parlour/SE -", # Season used to default to '1' if missing, episode never did "Rose's Beauty Parlour - SE -", ), ( "tv", "Cooking with Hyacinth S01E13 Biscuits 2160p DD5.1 Cookies", "{%s.N}/%sx%0e - %en/%s_N - %0sx%0e - %en (%r).%ext", "cooking.with.hyacinth/1x13 - Biscuits", "Cooking_with_Hyacinth - 01x13 - Biscuits (2160p)", ), ( "tv", "Daisy _ (1987) _ S01E02 _ 480i.avi", "%dn.%ext", "", "Daisy _ (1987) _ S01E02 _ 480i.avi", ), ( "tv", "Bruce.and.Violet.S126E202.Oh.Dear.Benz.4320p.mkv", "%sn/Season W%s/W%0e_%desc.%ext", "Bruce and Violet/Season W126", "W202", ), # %desc should be stripped, season and episode numbers >=100 handled correctly, and "and" remain lowercase ( "tv", "[www.sabnzbd.org]Candle.Light.Dinners.S02E13.Elite.Soups.dts.hvec-NZBLuv.mkv", "%s.N.S%0sE%0e.(%e.n).%G.I.%GI-%GI.%ext", "", "Candle.Light.Dinners.S02E13.(Elite.Soups).DTS.www.sabnzbd.org-hvec-NZBLuv", ), # GI ( "tv", "Candle.Light.Dinners.S02E13.DD+5.1.x265.Hi10-NZBLuv.mkv", "%s_N_S%0sE%0e_%G_I_%G.I_%G_I.%ext", "", "Candle_Light_Dinners_S02E13_H.265_10-bit_Dolby_Digital_Plus", ), # GI with spacer ( "movie", "Pantomimes.Lumineuses.1982.2160p.WEB-DL.DDP5.1.H.264-TheOpt.mkv", "%r/%year/%title-%G.I.%ext", "2160p/1982", "Pantomimes Lumineuses-TheOpt", ), ( "movie", "The Lucky Dog 1921 540i Tape ac3 mono-LnH proof sample.avi", "%year/%_t-%G.I.%ext", "1921", "The_Lucky_Dog-Proof-Sample", ), ( "movie", "Kid_Auto_Races_at_Venice_[2014]", "%0decades/%y_%_t", "2010s/2014_Kid_Auto_Races_at_Venice", "", ), ], ) @pytest.mark.parametrize("enable_sorting", [0, 1]) @pytest.mark.parametrize("category", ["sortme", "nosort", "*"]) @pytest.mark.parametrize("selected_types", [sample([0, 1, 2, 3], randint(0, 3)) for i in range(4)]) def test_sorter_get_final_path( self, s_class, enable_sorting, jobname, sort_string, category, selected_types, result_path, result_setname ): """Test the final path of the Sorter class""" selected_cats = ["*", "sortme"] # categories for which the sorter is active def _func(): path = ("/tmp/" if not sys.platform.startswith("win") else "c:\\tmp\\") + os.urandom(4).hex() sorter = sorting.Sorter( None, jobname, path, category, False, { "name": "test_sorter", "order": 0, "min_size": 1234, "multipart_label": " CD%1" if s_class == "movie" else "", "sort_string": sort_string, "sort_cats": selected_cats, "sort_type": selected_types, "is_active": enable_sorting, }, ) if ( bool(enable_sorting) and category in selected_cats and (len(selected_types) == 0 or any(t in selected_types for t in (sort_to_opts(sorter.type), 0))) ): if sys.platform.startswith("win"): assert sorter.get_final_path() == (path + "/" + result_path).replace("/", "\\") assert sorter.filename_set == result_setname.replace("/", "\\") else: assert sorter.get_final_path() == path + "/" + result_path assert sorter.filename_set == result_setname else: if sys.platform.startswith("win"): assert sorter.get_final_path() == (path + "/" + jobname).replace("/", "\\") else: assert sorter.get_final_path() == path + "/" + jobname assert sorter.filename_set == "" _func() @pytest.mark.parametrize( "sort_string, should_rename", [ ("%sn s%0se%0e.%ext", True), # %0e marker ("%sn s%se%e.%ext", True), # %e marker ("{%sn }s%se%e.%ext", True), # Same with lowercasing; test for issue #2578 ("%sn.%ext", False), # No episode marker ("%sn_%0se%0e", False), # No extension marker ("%r/%sn s%0se%0e.%ext", True), # %0e marker, with dir in sort string ("%r/%sn s%se%e.%ext", True), # %e marker, with dir in sort string ("%r/{%sn} s%se%e.%ext", True), # Same with lowercasing; test for issue #2578 ("%r/%sn.%ext", False), # No episode marker, with dir in sort string ("%r/%sn_%0se%0e", False), # No extension marker, with dir in sort string ], ) @pytest.mark.parametrize("generate_season_pack", [True, False]) @pytest.mark.parametrize("pack_files_have_season", [True, False]) @pytest.mark.parametrize("number_of_files", [0, 1, 2, 4]) @pytest.mark.parametrize("spacer", [".", "_", " "]) @pytest.mark.parametrize("extension", [".mkv", ""]) def test_sorter_rename_season_pack( self, sort_string, should_rename, generate_season_pack, pack_files_have_season, number_of_files, spacer, extension, ): # Initialise the sorter sorter = sorting.Sorter( None, "Pack" + spacer + "Renamer" + spacer + "S23" + spacer + "2160p-SABnzbd", SAB_CACHE_DIR, "*", False, { "name": "test_sorter", "order": 0, "min_size": 512, "multipart_label": "", "sort_string": sort_string, "sort_cats": ["*"], "sort_type": [0], "is_active": 1, }, ) """Test the season pack renaming of the Sorter class""" with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: base_dir = os.path.abspath(os.path.join(os.urandom(4).hex(), os.urandom(2).hex())) all_files = [] # Ensure the format never resembles a season or episode marker random_string = "-".join(os.urandom(2).hex()) # Create a fake filesystem with a random base directory and test files as specified ffs.fs.create_dir(base_dir) assert os.path.exists(base_dir) for i in range(1, number_of_files + 1): if generate_season_pack: test_file = ( "Yes-pack" + spacer + random_string + spacer + ("S23" if pack_files_have_season else "") + "E" + "{0:0>2}".format(i) + spacer + "2160p-SABnzbdTeam" + extension ) else: test_file = ( "No-pack" + spacer + random_string + "".join(choices(ascii_letters, k=randint(4, 12))) + spacer + "2160p-SABnzbdTeam" + extension ) all_files.append(test_file) ffs.fs.create_file(os.path.join(base_dir, test_file), st_size=1024) assert os.path.exists(os.path.join(base_dir, test_file)) # Filter files as they normally would have been by Sorter.rename() prior to calling the season pack renamer all_files = [f for f in all_files if sorter._filter_files(f, base_dir)] # Engage the sorter sorter.get_values() sorter.construct_path() # Run some sanity checks, mimicking what's normally done prior to season pack handling if sorter.rename_files and sorter.is_season_pack and len(all_files) > 1: # Call the season pack renamer directly, bypassing Sorter.rename() sorter._rename_season_pack(all_files, base_dir) # Check the result try: for f in all_files: if generate_season_pack and sorter.is_season_pack and should_rename and number_of_files >= 2: # Verify season pack files have been renamed assert not os.path.exists(os.path.join(base_dir, f)) # Also do a basic filename check for root, dirs, files in os.walk(base_dir): for filename in files: if "{" in sort_string: # Lowercasing marker in sort string, expect lowercase results assert re.fullmatch(r"pack renamer s23e0?\d.*" + extension, filename) else: assert re.fullmatch(r"Pack Renamer s23e0?\d.*" + extension, filename) else: # No season pack renaming should happen, verify original files are still in place assert os.path.exists(os.path.join(base_dir, f)) except AssertionError: # Get some insight into what *did* happen and re-raise the error for root, dirs, files in os.walk(base_dir): print(base_dir, dirs, files, all_files) raise AssertionError() @pytest.mark.parametrize( "s_class, job_tag, sort_string, sort_filename_result", # Supply sort_filename_result without extension [ ("tv", "S01E02", "%r/%sn s%0se%0e.%ext", "Simulated Job s01e02"), ("tv", "S01E02", "%r/%sn s%0se%0e", ""), ("movie", "2021", "%y_%.title.%r.%ext", "2021_Simulated.Job.2160p"), ("movie", "2021", "%y_%.title.%r", ""), ("date", "2020-02-29", "%y/%0m/%0d/%.t-%GI.%ext", "Simulated.Job-SAB"), ("date", "2020-02-29", "%y/%0m/%0d/%.t-%GI", ""), ], ) @pytest.mark.parametrize("size_limit, file_size", [(512, 1024), (1024, 512)]) @pytest.mark.parametrize("extension", [".mkv", ".data", ".mkv", ".vob"]) @pytest.mark.parametrize("number_of_files", [0, 1, 2, 4]) @pytest.mark.parametrize("generate_sequential_filenames", [True, False]) def test_sorter_rename( self, s_class, job_tag, sort_string, sort_filename_result, size_limit, file_size, extension, number_of_files, generate_sequential_filenames, ): """Test the file renaming of the Sorter class""" with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: # Make up a job name job_name = "Simulated.Job." + job_tag + ".2160p.Web.x264-SAB" # Prep the filesystem storage_dir = os.path.join(SAB_CACHE_DIR, "complete" + "".join(choices(ascii_letters, k=randint(4, 12)))) try: shutil.rmtree(storage_dir) except FileNotFoundError: pass job_dir = os.path.join(storage_dir, job_name) ffs.fs.create_dir(job_dir) assert os.path.exists(job_dir) # Create "downloaded" file(s) all_files = [] fixed_random = "".join(choices(ascii_letters, k=8)) for number in range(1, 1 + number_of_files): if not generate_sequential_filenames: job_file = "".join(choices(ascii_letters, k=randint(4, 12))) + extension else: job_file = fixed_random + ".CD" + str(number) + extension job_filepath = os.path.join(job_dir, job_file) ffs.fs.create_file(job_filepath, int("0644", 8), st_size=file_size) # Introduce a minor difference in file size, so we know which one will be renamed if # the largest file is targeted (e.g. single file, or no season pack and no sequential # naming in case of multiple files) file_size += 1 assert os.path.exists(job_filepath) all_files.append(job_file) # Initialise the sorter and rename sorter = sorting.Sorter( None, job_name, job_dir, "*", False, { "name": "test_sorter", "order": 0, "min_size": size_limit, "multipart_label": " CD%1" if s_class == "movie" else "", "sort_string": sort_string, "sort_cats": ["*"], "sort_type": [0], "is_active": 1, }, ) sorter.get_values() sorter.construct_path() sort_dest, is_ok = sorter.rename(all_files, job_dir) # Check the result try: if ( is_ok and number_of_files > 0 and sort_filename_result and file_size > size_limit and extension not in sorting.EXCLUDED_FILE_EXTS ): if number_of_files > 1 and generate_sequential_filenames and sorter.multipart_label: # Sequential file handling for n in range(1, number_of_files + 1): expected = os.path.join(sort_dest, sort_filename_result + " CD" + str(n) + extension) assert os.path.exists(expected) else: # Renaming only for the largest file (which in this test is always the last one created) for job_file in all_files: if (not sort_filename_result) or all_files.index(job_file) != len(all_files) - 1: # Smaller files expected = os.path.join(sort_dest, job_file) else: expected = os.path.join(sort_dest, sort_filename_result + extension) assert os.path.exists(expected) else: # No renaming at all for job_file in all_files: expected = os.path.join(sort_dest, job_file) assert os.path.exists(expected) except AssertionError: # Get some insight into what *did* happen and re-raise the error for root, dirs, files in os.walk(sort_dest): print(sort_dest, dirs, files) raise AssertionError() # Cleanup try: shutil.rmtree(storage_dir) except FileNotFoundError: pass @pytest.mark.parametrize( "job_name, result_sort_file, result_class", [ ("OGEL.NinjaGo.Masters.of.Jinspitzu.S13.1080p.CN.WEB-DL.AAC2.0.H.264", True, "tv"), ( "The.Hunt.for.Blue.November.1990.NORDiC.REMUX.2160p.DV.HDR.UHD-BluRay.HEVC.TrueHD.5.1-SLoWGoaTS", True, "movie", ), ("가요무대.1985-11-18.480p.Sat.KorSub", True, "date"), ("Virus.cmd", True, "unknown"), ("SABnzbd 0.3.9 LeadyNas Mono (incl. Python2.3).pkg", True, "unknown"), ], ) def test_sorter_type(self, job_name, result_sort_file, result_class): """Check if the sorter gets the type right""" sorter = sorting.Sorter( None, job_name, SAB_CACHE_DIR, "test_cat", False, { "name": "test_sorter", "order": 0, "min_size": 1234, "multipart_label": "", "sort_string": "test", "sort_cats": ["test_cat"], "sort_type": [0], "is_active": 1, }, ) assert sorter.type is result_class assert sorter.sorter_active is result_sort_file @pytest.mark.parametrize( "name, result", [ ("Undrinkable.2010.PROPER", True), ("Undrinkable.2010.EXTENDED.DVDRip.XviD-MoveIt", False), ("The.Choir.S01E02.The.Details.AC3.DVDRip.XviD-AD1100", False), ("The.Choir.S01E02.The.Real.Details.AC3.DVDRip.XviD-AD1100", False), ("The.Choir.S01E02.The.Details.REAL.AC3.DVDRip.XviD-AD1100", True), ("real.steal.2011.dvdrip.xvid.ac3-4lt1n", False), ("The.Stalking.Mad.S88E01.repack.ReaL.PROPER.CONVERT.1080p.WEB.h265-BTS", True), ("The.Stalking.Mad.S88E01.CONVERT.1080p.WEB.h265-BTS", False), ], ) def test_sorter_is_proper(self, name, result): """Test the is_proper method of the Sorter class""" sorter = sorting.Sorter.__new__(sorting.Sorter) # Skip __init__ sorter.guess = sorting.guess_what(name) assert sorter.is_proper() is result @pytest.mark.parametrize( "name, result_date, result_resolution, result_season, result_episode", [ ( "Undrinkable.2010.EXTENDED.DVDRip.XviD-MoveIt", datetime.date(2010, 1, 1), None, None, None, ), # Basic movie naming ("The.Choir.S01E02.The.Details.REAL.AC3.DVDRip.XviD-AD1100", None, None, "1", "2"), # Basic series naming ("666.2000.dvdrip.xvid.ac3-4lt1n", datetime.date(2000, 1, 1), None, None, None), # Numerical title ("The.Stalking.Mad.S09E876.CONVERT.1080p.WEB.h265-BTS", None, "1080p", "9", "876"), # Episode > 99 ( "The.Stalking.Mad.1999.S88E01.repack.ReaL.PROPER.CONVERT.1080p.WEB.h265-BTS", datetime.date(1999, 1, 1), "1080p", "88", "1", ), # Season episode with a year ("The.Walking.Sad.S03E04E05E08.1080p.WEB.h265-BTS", None, "1080p", "3", "4-5-8"), # Multi-episode ( "The.Walking.Sad.E16.1080p.WEB.h265-BTS", None, "1080p", "1", "16", ), # Episode only, season should be adjusted to 1 ( "The.Walking.Sad.E05E08.2160p.UHD.WEB.h265-BTS", None, "2160p", "1", "5-8", ), # Multi-episode only, season should be adjusted to 1 ("The.Balking.Fat.S11.4k.WEB.h265-BTS", None, "2160p", "11", None), # Season only ("가요무대.1985-11-18.480p.Sat.KorSub", datetime.date(1985, 11, 18), "480p", None, None), # Date ], ) def test_sorter_get_values(self, name, result_date, result_resolution, result_season, result_episode): """Test the methods of the Sorter class underpinning get_values()""" sorter = sorting.Sorter(None, name, SAB_CACHE_DIR, "*", False, None) sorter.guess = sorting.guess_what(name) sorter.get_values() # year if result_date and result_date.year: assert sorter.info["year"] == str(result_date.year) assert sorter.info["decade"] == str(result_date.year)[2:3] + "0" assert sorter.info["decade_two"] == str(result_date.year)[:3] + "0" else: assert sorter.info["year"] == "" assert sorter.info["decade"] == "" assert sorter.info["decade_two"] == "" # resolution if result_resolution: assert sorter.info["resolution"] == result_resolution else: assert sorter.info["resolution"] == "" # season if result_season: assert sorter.info["season_num"] == result_season if "-" in result_season: # handle multi-season formatting assert sorter.info["season_num_alt"] == "-".join(["0" + ep for ep in result_season.split("-")]) else: assert sorter.info["season_num_alt"] == result_season.rjust(2, "0") else: assert sorter.info["season_num"] == "" assert sorter.info["season_num_alt"] == "" # episode if result_episode: assert sorter.info["episode_num"] == result_episode if "-" in result_episode: # handle multi-episode formatting assert sorter.info["episode_num_alt"] == "-".join(["0" + ep for ep in result_episode.split("-")]) else: assert sorter.info["episode_num_alt"] == result_episode.rjust(2, "0") else: assert sorter.info["episode_num"] == "" assert sorter.info["episode_num_alt"] == "" # day if result_date and result_date.day and result_date.day != 1: assert sorter.info["day"] == str(result_date.day) assert sorter.info["day_two"] == str(result_date.day).rjust(2, "0") else: assert sorter.info["day"] == "" assert sorter.info["day_two"] == "" # month if result_date and result_date.month and result_date.month != 1: assert sorter.info["month"] == str(result_date.month) assert sorter.info["month_two"] == str(result_date.month).rjust(2, "0") else: assert sorter.info["month"] == "" assert sorter.info["month_two"] == "" @pytest.mark.parametrize( "data_set, job_name, sort_string, result_is_season_pack_initial, result_is_season_pack_later, result_globs", [ # Season in the filename, matching the jobname ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*01*in_2160p*": 4, "myfiles*": 0}, ), ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x02.nfo", "myfiles.1x02.srt"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*01*in_2160p*.mkv": 2, "myfiles*": 0, "*in_2160p.nfo": 1, "*in_2160p.srt": 1}, ), # small similar files (.nfo, .srt) ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4}, ), # No extension marker in the sort string # Season in the filename, not matching the jobname; jobname should take precedence ( ("myfiles.9x21.mkv", "myfiles.9x22.mkv", "myfiles.9x23.mkv", "myfiles.9x24.mkv"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 4, "myfiles*": 0}, ), ( ("myfiles.9x21.mkv", "myfiles.9x22.mkv", "myfiles.9x23.mkv", "myfiles.9x24.mkv"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4}, ), # No extension marker in the sort string # No season in the filename; shouldn't matter for the result ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 4, "myfiles*": 0}, ), ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4}, ), # No extension marker in the sort string # Multi-episode in the filename ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E07-09.mkv", "myfiles.E04-E05.mkv"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 4, "myfiles*": 0, "*07-08-09*": 1, "*04-05*": 1}, ), ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E07-09.mkv", "myfiles.E04-E05.mkv"), "My.Files.S05.4k-SABnzbd", "s%se%e_in_%r.%ext", True, True, {"*5*in_2160p*": 4, "myfiles*": 0, "*e7-8-9*": 1, "*e4-5*": 1}, ), # Episode marker without leading zero ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E07-09.mkv", "myfiles.E04-E05.mkv"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4}, ), # No extension marker in the sort string # No season in the jobname, shouldn't trigger season sorting even if the filenames have season info ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv"), "My.Files.4k-SABnzbd", "s%0se%0e_in_%r.%ext", False, False, {"*in_2160p*": 1, "myfiles*": 3}, ), # No season in the job name, only the largest file will be renamed ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv"), "My.Files.4k-SABnzbd", "s%0se%0e_in_%r.%ext", False, False, {"*in_2160p*": 1, "myfiles*": 3}, ), # No season in the job name, only the largest file will be renamed # Season in the filename, matching the jobname + unrelated file ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv", "foo.bar"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*01*in_2160p*": 4, "myfiles*": 0, "foo.bar": 1}, ), ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv", "foo.bar"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4, "foo.bar": 1}, ), # No extension marker in the sort string # Season in the filename, not matching the jobname; jobname should take precedence + unrelated file ( ("myfiles.9x21.mkv", "myfiles.9x22.mkv", "myfiles.9x23.mkv", "myfiles.9x24.mkv", "foo.bar"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 4, "myfiles*": 0, "foo.bar": 1}, ), ( ("myfiles.9x21.mkv", "myfiles.9x22.mkv", "myfiles.9x23.mkv", "myfiles.9x24.mkv", "foo.bar"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4, "foo.bar": 1}, ), # No extension marker in the sort string # No season in the filename; shouldn't matter for the result + unrelated file ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv", "foo.bar"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 4, "myfiles*": 0, "foo.bar": 1}, ), ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv", "foo.bar"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4, "foo.bar": 1}, ), # No extension marker in the sort string # No season in the jobname, shouldn't trigger season sorting even if the filenames have season info + unrelated file ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv", "foo.bar"), "My.Files.4k-SABnzbd", "s%0se%0e_in_%r.%ext", False, False, {"*in_2160p*": 2, "myfiles*": 3, "foo.bar": 0, "*.bar": 1}, ), # No season in the job name, only the largest file will be renamed (plus 'similar' .bar) ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv", "foo.bar"), "My.Files.4k-SABnzbd", "s%0se%0e_in_%r.%ext", False, False, {"*in_2160p*": 2, "myfiles*": 3, "foo.bar": 0, "*.bar": 1}, ), # No season in the job name, only the largest file will be renamed (plus 'similar' .bar) # Season in the filename, matching the jobname + unrelated file with episode info ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv", "foo Episode 666.bar"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*01*in_2160p*": 5, "myfiles*": 0, "foo Episode 666.bar": 0, "*.bar": 1}, ), # Episode 666 will be accepted regardless of the unrelated basename ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv", "foo Episode 666.bar"), "My.Files.S01.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4}, ), # No extension marker in the sort string # Season in the filename, not matching the jobname; jobname should take precedence + unrelated file with episode info ( ("myfiles.9x21.mkv", "myfiles.9x22.mkv", "myfiles.9x23.mkv", "myfiles.9x24.mkv", "foo Episode 666.bar"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 5, "myfiles*": 0, "foo Episode 666.bar": 0, "*.bar": 1}, ), # Episode 666 will be accepted regardless of the unrelated basename ( ("myfiles.9x21.mkv", "myfiles.9x22.mkv", "myfiles.9x23.mkv", "myfiles.9x24.mkv", "foo Episode 666.bar"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4}, ), # No extension marker in the sort string # No season in the filename; shouldn't matter for the result + unrelated file with episode info ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv", "foo Episode 666.bar"), "My.Files.S05.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*05*in_2160p*": 5, "myfiles*": 0, "foo Episode 666.bar": 0, "*.bar": 1}, ), ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv", "foo Episode 666.bar"), "My.Files.S06.4k-SABnzbd", "s%0se%0e_in_%r", True, False, {"*in_2160p*": 0, "myfiles*": 4, "foo Episode 666.bar": 1}, ), # No extension marker in the sort string # No season in the jobname, shouldn't trigger season sorting even if the filenames have season info + unrelated file with episode info ( ("myfiles.1x01.mkv", "myfiles.1x02.mkv", "myfiles.1x03.mkv", "myfiles.1x04.mkv", "foo Episode 666.bar"), "My.Files.4k-SABnzbd", "s%0se%0e_in_%r.%ext", False, False, {"*in_2160p*": 2, "myfiles*": 3, "foo Episode 666.bar": 0, "*.bar": 1}, ), # No season in the job name, only the largest file will be renamed ( ("myfiles.E01.mkv", "myfiles.E02.mkv", "myfiles.E03.mkv", "myfiles.E04.mkv", "foo Episode 666.bar"), "My.Files.4k-SABnzbd", "s%0se%0e_in_%r.%ext", False, False, {"*in_2160p*": 2, "myfiles*": 3, "foo Episode 666.bar": 0, "*.bar": 1}, ), # No season in the job name, only the largest file will be renamed # No episode number in any of the files, season pack renaming will try all files but not rename any ( ("myfiles a.mkv", "myfiles b.mkv", "myfiles c.mkv", "myfiles d.mkv"), "My.Files.S03.4k-SABnzbd", "s%0se%0e_in_%r.%ext", True, True, {"*in_2160p*": 1, "myfiles*": 3}, ), # Largest file will be renamed ], ) def test_sorter_rename_with_season_packs( self, data_set, job_name, sort_string, result_is_season_pack_initial, result_is_season_pack_later, result_globs ): """Run the renamer against assorted season packs in the data dir""" # Mock a minimal nzo job_dir = os.path.join(SAB_CACHE_DIR, "".join(choices(ascii_letters, k=randint(4, 12))), job_name) nzo = mock.Mock() nzo.final_name = job_name nzo.download_path = job_dir nzo.nzo_info = {} # Setup a sorter instance sorter = sorting.Sorter( nzo, job_name, job_dir, "*", False, { "name": "test_sorter", "order": 0, "min_size": 640 * 1024, "multipart_label": "", "sort_string": sort_string, "sort_cats": ["*"], "sort_type": [1, 2, 3, 4], "is_active": 1, }, ) assert sorter.is_season_pack is result_is_season_pack_initial sorter.get_values() with pyfakefs.fake_filesystem_unittest.Patcher() as ffs: # Prep the filesystem ffs.fs.create_dir(job_dir) assert os.path.exists(job_dir) # Create "downloaded" files file_size = 42 * 1024**2 for filename in data_set: job_filepath = os.path.join(job_dir, filename) # Create only mkv and bar as large files, keep anything else below the sorter's min_size if get_ext(filename) in (".mkv", ".bar"): size = file_size file_size -= randint(1, 1024) else: size = 666 ffs.fs.create_file(job_filepath, int("0644", 8), st_size=size) assert os.path.exists(job_filepath) # Sorter stuff, pt. 2 sorted_path = sorter.construct_path() # Check season pack status again after constructing the path assert sorter.is_season_pack is result_is_season_pack_later sorted_dest, sorted_ok = sorter.rename(globber(job_dir), job_dir) # Verify the results for pattern, number in result_globs.items(): try: assert len(glob := globber(sorted_dest or job_dir, pattern)) == number except AssertionError: # Print some details to help diagnose the issue pytest.fail( "Globbing for %s didn't returned the expected %s results in %s: %s" % (pattern, number, sorted_path, glob) ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4415884 SABnzbd-4.3.2/tests/test_functional_downloads.py0000644000000000000000000000354714625637243021223 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_downloads - Test the downloading flow """ from tests.testhelper import * from flaky import flaky @flaky class TestDownloadFlow(DownloadFlowBasics): def test_download_basic_rar5(self): self.download_nzb("basic_rar5", ["My_Test_Download.bin"]) def test_download_zip(self): self.download_nzb("test_zip", ["My_Test_Download.bin"]) def test_download_7zip(self): self.download_nzb("test_7zip", ["My_Test_Download.bin"]) def test_download_passworded(self): self.download_nzb("test_passworded{{secret}}", ["My_Test_Download.bin"]) @pytest.mark.xfail(reason="Probably #1633") def test_download_unicode_made_on_windows(self): self.download_nzb("test_win_unicode", ["frènch_german_demö.bin"]) def test_download_fully_obfuscated(self): # This is also covered by a unit test but added to test full flow self.download_nzb("obfuscated_single_rar_set", ["My_Test_Download.bin"]) def test_download_unicode_rar(self): self.download_nzb("unicode_rar", ["我喜欢编程_My_Test_Download.bin"]) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4416614 SABnzbd-4.3.2/tests/test_postproc.py0000644000000000000000000002543414625637243016657 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_postproc- Tests of various functions in newspack, among which rar_renamer() """ import os import re import shutil from unittest import mock from sabnzbd import postproc from sabnzbd.config import ConfigSorter, ConfigCat from sabnzbd.filesystem import globber_full, clip_path from sabnzbd.misc import sort_to_opts from tests.testhelper import * @pytest.mark.usefixtures("clean_cache_dir") class TestPostProc: # Tests of rar_renamer() (=deobfuscate) against various input directories def test_rar_renamer(self): # Function to deobfuscate one directory with rar_renamer() def deobfuscate_dir(sourcedir, expected_filename_matches): # We create a workingdir inside the sourcedir, because the filenames are really changed workingdir = os.path.join(sourcedir, "workingdir") # if workingdir is still there from previous run, remove it: if os.path.isdir(workingdir): try: shutil.rmtree(workingdir) except PermissionError: pytest.fail("Could not remove existing workingdir %s for rar_renamer" % workingdir) # create a fresh copy try: shutil.copytree(sourcedir, workingdir) except: pytest.fail("Could not create copy of files for rar_renamer") # And now let the magic happen: nzo = mock.Mock() nzo.final_name = "somedownloadname" nzo.download_path = workingdir number_renamed_files = postproc.rar_renamer(nzo) # run check on the resulting files if expected_filename_matches: for filename_match in expected_filename_matches: if len(globber_full(workingdir, filename_match)) != expected_filename_matches[filename_match]: pytest.fail("Failed filename_match %s in %s" % (filename_match, workingdir)) # Remove workingdir again try: shutil.rmtree(workingdir) except: pytest.fail("Could not remove existing workingdir %s for rar_renamer" % workingdir) return number_renamed_files # obfuscated, single rar set sourcedir = os.path.join(SAB_DATA_DIR, "obfuscated_single_rar_set") # Now define the filematches we want to see, in which amount ("*-*-*-*-*" are the input files): expected_filename_matches = {"*part007.rar": 1, "*-*-*-*-*": 0} assert deobfuscate_dir(sourcedir, expected_filename_matches) == 7 # obfuscated, two rar sets sourcedir = os.path.join(SAB_DATA_DIR, "obfuscated_two_rar_sets") expected_filename_matches = {"*part007.rar": 2, "*part009.rar": 1, "*-*-*-*-*": 0} assert deobfuscate_dir(sourcedir, expected_filename_matches) == 16 # obfuscated, but not a rar set sourcedir = os.path.join(SAB_DATA_DIR, "obfuscated_but_no_rar") expected_filename_matches = {"*.rar": 0, "*-*-*-*-*": 6} assert deobfuscate_dir(sourcedir, expected_filename_matches) == 0 # One obfuscated rar set, but first rar (.part1.rar) is missing sourcedir = os.path.join(SAB_DATA_DIR, "obfuscated_single_rar_set_missing_first_rar") # single rar set (of 6 obfuscated rar files), so we expect renaming # thus result must 6 rar files, and 0 obfuscated files expected_filename_matches = {"*.rar": 6, "*-*-*-*-*": 0} # 6 files should have been renamed assert deobfuscate_dir(sourcedir, expected_filename_matches) == 6 # Two obfuscated rar sets, but some rars are missing sourcedir = os.path.join(SAB_DATA_DIR, "obfuscated_double_rar_set_missing_rar") # Two sets, missing rar, so we expect no renaming # thus result should be 0 rar files, and still 8 obfuscated files expected_filename_matches = {"*.rar": 0, "*-*-*-*-*": 8} # 0 files should have been renamed assert deobfuscate_dir(sourcedir, expected_filename_matches) == 0 # fully encrypted rar-set, and obfuscated rar names sourcedir = os.path.join(SAB_DATA_DIR, "fully_encrypted_and_obfuscated_rars") # SABnzbd cannot do anything with this, so we expect no renaming expected_filename_matches = {"*.rar": 0, "*-*-*-*-*": 6} # 0 files should have been renamed assert deobfuscate_dir(sourcedir, expected_filename_matches) == 0 @pytest.mark.parametrize("category", ["testcat", "Default", None]) @pytest.mark.parametrize("has_jobdir", [True, False]) # With or without a job dir @pytest.mark.parametrize("has_catdir", [True, False]) # Complete directory is defined at category level @pytest.mark.parametrize("has_active_sorter", [True, False]) # Sorter active for the fake nzo @pytest.mark.parametrize("sort_string", ["%sn (%r)", "%sn (%r)/file.%ext", ""]) # Identical path result @pytest.mark.parametrize("marker_file", [None, ".marker"]) @pytest.mark.parametrize("do_folder_rename", [True, False]) def test_prepare_extraction_path( self, category, has_jobdir, has_catdir, has_active_sorter, sort_string, marker_file, do_folder_rename ): # Ensure global CFG_ vars are initialised sabnzbd.config.read_config(os.devnull) # Define a sorter and a category (as @set_config cannot handle those) ConfigSorter( "sorter__test_prepare_extraction_path", { "order": 0, "min_size": 42, "multipart_label": "", "sort_string": sort_string, "sort_cats": [category if category else "no_such_category"], "sort_type": [ sort_to_opts("all"), ], "is_active": int(has_active_sorter), }, ) assert sabnzbd.config.CFG_DATABASE["sorters"]["sorter__test_prepare_extraction_path"] if category: ConfigCat( category, { "order": 0, "pp": None, "script": None, "dir": ( os.path.join(SAB_CACHE_DIR, ("category_dir_for_" + category + ("*" if not has_jobdir else ""))) if has_catdir else None ), "newzbin": "", "priority": 0, }, ) assert sabnzbd.config.CFG_DATABASE["categories"][category] # Mock a minimal nzo, required as function input fake_nzo = mock.Mock() fake_nzo.final_name = "FOSS.Rules.S23E06.2160p-SABnzbd" fake_nzo.cat = category fake_nzo.nzo_info = {} # Placeholder to prevent a crash in sorting.get_titles() @set_config( { "download_dir": os.path.join(SAB_CACHE_DIR, "incomplete"), "complete_dir": os.path.join(SAB_CACHE_DIR, "complete"), "marker_file": marker_file, "folder_rename": do_folder_rename, } ) def _func(): ( tmp_workdir_complete, workdir_complete, file_sorter, not_create_job_dir, marker_file_result, ) = postproc.prepare_extraction_path(fake_nzo) tmp_workdir_complete = clip_path(tmp_workdir_complete) workdir_complete = clip_path(workdir_complete) # Verify marker file if marker_file and not not_create_job_dir: assert marker_file_result else: assert not marker_file_result # Verify sorter assert file_sorter if has_active_sorter and category and sort_string: assert file_sorter.sorter_active else: assert not file_sorter.sorter_active # Verify not_create_job_dir if category and has_catdir and not has_jobdir and not file_sorter.sorter_active: assert not_create_job_dir else: # Double negatives ftw assert not not_create_job_dir # Verify workdir_complete if not category or not has_catdir: # Using standard Complete directory as base assert workdir_complete.startswith(os.path.join(SAB_CACHE_DIR, "complete")) elif category and has_catdir: # Based on the category directory assert workdir_complete.startswith(os.path.join(SAB_CACHE_DIR, "category_dir_for_" + category)) # Check the job directory part (or the lack thereof) as well if has_active_sorter and category and sort_string: # Sorter path, with an extra job name work directory inside assert re.fullmatch( re.escape(SAB_CACHE_DIR) + r".*" + re.escape(os.sep) + r"Foss Rules \(2160p\)" + re.escape(os.sep) + fake_nzo.final_name + r"(\.\d+)?", workdir_complete, ) elif has_jobdir or not (category and has_catdir): # Standard job name directory assert re.fullmatch( re.escape(SAB_CACHE_DIR) + r".*" + re.escape(os.sep) + r"FOSS.Rules.S23E06.2160p-SABnzbd(\.\d+)?", workdir_complete, ) else: # No job directory at all assert re.fullmatch( re.escape(SAB_CACHE_DIR) + r".*" + re.escape(os.sep) + r"category_dir_for_([a-zA-Z]+)", workdir_complete, ) # Verify tmp_workdir_complete if do_folder_rename: if not not_create_job_dir: assert tmp_workdir_complete != workdir_complete assert tmp_workdir_complete.replace("_UNPACK_", "") == workdir_complete else: assert tmp_workdir_complete == workdir_complete _func() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.441732 SABnzbd-4.3.2/tests/testhelper.py0000644000000000000000000003430114625637243016117 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.testhelper - Basic helper functions """ import io import os import time from http.client import RemoteDisconnected from typing import BinaryIO, Optional, Dict, List import pytest from random import choice, randint import requests from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from string import ascii_lowercase, digits from unittest import mock from urllib3.exceptions import ProtocolError import xmltodict import functools import sabnzbd import sabnzbd.cfg as cfg from sabnzbd.constants import ( DB_HISTORY_NAME, DEF_ADMIN_DIR, DEF_INI_FILE, DEFAULT_PRIORITY, FORCE_PRIORITY, HIGH_PRIORITY, INTERFACE_PRIORITIES, LOW_PRIORITY, NORMAL_PRIORITY, REPAIR_PRIORITY, Status, PP_LOOKUP, ) import sabnzbd.database as db from sabnzbd.misc import pp_to_opts import sabnzbd.filesystem as filesystem import tests.sabnews SAB_HOST = "127.0.0.1" SAB_PORT = randint(4200, 4299) SAB_APIKEY = "apikey" SAB_BASE_DIR = os.path.dirname(os.path.abspath(__file__)) SAB_CACHE_DIR = os.path.join(SAB_BASE_DIR, "cache") SAB_DATA_DIR = os.path.join(SAB_BASE_DIR, "data") SAB_INCOMPLETE_DIR = os.path.join(SAB_CACHE_DIR, "Downloads", "incomplete") SAB_COMPLETE_DIR = os.path.join(SAB_CACHE_DIR, "Downloads", "complete") SAB_NEWSSERVER_HOST = "127.0.0.1" SAB_NEWSSERVER_PORT = 8888 def set_config(settings_dict): """Change config-values on the fly, per test""" def set_config_decorator(func): @functools.wraps(func) def wrapper_func(*args, **kwargs): # Setting up as requested for item, val in settings_dict.items(): getattr(cfg, item).set(val) # Perform test value = func(*args, **kwargs) # Reset values for item in settings_dict: getattr(cfg, item).set(getattr(cfg, item).default) return value return wrapper_func return set_config_decorator def set_platform(platform): """Change config-values on the fly, per test""" def set_platform_decorator(func): def wrapper_func(*args, **kwargs): # Save original values is_windows = sabnzbd.WIN32 is_macos = sabnzbd.MACOS # Set current platform if platform == "win32": sabnzbd.WIN32 = True sabnzbd.MACOS = False elif platform == "macos": sabnzbd.WIN32 = False sabnzbd.MACOS = True elif platform == "linux": sabnzbd.WIN32 = False sabnzbd.MACOS = False # Perform test value = func(*args, **kwargs) # Reset values sabnzbd.WIN32 = is_windows sabnzbd.MACOS = is_macos return value return wrapper_func return set_platform_decorator def get_url_result(url="", host=SAB_HOST, port=SAB_PORT): """Do basic request to web page""" arguments = {"apikey": SAB_APIKEY} return requests.get("http://%s:%s/%s/" % (host, port, url), params=arguments).text def get_api_result(mode, host=SAB_HOST, port=SAB_PORT, extra_arguments={}): """Build request to SABnzbd""" arguments = {"apikey": SAB_APIKEY, "mode": mode} arguments.update(extra_arguments) r = requests.get("http://%s:%s/api" % (host, port), params=arguments) if "xml" in r.headers["Content-Type"]: return xmltodict.parse(r.text) if "json" in r.headers["Content-Type"]: return r.json() return r.text def create_nzb(nzb_dir: str, metadata: Optional[Dict[str, str]] = None) -> str: """Create NZB from directory using SABNews""" nzb_dir_full = os.path.join(SAB_DATA_DIR, nzb_dir) return tests.sabnews.create_nzb(nzb_dir=nzb_dir_full, metadata=metadata) def create_and_read_nzb_fp(nzbdir: str, metadata: Optional[Dict[str, str]] = None) -> BinaryIO: """Create NZB, return data and delete file""" # Create NZB-file to import nzb_path = create_nzb(nzbdir, metadata) with open(nzb_path, "rb") as nzb_data_fp: nzb_data = nzb_data_fp.read() # Remove the created NZB-file os.remove(nzb_path) return io.BytesIO(nzb_data) def random_name(length: int = 16) -> str: """Shorthand to create a simple random string""" return "".join(choice(ascii_lowercase + digits) for _ in range(length)) class FakeHistoryDB(db.HistoryDB): """ HistoryDB class with added control of the db_path via an argument and the capability to generate history entries. """ category_options = ["catA", "catB", "1234", "يوزنت"] distro_names = ["Ubuntu", "デビアン", "Gentoo_Hobby_Edition", "Красная Шляпа"] status_options = [ Status.COMPLETED, Status.EXTRACTING, Status.FAILED, Status.MOVING, Status.QUICK_CHECK, Status.REPAIRING, Status.RUNNING, Status.VERIFYING, ] def __init__(self, db_path): db.HistoryDB.db_path = db_path super().__init__() def add_fake_history_jobs(self, number_of_entries=1): """Generate a history db with any number of fake entries""" for _ in range(0, number_of_entries): nzo = mock.Mock() # Mock all input build_history_info() needs distro_choice = choice(self.distro_names) distro_random = random_name() nzo.password = choice(["secret", ""]) nzo.correct_password = "secret" nzo.final_name = "%s.%s.Linux.ISO-Usenet" % (distro_choice, distro_random) nzo.filename = "%s.%s.Linux-Usenet%s.nzb" % ( (distro_choice, distro_random, "{{" + nzo.password + "}}") if nzo.password else (distro_choice, distro_random, "") ) nzo.cat = choice(self.category_options) nzo.script = "placeholder_script" nzo.url = "placeholder_url" nzo.status = choice([Status.COMPLETED, choice(self.status_options)]) nzo.fail_msg = "¡Fracaso absoluto!" if nzo.status == Status.FAILED else "" nzo.nzo_id = "SABnzbd_nzo_%s" % ("".join(choice(ascii_lowercase + digits) for i in range(8))) nzo.bytes_downloaded = randint(1024, 1024**4) nzo.md5sum = "".join(choice("abcdef" + digits) for i in range(32)) nzo.repair, nzo.unpack, nzo.delete = pp_to_opts(choice(list(PP_LOOKUP.keys()))) # for "pp" nzo.nzo_info = {"download_time": randint(1, 10**4)} nzo.unpack_info = {"unpack_info": "placeholder unpack_info line\r\n" * 3} nzo.duplicate_key = "show/season/episode" nzo.futuretype = False # for "report", only True when fetching an URL nzo.download_path = os.path.join(os.path.dirname(db.HistoryDB.db_path), "placeholder_downpath") # Mock time when calling add_history_db() to randomize completion times almost_time = mock.Mock(return_value=time.time() - randint(0, 10**8)) with mock.patch("time.time", almost_time): self.add_history_db( nzo, storage=os.path.join(os.path.dirname(db.HistoryDB.db_path), "placeholder_workdir"), postproc_time=randint(1, 10**3), script_output="", script_line="", ) @pytest.mark.usefixtures("run_sabnzbd", "run_sabnews_and_selenium") class SABnzbdBaseTest: driver = None def no_page_crash(self): # Do a base test if CherryPy did not report test assert "500 Internal Server Error" not in self.driver.title def open_page(self, url): # Open a page and test for crash self.driver.get(url) self.no_page_crash() def scroll_to_top(self): self.driver.find_element(By.TAG_NAME, "body").send_keys(Keys.CONTROL + Keys.HOME) time.sleep(2) def wait_for_ajax(self): # We catch common nonsense errors from Selenium try: wait = WebDriverWait(self.driver, 15) wait.until(lambda driver_wait: self.driver.execute_script("return jQuery.active") == 0) wait.until(lambda driver_wait: self.driver.execute_script("return document.readyState") == "complete") except (RemoteDisconnected, ProtocolError): pass @staticmethod def selenium_wrapper(func, *args): """Wrapper with retries for more stable Selenium""" for _ in range(3): try: return func(*args) except WebDriverException as e: # Try again in 2 seconds! time.sleep(2) pass else: raise e class DownloadFlowBasics(SABnzbdBaseTest): def is_server_configured(self): """Check if the wizard was already performed. If not: run the wizard! """ with open(os.path.join(SAB_CACHE_DIR, DEF_INI_FILE), "r") as config_file: if f"[[{SAB_NEWSSERVER_HOST}]]" not in config_file.read(): self.start_wizard() def start_wizard(self): # Language-selection self.open_page("http://%s:%s/sabnzbd/wizard/" % (SAB_HOST, SAB_PORT)) self.selenium_wrapper(self.driver.find_element, By.ID, "en").click() self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, "button.btn.btn-default").click() # Fill server-info self.no_page_crash() host_inp = self.selenium_wrapper(self.driver.find_element, By.NAME, "host") host_inp.clear() host_inp.send_keys(SAB_NEWSSERVER_HOST) # Disable SSL for testing self.selenium_wrapper(self.driver.find_element, By.NAME, "ssl").click() # This will fail if the translations failed to compile! self.selenium_wrapper(self.driver.find_element, By.PARTIAL_LINK_TEXT, "Advanced Settings").click() # Change port port_inp = self.selenium_wrapper(self.driver.find_element, By.NAME, "port") port_inp.clear() port_inp.send_keys(SAB_NEWSSERVER_PORT) # Test server-check self.selenium_wrapper(self.driver.find_element, By.ID, "serverTest").click() self.wait_for_ajax() assert "Connection Successful" in self.selenium_wrapper(self.driver.find_element, By.ID, "serverResponse").text # Final page done self.selenium_wrapper(self.driver.find_element, By.ID, "next-button").click() self.no_page_crash() check_result = self.selenium_wrapper(self.driver.find_element, By.CLASS_NAME, "quoteBlock").text assert "http://%s:%s/sabnzbd" % (SAB_HOST, SAB_PORT) in check_result # Go to SAB! self.selenium_wrapper(self.driver.find_element, By.CSS_SELECTOR, ".btn.btn-success").click() self.no_page_crash() def download_nzb(self, nzb_dir: str, file_output: List[str], dir_name_as_job_name: bool = False): # Verify if the server was setup before we start self.is_server_configured() # Create NZB nzb_path = create_nzb(nzb_dir) # Add NZB if dir_name_as_job_name: test_job_name = os.path.basename(nzb_dir) else: test_job_name = "testfile_%s" % time.time() api_result = get_api_result("addlocalfile", extra_arguments={"name": nzb_path, "nzbname": test_job_name}) assert api_result["status"] # Remove NZB-file os.remove(nzb_path) # See how it's doing self.open_page("http://%s:%s/sabnzbd/" % (SAB_HOST, SAB_PORT)) # We wait for 20 seconds to let it complete for _ in range(20): try: # Locate status of our job status_text = self.driver.find_element( By.XPATH, ( '//div[@id="history-tab"]//tr[td/div/span[contains(text(), "%s")]]/td[contains(@class, "status")]' % test_job_name ), ).text # Always sleep to give it some time time.sleep(1) if status_text == "Completed": break except WebDriverException: time.sleep(1) else: pytest.fail("Download did not complete") # Verify all files in the expected file_output are present among the completed files. # Sometimes par2 can also be included, but we accept that. For example when small # par2 files get assembled in after the download already finished (see #1509) for _ in range(10): completed_files = filesystem.globber(os.path.join(SAB_COMPLETE_DIR, test_job_name), "*") try: for filename in file_output: assert filename in completed_files # All filenames found break except AssertionError: print("Expected filename %s not found in completed_files %s" % (filename, completed_files)) # Wait a sec before trying again with a fresh list of completed files time.sleep(1) else: pytest.fail("Time ran out waiting for expected filenames to show up") # Verify if the garbage collection works (see #1628) # We need to give it a second to calm down and clear the variables time.sleep(2) gc_results = get_api_result("gc_stats")["value"] if gc_results: pytest.fail(f"Objects were left in memory after the job finished! {gc_results}") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4418008 SABnzbd-4.3.2/tests/test_cfg.py0000644000000000000000000001155314625637243015542 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_cfg - Testing functions in cfg.py """ import sys import pytest import sabnzbd.cfg as cfg class TestValidators: def test_clean_nice_ionice_parameters_allowed(self): """Allowed nice and ionice parameters https://linux.die.net/man/1/nice https://linux.die.net/man/1/ionice """ def assert_allowed(inp_value): """Helper function to check for block""" msg, value = cfg.clean_nice_ionice_parameters(inp_value) assert msg is None assert value == inp_value # nice assert_allowed("-n1") assert_allowed("-n-11") assert_allowed("-n 3") assert_allowed("-n -4") assert_allowed("--adjustment=11") assert_allowed("--adjustment=-7") assert_allowed("--adjustment 20") assert_allowed("--adjustment -8") # ionice assert_allowed("-c1") assert_allowed("-c-11") assert_allowed("-c 3") assert_allowed("-c -4") assert_allowed("--classdata=1") assert_allowed("--classdata=-11") assert_allowed("--classdata 3") assert_allowed("--classdata -4") assert_allowed("-t") assert_allowed("--ignore") assert_allowed("-c 11 -n 12 -t") assert_allowed("-c 11 --classdata=12 --ignore") assert_allowed("--ignore -n9 --class=7") assert_allowed("-t -n9 -c7") def test_clean_nice_ionice_parameters_blocked(self): """Should all be blocked""" def assert_blocked(inp_value): """Helper function to check for block""" msg, value = cfg.clean_nice_ionice_parameters(inp_value) assert msg assert msg.startswith("Incorrect parameter") assert value is None assert_blocked("-ca") assert_blocked("-t11") assert_blocked("-p 11") assert_blocked("123") assert_blocked("/bin/sh /tmp/test.sh") assert_blocked("'/evil.sh' 11") assert_blocked("; 11") assert_blocked("python evil.py") assert_blocked("-n5 /bin/echo 666") assert_blocked("4 && test.sh") assert_blocked("-t | bla.py") assert_blocked("5 || now") assert_blocked("echo 'how;now;brown;cow'") assert_blocked("-c'echo'") assert_blocked("--classdata=;/bin/echo") def test_validate_single_tag(self): assert cfg.validate_single_tag(["TV", ">", "HD"]) == (None, ["TV > HD"]) assert cfg.validate_single_tag(["TV", ">", "HD", "Plus"]) == (None, ["TV", ">", "HD", "Plus"]) assert cfg.validate_single_tag(["alt.bin", "alt.tv"]) == (None, ["alt.bin", "alt.tv"]) assert cfg.validate_single_tag(["alt.group"]) == (None, ["alt.group"]) def test_all_lowercase(self): assert cfg.all_lowercase("") == (None, "") assert cfg.all_lowercase("Bla") == (None, "bla") assert cfg.all_lowercase(["foo", "bar"]) == (None, ["foo", "bar"]) assert cfg.all_lowercase(["foo ", " bar"]) == (None, ["foo", "bar"]) def test_lower_case_ext(self): assert cfg.lower_case_ext("") == (None, "") assert cfg.lower_case_ext(".Bla") == (None, "bla") assert cfg.lower_case_ext([".foo", ".bar"]) == (None, ["foo", "bar"]) assert cfg.lower_case_ext([".foo ", " .bar"]) == (None, ["foo", "bar"]) def test_validate_safedir(self): assert cfg.validate_safedir("", "", "def") == (None, "def") assert cfg.validate_safedir("", "C:\\", "") == (None, "C:\\") def test_validate_host(self): # valid input assert cfg.validate_host("127.0.0.1") == (None, "127.0.0.1") assert cfg.validate_host("0.0.0.0") == (None, "0.0.0.0") assert cfg.validate_host("1.1.1.1") == (None, "1.1.1.1") assert cfg.validate_host("::1") == (None, "::1") assert cfg.validate_host("::") == (None, "::") # non-valid input. Should return None as second parameter assert not cfg.validate_host("0.0.0.0.")[1] # Trailing dot assert not cfg.validate_host("kajkdjflkjasd")[1] # does not resolve assert not cfg.validate_host("100")[1] # just a number ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4418676 SABnzbd-4.3.2/tests/test_rss.py0000644000000000000000000001000014625637243015574 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_misc - Testing functions in misc.py """ import datetime import time import configobj import sabnzbd.rss as rss import sabnzbd.config class TestRSS: @staticmethod def setup_rss(feed_name, feed_url): """Setup the basic settings to get things going""" # Setup the config settings sabnzbd.config.CFG_OBJ = configobj.ConfigObj() sabnzbd.config.ConfigRSS(feed_name, {"uri": feed_url}) # Need to create the Default category # Otherwise it will try to save the config sabnzbd.config.ConfigCat("*", {}) sabnzbd.config.ConfigCat("tv", {}) sabnzbd.config.ConfigCat("movies", {}) def test_rss_newznab_parser(self): """Test basic RSS-parsing of custom elements Harder to test in functional test """ feed_name = "TestFeedNewznab" self.setup_rss(feed_name, "https://sabnzbd.org/tests/rss_newznab_test.xml") # Start the RSS reader rss_obj = rss.RSSReader() rss_obj.run_feed(feed_name) # Is the feed processed? assert feed_name in rss_obj.jobs assert "https://cdn.nzbgeek.info/cdn?t=get&id=FakeKey&apikey=FakeKey" in rss_obj.jobs[feed_name] # Check some job-data job_data = rss_obj.jobs[feed_name]["https://cdn.nzbgeek.info/cdn?t=get&id=FakeKey&apikey=FakeKey"] assert job_data["title"] == "FakeShow.S04E03.720p.WEB.H264-Obfuscated" assert job_data["infourl"] == "https://nzbgeek.info/geekseek.php?guid=FakeKey" assert job_data["orgcat"] == "TV > HD" assert job_data["cat"] == "tv" assert job_data["episode"] == "3" assert job_data["season"] == "4" assert job_data["size"] == 1209464000 # feedparser returns UTC so SABnzbd converts to locale # of the system, so now we have to return to UTC adjusted_date = datetime.datetime(2018, 4, 13, 5, 46, 25) - datetime.timedelta(seconds=time.timezone) assert job_data["age"] == adjusted_date def test_rss_nzedb_parser(self): feed_name = "TestFeednZEDb" self.setup_rss(feed_name, "https://sabnzbd.org/tests/rss_nzedb_test.xml") # Start the RSS reader rss_obj = rss.RSSReader() rss_obj.run_feed(feed_name) # Is the feed processed? assert feed_name in rss_obj.jobs assert "https://nzbfinder.ws/getnzb/FakeKey.nzb&i=46181&r=FakeKey" in rss_obj.jobs[feed_name] # Check some job-data # Added fake season and episode to test file job_data = rss_obj.jobs[feed_name]["https://nzbfinder.ws/getnzb/FakeKey.nzb&i=46181&r=FakeKey"] assert job_data["title"] == "Movie.With.a.Dog.2018.720p.BluRay.x264-SPRiNTER" assert job_data["infourl"] == "https://nzbfinder.ws/details/FakeKey" assert job_data["orgcat"] == "Movies > HD" assert job_data["cat"] == "movies" assert job_data["episode"] == "720" assert job_data["season"] == "2018" assert job_data["size"] == 5164539914 # feedparser returns UTC so SABnzbd converts to locale # of the system, so now we have to return to UTC adjusted_date = datetime.datetime(2019, 3, 2, 17, 18, 7) - datetime.timedelta(seconds=time.timezone) assert job_data["age"] == adjusted_date ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.442024 SABnzbd-4.3.2/tests/test_file_extension.py0000644000000000000000000000572514625637243020022 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ Testing SABnzbd correct extension functionality module """ import os from tests.testhelper import * import sabnzbd.utils.file_extension as file_extension class Test_File_Extension: def test_has_popular_extension(self): assert file_extension.has_popular_extension("blabla/blabla.mkv") assert file_extension.has_popular_extension("blabla/blabla.srt") assert file_extension.has_popular_extension("djjddj/aaaaa.epub") assert file_extension.has_popular_extension("test/testing.r01") assert file_extension.has_popular_extension("test/testing.s91") assert not file_extension.has_popular_extension("test/testing") assert not file_extension.has_popular_extension("test/testing.rar01") assert not file_extension.has_popular_extension("98ads098f098fa.a0ds98f098asdf") assert not file_extension.has_popular_extension("blabla/blabla.yyy") # user defined ext_rename_ignore @set_config({"ext_rename_ignore": "xxx, yyy, zzz"}) def test_ext_rename_ignore(self): assert file_extension.has_popular_extension("blabla/blabla.yyy") def test_what_is_most_likely_extension(self): # These are real-content files, where the contents determine the extension filename = "tests/data/test_file_extension/apeeengeee" # A PNG assert os.path.isfile(filename) assert file_extension.what_is_most_likely_extension(filename) == ".png" filename = "tests/data/test_file_extension/somepeedeef" # Some PDF assert os.path.isfile(filename) assert file_extension.what_is_most_likely_extension(filename) == ".pdf" filename = "tests/data/test_file_extension/my_matroska" # my Matroska MKV assert os.path.isfile(filename) assert file_extension.what_is_most_likely_extension(filename) == ".mkv" filename = "tests/data/test_file_extension/sometxtfile" # a txt file assert os.path.isfile(filename) assert file_extension.what_is_most_likely_extension(filename) == ".txt" filename = "tests/data/test_file_extension/some_nzb_file" # a NZB file assert os.path.isfile(filename) assert file_extension.what_is_most_likely_extension(filename) == ".nzb" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4421144 SABnzbd-4.3.2/tests/test_encoding.py0000644000000000000000000000611514625637243016567 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_misc - Testing functions in encoding.py """ import sabnzbd.encoding as enc class TestEncoding: def test_correct_unknown_encoding(self): # Windows encoding in bytes assert "frènch_german_demö" == enc.correct_unknown_encoding(b"fr\xe8nch_german_dem\xf6") # Windows encoding in string that's already UTF8 assert "demotöwers" == enc.correct_unknown_encoding("demot\udcf6wers") def test_correct_cherrypy_encoding(self): raw_input = "aaazzz" # correct UTF8 corrected_output = enc.correct_cherrypy_encoding(raw_input) assert corrected_output == "aaazzz" # Let's create some "manual" strings of separate chars: # typical use case: raw chars in a string: 2-byte UTF8 # Ω (capital omega) in UTF8: 0xCE 0xA9 raw_input = "aaa" + chr(0xCE) + chr(0xA9) + "zzz" # Ω (capital omega) corrected_output = enc.correct_cherrypy_encoding(raw_input) assert corrected_output == "aaaΩzzz" # typical use case: raw chars in a string: 3-byte UTF8 # ∇ (nabla) in UTF8: 0xE2 0x88 0x87 raw_input = "aaa" + chr(0xE2) + chr(0x88) + chr(0x87) + "zzz" # ∇ (nabla) corrected_output = enc.correct_cherrypy_encoding(raw_input) assert corrected_output == "aaa∇zzz" # typical use case: raw chars in a string: 4-byte UTF8 raw_input = "aaa" + chr(0xF0) + chr(0x9F) + chr(0x9A) + chr(0x80) + "zzz" # "correct" 4-byte UTF8 for "rocket" corrected_output = enc.correct_cherrypy_encoding(raw_input) assert corrected_output == "aaa🚀zzz" # and now more automatic: craft from utf8 nice_utf8_string = "aaa你好🚀🤔zzzαβγ" # correct UTF8 # now break it raw_input = "" for i in nice_utf8_string.encode("utf-8"): raw_input += chr(i) assert raw_input != nice_utf8_string corrected_output = enc.correct_cherrypy_encoding(raw_input) assert corrected_output == nice_utf8_string # this is not valid UTF8, so string cannot be repaired, so stay the same raw_input = "aaa" + chr(0xF0) + chr(0x9F) + "zzz" # two bytes (instead of four) ... not valid UTF8 corrected_output = enc.correct_cherrypy_encoding(raw_input) assert corrected_output == raw_input # check nothing changed ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1716993699.44274 SABnzbd-4.3.2/tests/test_functional_adding_nzbs_clean.py0000644000000000000000000001245414625637243022652 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_adding_nzbs_clean - Tests for settings interaction when adding NZBs (clean SABnzbd instance) """ import time from zipfile import ZipFile import tests.test_functional_adding_nzbs as test_functional_adding_nzbs from sabnzbd.constants import STOP_PRIORITY from tests.testhelper import * @pytest.mark.usefixtures("run_sabnzbd") class TestAddingNZBsClean: # Copy from the base class _api_set_config = test_functional_adding_nzbs.TestAddingNZBs._api_set_config _create_random_nzb = test_functional_adding_nzbs.TestAddingNZBs._create_random_nzb _add_backup_directory = test_functional_adding_nzbs.TestAddingNZBs._add_backup_directory _clear_and_reset_backup_directory = test_functional_adding_nzbs.TestAddingNZBs._clear_and_reset_backup_directory def test_adding_nzbs_nzoids(self): """Test if we return the right output""" # Create NZB and zipped version basenzbfile = self._create_random_nzb() zipnzbfile = basenzbfile + ".zip" with ZipFile(zipnzbfile, "w") as zipobj: zipobj.write(basenzbfile) assert os.path.exists(zipnzbfile) # Test for both normal and zipped version for nzbfile in (basenzbfile, zipnzbfile): # Pause the queue at first assert get_api_result(mode="pause")["status"] is True # Add the job a first time job1 = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile}) assert job1["status"] assert job1["nzo_ids"] # 1=Discard self._api_set_config("no_dupes", 1) # Add the job a second time, it should be added with ALTERNATIVE label job2 = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile}) assert job2["status"] assert job2["nzo_ids"] queue = get_api_result(mode="queue", extra_arguments={"nzo_ids": job2["nzo_ids"][0]}) job_in_queue = queue["queue"]["slots"][0] assert "ALTERNATIVE" in job_in_queue["labels"] assert job_in_queue["status"] == "Paused" # Stop the first job get_api_result( mode="queue", extra_arguments={"name": "priority", "value": job1["nzo_ids"][0], "value2": STOP_PRIORITY} ) # Wait for the job to be removed and appear in the history for _ in range(10): try: history = get_api_result(mode="history", extra_arguments={"nzo_ids": job1["nzo_ids"][0]})["history"] assert history["slots"][0]["nzo_id"] == job1["nzo_ids"][0] assert history["slots"][0]["status"] == "Failed" break except (IndexError, AssertionError): time.sleep(1) # Now the second job should no longer be paused and labelled queue = get_api_result(mode="queue", extra_arguments={"nzo_ids": job2["nzo_ids"][0]}) job_in_queue = queue["queue"]["slots"][0] assert "ALTERNATIVE" not in job_in_queue["labels"] assert job_in_queue["status"] == "Queued" # Reset duplicate detection self._api_set_config("no_dupes", 0) # Test unwanted extensions Fail to history self._api_set_config("unwanted_extensions", ["bin"]) self._api_set_config("action_on_unwanted_extensions", 2) job = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile}) assert job["status"] assert job["nzo_ids"] # Wait for the job to be removed and appear in the history for _ in range(10): try: assert not get_api_result(mode="queue", extra_arguments={"nzo_ids": job["nzo_ids"][0]})["queue"] history = get_api_result(mode="history", extra_arguments={"nzo_ids": job["nzo_ids"][0]})["history"] assert history["slots"][0]["nzo_id"] == job["nzo_ids"][0] assert history["slots"][0]["status"] == "Failed" except (IndexError, AssertionError): time.sleep(1) # Reset and clean up get_api_result( mode="set_config_default", extra_arguments={"keyword": ["unwanted_extensions", "action_on_unwanted_extensions"]}, ) # Delete all jobs from queue and history for mode in ("queue", "history"): get_api_result(mode=mode, extra_arguments={"name": "delete", "value": "all", "del_files": 1}) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4428506 SABnzbd-4.3.2/tests/__init__.py0000644000000000000000000000004414625637243015474 0ustar00runnerstaff# Needed for correct test-detection ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4429383 SABnzbd-4.3.2/tests/test_getipaddress.py0000644000000000000000000000307314625637243017457 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_utils.test_check_dir - Testing SABnzbd checkdir util """ from sabnzbd.cfg import selftest_host from sabnzbd.getipaddress import * from sabnzbd.misc import is_ipv4_addr, is_ipv6_addr class TestGetIpAddress: def test_addresslookup4(self): address = addresslookup4(selftest_host()) assert address for item in address: assert isinstance(item[0], type(socket.AF_INET)) def test_public_ipv4(self): if publicipv4 := public_ipv4(): assert is_ipv4_addr(publicipv4) def test_local_ipv4(self): if localipv4 := local_ipv4(): assert is_ipv4_addr(localipv4) def test_public_ipv6(self): if test_ipv6 := public_ipv6(): # Not all systems have IPv6 assert is_ipv6_addr(test_ipv6) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4430413 SABnzbd-4.3.2/tests/test_functional_api.py0000644000000000000000000015202514625637243017776 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_api - Functional tests for the API """ import shutil import stat import sys from math import ceil from random import sample from typing import List from tavern.core import run from warnings import warn import sabnzbd.interface as interface from sabnzbd.constants import DEF_SORTER_RENAME_SIZE from sabnzbd.misc import from_units from tests.testhelper import * class ApiTestFunctions: """Collection of (wrapper) functions for API testcases""" def _get_api_json(self, mode, extra_args={}): """Wrapper for API calls with json output""" extra = {"output": "json", "apikey": SAB_APIKEY} extra.update(extra_args) return get_api_result(mode=mode, host=SAB_HOST, port=SAB_PORT, extra_arguments=extra) def _get_api_xml(self, mode, extra_args={}): """Wrapper for API calls with xml output""" extra = {"output": "xml", "apikey": SAB_APIKEY} extra.update(extra_args) return get_api_result(mode=mode, host=SAB_HOST, port=SAB_PORT, extra_arguments=extra) def _setup_script_dir(self, dir_name, script=None): """ Set the script_dir relative to SAB_CACHE_DIR, copy the example scripts there, and add an optional extra script with the given name. To unset the script_dir set the value of dir_name to an empty string. """ script_dir_extra = {"section": "misc", "keyword": "script_dir", "value": ""} if dir_name: script_dir = os.path.join(SAB_CACHE_DIR, dir_name) script_dir_extra["value"] = script_dir try: if not os.path.exists(script_dir): # Make the example scripts available in the scriptdir shutil.copytree(os.path.join(SAB_BASE_DIR, "..", "scripts"), script_dir) except Exception: pytest.fail("Cannot copy example scripts to %s", script_dir) if script: try: script_path = os.path.join(script_dir, script) with open(script_path, "w") as f: f.write("#!%s\n" % sys.executable) f.write("print('script %s says hi!\n' % __file__)") if not sys.platform.startswith("win"): os.chmod(script_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) except Exception: pytest.fail("Cannot add script %s to script_dir" % script) self._get_api_json("set_config", extra_args=script_dir_extra) def _record_slots(self, keys): """Return a list of dicts, storing queue info for the items in iterable 'keys'""" record = [] for slot in self._get_api_json("queue")["queue"]["slots"]: record.append({key: slot[key] for key in keys}) return record def _run_tavern(self, test_name, extra_vars=None): """Run tavern tests in ${test_name}.yaml""" vars = [ ("SAB_HOST", SAB_HOST), ("SAB_PORT", SAB_PORT), ("SAB_VERSION", sabnzbd.__version__), ("SAB_APIKEY", SAB_APIKEY), ] if extra_vars: vars.append(extra_vars) if hasattr(self, "history_size"): vars.append(("daemon_history_size", self.history_size)) result = run( os.path.join(SAB_DATA_DIR, "tavern", test_name + ".yaml"), tavern_global_cfg={"variables": dict(vars)}, pytest_args=["--tavern-file-path-regex", "api_.*.yaml"], ) assert result is result.OK def _get_api_history(self, extra={}): """Wrapper for history-related api calls""" # Set a higher default limit; the default is 10 via cfg(history_limit) if "limit" not in extra.keys() and "name" not in extra.keys(): # History calls that use 'name' don't need the limit parameter extra["limit"] = self.history_size * 2 # Fake history entries never have files, but randomize del_files anyway if "name" in extra.keys() and "del_files" not in extra.keys(): if extra["name"] == "delete": extra["del_files"] = randint(0, 1) return self._get_api_json("history", extra_args=extra) def _create_random_queue(self, minimum_size): """ Ensure the queue has a minimum number of jobs entries, adding random new jobs as necessary; excess jobs are not trimmed. Note that while the queue is paused overall to prevent downloading, the individual jobs do not have their priority set to paused. """ # Make sure the queue is paused assert self._get_api_json("pause")["status"] is True # Only add jobs if we have to, generating new ones is expensive queue_size = len(self._get_api_json("queue")["queue"]["slots"]) if queue_size >= minimum_size: return else: minimum_size -= queue_size for _ in range(0, minimum_size): job_name = "%s-CRQ" % random_name() job_dir = os.path.join(SAB_CACHE_DIR, job_name) # Create the job_dir and fill it with a bunch of smallish files with # random names, sizes and content. Note that some of the tests # expect at least two files per NZB. try: os.mkdir(job_dir) for number_of_files in range(0, randint(4, 6)): job_file = "%s.%s" % (random_name(), random_name(3)) with open(os.path.join(job_dir, job_file), "wb") as f: f.write(os.urandom(randint(1, 512 * 1024))) except Exception: pytest.fail("Failed to create random queue stuffings") # Fabricate the NZB nzb_file = create_nzb(job_dir) # Add job to queue assert ( self._get_api_json("addlocalfile", extra_args={"name": nzb_file, "nzbname": job_name})["status"] is True ) # Remove cruft try: shutil.rmtree(job_dir) except Exception: warn("Failed to remove %s" % job_dir) def _purge_queue(self, del_files=0): """Clear the entire queue""" self._get_api_json("queue", extra_args={"name": "purge", "del_files": del_files}) assert len(self._get_api_json("queue")["queue"]["slots"]) == 0 def _get_files(self, nzo_id: str) -> List[str]: files_json = self._get_api_json("get_files", extra_args={"value": nzo_id}) assert "files" in files_json return [file["nzf_id"] for file in files_json["files"]] @pytest.mark.usefixtures("run_sabnzbd") class TestOtherApi(ApiTestFunctions): """Test API function not directly involving either history or queue""" def test_api_version_testhelper(self): """Check the version, testhelper style""" assert "version" in get_api_result("version", SAB_HOST, SAB_PORT) def test_api_version_tavern(self): """Same same, tavern style""" self._run_tavern("api_version") def test_api_version_json(self): assert self._get_api_json("version")["version"] == sabnzbd.__version__ def test_api_version_xml(self): assert self._get_api_xml("version")["version"] == sabnzbd.__version__ def test_api_server_stats(self): """Verify server stats format""" self._run_tavern("api_server_stats") @pytest.mark.parametrize("extra_args", [{}, {"name": "change_complete_action", "value": ""}]) def test_api_nonexistent_mode(self, extra_args): # Invalid mode actually returns a proper error json = self._get_api_json("eueuq", extra_args=extra_args) assert json["status"] is False assert json["error"] @pytest.mark.parametrize("speed_pct", [randint(1, 99), 100, 0]) def test_api_speedlimit_pct(self, speed_pct): # Set a linespeed, otherwise percentage values cannot be used linespeed_value = randint(2, 1000) linespeed_unit = choice("KM") linespeed = str(linespeed_value) + linespeed_unit self._get_api_json( mode="set_config", extra_args={"section": "misc", "keyword": "bandwidth_max", "value": linespeed} ) # Speedlimit as a percentage of linespeed assert self._get_api_json("config", extra_args={"name": "speedlimit", "value": speed_pct})["status"] is True # Verify results for both relative and absolute speedlimit json = self._get_api_json("queue") if speed_pct != 0: assert int(json["queue"]["speedlimit"]) == speed_pct assert pytest.approx( float(self._get_api_json("queue")["queue"]["speedlimit_abs"]), abs=1, rel=0.005 ) == speed_pct / 100 * from_units(linespeed) else: assert int(json["queue"]["speedlimit"]) == 0 assert int(json["queue"]["speedlimit_abs"]) == 0 @pytest.mark.parametrize( "test_with_units, limit_pct, should_limit", [ (False, randint(1, 99), True), (True, randint(1, 99), True), (False, 100, True), (True, 100, True), (True, 0, False), # A value of zero by design equals 'no limit' (False, 0, False), (True, 101, True), (False, 200, True), ], ) def test_api_speedlimit_abs(self, test_with_units, limit_pct, should_limit): # Set a linespeed, otherwise percentage values cannot be used linespeed_value = randint(2, 1000) linespeed = str(linespeed_value) + "M" self._get_api_json( mode="set_config", extra_args={"section": "misc", "keyword": "bandwidth_max", "value": linespeed} ) if test_with_units: # Avoid excessive rounding errors with low linespeed and limit_pct values if round(limit_pct / 100 * linespeed_value) > 20: speed_abs = str(round(limit_pct / 100 * linespeed_value)) + "M" else: speed_abs = str(round(limit_pct * 2**10 * linespeed_value / 100)) + "K" else: speed_abs = str(round(limit_pct / 100 * from_units(linespeed))) assert self._get_api_json("config", extra_args={"name": "speedlimit", "value": speed_abs})["status"] is True # Verify the result, both absolute and relative json = self._get_api_json("queue") if should_limit: assert float(json["queue"]["speedlimit_abs"]) == from_units(speed_abs) assert ( pytest.approx(float(json["queue"]["speedlimit"]), abs=1, rel=0.005) == from_units(speed_abs) / from_units(linespeed) * 100 ) else: assert int(json["queue"]["speedlimit_abs"]) == 0 assert int(json["queue"]["speedlimit"]) == 0 @pytest.mark.parametrize( "language, value, translation", [ ("nl", "Error", "Fout"), # Ascii ("he", "Error", "שגיאה"), # Unicode ("en", "Error", "Error"), # Ask for a translation while the language is set to English ("nb", "Ooooooooops", "Ooooooooops"), # Non-existent/untranslated should mirror the input value ], ) def test_api_translate(self, language, value, translation): # Set language assert ( self._get_api_json( mode="set_config", extra_args={"section": "misc", "keyword": "language", "value": language} )["config"]["misc"]["language"] == language ) # Translate assert self._get_api_json("translate", extra_args={"value": value})["value"] == translation # Restore language setting to default assert self._get_api_json("set_config_default", extra_args={"keyword": "language"})["status"] is True def test_api_translate_empty(self): assert ( self._get_api_json("set_config", extra_args={"section": "misc", "keyword": "language", "value": "de"})[ "config" ]["misc"]["language"] == "de" ) # Apparently, this returns some stats on the translation for the active language assert "Last-Translator" in self._get_api_json("translate", extra_args={"value": ""})["value"] # Restore language setting to default assert self._get_api_json("set_config_default", extra_args={"keyword": "language"})["status"] is True def test_api_get_clear_warnings(self): # Trigger warnings by sending requests with a truncated apikey for _ in range(0, 2): assert interface._MSG_APIKEY_INCORRECT in self._get_api_json( "shutdown", extra_args={"apikey": SAB_APIKEY[:-1]} ) # Take delivery of our freshly baked warnings json = self._get_api_json("warnings") assert "warnings" in json.keys() assert len(json["warnings"]) > 0 for warning in json["warnings"]: for key in ("type", "text", "time"): assert key in warning.keys() assert interface._MSG_APIKEY_INCORRECT.lower() in json["warnings"][-1]["text"].lower() # Clear all warnings assert self._get_api_json("warnings", extra_args={"name": "clear"})["status"] is True # Verify they're gone json = self._get_api_json("warnings") assert "warnings" in json.keys() assert len(json["warnings"]) == 0 # Check queue output as well assert int(self._get_api_json("queue", extra_args={"limit": 1})["queue"]["have_warnings"]) == 0 def test_api_pause_resume_pp(self): # TODO include this in the queue output, like the other pause states? # Very basic test only, pp pause state cannot be verified for now assert self._get_api_json("pause_pp")["status"] is True assert self._get_api_json("resume_pp")["status"] is True @pytest.mark.parametrize("set_watched_dir", [False, True]) def test_api_watched_now(self, set_watched_dir): value = SAB_CACHE_DIR if set_watched_dir else "" assert ( self._get_api_json( mode="set_config", extra_args={"section": "misc", "keyword": "dirscan_dir", "value": value} )["config"]["misc"]["dirscan_dir"] == value ) # Returns True even when no watched dir is set... assert self._get_api_json("watched_now")["status"] is True # is set_watched_dir @pytest.mark.parametrize("set_quota", [False, True]) def test_api_reset_quota(self, set_quota): quota_config = [ ("quota_period", "m"), ("quota_day", "13"), ("quota_size", "123G") if set_quota else ("quota_size", ""), ] for keyword, value in quota_config: assert ( self._get_api_json( mode="set_config", extra_args={"section": "misc", "keyword": keyword, "value": value} )["config"]["misc"][keyword] == value ) # Reset the quota and verify the response for all output types xml = self._get_api_xml("reset_quota") assert len(xml) > 0 # Test for issue #1161 assert xml["result"]["status"] == "True" json = self._get_api_json("reset_quota") assert len(json) > 0 # Test for issue #1161 assert json["status"] is True @pytest.mark.parametrize("name, keyword", [("nzbkey", "nzb_key"), ("apikey", "api_key")]) def test_api_set_keys(self, name, keyword): original_key = self._get_api_json("get_config", extra_args={"section": "misc", "keyword": keyword})["config"][ "misc" ][keyword] # Ask the server for a new key json = self._get_api_json("config", extra_args={"name": "set_" + name}) assert "error" not in json.keys() assert len(json[name]) == 32 assert json[name] != original_key # Reset the apikey to prevent getting locked out if name == "apikey": self._get_api_json( "set_config", extra_args={"apikey": json[name], "section": "misc", "keyword": keyword, "value": "apikey"}, ) @pytest.mark.parametrize("identifier", ["name", "keyword"]) @pytest.mark.parametrize( "sorter_name, sorter_conf", [ [ "MyFirstSorter", { "order": 0, "min_size": "1234K", "multipart_label": "CD%1", "sort_string": "%title (%y)/%title (%y).%ext", "sort_cats": ["*", "test"], "sort_type": [3], "is_active": 0, }, ], [ "MySecondSorter", { "order": randint(0, 99), "min_size": "666G", "multipart_label": "", "sort_string": "%s_n/my series S%0sE%0e.%ext", "sort_cats": ["tv"], "sort_type": [1, 2], "is_active": 1, }, ], [ "MyThirdSorter", { "order": 42, "sort_string": "%s_n/my series S%0sE%0e.%ext", "sort_cats": ["tv"], "sort_type": [1, 2], "is_active": 1, }, # Intentionally leave out min_size and multipart_label ], ], ) def test_api_handle_sorter_api(self, identifier, sorter_name, sorter_conf): """Test handling of set_config for sorters""" # Set a sorter via the api extra_args = {"section": "sorters", identifier: sorter_name} extra_args.update(sorter_conf) json_set = self._get_api_json(mode="set_config", extra_args=extra_args) # Get the configured sorter json_get = self._get_api_json(mode="get_config", extra_args={"section": "sorters", "keyword": sorter_name}) # Verify the result; responses to both commands should be identical for json in json_set, json_get: assert json["config"]["sorters"] for setting, value in json["config"]["sorters"][0].items(): if configured_value := sorter_conf.get(setting): assert value == configured_value else: # Check against the default value for anything not specified in sorter_conf if setting == "min_size": assert value == DEF_SORTER_RENAME_SIZE if setting == "multipart_label": assert value == "" # Remove sorter json_del = self._get_api_json( mode="del_config", extra_args={ "section": "sorters", "keyword": sorter_name, }, ) assert json_del["status"] == True # Try getting the deleted sorter again and make sure it's actually gone json_get_again = self._get_api_json( mode="get_config", extra_args={"section": "sorters", "keyword": sorter_name} ) assert json_get_again["config"] == {} @pytest.mark.usefixtures("run_sabnzbd") class TestQueueApi(ApiTestFunctions): """Test queue-related API responses""" def test_api_queue_empty_format(self): """Verify formatting, presence of fields for empty queue""" self._purge_queue() self._run_tavern("api_queue_empty") @pytest.mark.parametrize("extra_args", [{"name": "woooooops", "value": "so False"}, {"name": "woooooops"}]) def test_api_queue_nonexistent_name(self, extra_args): # Invalid name returns regular output for the given mode (regardless of value). assert self._get_api_json("queue", extra_args=extra_args)["queue"]["version"] # Also check repeat actions (e.g. pausing an already paused queue) @pytest.mark.parametrize( "action1, action2", [("pause", "resume"), ("resume", "pause"), ("pause", "pause"), ("resume", "resume")] ) def test_api_queue_pause_resume(self, action1, action2): self._purge_queue() for action in (action1, action2): assert self._get_api_json(action)["status"] is True assert self._get_api_json("queue")["queue"]["paused"] is (action == "pause") # Also check repeat actions (e.g. pausing an already paused job) @pytest.mark.parametrize( "action1, action2", [("pause", "resume"), ("resume", "pause"), ("pause", "pause"), ("resume", "resume")] ) def test_api_queue_pause_resume_single_job(self, action1, action2): self._create_random_queue(minimum_size=4) nzo_ids = [slot["nzo_id"] for slot in self._get_api_json("queue")["queue"]["slots"]] change_me = nzo_ids.pop() for action in (action1, action2): json = self._get_api_json("queue", extra_args={"name": action, "value": change_me}) assert json["status"] is True assert isinstance(json["nzo_ids"], list) assert change_me in json["nzo_ids"] # Verify the correct job was indeed paused (and nothing else) for slot in self._get_api_json("queue")["queue"]["slots"]: if action == "pause" and slot["nzo_id"] == change_me: assert slot["status"] == Status.PAUSED else: assert slot["status"] != Status.PAUSED @pytest.mark.parametrize("sample_size", [i for i in range(0, 5)]) @pytest.mark.parametrize("select_filename", [True, False]) def test_api_queue_search_and_nzo_ids(self, sample_size, select_filename): queue_size = max(4, sample_size) self._create_random_queue(minimum_size=queue_size) jobs = {slot["nzo_id"]: slot["filename"] for slot in self._get_api_json("queue")["queue"]["slots"]} extra = {} find_nzo_ids = [] return_size_nzo_id = queue_size return_size_filename = queue_size # Take a sample of nzo_ids if sample_size: return_size_nzo_id = sample_size find_nzo_ids = sample(list(jobs.keys()), sample_size) extra["nzo_ids"] = ",".join(find_nzo_ids) # Select a filename to search for if select_filename: return_size_filename = 1 find_filename_nzo_id = choice(list(jobs.keys())) # Selects a single nzo_id find_filename = jobs[find_filename_nzo_id] extra["search"] = find_filename # Calculate the expected number of results return_size = min(return_size_nzo_id, return_size_filename) if select_filename and sample_size and find_filename_nzo_id not in find_nzo_ids: # When selecting by both nzo_ids and filename, the matches may be mutually exclusive return_size = 0 # Fetch results json = self._get_api_json("queue", extra_args=extra) # Verify assert len(json["queue"]["slots"]) == return_size if return_size != 0: found = {slot["nzo_id"]: slot["filename"] for slot in json["queue"]["slots"]} if select_filename: assert found[find_filename_nzo_id] == find_filename else: for nzo_id in find_nzo_ids: assert nzo_id in found @pytest.mark.parametrize("select_by", ["search", "nzo_ids"]) def test_api_queue_restrict_no_results_search_and_nzo_ids(self, select_by): fake_search = "FakeSearch_%s" % random_name() json = self._get_api_json("queue", extra_args={select_by: fake_search}) assert len(json["queue"]["slots"]) == 0 @pytest.mark.parametrize("delete_count", [1, 2, 5, 9, 10]) def test_api_queue_delete_jobs(self, delete_count): number_of_jobs = max(10, delete_count) self._create_random_queue(minimum_size=number_of_jobs) original_nzo_ids = [slot["nzo_id"] for slot in self._get_api_json("queue")["queue"]["slots"]] # Select random nzo_ids to delete delete_me = sample(original_nzo_ids, delete_count) delete_me.sort() json = self._get_api_json("queue", extra_args={"name": "delete", "value": ",".join(delete_me)}) # Verify the returned json assert json["status"] is True assert isinstance(json["nzo_ids"], list) deleted_nzo_ids = json["nzo_ids"] deleted_nzo_ids.sort() assert deleted_nzo_ids == delete_me # Check the remaining queue items remaining_nzo_ids = [slot["nzo_id"] for slot in self._get_api_json("queue")["queue"]["slots"]] assert len(remaining_nzo_ids) == len(original_nzo_ids) - delete_count for nzo_id in deleted_nzo_ids: assert nzo_id not in remaining_nzo_ids @pytest.mark.parametrize( "should_work, set_scriptsdir, value", [ (True, False, "hibernate_pc"), (True, False, "standby_pc"), (True, True, "shutdown_program"), (False, False, "invalid_option"), ], ) def test_api_queue_change_complete_action(self, should_work, set_scriptsdir, value): # To safeguard against actually triggering any of the actions, pause the # queue and add some random job before setting any end-of-queue actions. self._create_random_queue(minimum_size=1) # Run the queue complete action api call prev_value = self._get_api_json("queue")["queue"]["finishaction"] json = self._get_api_json("queue", extra_args={"name": "change_complete_action", "value": value}) assert json["status"] is True # 'is should_work' fails here, because status is always True # Verify the new setting instead new_value = self._get_api_json("queue")["queue"]["finishaction"] if should_work and value == "": assert new_value is None elif should_work: assert new_value == value else: # This assert fails because script values go unchecked, issue #1650 assert new_value == prev_value # Unset the queue completion action self._get_api_json("queue", extra_args={"name": "change_complete_action", "value": ""}) def test_api_queue_single_format(self): """Verify formatting, presence of fields for single queue entry""" self._create_random_queue(minimum_size=1) self._run_tavern("api_queue_format") @pytest.mark.parametrize( "sort_by, slot_name, sort_order", [ ("avg_age", "avg_age", "asc"), ("avg_age", "avg_age", "desc"), ("name", "filename", "asc"), ("name", "filename", "desc"), ("size", "size", "asc"), # Issue #1666, incorrect (reversed) sort order for avg_age ("size", "size", "desc"), ], ) def test_api_queue_sort(self, sort_by, slot_name, sort_order): self._create_random_queue(minimum_size=8) original_order = [slot[slot_name] for slot in self._get_api_json("queue")["queue"]["slots"]] # API returns "-" instead of their age for jobs dated prior to the 21st century geriatric_entry = "-" # Sort the queue assert ( self._get_api_json("queue", extra_args={"name": "sort", "sort": sort_by, "dir": sort_order})["status"] is True ) new_order = [slot[slot_name] for slot in self._get_api_json("queue")["queue"]["slots"]] def age_in_minutes(age): # Helper function for list.sort() to deal with d/h/m in avg_age values if age.endswith("d"): return int(age.strip("d")) * 60 * 24 if age.endswith("h"): return int(age.strip("h")) * 60 if age.endswith("m"): return int(age.strip("m")) if age == geriatric_entry: return int(time.time() / 60) pytest.fail("Unexpected value %s for avg_age" % age) def size_in_bytes(size): # Helper function for list.sort() to deal with B/KB/MB in size values if size.endswith(" MB"): return float(size.strip(" MB")) * 1024**2 if size.endswith(" KB"): return float(size.strip(" KB")) * 1024 if size.endswith(" B"): return float(size.strip(" B")) pytest.fail("Unexpected value %s for size" % size) # Sort the record of the original queue the same way the api sorted the actual queue key = None if sort_by == "avg_age": key = age_in_minutes elif sort_by == "size": key = size_in_bytes original_order.sort(reverse=(sort_order == "desc"), key=key) # Filter out geriatric entries new_order = list(filter((geriatric_entry).__ne__, new_order)) original_order = list(filter((geriatric_entry).__ne__, original_order)) # Verify the result assert new_order == original_order @pytest.mark.parametrize( "queue_size, index_from, index_to, value2_is_nzo_id", [ (5, 4, 1, True), (5, 4, 0, False), (5, 0, 4, True), (5, 2, 3, False), (2, 1, 0, False), (2, 0, 1, True), ], ) def test_api_queue_move(self, queue_size, index_from, index_to, value2_is_nzo_id): self._purge_queue() self._create_random_queue(minimum_size=queue_size) original = self._record_slots(keys=("index", "nzo_id")) if index_from > index_to: # Promoting job index_shifted = index_to + 1 else: # Demoting index_shifted = index_to - 1 nzo_id_to_move = original[index_from]["nzo_id"] nzo_id_move_to = original[index_to]["nzo_id"] if value2_is_nzo_id: extra = {"value": nzo_id_to_move, "value2": nzo_id_move_to} else: extra = {"value": nzo_id_to_move, "value2": index_to} json = self._get_api_json("switch", extra_args=extra) assert json["result"]["position"] == index_to assert isinstance(json["result"]["priority"], int) for slot in self._get_api_json("queue")["queue"]["slots"]: if slot["index"] == index_from: assert slot["nzo_id"] != nzo_id_to_move if slot["index"] == index_to: assert slot["nzo_id"] == nzo_id_to_move if slot["index"] == index_shifted: assert slot["nzo_id"] == nzo_id_move_to def test_api_queue_change_job_cat(self): self._create_random_queue(minimum_size=4) original = self._record_slots(keys=("nzo_id", "cat")) value2 = choice(self._get_api_json("get_cats")["categories"]) assert value2 nzo_id = choice(original)["nzo_id"] json = self._get_api_json("change_cat", extra_args={"value": nzo_id, "value2": value2}) assert "error" not in json.keys() assert json["status"] is True changed = self._record_slots(keys=("nzo_id", "cat")) for row in range(0, len(original)): if changed[row]["nzo_id"] == nzo_id: assert changed[row]["cat"] == value2 else: # All other jobs should remain unchanged assert changed[row] == original[row] @pytest.mark.parametrize( "script_filename, create_scriptfile, should_work", [ ("helloworld.py", True, True), ("helloworld2.py", False, False), ("my_scripted_script_.py", True, True), ("유닉스.py", True, True), pytest.param( "유닉스.sh", True, True, marks=pytest.mark.skipif(sys.platform.startswith("win"), reason="Not for Windows"), ), pytest.param( "لغة برمجة نصية", False, False, marks=pytest.mark.skipif(sys.platform.startswith("win"), reason="Not for Windows"), ), pytest.param( ".dotfilehiddenfile.sh", True, False, marks=pytest.mark.skipif(sys.platform.startswith("win"), reason="Not for Windows"), ), ("None", False, True), ("", False, False), ], ) def test_api_queue_change_job_script(self, script_filename, create_scriptfile, should_work): self._create_random_queue(minimum_size=4) if create_scriptfile: self._setup_script_dir("scripts", script=script_filename) else: self._setup_script_dir("scripts") original = self._record_slots(keys=("nzo_id", "script")) nzo_id = choice(original)["nzo_id"] json = self._get_api_json("change_script", extra_args={"value": nzo_id, "value2": script_filename}) if should_work: assert "error" not in json.keys() assert json["status"] is should_work changed = self._record_slots(keys=("nzo_id", "script")) for row in range(0, len(original)): if should_work and changed[row]["nzo_id"] == nzo_id: assert changed[row]["script"] == script_filename else: # All other jobs should remain unchanged assert changed[row] == original[row] @pytest.mark.parametrize("value2", [DEFAULT_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY]) def test_api_queue_change_job_prio(self, value2): self._create_random_queue(minimum_size=4) original = self._record_slots(keys=("nzo_id", "priority")) nzo_id = choice(original)["nzo_id"] json = self._get_api_json("queue", extra_args={"name": "priority", "value": nzo_id, "value2": value2}) assert "error" not in json.keys() assert "position" in json.keys() changed = self._record_slots(keys=("nzo_id", "priority")) for row in range(0, len(original)): if changed[row]["nzo_id"] == nzo_id: assert row == json["position"] assert changed[row]["priority"] == INTERFACE_PRIORITIES.get(value2, NORMAL_PRIORITY) @pytest.mark.parametrize( "value2, expected_status, should_work", [ (0, True, True), (1, True, True), (2, True, True), (3, True, True), (choice("RUD"), False, False), # Unsupported notation for value2 (-1, False, False), # Docs used to say -1 means the (category) default, see #1644 ], ) def test_api_queue_change_job_postproc(self, value2, expected_status, should_work): self._create_random_queue(minimum_size=4) original = self._record_slots(keys=("nzo_id", "unpackopts")) nzo_id = choice(original)["nzo_id"] json = self._get_api_json("change_opts", extra_args={"value": nzo_id, "value2": value2}) assert json["status"] is expected_status if should_work: changed = self._record_slots(keys=("nzo_id", "unpackopts")) for row in range(0, len(original)): if changed[row]["nzo_id"] == nzo_id: assert changed[row]["unpackopts"] == str(value2) else: # All other jobs should remain unchanged assert changed[row] == original[row] else: new = self._record_slots(keys=("nzo_id", "unpackopts")) assert new == original @pytest.mark.parametrize( "value2, value3, expected_name, expected_password, should_work", [ ("Ubuntu", None, "Ubuntu", None, True), ("デビアン", None, "デビアン", None, True), ("OpenBSD 6.8 {{25!}}", None, "OpenBSD 6.8", "25!", True), ("Gentoo_Hobby_Edition {{secret}} ", None, "Gentoo_Hobby_Edition", "secret", True), ("Mandrake{{now{{Mageia}}", None, "Mandrake", "now{{Mageia", True), ("Красная Шляпа", "Գաղտնաբառ", "Красная Шляпа", "Գաղտնաբառ", True), ("לינוקס", "معلومات{{{{ سرية", "לינוקס", "معلومات{{{{ سرية", True), ("Hello/kITTY", None, "Hello", "kITTY", True), ("thư điện tử password=mật_khẩu", None, "thư điện tử", "mật_khẩu", True), ("{{Jobname{{PassWord}}", None, "{{Jobname", "PassWord", True), # Issue #1659 ("password=PartOfTheJobname", None, "password=PartOfTheJobname", None, True), # Issue #1659 ("/Jobname", None, "+Jobname", None, True), # Issue #1659 ("", None, None, None, False), ("", "PassWord", None, "PassWord", False), (None, None, None, None, False), (None, "PassWord", None, "PassWord", False), ("Job}}Name{{FTW", None, "Job}}Name{{FTW", None, True), # Issue #1659 (".{{PasswordOnly}}", None, ".{{PasswordOnly}}", None, True), # Issue #1659 # Supplying password through value3 should leave any {{...}} in value2 alone ("Foo{{Bar}}", "PassFromValue3", "Foo{{Bar}}", "PassFromValue3", True), ], ) def test_api_queue_change_job_name(self, value2, value3, expected_name, expected_password, should_work): self._create_random_queue(minimum_size=4) original = self._record_slots(keys=("nzo_id", "filename", "password")) nzo_id = choice(original)["nzo_id"] extra = [("name", "rename"), ("value", nzo_id), ("value2", value2)] if value3: extra.append(("value3", value3)) json = self._get_api_json("queue", extra_args=dict(extra)) assert json["status"] is should_work if should_work: assert "error" not in json.keys() else: assert "error" in json.keys() changed = self._record_slots(keys=("nzo_id", "filename", "password")) for row in range(0, len(original)): if should_work and changed[row]["nzo_id"] == nzo_id: assert len(changed[row]["filename"]) > 0 assert changed[row]["filename"] == expected_name if expected_password: assert changed[row]["password"] == expected_password if value3: assert len(changed[row]["filename"]) == len(value2) else: assert changed[row]["password"] == original[row]["password"] else: # All other jobs should remain unchanged assert changed[row] == original[row] def test_api_queue_get_files_format(self): """Verify formatting, presence of fields for mode=get_files""" self._create_random_queue(minimum_size=1) nzo_id = self._get_api_json("queue")["queue"]["slots"][0]["nzo_id"] # Pass the nzo_id this way rather than fetching it in a tavern stage, as # the latter (while fine with json output) seems buggy when combined # with validation functions (as used for the text and xml outputs). self._run_tavern("api_get_files_format", extra_vars=("nzo_id", nzo_id)) def test_api_queue_delete_nzf(self): self._create_random_queue(minimum_size=4) # Select a job and file to delete nzo_ids = [slot["nzo_id"] for slot in self._get_api_json("queue")["queue"]["slots"]] nzo_id = choice(nzo_ids) nzf_ids = self._get_files(nzo_id) assert nzf_ids nzf_id = choice(nzf_ids) # Remove the file from the job json = self._get_api_json("queue", extra_args={"name": "delete_nzf", "value": nzo_id, "value2": nzf_id}) assert json["status"] is True assert nzf_id in json["nzf_ids"] # Verify it's really gone changed_nzf_ids = self._get_files(nzo_id) assert nzf_id not in changed_nzf_ids assert len(changed_nzf_ids) == len(nzf_ids) - 1 # Try to remove a non-existent file json = self._get_api_json("queue", extra_args={"name": "delete_nzf", "value": nzo_id, "value2": "FAKE"}) assert json["status"] is False assert json["nzf_ids"] == [] # Attempt to remove multiple nzf_ids at once nzo_ids.remove(nzo_id) nzo_id = choice(nzo_ids) original_nzf_ids = self._get_files(nzo_id) nzf_ids_to_remove = sample(original_nzf_ids, k=2) json = self._get_api_json( mode="queue", extra_args={"name": "delete_nzf", "value": nzo_id, "value2": ",".join(nzf_ids_to_remove)} ) assert json["status"] is True assert len(json["nzf_ids"]) == len(nzf_ids_to_remove) # Verify they are really gone changed_nzf_ids = self._get_files(nzo_id) for nzf_id in nzf_ids_to_remove: assert nzf_id not in changed_nzf_ids assert len(changed_nzf_ids) == len(original_nzf_ids) - len(nzf_ids_to_remove) def test_api_move_nzf_bulk(self): # Clear queue so we don't use any of the files from the # delete_nzf test, since we expect at least 4 files self._purge_queue() self._create_random_queue(minimum_size=1) # Select a job and file to delete nzo_ids = [slot["nzo_id"] for slot in self._get_api_json("queue")["queue"]["slots"]] nzo_id = choice(nzo_ids) nzf_ids = self._get_files(nzo_id) assert nzf_ids # Move the bottom 2 up json = self._get_api_json( mode="move_nzf_bulk", extra_args={"name": "top", "value": nzo_id, "nzf_ids": ",".join(nzf_ids[-2:])} ) assert json["status"] is True new_nzf_ids = self._get_files(nzo_id) assert new_nzf_ids[:2] == nzf_ids[-2:] # Move the top 2 down nzf_ids = self._get_files(nzo_id) json = self._get_api_json( mode="move_nzf_bulk", extra_args={"name": "bottom", "value": nzo_id, "nzf_ids": ",".join(nzf_ids[:2])} ) assert json["status"] is True new_nzf_ids = self._get_files(nzo_id) assert new_nzf_ids[-2:] == nzf_ids[:2] # Move the last 2 up 2 spots nzf_ids = self._get_files(nzo_id) json = self._get_api_json( mode="move_nzf_bulk", extra_args={"name": "up", "value": nzo_id, "nzf_ids": ",".join(nzf_ids[-2:]), "size": "2"}, ) assert json["status"] is True new_nzf_ids = self._get_files(nzo_id) assert new_nzf_ids[-4:-2] == nzf_ids[-2:] # Move the first 2 down 2 spots nzf_ids = self._get_files(nzo_id) json = self._get_api_json( mode="move_nzf_bulk", extra_args={"name": "down", "value": nzo_id, "nzf_ids": ",".join(nzf_ids[:2]), "size": "2"}, ) assert json["status"] is True new_nzf_ids = self._get_files(nzo_id) assert new_nzf_ids[2:4] == nzf_ids[:2] # See failure if called with valid nzf_id but missing size json = self._get_api_json( mode="move_nzf_bulk", extra_args={"name": "up", "value": nzo_id, "nzf_ids": ",".join(nzf_ids[:2])} ) assert json["status"] is False @pytest.mark.usefixtures("run_sabnzbd", "generate_fake_history", "update_history_specs") class TestHistoryApi(ApiTestFunctions): """Test history-related API responses""" def test_api_history_format(self): """Verify formatting, presence of expected history fields""" # Checks all output styles: json, text and xml self._run_tavern("api_history_format") def test_api_history_slot_count(self): slot_limit = randint(1, self.history_size - 1) json = self._get_api_history({"limit": slot_limit}) assert len(json["history"]["slots"]) == slot_limit def test_api_history_restrict_cat(self): slot_sum = 0 # Loop over all categories in the fake history, plus the Default category cats = list(self.history_category_options) cats.extend("*") for cat in cats: json = self._get_api_history({"category": cat}) slot_sum += len(json["history"]["slots"]) # All results should be from the correct category for slot in json["history"]["slots"]: if cat != "*": assert slot["category"] == cat # Total number of slots should match the sum of all category slots json = self._get_api_history({"limit": self.history_size}) slot_total = len(json["history"]["slots"]) assert slot_sum == slot_total def test_api_history_restrict_invalid_cat(self): fake_cat = "FakeCat_%s" % random_name() json = self._get_api_history({"category": fake_cat}) assert len(json["history"]["slots"]) == 0 def test_api_history_restrict_cat_and_limit(self): cats = self.history_category_options for cat in cats: limit = min(randint(1, 5), self.history_size) json = self._get_api_history({"category": cat, "limit": limit}) assert len(json["history"]["slots"]) <= limit for slot in json["history"]["slots"]: # All results should be from the correct category assert slot["category"] == cat def test_api_history_restrict_invalid_cat_and_limit(self): fake_cat = "FakeCat_%s" % random_name() json = self._get_api_history({"category": fake_cat, "limit": randint(1, 5)}) assert len(json["history"]["slots"]) == 0 def test_api_history_restrict_invalid_cat_and_search(self): fake_cat = "FakeCat_%s" % random_name() for distro in self.history_distro_names: json = self._get_api_history({"category": fake_cat, "search": distro}) assert len(json["history"]["slots"]) == 0 def test_api_history_restrict_search(self): slot_sum = 0 for distro in self.history_distro_names: json = self._get_api_history({"search": distro}) slot_sum += len(json["history"]["slots"]) assert slot_sum == self.history_size def test_api_history_restrict_nzo_ids(self): nzo_ids = [slot["nzo_id"] for slot in self._get_api_history()["history"]["slots"]] find_me = sample(nzo_ids, randint(1, self.history_size - 1)) json = self._get_api_history({"nzo_ids": ",".join(find_me)}) assert len(json["history"]["slots"]) == len(find_me) found = [slot["nzo_id"] for slot in json["history"]["slots"]] for nzo_id in find_me: assert nzo_id in found @pytest.mark.parametrize("select_by", ["search", "nzo_ids"]) def test_api_history_restrict_no_results_search_and_nzo_ids(self, select_by): fake_search = "FakeSearch_%s" % random_name() json = self._get_api_history({select_by: fake_search}) assert len(json["history"]["slots"]) == 0 def test_api_history_restrict_cat_and_search_and_limit(self): """Combine search, category and limits requirements into a single query""" limit_sum = 0 slot_sum = 0 limits = [randint(1, ceil(self.history_size / 10)) for _ in range(0, len(self.history_distro_names))] for distro, limit in zip(self.history_distro_names, limits): for cat in self.history_category_options: json = self._get_api_history({"search": distro, "limit": limit, "category": cat}) slot_count = len(json["history"]["slots"]) assert slot_count <= limit slot_sum += slot_count limit_sum += min(limit, slot_count) for slot in json["history"]["slots"]: assert slot["category"] == cat # Verify the number of results assert slot_sum <= sum(limits) * len(self.history_category_options) assert slot_sum == limit_sum def test_api_history_limit_failed(self): json = self._get_api_history({"failed_only": 1}) failed_count = len(json["history"]["slots"]) # Now get all history and select jobs with status failed json = self._get_api_history() failed_sum = 0 for slot in json["history"]["slots"]: if slot["status"] == Status.FAILED: failed_sum += 1 assert failed_count == failed_sum def test_api_history_delete_single(self): # Collect a single random nzo_id json = self._get_api_history({"start": randint(0, self.history_size - 1), "limit": 1}) delete_this = { "nzo_id": str(json["history"]["slots"][0]["nzo_id"]), "name": str(json["history"]["slots"][0]["name"]), } json = self._get_api_history({"name": "delete", "value": delete_this["nzo_id"]}) assert json["status"] is True # Verify the job is actually gone. Unfortunately, it appears searching # the history by nzo_id isn't possible so we take a detour and search by # name, only to check the nzo_id of the returned entries (if any). json = self._get_api_history({"search": delete_this["name"]}) # Searching by name could match other jobs too, so we can't rely on "noofslots" here for slot in json["history"]["slots"]: assert slot["nzo_id"] != delete_this["nzo_id"] # Try to delete a non-existing one, it just returns true json = self._get_api_history({"name": "delete", "value": "fake"}) assert json["status"] is True def test_api_history_delete_multiple(self): # Collect several nzo_ids to delete limit = randint(2, 2 + ceil(self.history_size / 10)) json = self._get_api_history({"start": randint(0, self.history_size - limit - 1), "limit": limit}) delete_these = {"nzo_id": [], "name": []} for slot in json["history"]["slots"]: for item in ("nzo_id", "name"): delete_these[item].append(slot[item]) # Delete 'm all json = self._get_api_history({"name": "delete", "value": ",".join(delete_these["nzo_id"])}) assert json["status"] is True # Verify for name in delete_these["name"]: json = self._get_api_history({"search": name}) for slot in json["history"]["slots"]: assert slot["nzo_id"] not in delete_these["nzo_id"] def test_api_history_delete_failed(self): # Check the number of failed entries currently in the history json = self._get_api_history({"failed_only": 1}) failed_count = len(json["history"]["slots"]) original_history_size = int(self.history_size) if failed_count > 0: # Remove all failed entries json = self._get_api_history({"name": "delete", "value": "failed"}) assert json["status"] is True # Verify no failed history entries remain json = self._get_api_history() for slot in json["history"]["slots"]: assert slot["status"] != Status.FAILED # Make sure nothing else got axed new_history_size = original_history_size - failed_count assert len(json["history"]["slots"]) == new_history_size else: warn("Fake history doesn't contain any failed jobs") new_history_size = original_history_size # A rerun of the delete action shouldn't have any effect, since no failed entries should remain json = self._get_api_history({"name": "delete", "value": "failed"}) assert json["status"] is True json = self._get_api_history() assert len(json["history"]["slots"]) == new_history_size def test_api_history_delete_completed(self): json = self._get_api_history({"name": "delete", "value": "completed"}) assert json["status"] is True json = self._get_api_history() for slot in json["history"]["slots"]: assert slot["status"] != Status.COMPLETED @pytest.mark.usefixtures("run_sabnzbd", "generate_fake_history", "update_history_specs") class TestHistoryApiPart2(ApiTestFunctions): """Test history-related API responses, part 2. A separate testcase is needed because the previous one ran out of history entries to delete.""" def test_api_history_delete_all(self): json = self._get_api_history({"name": "delete", "value": "all"}) assert json["status"] is True json = self._get_api_history() for slot in json["history"]["slots"]: assert slot["status"] != Status.COMPLETED assert slot["status"] != Status.FAILED def test_api_history_delete_everything(self): json = self._get_api_history() delete_these = [slot["nzo_id"] for slot in json["history"]["slots"]] assert len(delete_these) == len(json["history"]["slots"]) # Kill 'm with fire! json = self._get_api_history({"name": "delete", "value": ",".join(delete_these)}) assert json["status"] is True # Make sure nothing survived json = self._get_api_history() assert json["history"]["noofslots"] == 0 def test_api_history_empty_format(self): """Verify formatting, presence of fields for empty history""" # Checks all output styles: json, text and xml self._run_tavern("api_history_empty") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4431427 SABnzbd-4.3.2/tests/test_newsunpack.py0000644000000000000000000003277314625637243017170 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_newsunpack - Tests of various functions in newspack """ import glob import logging import os.path import shutil from unittest.mock import call from tests.testhelper import * import sabnzbd import sabnzbd.newsunpack as newsunpack from sabnzbd.constants import JOB_ADMIN from sabnzbd.misc import format_time_string class TestNewsUnpackFunctions: def test_is_sfv_file(self): assert newsunpack.is_sfv_file("tests/data/good_sfv_unicode.sfv") assert newsunpack.is_sfv_file("tests/data/one_line.sfv") assert not newsunpack.is_sfv_file("tests/data/only_comments.sfv") assert not newsunpack.is_sfv_file("tests/data/random.bin") def test_is_sevenfile(self): # False, because the command is not set assert not newsunpack.SEVENZIP_COMMAND assert not newsunpack.is_sevenfile("tests/data/test_7zip/testfile.7z") # Set the command to get some real results newsunpack.find_programs(".") assert newsunpack.SEVENZIP_COMMAND assert not newsunpack.is_sevenfile("tests/data/only_comments.sfv") assert not newsunpack.is_sevenfile("tests/data/random.bin") assert not newsunpack.is_sevenfile("tests/data/par2file/basic_16k.par2") assert newsunpack.is_sevenfile("tests/data/test_7zip/testfile.7z") def test_sevenzip(self): testzip = newsunpack.SevenZip("tests/data/test_7zip/testfile.7z") assert testzip.namelist() == ["My_Test_Download.bin"] # Basic check that we can get data from the 7zip assert len(testzip.open(testzip.namelist()[0]).read()) == 102400 # Test with a non-7zip file with pytest.raises(TypeError): newsunpack.SevenZip("tests/data/basic_rar5/testfile.rar") @pytest.mark.usefixtures("clean_cache_dir") class TestPar2Repair: @staticmethod def _run_par2repair(test_dir, caplog, break_file=None, remove_file=None): # Create data-directory with copy of our test-files temp_test_dir = os.path.join(SAB_CACHE_DIR, "par2repair_temp") test_dir_admin = os.path.join(temp_test_dir, JOB_ADMIN) os.mkdir(temp_test_dir) assert os.path.exists(temp_test_dir) os.mkdir(test_dir_admin) assert os.path.exists(test_dir_admin) # Copy all test files for file in glob.glob(test_dir + "/*"): shutil.copy(file, temp_test_dir) # Break a specific file, if requested if break_file: with open(os.path.join(temp_test_dir, break_file), "wb") as bf: bf.seek(10) bf.write(b"booh") # Remove a specific file, if requested if remove_file: os.unlink(os.path.join(temp_test_dir, remove_file)) # Make sure all programs are found newsunpack.find_programs(".") # Needed to store the POpen-reference sabnzbd.PostProcessor = mock.Mock() # Mock basic NZO structure nzo = mock.Mock() nzo.download_path = temp_test_dir nzo.admin_path = test_dir_admin nzo.fail_msg = "" nzo.extrapars = {"test": []} nzo.par2packs = {"test": None} for file in glob.glob(test_dir + "/*.par2"): # Simple NZF mock for the filename parfile = mock.Mock() parfile.filename = os.path.basename(file) nzo.extrapars["test"].append(parfile) # We want to collect all updates nzo.set_action_line = mock.Mock() nzo.set_unpack_info = mock.Mock() nzo.renamed_file = mock.Mock() # Run repair with caplog.at_level(logging.DEBUG): readd, result = newsunpack.par2_repair(nzo=nzo, setname="test") # Verify we only have the rar-files left dir_contents = os.listdir(temp_test_dir) dir_contents.sort() # Always cleanup, to be sure shutil.rmtree(temp_test_dir) assert not os.path.exists(temp_test_dir) # Verify result assert result assert not readd # Verify history updates # Try with multiple values, as it can take longer sometimes for text in ("[test] Verified in %s, repair is required", "[test] Repaired in %s"): for i in range(10): try: nzo.set_unpack_info.assert_has_calls([call("Repair", text % format_time_string(i))]) break except AssertionError: pass else: # It never succeeded raise AssertionError("Failed to match: %s" % text) # Check externally return nzo, dir_contents def test_basic(self, caplog): # Run code nzo, dir_contents = self._run_par2repair("tests/data/par2repair/basic", caplog) assert dir_contents == [ "__ADMIN__", "notarealfile.rar", "par2test.part1.rar", "par2test.part2.rar", "par2test.part3.rar", "par2test.part4.rar", "par2test.part5.rar", "par2test.part6.rar", ] # Verify renames nzo.renamed_file.assert_has_calls( [ call( { "par2test.part3.rar": "foorbar.rar", "par2test.part4.rar": "stillrarbutnotagoodname.txt", "par2test.part1.rar": "par2test.part1.11.rar", } ) ] ) if sabnzbd.WIN32 and cfg.enable_multipar(): # Multipar output status updates nzo.set_action_line.assert_has_calls( [ call("Repair", "Quick Checking"), call("Repair", "Starting Repair"), call("Checking", "01/06"), call("Checking", "02/06"), call("Checking", "03/06"), call("Checking", "04/06"), call("Checking", "05/06"), call("Checking", "06/06"), # We only know total of missing files, so not how many will be found call("Checking extra files", "01/05"), call("Checking extra files", "02/05"), call("Verifying", "01/03"), call("Verifying", "02/03"), call("Verifying", "03/03"), call("Repairing", " 0%"), call("Repairing", "100% "), call("Verifying repair", "01/03"), call("Verifying repair", "02/03"), call("Verifying repair", "03/03"), ] ) else: # par2cmdline output status updates # Verify output in chunks, as it outputs every single % during repair nzo.set_action_line.assert_has_calls( [ call("Repair", "Quick Checking"), call("Repair", "Starting Repair"), call("Verifying", "01/06"), call("Verifying", "02/06"), call("Verifying", "03/06"), call("Verifying", "04/06"), call("Verifying", "05/06"), call("Verifying", "06/06"), call("Checking extra files", "01"), call("Checking extra files", "02"), call("Checking extra files", "03"), call("Repairing", " 0%"), ] ) nzo.set_action_line.assert_has_calls( [ call("Repairing", "100% "), call("Verifying repair", "01/03"), call("Verifying repair", "02/03"), call("Verifying repair", "03/03"), ] ) def test_filejoin(self, caplog): # Run code nzo, dir_contents = self._run_par2repair("tests/data/par2repair/filejoin", caplog) # All joinable files will be removed assert dir_contents == ["__ADMIN__", "par2test.bin"] # There are no renames in case of filejoin by par2repair! nzo.renamed_file.assert_not_called() if sabnzbd.WIN32 and cfg.enable_multipar(): # Multipar output status updates, which is limited because Multipar doesn't say much.. nzo.set_action_line.assert_has_calls( [ call("Repair", "Quick Checking"), call("Repair", "Starting Repair"), call("Checking", "01/01"), call("Verifying", "01"), call("Verifying", "02"), call("Verifying", "03"), call("Verifying", "04"), call("Verifying", "05"), call("Verifying", "06"), call("Verifying", "07"), call("Verifying", "08"), call("Verifying", "09"), call("Verifying", "10"), call("Verifying", "11"), call("Joining", "11"), call("Verifying repair", "01/01"), ] ) else: # par2cmdline output status updates # Verify output in chunks, as it outputs every single % during repair nzo.set_action_line.assert_has_calls( [ call("Repair", "Quick Checking"), call("Repair", "Starting Repair"), call("Verifying", "01/01"), call("Checking extra files", "01"), call("Checking extra files", "02"), call("Checking extra files", "03"), call("Checking extra files", "04"), call("Checking extra files", "05"), call("Checking extra files", "06"), call("Checking extra files", "07"), call("Checking extra files", "08"), call("Checking extra files", "09"), call("Checking extra files", "10"), call("Checking extra files", "11"), call("Repairing", " 0%"), ] ) nzo.set_action_line.assert_has_calls( [ call("Repairing", "100% "), call("Verifying repair", "01/01"), ] ) def test_broken_filejoin(self, caplog): # Run code nzo, dir_contents = self._run_par2repair( "tests/data/par2repair/filejoin", caplog, break_file="par2test.bin.005", remove_file="par2test.bin.010" ) # There are no renames in case of filejoin by par2repair! nzo.renamed_file.assert_not_called() # All joinable files should be removed assert dir_contents == ["__ADMIN__", "par2test.bin"] if sabnzbd.WIN32 and cfg.enable_multipar(): # Multipar output status updates, which is limited because Multipar doesn't say much.. nzo.set_action_line.assert_has_calls( [ call("Repair", "Quick Checking"), call("Repair", "Starting Repair"), call("Checking", "01/01"), call("Verifying", "01"), call("Verifying", "02"), call("Verifying", "03"), call("Verifying", "04"), call("Verifying", "05"), call("Verifying", "06"), call("Verifying", "07"), call("Verifying", "08"), call("Verifying", "09"), call("Repairing", " 0%"), call("Repairing", "100% "), call("Verifying repair", "01/01"), ] ) else: # Verify output in chunks, as it outputs every single % during repair nzo.set_action_line.assert_has_calls( [ call("Repair", "Quick Checking"), call("Repair", "Starting Repair"), call("Verifying", "01/01"), call("Checking extra files", "01"), call("Checking extra files", "02"), call("Checking extra files", "03"), call("Checking extra files", "04"), call("Checking extra files", "05"), call("Checking extra files", "06"), call("Checking extra files", "07"), call("Checking extra files", "08"), call("Checking extra files", "09"), call("Repairing", " 0%"), ] ) nzo.set_action_line.assert_has_calls( [ call("Repairing", "100% "), call("Verifying repair", "01/01"), ] ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4432292 SABnzbd-4.3.2/tests/test_functional_misc.py0000644000000000000000000002064014625637243020155 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_misc - Functional tests of various functions """ import shutil import subprocess import sys import sabnzbd.encoding from sabnzbd.filesystem import save_compressed from sabnzbd.constants import JOB_ADMIN from tests.testhelper import * class TestShowLogging(SABnzbdBaseTest): def test_showlog(self): """Test the output of the filtered-log button""" # Basic URL-fetching, easier than Selenium file download log_result = get_api_result("showlog") # Make sure it has basic log stuff assert "The log" in log_result assert "Full executable path" in log_result # Make sure sabnzbd.ini was appended assert "__encoding__ = utf-8" in log_result assert "[misc]" in log_result class TestQueueRepair(SABnzbdBaseTest): def test_queue_repair(self): """Test full queue repair by manually adding an orphaned job""" nzb_fp = create_and_read_nzb_fp("basic_rar5") test_job_name = "testfile_%s" % time.time() # Create folder and save compressed NZB like SABnzbd would do admin_path = os.path.join(SAB_INCOMPLETE_DIR, test_job_name, JOB_ADMIN) os.makedirs(admin_path) save_compressed(admin_path, test_job_name, nzb_fp) assert os.path.exists(os.path.join(admin_path, test_job_name + ".nzb.gz")) # Pause the queue do we don't download stuff assert get_api_result("pause") == {"status": True} # Request queue repair assert get_api_result("restart_repair") == {"status": True} # Let's check the queue, this can take long on GitHub Actions for _ in range(60): queue_result_slots = {} try: # Can give timeout if still restarting queue_result_slots = get_api_result("queue", extra_arguments={"limit": 10000})["queue"]["slots"] except requests.exceptions.RequestException: pass # Check if the repaired job was added to the queue if queue_result_slots: break time.sleep(1) else: # The loop never stopped, so we fail pytest.fail("Did not find the repaired job in the queue") return # Verify filename assert test_job_name in [slot["filename"] for slot in queue_result_slots] # Let's remove this thing get_api_result("queue", extra_arguments={"name": "delete", "value": "all"}) assert len(get_api_result("queue")["queue"]["slots"]) == 0 # Unpause assert get_api_result("resume") == {"status": True} class TestSamplePostProc: def test_sample_post_proc(self): """Make sure we don't break things""" # Set parameters script_params = [ "somedir222", "nzbname", "frènch_german_demö", "Index12", "Cat88", "MyGroup", "PP0", "https://example.com/", ] script_call = [sys.executable, "scripts/Sample-PostProc.py", "server"] script_call.extend(script_params) # Set parameters via env env = os.environ.copy() env["SAB_VERSION"] = "frènch_german_demö_version" # Run script and check output script_call = subprocess.Popen(script_call, stdout=subprocess.PIPE, env=env) script_output, errs = script_call.communicate(timeout=15) # This is a bit bad, since we use our own function # But in a way it is also a test if the function does its job! script_output = sabnzbd.encoding.platform_btou(script_output) # Check if all parameters are there for param in script_params: assert param in script_output assert env["SAB_VERSION"] in script_output class TestExtractPot: def test_extract_pot(self): """Simple test if translation extraction still works""" script_call = [sys.executable, "tools/extract_pot.py"] # Run script and check output script_call = subprocess.Popen(script_call, stdout=subprocess.PIPE) script_output, errs = script_call.communicate(timeout=15) script_output = sabnzbd.encoding.platform_btou(script_output) # Success message? assert "Creating POT file" in script_output assert "Finished creating POT file" in script_output assert "Post-process POT file" in script_output assert "Finished post-process POT file" in script_output assert "Creating email POT file" in script_output assert "Finished creating email POT file" in script_output # Check if the file was modified less than 30 seconds ago cur_time = time.time() assert (cur_time - os.path.getmtime("po/main/SABnzbd.pot")) < 30 assert (cur_time - os.path.getmtime("po/email/SABemail.pot")) < 30 # Reset the translation updates try: lang_command = "git checkout @ -- %s/../po/main/SABnzbd.pot" % SAB_BASE_DIR subprocess.Popen(lang_command.split()).communicate(timeout=30) lang_command = "git checkout @ -- %s/../po/email/SABemail.pot" % SAB_BASE_DIR subprocess.Popen(lang_command.split()).communicate(timeout=30) except: pass @pytest.mark.skipif(sys.platform.startswith("win"), reason="Skipping on Windows") @pytest.mark.skipif(sys.platform.startswith("darwin"), reason="Fails for now due to PyObjC problem") class TestDaemonizing(SABnzbdBaseTest): def test_daemonizing(self): """Simple test to see if daemon-mode still works. Also test removal of large "sabnzbd.error.log" We inherit from SABnzbdBaseTest so we can use it's clean-up logic! """ daemon_host = "localhost" daemon_port = 23456 ini_location = os.path.join(SAB_CACHE_DIR, "daemon_test") # Create large output-file error_log_path = os.path.join(ini_location, sabnzbd.cfg.log_dir(), sabnzbd.constants.DEF_LOG_ERRFILE) os.makedirs(os.path.dirname(error_log_path), exist_ok=True) with open(error_log_path, "wb") as large_log: large_log.seek(6 * 1024 * 1024) large_log.write(b"\1") # We need the basic-config to set the API-key # Otherwise we can't shut it down at the end shutil.copyfile(os.path.join(SAB_DATA_DIR, "sabnzbd.basic.ini"), os.path.join(ini_location, "sabnzbd.ini")) # Combine it all into the script call script_call = [ sys.executable, "SABnzbd.py", "-d", "-s", "%s:%s" % (daemon_host, daemon_port), "-f", ini_location, "--pid", ini_location, ] # Run script and check output script_call = subprocess.Popen(script_call, stdout=subprocess.PIPE) script_output, errs = script_call.communicate(timeout=15) # No error or output should be thrown by main process assert not script_output assert not errs # It should be online after 3 seconds time.sleep(3.0) assert "version" in get_api_result("version", daemon_host, daemon_port) # Did it create the PID file pid_file = os.path.join(ini_location, "sabnzbd-%d.pid" % daemon_port) assert os.path.exists(pid_file) # Did it remove the bad log file? assert os.path.exists(error_log_path) assert os.path.getsize(error_log_path) < 1024 try: # Let's shut it down and give it some time to do so get_url_result("shutdown", daemon_host, daemon_port) time.sleep(3.0) except requests.exceptions.RequestException: # Shutdown can be faster than the request pass ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4433231 SABnzbd-4.3.2/tests/test_filesystem.py0000644000000000000000000015227214625637243017173 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_filesystem - Testing functions in filesystem.py """ import stat import sys import os import random import shutil from pathlib import Path import tempfile import pyfakefs.fake_filesystem_unittest as ffs from pyfakefs.fake_filesystem import OSType import sabnzbd.cfg import sabnzbd.filesystem as filesystem from sabnzbd.constants import DEF_FOLDER_MAX, DEF_FILE_MAX from tests.testhelper import * # Set the global uid for fake filesystems to a non-root user; # by default this depends on the user running pytest. global_uid = 1000 ffs.set_uid(global_uid) class TestFileFolderNameSanitizer: def test_empty(self): assert filesystem.sanitize_filename(None) is None assert filesystem.sanitize_foldername(None) is None @set_platform("win32") def test_colon_handling_windows(self): assert filesystem.sanitize_filename("test:aftertest") == "test-aftertest" assert filesystem.sanitize_filename(":") == "-" assert filesystem.sanitize_filename("test:") == "test-" assert filesystem.sanitize_filename("test: ") == "test-" # They should act the same assert filesystem.sanitize_filename("test:aftertest") == filesystem.sanitize_foldername("test:aftertest") @set_platform("macos") def test_colon_handling_macos(self): assert filesystem.sanitize_filename("test:aftertest") == "aftertest" assert filesystem.sanitize_filename(":aftertest") == "aftertest" assert filesystem.sanitize_filename("::aftertest") == "aftertest" assert filesystem.sanitize_filename(":after:test") == "test" # Empty after sanitising with macos colon handling assert filesystem.sanitize_filename(":") == "unknown" assert filesystem.sanitize_filename("test:") == "unknown" assert filesystem.sanitize_filename("test: ") == "unknown" @set_platform("linux") def test_colon_handling_other(self): assert filesystem.sanitize_filename("test:aftertest") == "test:aftertest" assert filesystem.sanitize_filename(":") == ":" assert filesystem.sanitize_filename("test:") == "test:" assert filesystem.sanitize_filename("test: ") == "test:" @set_platform("win32") def test_win_devices_on_win(self): assert filesystem.sanitize_filename(None) is None assert filesystem.sanitize_filename("aux.txt") == "_aux.txt" assert filesystem.sanitize_filename("txt.aux") == "txt.aux" assert filesystem.sanitize_filename("$mft") == "Smft" assert filesystem.sanitize_filename("a$mft") == "a$mft" @set_platform("linux") def test_win_devices_not_win(self): # Linux and macOS are the same for this assert filesystem.sanitize_filename(None) is None assert filesystem.sanitize_filename("aux.txt") == "aux.txt" assert filesystem.sanitize_filename("txt.aux") == "txt.aux" assert filesystem.sanitize_filename("$mft") == "$mft" assert filesystem.sanitize_filename("a$mft") == "a$mft" @set_platform("win32") def test_file_illegal_chars_win32(self): assert filesystem.sanitize_filename("test" + filesystem.CH_ILLEGAL_WIN + "aftertest") == ( "test" + filesystem.CH_LEGAL_WIN + "aftertest" ) assert ( filesystem.sanitize_filename("test" + chr(0) + chr(1) + chr(15) + chr(31) + "aftertest") == "test____aftertest" ) @set_platform("win32") def test_folder_illegal_chars_win32(self): assert ( filesystem.sanitize_foldername("test" + chr(0) + chr(9) + chr(13) + chr(31) + "aftertest") == "test____aftertest" ) @set_platform("linux") def test_file_illegal_chars_linux(self): assert filesystem.sanitize_filename("test/aftertest") == "test+aftertest" assert filesystem.sanitize_filename("/test") == "+test" assert filesystem.sanitize_filename("test/") == "test+" assert filesystem.sanitize_filename(r"/test\/aftertest/") == r"+test\+aftertest+" assert filesystem.sanitize_filename("/") == "+" assert filesystem.sanitize_filename("///") == "+++" assert filesystem.sanitize_filename("../") == "..+" assert filesystem.sanitize_filename("../test") == "..+test" @set_platform("linux") def test_folder_illegal_chars_linux(self): assert filesystem.sanitize_foldername('test"aftertest') == "test'aftertest" assert filesystem.sanitize_foldername("test:") == "test-" assert filesystem.sanitize_foldername("test<>?*|aftertest") == "test<>?*|aftertest" def test_char_collections(self): assert len(filesystem.CH_ILLEGAL) == len(filesystem.CH_LEGAL) assert len(filesystem.CH_ILLEGAL_WIN) == len(filesystem.CH_LEGAL_WIN) @set_platform("linux") def test_legal_chars_linux(self): # Illegal on Windows but not on Linux, unless sanitize_safe is active. # Don't bother with '/' which is illegal in filenames on all platforms. char_ill = filesystem.CH_ILLEGAL_WIN.replace("/", "") assert filesystem.sanitize_filename("test" + char_ill + "aftertest") == ("test" + char_ill + "aftertest") for char in char_ill: # Try at start, middle, and end of a filename. assert filesystem.sanitize_filename("test" + char * 2 + "aftertest") == ("test" + char * 2 + "aftertest") assert filesystem.sanitize_filename("test" + char * 2) == ("test" + char * 2).strip() assert filesystem.sanitize_filename(char * 2 + "test") == (char * 2 + "test").strip() @set_platform("linux") @set_config({"sanitize_safe": True}) def test_sanitize_safe_linux(self): # Set sanitize_safe to on, simulating Windows-style restrictions. assert filesystem.sanitize_filename("test" + filesystem.CH_ILLEGAL_WIN + "aftertest") == ( "test" + filesystem.CH_LEGAL_WIN + "aftertest" ) for index in range(0, len(filesystem.CH_ILLEGAL_WIN)): char_leg = filesystem.CH_LEGAL_WIN[index] char_ill = filesystem.CH_ILLEGAL_WIN[index] assert filesystem.sanitize_filename("test" + char_ill * 2 + "aftertest") == ( "test" + char_leg * 2 + "aftertest" ) # Illegal chars that also get caught by strip() never make it far # enough to be replaced by their legal equivalents if they appear # on either end of the filename. if char_ill.strip(): assert filesystem.sanitize_filename("test" + char_ill * 2) == ("test" + char_leg * 2) assert filesystem.sanitize_filename(char_ill * 2 + "test") == (char_leg * 2 + "test") def test_filename_dot(self): # All dots should survive in filenames assert filesystem.sanitize_filename(".test") == ".test" assert filesystem.sanitize_filename("..test") == "..test" assert filesystem.sanitize_filename("test.") == "test." assert filesystem.sanitize_filename("test..") == "test.." assert filesystem.sanitize_filename("test.aftertest") == "test.aftertest" assert filesystem.sanitize_filename("test..aftertest") == "test..aftertest" assert filesystem.sanitize_filename("test.aftertest.") == "test.aftertest." assert filesystem.sanitize_filename("test.aftertest..") == "test.aftertest.." def test_foldername_dot(self): # Dot should be removed from the end of directory names only assert filesystem.sanitize_foldername(".test") == ".test" assert filesystem.sanitize_foldername("..test") == "..test" assert filesystem.sanitize_foldername("test.") == "test" assert filesystem.sanitize_foldername("test..") == "test" assert filesystem.sanitize_foldername("test.aftertest") == "test.aftertest" assert filesystem.sanitize_foldername("test..aftertest") == "test..aftertest" assert filesystem.sanitize_foldername("test.aftertest.") == "test.aftertest" assert filesystem.sanitize_foldername("test.aftertest..") == "test.aftertest" assert filesystem.sanitize_foldername("test. aftertest. . . .") == "test. aftertest" assert filesystem.sanitize_foldername("/test/this.") == "+test+this" assert filesystem.sanitize_foldername("/test./this.") == "+test.+this" assert filesystem.sanitize_foldername("/test. /this . ") == "+test. +this" def test_long_foldername(self): assert len(filesystem.sanitize_foldername("test" * 100)) == DEF_FOLDER_MAX assert len(filesystem.sanitize_foldername("a" * DEF_FOLDER_MAX)) == DEF_FOLDER_MAX assert len(filesystem.sanitize_foldername("a" * (DEF_FOLDER_MAX + 1))) == DEF_FOLDER_MAX def test_filename_empty_result(self): # Nothing remains after sanitizing the filename assert filesystem.sanitize_filename("\n") == "unknown" assert filesystem.sanitize_filename("\r\n") == "unknown" assert filesystem.sanitize_filename("\n\r") == "unknown" assert filesystem.sanitize_filename("\t\t\t") == "unknown" assert filesystem.sanitize_filename(" ") == "unknown" assert filesystem.sanitize_filename(" ") == "unknown" def test_foldername_empty_result(self): # Nothing remains after sanitizing the foldername assert filesystem.sanitize_foldername("\n") == "unknown" assert filesystem.sanitize_foldername("\r\n") == "unknown" assert filesystem.sanitize_foldername("\n\r") == "unknown" assert filesystem.sanitize_foldername("\t\t\t") == "unknown" assert filesystem.sanitize_foldername(" ") == "unknown" assert filesystem.sanitize_foldername(" ") == "unknown" assert filesystem.sanitize_foldername(" . .") == "unknown" def test_filename_too_long(self): # Note: some filesystem can handle up to 255 UTF chars (which is more than 255 bytes) in the filename, # but we stay on the safe side: max DEF_FILE_MAX bytes # PART 1: Base cases: Nothing should happen: # normal filename name = "a" * 200 + ".ext" sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname == name # Unicode / UTF8 is OK ... as total filename length is not too long name = "BASE" + "你" * 50 + "blabla.ext" sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname == name # filename with very long extension, but total filename is no problem, so no change name = "hello.ext" + "e" * 200 sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname == name # no change # PART 2: base truncating name = "BASE" + "a" * 300 + ".mylongext" sanitizedname = filesystem.sanitize_filename(name) assert len(sanitizedname) <= DEF_FILE_MAX assert sanitizedname.startswith("BASEaaaaaaaaaaaaaaa") assert sanitizedname.endswith(".mylongext") # too long filename, so truncate keeping the start of name and ext should stay the same name = "BASE" + "a" * 200 + ".EXT" + "e" * 200 sanitizedname = filesystem.sanitize_filename(name) assert len(sanitizedname) <= DEF_FILE_MAX newname, newext = os.path.splitext(sanitizedname) assert newname.startswith("BASEaaaaa") assert newext.startswith(".EXTeeeee") # PART 3: more exotic cases # insert NON-ASCII chars, which should stay in place because overall length is no problem name = "aaaa" + 10 * chr(188) + 10 * chr(222) + "bbbb.ext" sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname == name # insert NON-ASCII chars, which should get removed because overall length is too long name = "aaaa" + 200 * chr(188) + 200 * chr(222) + "bbbb.ext" sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname == "aaaabbbb.ext" # Unicode / UTF8 ... total filename length might be too long for certain filesystems name = "BASE" + "你" * 200 + ".ext" sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname.startswith("BASE") assert sanitizedname.endswith(".ext") # Linux / POSIX: a hidden file (no extension), with size 200, so do not truncate at all name = "." + "a" * 200 sanitizedname = filesystem.sanitize_filename(name) assert sanitizedname == name # no change class TestSanitizeFiles(ffs.TestCase): def setUp(self): self.setUpPyfakefs() self.fs.os = OSType.WINDOWS # Disable randomisation of directory listings self.fs.shuffle_listdir_results = False def test_sanitize_files_input(self): assert [] == filesystem.sanitize_files(folder=None) assert [] == filesystem.sanitize_files(filelist=None) assert [] == filesystem.sanitize_files(folder=None, filelist=None) @set_platform("win32") @set_config({"sanitize_safe": True}) def test_sanitize_files(self): # The very specific tests of sanitize_filename() are above # Here we just want to see that sanitize_files() works as expected input_list = [r"c:\test\con.man", r"c:\test\foo:bar"] output_list = [r"c:\test\_con.man", r"c:\test\foo-bar"] # Test both the "folder" and "filelist" based calls for kwargs in ({"folder": r"c:\test"}, {"filelist": input_list}): # Create source files for file in input_list: self.fs.create_file(file) assert output_list == filesystem.sanitize_files(**kwargs) # Make sure the old ones are gone for file in input_list: assert not os.path.exists(file) # Make sure the new ones are there for file in output_list: assert os.path.exists(file) os.remove(file) assert not os.path.exists(file) class TestSameDirectory: def test_nothing_in_common_win_paths(self): assert 0 == filesystem.same_directory("C:\\", "D:\\") assert 0 == filesystem.same_directory("C:\\", "/home/test") def test_nothing_in_common_unix_paths(self): assert 0 == filesystem.same_directory("/home/", "/data/test") assert 0 == filesystem.same_directory("/test/home/test", "/home/") assert 0 == filesystem.same_directory("/test/../home", "/test") assert 0 == filesystem.same_directory("/test/./test", "/test") @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") @set_platform("linux") def test_posix_fun(self): assert 1 == filesystem.same_directory("/test", "/test") # IEEE 1003.1-2017 par. 4.13 for details assert 0 == filesystem.same_directory("/test", "//test") assert 1 == filesystem.same_directory("/test", "///test") assert 1 == filesystem.same_directory("/test", "/test/") assert 1 == filesystem.same_directory("/test", "/test//") assert 1 == filesystem.same_directory("/test", "/test///") def test_same(self): assert 1 == filesystem.same_directory("/home/123", "/home/123") assert 1 == filesystem.same_directory("/test/../test", "/test") assert 1 == filesystem.same_directory("test/../test", "test") assert 1 == filesystem.same_directory("/test/./test", "/test/test") assert 1 == filesystem.same_directory("./test", "test") def test_subfolder(self): assert 2 == filesystem.same_directory("/home/test123", "/home/test123/sub") assert 2 == filesystem.same_directory("/test", "/test/./test") assert 2 == filesystem.same_directory("/home/../test", "/test/./test") @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Relies on os.sep so should only run on Windows") def test_windows(self): assert 1 == filesystem.same_directory("D:\\", "D:\\") assert 2 == filesystem.same_directory("\\\\?\\C:\\", "\\\\?\\C:\\Users\\") assert 1 == filesystem.same_directory("/HOME/123", "/home/123") assert 1 == filesystem.same_directory("D:\\", "d:\\") assert 2 == filesystem.same_directory("\\\\?\\c:\\", "\\\\?\\C:\\Users\\") def test_looks_likesubfolder_but_isnt(self): assert 0 == filesystem.same_directory("/mnt/sabnzbd", "/mnt/sabnzbd-data") @pytest.mark.skipif(sys.platform.startswith(("win", "darwin")), reason="Requires a case-sensitive filesystem") @set_platform("linux") def test_capitalization_linux(self): assert 2 == filesystem.same_directory("/home/test123", "/home/test123/sub") assert 0 == filesystem.same_directory("/test", "/Test") assert 0 == filesystem.same_directory("tesT", "Test") assert 0 == filesystem.same_directory("/test/../Home", "/home") class TestClipLongPath: def test_empty(self): assert filesystem.clip_path(None) is None assert filesystem.long_path(None) is None @set_platform("win32") def test_clip_path_win(self): assert filesystem.clip_path(r"\\?\UNC\test") == r"\\test" assert filesystem.clip_path(r"\\?\F:\test") == r"F:\test" @set_platform("win32") def test_nothing_to_clip_win(self): assert filesystem.clip_path(r"\\test") == r"\\test" assert filesystem.clip_path(r"F:\test") == r"F:\test" assert filesystem.clip_path("/test/dir") == "/test/dir" @set_platform("linux") def test_clip_path_non_win(self): # Shouldn't have any effect on platforms other than Windows assert filesystem.clip_path(r"\\?\UNC\test") == r"\\?\UNC\test" assert filesystem.clip_path(r"\\?\F:\test") == r"\\?\F:\test" assert filesystem.clip_path(r"\\test") == r"\\test" assert filesystem.clip_path(r"F:\test") == r"F:\test" assert filesystem.clip_path("/test/dir") == "/test/dir" @set_platform("win32") def test_long_path_win(self): assert filesystem.long_path(r"\\test") == r"\\?\UNC\test" assert filesystem.long_path(r"F:\test") == r"\\?\F:\test" @set_platform("win32") def test_nothing_to_lenghten_win(self): assert filesystem.long_path(r"\\?\UNC\test") == r"\\?\UNC\test" assert filesystem.long_path(r"\\?\F:\test") == r"\\?\F:\test" @set_platform("linux") def test_long_path_non_win(self): # Shouldn't have any effect on platforms other than Windows assert filesystem.long_path(r"\\?\UNC\test") == r"\\?\UNC\test" assert filesystem.long_path(r"\\?\F:\test") == r"\\?\F:\test" assert filesystem.long_path(r"\\test") == r"\\test" assert filesystem.long_path(r"F:\test") == r"F:\test" assert filesystem.long_path("/test/dir") == "/test/dir" @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") class TestCheckMountLinux(ffs.TestCase): # Our collection of fake directories test_dirs = ["/media/test/dir", "/mnt/TEST/DIR"] def setUp(self): self.setUpPyfakefs() self.fs.path_separator = "/" self.fs.is_case_sensitive = True for test_dir in self.test_dirs: self.fs.create_dir(test_dir, perm_bits=755) # Sanity check the fake filesystem assert os.path.exists(test_dir) is True @set_platform("linux") def test_bare_mountpoint_linux(self): assert filesystem.mount_is_available("/media") is True assert filesystem.mount_is_available("/media/") is True assert filesystem.mount_is_available("/mnt") is True assert filesystem.mount_is_available("/mnt/") is True @set_platform("linux") def test_existing_dir_linux(self): assert filesystem.mount_is_available("/media/test") is True assert filesystem.mount_is_available("/media/test/dir/") is True assert filesystem.mount_is_available("/media/test/DIR/") is True assert filesystem.mount_is_available("/mnt/TEST") is True assert filesystem.mount_is_available("/mnt/TEST/dir/") is True assert filesystem.mount_is_available("/mnt/TEST/DIR/") is True @set_platform("linux") # Cut down a bit on the waiting time @set_config({"wait_ext_drive": 1}) def test_dir_nonexistent_linux(self): # Filesystem is case-sensitive on this platform assert filesystem.mount_is_available("/media/TEST") is False # Issue #1457 assert filesystem.mount_is_available("/media/TesT/") is False assert filesystem.mount_is_available("/mnt/TeSt/DIR") is False assert filesystem.mount_is_available("/mnt/test/DiR/") is False @set_platform("linux") def test_dir_outsider_linux(self): # Outside of /media and /mnt assert filesystem.mount_is_available("/test/that/") is True # Root directory assert filesystem.mount_is_available("/") is True @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") class TestCheckMountMacOS(ffs.TestCase): # Our faked macos directory test_dir = "/Volumes/test/dir" def setUp(self): self.setUpPyfakefs() self.fs.os = OSType.MACOS self.fs.create_dir(self.test_dir, perm_bits=755) # Verify the fake filesystem does its thing assert os.path.exists(self.test_dir) is True @set_platform("macos") def test_bare_mountpoint_macos(self): assert filesystem.mount_is_available("/Volumes") is True assert filesystem.mount_is_available("/Volumes/") is True @set_platform("macos") def test_existing_dir_macos(self): assert filesystem.mount_is_available("/Volumes/test") is True assert filesystem.mount_is_available("/Volumes/test/dir/") is True # Filesystem is set case-insensitive for this platform assert filesystem.mount_is_available("/VOLUMES/test") is True assert filesystem.mount_is_available("/volumes/Test/dir/") is True @set_platform("macos") # Cut down a bit on the waiting time @set_config({"wait_ext_drive": 1}) def test_dir_nonexistent_macos(self): # Within /Volumes assert filesystem.mount_is_available("/Volumes/nosuchdir") is False # Issue #1457 assert filesystem.mount_is_available("/Volumes/noSuchDir/") is False assert filesystem.mount_is_available("/Volumes/nosuchDIR/subdir") is False assert filesystem.mount_is_available("/Volumes/NOsuchdir/subdir/") is False @set_platform("macos") def test_dir_outsider_macos(self): # Outside of /Volumes assert filesystem.mount_is_available("/test/that/") is True # Root directory assert filesystem.mount_is_available("/") is True class TestCheckMountWin(ffs.TestCase): # Our faked windows directory test_dir = r"F:\test\dir" def setUp(self): self.setUpPyfakefs() self.fs.os = OSType.WINDOWS self.fs.create_dir(self.test_dir) # Sanity check the fake filesystem assert os.path.exists(self.test_dir) is True @set_platform("win32") def test_existing_dir_win(self): assert filesystem.mount_is_available("F:\\test") is True assert filesystem.mount_is_available("F:\\test\\dir\\") is True # Filesystem and drive letters are case-insensitive on this platform assert filesystem.mount_is_available("f:\\Test") is True assert filesystem.mount_is_available("f:\\test\\DIR\\") is True @set_platform("win32") def test_bare_mountpoint_win(self): assert filesystem.mount_is_available("F:\\") is True assert filesystem.mount_is_available("Z:\\") is False @set_platform("win32") def test_dir_nonexistent_win(self): # The existence of the drive letter is what really matters assert filesystem.mount_is_available("F:\\NoSuchDir") is True assert filesystem.mount_is_available("F:\\NoSuchDir\\") is True assert filesystem.mount_is_available("F:\\NOsuchdir\\subdir") is True assert filesystem.mount_is_available("F:\\nosuchDIR\\subdir\\") is True @set_platform("win32") # Cut down a bit on the waiting time @set_config({"wait_ext_drive": 1}) def test_dir_on_nonexistent_drive_win(self): # Non-existent drive-letter assert filesystem.mount_is_available("H:\\NoSuchDir") is False assert filesystem.mount_is_available("E:\\NoSuchDir\\") is False assert filesystem.mount_is_available("L:\\NOsuchdir\\subdir") is False assert filesystem.mount_is_available("L:\\nosuchDIR\\subdir\\") is False @set_platform("win32") def test_dir_outsider_win(self): # Outside the local filesystem assert filesystem.mount_is_available("//test/that/") is True @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") class TestListdirFull(ffs.TestCase): # Basic fake filesystem setup stanza def setUp(self): self.setUpPyfakefs() self.fs.path_separator = "/" self.fs.is_case_sensitive = True def test_nonexistent_dir(self): assert filesystem.listdir_full("/foo/bar") == [] def test_no_exceptions(self): test_files = ( "/test/dir/file1.ext", "/test/dir/file2", "/test/dir/sub/sub/sub/dir/file3.ext", ) for file in test_files: self.fs.create_file(file) assert os.path.exists(file) is True # List our fake directory structure results_subdir = filesystem.listdir_full("/test/dir") assert len(results_subdir) == 3 for entry in test_files: assert (entry in results_subdir) is True # List the same directory again, this time using its parent as the function argument. # Results should be identical, since there's nothing in /test but that one subdirectory results_parent = filesystem.listdir_full("/test") # Don't make assumptions about the sorting of the lists of results results_parent.sort() results_subdir.sort() assert results_parent == results_subdir # List that subsubsub-directory; no sorting required for a single result assert filesystem.listdir_full("/test/dir/sub/sub") == ["/test/dir/sub/sub/sub/dir/file3.ext"] # Test non-recursive version assert filesystem.listdir_full(r"/test", recursive=False) == [] assert filesystem.listdir_full(r"/test/dir/sub", recursive=False) == [] assert len(filesystem.listdir_full(r"/test/dir", recursive=False)) == 2 def test_exception_appledouble(self): # Anything below a .AppleDouble directory should be omitted test_file = "/foo/bar/.AppleDouble/Oooooo.ps" self.fs.create_file(test_file) assert os.path.exists(test_file) is True assert filesystem.listdir_full("/foo") == [] assert filesystem.listdir_full("/foo/bar") == [] assert filesystem.listdir_full("/foo/bar/.AppleDouble") == [] assert filesystem.listdir_full("/foo", recursive=False) == [] assert filesystem.listdir_full("/foo/bar", recursive=False) == [] assert filesystem.listdir_full("/foo/bar/.AppleDouble", recursive=False) == [] def test_exception_dsstore(self): # Anything below a .DS_Store directory should be omitted for file in ( "/some/FILE", "/some/.DS_Store/oh.NO", "/some/.DS_Store/subdir/The.End", ): self.fs.create_file(file) assert os.path.exists(file) is True assert filesystem.listdir_full("/some") == ["/some/FILE"] assert filesystem.listdir_full("/some/.DS_Store/") == [] assert filesystem.listdir_full("/some/.DS_Store/subdir") == [] assert filesystem.listdir_full("/some", recursive=False) == ["/some/FILE"] assert filesystem.listdir_full("/some/.DS_Store/", recursive=False) == [] assert filesystem.listdir_full("/some/.DS_Store/subdir", recursive=False) == [] def test_exception_resource_files(self): for file in ( "/rsc/base_file", "/rsc/._base_file", "/rsc/not._base_file", ): self.fs.create_file(file) assert os.path.exists(file) is True assert filesystem.listdir_full("/rsc") == ["/rsc/base_file", "/rsc/not._base_file"] def test_invalid_file_argument(self): # This is obviously not intended use; the function expects a directory # as its argument, not a file. Test anyway. test_file = "/dev/sleepy" self.fs.create_file(test_file) assert os.path.exists(test_file) is True assert filesystem.listdir_full(test_file) == [] class TestListdirFullWin(ffs.TestCase): # Basic fake filesystem setup stanza def setUp(self): self.setUpPyfakefs() self.fs.os = OSType.WINDOWS def test_nonexistent_dir(self): assert filesystem.listdir_full(r"F:\foo\bar") == [] def test_no_exceptions(self): test_files = ( r"f:\test\dir\file1.ext", r"f:\test\dir\file2", r"f:\test\dir\sub\sub\sub\dir\file3.ext", ) for file in test_files: self.fs.create_file(file) assert os.path.exists(file) is True # List our fake directory structure results_subdir = filesystem.listdir_full(r"f:\test\dir") assert len(results_subdir) == 3 for entry in test_files: assert (entry in results_subdir) is True # List the same directory again, this time using its parent as the function argument. # Results should be identical, since there's nothing in /test but that one subdirectory results_parent = filesystem.listdir_full(r"f:\test") # Don't make assumptions about the sorting of the lists of results results_parent.sort() results_subdir.sort() assert results_parent == results_subdir # List that subsubsub-directory; no sorting required for a single result assert filesystem.listdir_full(r"F:\test\dir\SUB\sub")[0].lower() == r"f:\test\dir\sub\sub\sub\dir\file3.ext" # Test non-recursive version assert filesystem.listdir_full(r"f:\test", recursive=False) == [] assert filesystem.listdir_full(r"F:\test\dir\SUB", recursive=False) == [] assert len(filesystem.listdir_full(r"f:\test\dir", recursive=False)) == 2 def test_exception_appledouble(self): # Anything below a .AppleDouble directory should be omitted test_file = r"f:\foo\bar\.AppleDouble\Oooooo.ps" self.fs.create_file(test_file) assert os.path.exists(test_file) is True assert filesystem.listdir_full(r"f:\foo") == [] assert filesystem.listdir_full(r"f:\foo\bar") == [] assert filesystem.listdir_full(r"F:\foo\bar\.AppleDouble") == [] assert filesystem.listdir_full(r"f:\foo", recursive=False) == [] assert filesystem.listdir_full(r"f:\foo\bar", recursive=False) == [] assert filesystem.listdir_full(r"F:\foo\bar\.AppleDouble", recursive=False) == [] def test_exception_dsstore(self): # Anything below a .DS_Store directory should be omitted for file in ( r"f:\some\FILE", r"f:\some\.DS_Store\oh.NO", r"f:\some\.DS_Store\subdir\The.End", ): self.fs.create_file(file) assert os.path.exists(file) is True assert filesystem.listdir_full(r"f:\some") == [r"f:\some\FILE"] assert filesystem.listdir_full(r"f:\some\.DS_Store") == [] assert filesystem.listdir_full(r"f:\some\.DS_Store\subdir") == [] assert filesystem.listdir_full(r"f:\some", recursive=True) == [r"f:\some\FILE"] assert filesystem.listdir_full(r"f:\some\.DS_Store", recursive=True) == [] assert filesystem.listdir_full(r"f:\some\.DS_Store\subdir", recursive=True) == [] def test_exception_resource_files(self): for file in ( r"f:\rsc\base_file", r"f:\rsc\._base_file", r"f:\rsc\not._base_file", ): self.fs.create_file(file) assert os.path.exists(file) is True assert filesystem.listdir_full(r"f:\rsc") == [r"f:\rsc\base_file", r"f:\rsc\not._base_file"] def test_invalid_file_argument(self): # This is obviously not intended use; the function expects a directory # as its argument, not a file. Test anyway. test_file = r"f:\dev\sleepy" self.fs.create_file(test_file) assert os.path.exists(test_file) is True assert filesystem.listdir_full(test_file) == [] @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") class TestGetUniqueDirFilename(ffs.TestCase): # Basic fake filesystem setup stanza def setUp(self): self.setUpPyfakefs() self.fs.path_separator = "/" self.fs.is_case_sensitive = True # Reduce the waiting time when the function calls check_mount() @set_config({"wait_ext_drive": 1}) def test_nonexistent_dir(self): # Absolute path assert filesystem.get_unique_dir("/foo/bar", n=0, create_dir=False) == "/foo/bar" # Absolute path in a location that matters to check_mount assert filesystem.get_unique_dir("/mnt/foo/bar", n=0, create_dir=False) == "/mnt/foo/bar" # Relative path if self.fs.cwd != "/": os.chdir("/") assert filesystem.get_unique_dir("foo/bar", n=0, create_dir=False) == "foo/bar" def test_nonexistent_dir_without_permission(self): some_dir = "/foo/bar" self.fs.create_dir(some_dir) # Remove write permission from the directory. os.chmod(some_dir, 0o500) assert filesystem.get_unique_dir(os.path.join(some_dir, "nonexistent"), create_dir=True) is False def test_creating_dir(self): # First call also creates the directory for us assert filesystem.get_unique_dir("/foo/bar", n=0, create_dir=True) == "/foo/bar" # Verify creation of the path assert os.path.exists("/foo/bar") is True # Directories from previous loops get in the way for dir_n in range(1, 11): # Go high enough for double digits assert filesystem.get_unique_dir("/foo/bar", n=0, create_dir=True) == "/foo/bar." + str(dir_n) assert os.path.exists("/foo/bar." + str(dir_n)) is True # Explicitly set parameter n assert filesystem.get_unique_dir("/foo/bar", n=666, create_dir=True) == "/foo/bar.666" assert os.path.exists("/foo/bar.666") is True def test_nonexistent_file(self): assert filesystem.get_unique_filename("/dir/file.name") == "/dir/file.name" # Relative path assert filesystem.get_unique_filename("dir/file.name") == "dir/file.name" def test_existing_file(self): test_file = "/dir/file.name" max_obstruct = 11 # High enough for double digits self.fs.create_file(test_file) assert os.path.exists(test_file) # Create obstructions for n in range(1, max_obstruct): file_n = "/dir/file." + str(n) + ".name" self.fs.create_file(file_n) assert os.path.exists(file_n) assert filesystem.get_unique_filename(test_file) == "/dir/file." + str(max_obstruct) + ".name" def test_existing_file_without_extension(self): test_file = "/some/filename" # Create obstructions self.fs.create_file(test_file) assert os.path.exists(test_file) first_filename = filesystem.get_unique_filename(test_file) assert first_filename == "/some/filename.1" self.fs.create_file(first_filename) assert filesystem.get_unique_filename(test_file) == "/some/filename.2" @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows specific tests") class TestGetUniqueDirFilenameWin(ffs.TestCase): # Basic fake filesystem setup stanza def setUp(self): self.setUpPyfakefs() self.fs.os = OSType.WINDOWS # Reduce the waiting time when the function calls check_mount() @set_config({"wait_ext_drive": 1}) def test_nonexistent_dir(self): # Absolute path assert filesystem.get_unique_dir(r"C:\No\Such\Dir", n=0, create_dir=False).lower() == r"c:\no\such\dir" # Relative path assert filesystem.get_unique_dir(r"foo\bar", n=0, create_dir=False).lower() == r"foo\bar" def test_creating_dir(self): # First call also creates the directory for us assert filesystem.get_unique_dir(r"C:\foo\BAR", n=0, create_dir=True).lower() == r"c:\foo\bar" # Verify creation of the path assert os.path.exists(r"c:\foo\bar") is True # Directories from previous loops get in the way for dir_n in range(1, 11): # Go high enough for double digits assert filesystem.get_unique_dir(r"c:\foo\bar", n=0, create_dir=True) == r"c:\foo\bar." + str(dir_n) assert os.path.exists(r"c:\foo\bar." + str(dir_n)) is True # Explicitly set parameter n assert filesystem.get_unique_dir(r"c:\Foo\Bar", n=666, create_dir=True).lower() == r"c:\foo\bar.666" assert os.path.exists(r"c:\foo\bar.666") is True def test_nonexistent_file(self): assert filesystem.get_unique_filename(r"C:\DIR\file.name").lower() == r"c:\dir\file.name" # Relative path assert filesystem.get_unique_filename(r"DIR\file.name").lower() == r"dir\file.name" def test_existing_file(self): test_file = r"C:\dir\file.name" max_obstruct = 11 # High enough for double digits self.fs.create_file(test_file) assert os.path.exists(test_file) # Create obstructions for n in range(1, max_obstruct): file_n = r"C:\dir\file." + str(n) + ".name" self.fs.create_file(file_n) assert os.path.exists(file_n) assert filesystem.get_unique_filename(test_file).lower() == r"c:\dir\file." + str(max_obstruct) + ".name" def test_existing_file_without_extension(self): test_file = r"c:\some\filename" # Create obstructions self.fs.create_file(test_file) assert os.path.exists(test_file) assert filesystem.get_unique_filename(test_file).lower() == r"c:\some\filename.1" class TestCreateAllDirsWin(ffs.TestCase): # Basic fake filesystem setup stanza def setUp(self): self.setUpPyfakefs() self.fs.os = OSType.WINDOWS @set_platform("win32") def test_create_all_dirs(self): self.directory = self.fs.create_dir(r"C:\Downloads") # Also test for no crash when folder already exists for folder in (r"C:\Downloads", r"C:\Downloads\Show\Test", r"C:\Downloads\Show\Test2", r"C:\Downloads\Show"): assert filesystem.create_all_dirs(folder) == folder assert os.path.exists(folder) class PermissionCheckerHelper: @staticmethod def assert_dir_perms(path, expected_perms): assert stat.filemode(os.stat(path).st_mode) == "d" + stat.filemode(expected_perms)[1:] @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") class TestCreateAllDirs(ffs.TestCase, PermissionCheckerHelper): def setUp(self): self.setUpPyfakefs() self.fs.path_separator = "/" self.fs.is_case_sensitive = True def test_basic_folder_creation(self): self.fs.create_dir("/test_base") # Also test for no crash when folder already exists for folder in ("/test_base", "/test_base/show/season 1/episode 1", "/test_base/show"): assert filesystem.create_all_dirs(folder) == folder assert os.path.exists(folder) @set_config({"permissions": "0777"}) def test_permissions_777(self): self._permissions_runner("/test_base777") self._permissions_runner("/test_base777_nomask", apply_permissions=False) @set_config({"permissions": "0770"}) def test_permissions_770(self): self._permissions_runner("/test_base770") self._permissions_runner("/test_base770_nomask", apply_permissions=False) @set_config({"permissions": "0600"}) def test_permissions_600(self): self._permissions_runner("/test_base600") self._permissions_runner("/test_base600_nomask", apply_permissions=False) @set_config({"permissions": "0700"}) def test_permissions_450(self): with pytest.raises(OSError): self._permissions_runner("/test_base450", perms_base="0450") def test_no_permissions(self): self._permissions_runner("/test_base_perm700", perms_base="0700") self._permissions_runner("/test_base_perm750", perms_base="0750") self._permissions_runner("/test_base_perm777", perms_base="0777") self._permissions_runner("/test_base_perm600", perms_base="0600") def _permissions_runner(self, test_base, perms_base="0700", apply_permissions=True): # Create base directory and set the base permissions perms_base_int = int(perms_base, 8) self.fs.create_dir(test_base, perms_base_int) assert os.path.exists(test_base) is True self.assert_dir_perms(test_base, perms_base_int) # Create directories with permissions new_dir = os.path.join(test_base, "se 1", "ep1") filesystem.create_all_dirs(new_dir, apply_permissions=apply_permissions) # If permissions needed to be set, verify the new folder has the # right permissions and verify the base didn't change if apply_permissions and cfg.permissions(): perms_test_int = int(cfg.permissions(), 8) else: # Get the current permissions, since os.mkdir masks that out perms_test_int = int("0777", 8) & ~sabnzbd.ORG_UMASK self.assert_dir_perms(new_dir, perms_test_int) self.assert_dir_perms(test_base, perms_base_int) class TestSetPermissionsWin(ffs.TestCase): @set_platform("win32") def test_win32(self): # Should not do or return anything on Windows assert filesystem.set_permissions(r"F:\who\cares", recursive=False) is None @pytest.mark.skipif(sys.platform.startswith("win"), reason="Non-Windows tests") class TestSetPermissions(ffs.TestCase, PermissionCheckerHelper): # Basic fake filesystem setup stanza def setUp(self): self.setUpPyfakefs() self.fs.path_separator = "/" self.fs.is_case_sensitive = True self.fs.umask = int("0755", 8) # rwxr-xr-x def _runner(self, perms_before_test): """ Generic test runner for permissions testing. The permissions are set per test via the relevant sab config option; the filesystem parameter in setUp(). Note that the umask set in the environment before starting the program also affects the results if sabnzbd.cfg.permissions isn't set. Arguments: str perms_test: permissions for test objects, chmod style "0755". """ # We expect the cfg.permissions to be applied, or the original to be kept if none are set perms_before_test = int(perms_before_test, 8) if sabnzbd.cfg.permissions(): perms_after_test = int(sabnzbd.cfg.permissions(), 8) else: perms_after_test = perms_before_test # Setup and verify fake dir test_dir = "/test" self.fs.create_dir(test_dir, perms_before_test) assert os.path.exists(test_dir) is True self.assert_dir_perms(test_dir, perms_before_test) # Setup and verify fake files for file in ( "foobar", "file.ext", "sub/dir/.nzb", "another/sub/dir/WithSome.File", ): file = os.path.join(test_dir, file) basefolder = os.path.dirname(file) # Create the folder, so it has the expected permissions if not os.path.exists(basefolder): try: self.fs.create_dir(basefolder, perms_before_test) except PermissionError: ffs.set_uid(0) self.fs.create_file(file, perms_before_test) assert os.path.exists(basefolder) is True self.assert_dir_perms(basefolder, perms_before_test) # Add a random one of the forbidden bits file_perms_before_test = perms_before_test | choice( (stat.S_ISUID, stat.S_ISGID, stat.S_IXUSR, stat.S_IXGRP, stat.S_IXOTH) ) # Then, create the file try: self.fs.create_file(file, file_perms_before_test) except PermissionError: ffs.set_uid(0) self.fs.create_file(file, file_perms_before_test) assert os.path.exists(file) is True assert stat.filemode(os.stat(file).st_mode)[1:] == stat.filemode(file_perms_before_test)[1:] # Set permissions, recursive by default filesystem.set_permissions(test_dir) # Check the results for root, dirs, files in os.walk(test_dir): for directory in [os.path.join(root, d) for d in dirs]: # Permissions on directories should now match perms_after self.assert_dir_perms(directory, perms_after_test) for file in [os.path.join(root, f) for f in files]: # Files also shouldn't have any executable or special bits set assert ( stat.filemode(os.stat(file).st_mode)[1:] == stat.filemode( perms_after_test & ~(stat.S_ISUID | stat.S_ISGID | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) )[1:] ) # Cleanup ffs.set_uid(0) self.fs.remove_object(test_dir) assert os.path.exists(test_dir) is False ffs.set_uid(global_uid) @set_platform("linux") def test_empty_permissions_setting(self): # World writable directory self._runner("0777") self._runner("0450") @set_platform("linux") @set_config({"permissions": "0760"}) def test_dir0777_permissions0760_setting(self): # World-writable directory, permissions 760 self._runner("0777") @set_platform("linux") @set_config({"permissions": "0617"}) def test_dir0450_permissions0617_setting(self): # Insufficient base access self._runner("0450") @set_platform("linux") @set_config({"permissions": "2455"}) def test_dir0444_permissions2455_setting(self): # Insufficient access, permissions with setgid (should be stripped) self._runner("0444") @set_platform("linux") @set_config({"permissions": "4755"}) def test_dir1755_permissions4755_setting(self): # Sticky bit on directory, permissions with setuid (should be stripped) self._runner("1755") class TestRenamer: # test filesystem.renamer() for different scenario's def test_renamer(self): # First of all, create a working directory (with a random name) dirname = os.path.join(SAB_DATA_DIR, "testdir" + str(random.randint(10000, 99999))) os.mkdir(dirname) # base case: rename file within directory filename = os.path.join(dirname, "myfile.txt") Path(filename).touch() # create file newfilename = os.path.join(dirname, "newfile.txt") assert newfilename == filesystem.renamer(filename, newfilename) assert not os.path.isfile(filename) assert os.path.isfile(newfilename) # standard behaviour: renaming (moving) into an exiting other directory *is* allowed filename = os.path.join(dirname, "myfile.txt") Path(filename).touch() # create file sameleveldirname = os.path.join(SAB_DATA_DIR, "othertestdir" + str(random.randint(10000, 99999))) os.mkdir(sameleveldirname) newfilename = os.path.join(sameleveldirname, "newfile.txt") assert newfilename == filesystem.renamer(filename, newfilename) assert not os.path.isfile(filename) assert os.path.isfile(newfilename) shutil.rmtree(sameleveldirname) # Default: renaming into a non-existing subdirectory not allowed Path(filename).touch() # create file newfilename = os.path.join(dirname, "nonexistingsubdir", "newfile.txt") try: # Should fail filesystem.renamer(filename, newfilename) except: pass assert os.path.isfile(filename) assert not os.path.isfile(newfilename) # Creation of subdirectory is allowed if create_local_directories=True Path(filename).touch() newfilename = os.path.join(dirname, "newsubdir", "newfile.txt") try: filesystem.renamer(filename, newfilename, create_local_directories=True) except: pass assert not os.path.isfile(filename) assert os.path.isfile(newfilename) # Creation of subdirectory plus deeper sudbdir is allowed if create_local_directories=True Path(filename).touch() newfilename = os.path.join(dirname, "newsubdir", "deepersubdir", "newfile.txt") try: filesystem.renamer(filename, newfilename, create_local_directories=True) except: pass assert not os.path.isfile(filename) assert os.path.isfile(newfilename) # ... escaping the directory plus subdir creation is not allowed Path(filename).touch() newfilename = os.path.join(dirname, "..", "newsubdir", "newfile.txt") try: filesystem.renamer(filename, newfilename, create_local_directories=True) except: pass assert os.path.isfile(filename) assert not os.path.isfile(newfilename) # Cleanup working directory shutil.rmtree(dirname) class TestUnwantedExtensions: # Only test lowercase extensions without a leading dot: the unwanted_extensions # setting is sanitized accordingly in interface.saveSwitches() before saving. test_extensions = "iso, cmd, bat, sh, re:r[0-9]{2}, sab*" # Test parameters as (filename, result) tuples, with result given for blacklist mode test_params = [ ("ubuntu.iso", True), ("par2.cmd", True), ("freedos.BAT", True), ("Debian.installer.SH", True), ("FREEBSD.ISO", True), ("par2.CmD", True), ("freedos.baT", True), ("Debian.Installer.sh", True), ("ubuntu.torrent", False), ("par2.cmd.notcmd", False), ("freedos.tab", False), (".SH.hs", False), ("regexp.r0611", False), ("regexp.007", False), ("regexp.A01", False), ("regexp.r9", False), ("regexp.r2d2", False), ("regexp.r2d", False), ("regexp.r00", True), ("regexp.R42", True), ("test.sabnzbd", True), ("pass.sab", True), ("fail.sb", False), ("No_Extension", False), ("r42", False), (480, False), (None, False), ("", False), ([], False), ] @set_config({"unwanted_extensions_mode": 0, "unwanted_extensions": test_extensions}) def test_has_unwanted_extension_blacklist_mode(self): for filename, result in self.test_params: assert filesystem.has_unwanted_extension(filename) is result @set_config({"unwanted_extensions_mode": 1, "unwanted_extensions": test_extensions}) def test_has_unwanted_extension_whitelist_mode(self): for filename, result in self.test_params: if filesystem.get_ext(filename): assert filesystem.has_unwanted_extension(filename) is not result else: # missing extension is never considered unwanted assert filesystem.has_unwanted_extension(filename) is False @set_config({"unwanted_extensions_mode": 0, "unwanted_extensions": ""}) def test_has_unwanted_extension_empty_blacklist(self): for filename, result in self.test_params: assert filesystem.has_unwanted_extension(filename) is False @set_config({"unwanted_extensions_mode": 1, "unwanted_extensions": ""}) def test_has_unwanted_extension_empty_whitelist(self): for filename, result in self.test_params: if filesystem.get_ext(filename): assert filesystem.has_unwanted_extension(filename) is True else: # missing extension is never considered unwanted assert filesystem.has_unwanted_extension(filename) is False class TestOtherFileSystemFunctions: def test_directory_is_writable(self): # very basic test of directory_is_writable() # let's test on the tempdir provided by the OS: assert filesystem.directory_is_writable(tempfile.gettempdir()) def test_filesystem_capabilities(self): # test the filesystem is capable of long and unicode filenames # any modern filesystem (ext3, ext4, ntfs, modern FAT) should succeed assert filesystem.check_filesystem_capabilities(tempfile.gettempdir()) @pytest.mark.parametrize( "name, ext_to_remove, output", [ ("Test.nzb", (".nzb",), "Test"), ("Test.nzb.nzb.nzb.nzb.nzb", (".nzb",), "Test"), ("Test.not", (".nzb",), "Test.not"), ("No.par2.Test.par2.nzb", (".nzb", ".par2"), "No.par2.Test"), ], ) def test_strip_extensions(self, name, ext_to_remove, output): assert filesystem.strip_extensions(name, ext_to_remove) == output ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.443543 SABnzbd-4.3.2/tests/test_happyeyeballs.py0000644000000000000000000000672014625637243017645 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_happyeyeballs - Testing SABnzbd happyeyeballs """ import os import sys import socket import pytest from flaky import flaky from sabnzbd.happyeyeballs import happyeyeballs, IPV6_MAPPING from sabnzbd.misc import is_ipv4_addr, is_ipv6_addr @flaky class TestHappyEyeballs: """Tests of happyeyeballs() against various websites/servers happyeyeballs() returns the quickest IP address (IPv4, or IPv6 if available end-to-end), or None (if not resolvable, or not reachable) """ def test_google_http(self): addrinfo = happyeyeballs("www.google.com", port=80) assert is_ipv4_addr(addrinfo.ipaddress) or is_ipv6_addr(addrinfo.ipaddress) assert "google" in addrinfo.canonname def test_google_https(self): addrinfo = happyeyeballs("www.google.com", port=443) assert is_ipv4_addr(addrinfo.ipaddress) or is_ipv6_addr(addrinfo.ipaddress) assert "google" in addrinfo.canonname def test_google_http_want_ipv4(self): addrinfo = happyeyeballs("www.google.com", port=80, family=socket.AF_INET) assert is_ipv4_addr(addrinfo.ipaddress) and not is_ipv6_addr(addrinfo.ipaddress) assert "google" in addrinfo.canonname def test_google_http_want_ipv6(self): # TODO: timeout needed for IPv4-only CI environment? if addrinfo := happyeyeballs("www.google.com", port=80, timeout=2, family=socket.AF_INET6): assert not is_ipv4_addr(addrinfo.ipaddress) and is_ipv6_addr(addrinfo.ipaddress) assert "google" in addrinfo.canonname def test_not_resolvable(self): assert happyeyeballs("not.resolvable.invalid", port=80) is None def test_ipv6_only(self): if addrinfo := happyeyeballs("ipv6.google.com", port=443, timeout=2): assert is_ipv6_addr(addrinfo.ipaddress) assert "google" in addrinfo.canonname def test_google_unreachable_port(self): assert happyeyeballs("www.google.com", port=33333, timeout=1) is None @pytest.mark.xfail(reason="CI sometimes blocks this") def test_nntp(self): if ip := happyeyeballs("news.newshosting.com", port=119).ipaddress: assert is_ipv4_addr(ip) or is_ipv6_addr(ip) @pytest.mark.skipif(sys.platform.startswith("darwin"), reason="Resolves strangely on macOS CI") @pytest.mark.parametrize("hostname", IPV6_MAPPING.keys()) def test_ipv6_mapping(self, hostname): # This test will let us remove hostnames from the mapping # once the providers add IPv6 to their main hostname with pytest.raises(socket.gaierror): # Print results for us to see the new information print(socket.getaddrinfo(hostname, 119, socket.AF_INET6, socket.SOCK_STREAM)) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.443627 SABnzbd-4.3.2/tests/test_api_and_interface.py0000644000000000000000000002566414625637243020426 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_api - Tests for API functions """ import cherrypy import pytest from tests.testhelper import * import sabnzbd.api as api import sabnzbd.interface as interface class TestApiInternals: """Test internal functions of the API""" def test_empty(self): with pytest.raises(TypeError): api.api_handler(None) with pytest.raises(AttributeError): api.api_handler("") def test_mode_invalid(self): assert "not implemented" in str(api.api_handler({"mode": "invalid"})) def test_version(self): assert sabnzbd.__version__ in str(api.api_handler({"mode": "version"})) def test_auth(self): assert "apikey" in str(api.api_handler({"mode": "auth"})) def set_remote_host_or_ip(hostname: str = "localhost", remote_ip: str = "127.0.0.1"): """Change CherryPy's "Host" and "remote.ip"-values""" cherrypy.request.headers["Host"] = hostname cherrypy.request.remote.ip = remote_ip class TestSecuredExpose: """Test the security handling""" main_page = sabnzbd.interface.MainPage() def api_wrapper(self, *args, **kwargs): """Wrapper to convert bytes to str""" if api_response := self.main_page.api(*args, **kwargs): return str(api_response) def check_full_access(self, redirect_match: str = r".*wizard.*"): """Basic test if we have full access to API and interface""" assert sabnzbd.__version__ in self.api_wrapper(mode="version") # Passed authentication assert api._MSG_NOT_IMPLEMENTED in self.api_wrapper(apikey=sabnzbd.cfg.api_key()) # Raises a redirect to the wizard with pytest.raises(cherrypy._cperror.HTTPRedirect, match=redirect_match): self.main_page.index() def test_basic(self): set_remote_host_or_ip() self.check_full_access() def test_api_no_or_wrong_api_key(self): set_remote_host_or_ip() # Get blocked assert interface._MSG_APIKEY_REQUIRED in self.api_wrapper() assert interface._MSG_APIKEY_REQUIRED in self.api_wrapper(mode="queue") # Allowed to access "auth" and "version" without key assert "apikey" in self.api_wrapper(mode="auth") assert sabnzbd.__version__ in self.api_wrapper(mode="version") # Blocked when you do something wrong assert interface._MSG_APIKEY_INCORRECT in self.api_wrapper(mode="queue", apikey="wrong") def test_api_nzb_key(self): set_remote_host_or_ip() # It should only access the nzb-functions, nothing else assert api._MSG_NO_VALUE in self.api_wrapper(mode="addfile", apikey=sabnzbd.cfg.nzb_key()) assert interface._MSG_APIKEY_INCORRECT in self.api_wrapper(mode="set_config", apikey=sabnzbd.cfg.nzb_key()) assert interface._MSG_APIKEY_INCORRECT in self.main_page.shutdown(apikey=sabnzbd.cfg.nzb_key()) def test_check_hostname_basic(self): # Block bad host set_remote_host_or_ip(hostname="not_me") assert interface._MSG_ACCESS_DENIED_HOSTNAME in self.api_wrapper() assert interface._MSG_ACCESS_DENIED_HOSTNAME in self.main_page.index() # Block empty value set_remote_host_or_ip(hostname="") assert interface._MSG_ACCESS_DENIED_HOSTNAME in self.api_wrapper() assert interface._MSG_ACCESS_DENIED_HOSTNAME in self.main_page.index() # Fine if ip-address for test_hostname in ( "100.100.100.100", "100.100.100.100:8080", "[2001:db8:3333:4444:5555:6666:7777:8888]", "[2001:db8:3333:4444:5555:6666:7777:8888]:8080", "test.local", "test.local:8080", "test.local.", ): set_remote_host_or_ip(hostname=test_hostname) self.check_full_access() @set_config({"username": "foo", "password": "bar"}) def test_check_hostname_not_user_password(self): set_remote_host_or_ip(hostname="not_me") self.check_full_access(redirect_match=r".*login.*") @set_config({"host_whitelist": "test.com, not_evil"}) def test_check_hostname_whitelist(self): set_remote_host_or_ip(hostname="test.com") self.check_full_access() set_remote_host_or_ip(hostname="not_evil") self.check_full_access() def test_dual_stack(self): set_remote_host_or_ip(remote_ip="::ffff:192.168.0.10") self.check_full_access() @set_config({"local_ranges": "132.10."}) def test_dual_stack_local_ranges(self): # Without custom local_ranges this one would be allowed set_remote_host_or_ip(remote_ip="::ffff:192.168.0.10") self.check_inet_blocks(inet_exposure=0) # But now we only allow the custom ones set_remote_host_or_ip(remote_ip="::ffff:132.10.0.10") self.check_full_access() def check_inet_allows(self, inet_exposure: int): """Each should allow all previous ones and the current one""" # Level 1: nzb if inet_exposure >= 1: assert api._MSG_NO_VALUE in self.api_wrapper(mode="addfile", apikey=sabnzbd.cfg.nzb_key()) assert api._MSG_NO_VALUE in self.api_wrapper(mode="addfile", apikey=sabnzbd.cfg.api_key()) # Level 2: basic API if inet_exposure >= 2: assert api._MSG_NO_VALUE in self.api_wrapper(mode="get_files", apikey=sabnzbd.cfg.api_key()) assert api._MSG_NO_VALUE in self.api_wrapper(mode="change_script", apikey=sabnzbd.cfg.api_key()) # Sub-function assert "status" in self.api_wrapper(mode="queue", name="resume", apikey=sabnzbd.cfg.api_key()) # Level 3: full API if inet_exposure >= 3: assert "misc" in self.api_wrapper(mode="get_config", apikey=sabnzbd.cfg.api_key()) # Sub-function assert "The hostname is not set" in self.api_wrapper( mode="config", name="test_server", apikey=sabnzbd.cfg.api_key() ) # Level 4: full interface if inet_exposure >= 4: self.check_full_access() def check_inet_blocks(self, inet_exposure: int): """We count from the most exposure down""" # Level 4: full interface, no blocking # Level 3: full API if inet_exposure <= 3: assert interface._MSG_ACCESS_DENIED in self.main_page.index() # Level 2: basic API if inet_exposure <= 2: assert interface._MSG_ACCESS_DENIED in self.api_wrapper(mode="get_config", apikey=sabnzbd.cfg.api_key()) assert interface._MSG_ACCESS_DENIED in self.api_wrapper( mode="config", name="set_nzbkey", apikey=sabnzbd.cfg.api_key() ) # Level 1: nzb if inet_exposure <= 1: assert interface._MSG_ACCESS_DENIED in self.api_wrapper(mode="get_scripts", apikey=sabnzbd.cfg.api_key()) assert interface._MSG_ACCESS_DENIED in self.api_wrapper( mode="queue", name="resume", apikey=sabnzbd.cfg.api_key() ) # Level 0: nothing, already checked above, but just to be sure if inet_exposure <= 0: assert interface._MSG_ACCESS_DENIED in self.api_wrapper(mode="addfile", apikey=sabnzbd.cfg.api_key()) # Check with or without API-key assert interface._MSG_ACCESS_DENIED in self.api_wrapper(mode="auth", apikey=sabnzbd.cfg.api_key()) assert interface._MSG_ACCESS_DENIED in self.api_wrapper(mode="auth") def test_inet_exposure(self): # Run all tests as external user set_remote_host_or_ip(hostname="100.100.100.100", remote_ip="11.11.11.11") # We don't use the wrapper, it would require creating many extra functions # Option 5 is special, so it also gets it's own special test for inet_exposure in range(6): sabnzbd.cfg.inet_exposure.set(inet_exposure) self.check_inet_allows(inet_exposure=inet_exposure) self.check_inet_blocks(inet_exposure=inet_exposure) # Reset it sabnzbd.cfg.inet_exposure.set(sabnzbd.cfg.inet_exposure.default) @set_config({"inet_exposure": 5, "username": "foo", "password": "bar"}) def test_inet_exposure_login_for_external(self): # Local user: full access set_remote_host_or_ip() self.check_full_access() # Remote user: redirect to login set_remote_host_or_ip(hostname="100.100.100.100", remote_ip="11.11.11.11") self.check_full_access(redirect_match=r".*login.*") @set_config({"api_warnings": False}) def test_no_text_warnings(self): assert self.main_page.index() is None assert cherrypy.response.status == 403 assert self.api_wrapper(mode="queue") is None assert cherrypy.response.status == 403 set_remote_host_or_ip(hostname="not_me") assert self.api_wrapper() is None assert cherrypy.response.status == 403 class TestHistory: @pytest.mark.usefixtures("run_sabnzbd") def test_add_active_history_consistency(self): """Verify that add_active_history has the same structure as fetch_history""" history_db = os.path.join(SAB_CACHE_DIR, DEF_ADMIN_DIR, DB_HISTORY_NAME) with FakeHistoryDB(history_db) as fake_history: fake_history.add_fake_history_jobs(1) jobs, total_items = fake_history.fetch_history() history_job = jobs[-1] # Add minimal attributes to create pp-job nzo = mock.Mock() nzo.final_name = "test_add_active_history" nzo.repair, nzo.unpack, nzo.delete = pp_to_opts(choice(list(PP_LOOKUP.keys()))) nzo.download_path = os.path.join(os.path.dirname(db.HistoryDB.db_path), "placeholder_downpath") nzo.bytes_downloaded = randint(1024, 1024**4) nzo.unpack_info = {"unpack_info": "placeholder unpack_info line\r\n" * 3} api.add_active_history([nzo], jobs) # Make sure the job was added to the list pp_job = jobs[-1] assert pp_job["name"] == nzo.final_name assert pp_job["name"] != history_job["name"] # Compare the keys, so not the values! pp_keys = list(pp_job.keys()) pp_keys.sort() history_keys = list(history_job.keys()) history_keys.sort() assert pp_keys == history_keys ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4437284 SABnzbd-4.3.2/tests/sabnews.py0000644000000000000000000001775214625637243015415 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.sabnews - Fake newsserver to use in end-to-end testing Run sabnews.py -h for parameters! """ import argparse import asyncio import logging import os import re import time from random import randint import sabctools logging.getLogger().setLevel(logging.INFO) # Expecting the following message-id: # ARTICLE \r\n ARTICLE_INFO = re.compile( b"^(ARTICLE|BODY) (?P.*)\\|part=(?P\\d+)\\|start=(?P\\d+)\\|size=(?P\\d+)>)\\r\\n$", re.MULTILINE, ) YENC_ESCAPE = [0x00, 0x0A, 0x0D, ord("="), ord(".")] class NewsServerProtocol(asyncio.Protocol): def __init__(self): self.transport = None self.connected = False self.in_article = False super().__init__() def connection_made(self, transport): logging.info("Connection from %s", transport.get_extra_info("peername")) self.transport = transport self.connected = True self.transport.write(b"200 Welcome (SABNews)\r\n") def data_received(self, message): logging.debug("Data received: %s", message.strip()) # Handle basic commands if message.startswith(b"QUIT"): self.close_connection() elif message.startswith((b"ARTICLE", b"BODY")): parsed_message = ARTICLE_INFO.search(message) self.serve_article(parsed_message) # self.transport.write(data) def serve_article(self, parsed_message): # Check if we parsed everything try: message_id = parsed_message.group("message_id") file = parsed_message.group("file").decode("utf-8") file_base = os.path.basename(file) part = int(parsed_message.group("part")) start = int(parsed_message.group("start")) size = int(parsed_message.group("size")) except (AttributeError, ValueError): logging.warning("Can't parse article information") self.transport.write(b"430 No Such Article Found (bad message-id)\r\n") return # Check if file exists if not os.path.exists(file): logging.warning("File not found: %s", file) self.transport.write(b"430 No Such Article Found (no file on disk)\r\n") return # Check if sizes are valid file_size = os.path.getsize(file) if start + size > file_size: logging.warning("Invalid start/size attributes") self.transport.write(b"430 No Such Article Found (invalid start/size attributes)\r\n") return logging.debug("Serving %s" % message_id) # File is found, send headers self.transport.write(b"222 0 %s\r\n" % message_id) self.transport.write(b"Message-ID: %s\r\n" % message_id) self.transport.write(b'Subject: "%s"\r\n\r\n' % file_base.encode("utf-8")) # Write yEnc headers self.transport.write( b"=ybegin part=%d line=128 size=%d name=%s\r\n" % (part, file_size, file_base.encode("utf-8")) ) self.transport.write(b"=ypart begin=%d end=%d\r\n" % (start + 1, start + size)) with open(file, "rb") as inp_file: inp_file.seek(start) inp_buffer = inp_file.read(size) # Encode data output_string, crc = sabctools.yenc_encode(inp_buffer) self.transport.write(output_string) # Write footer self.transport.write(b"\r\n=yend size=%d part=%d pcrc32=%08x\r\n" % (size, part, crc)) self.transport.write(b".\r\n") def close_connection(self): logging.debug("Closing connection") self.transport.write(b"205 Connection closing\r\n") self.transport.close() async def serve_sabnews(hostname, port): # Start server logging.info("Starting SABNews on %s:%d", hostname, port) loop = asyncio.get_running_loop() server = await loop.create_server(lambda: NewsServerProtocol(), hostname, port) async with server: await server.serve_forever() def create_nzb(nzb_file=None, nzb_dir=None, metadata=None): article_size = 500000 files_for_nzb = [] output_file = "" # Either use directory or single file if nzb_dir: nzb_dir = os.path.normpath(nzb_dir) if not os.path.exists(nzb_dir) or not os.path.isdir(nzb_dir): raise NotADirectoryError("%s is not a valid directory" % nzb_dir) # List all files files_for_nzb = [os.path.join(nzb_dir, fl) for fl in os.listdir(nzb_dir)] files_for_nzb = [fl for fl in files_for_nzb if os.path.isfile(fl)] output_file = os.path.join(nzb_dir, os.path.basename(os.path.normpath(nzb_dir)) + ".nzb") if nzb_file: if not os.path.exists(nzb_file) or not os.path.isfile(nzb_file): raise FileNotFoundError("Cannot find %s or it is not a file" % nzb_file) files_for_nzb = [nzb_file] output_file = os.path.splitext(nzb_file)[0] + ".nzb" if not files_for_nzb: raise RuntimeError("No files found to include in NZB") # Let's write a file! with open(output_file, "w", encoding="utf-8") as nzb: nzb.write('\n') nzb.write('\n') nzb.write('\n') if metadata: nzb.write("\n") for meta_name, meta_value in metadata.items(): nzb.write('%s\n' % (meta_name, meta_value)) nzb.write("\n") nzb_time = time.time() - randint(0, int(time.time() - 746863566)) for fl in files_for_nzb: nzb.write('\n' % (nzb_time, os.path.basename(fl))) nzb.write("alt.binaries.test\n") nzb.write("\n") # Create segments file_size = os.path.getsize(fl) for seg_nr, seg_start in enumerate(range(0, file_size, article_size), 1): segement_size = min(article_size, file_size - seg_start) nzb.write( 'file=%s|part=%s|start=%d|size=%d\n' % (seg_nr, segement_size, fl, seg_nr, seg_start, segement_size) ) nzb.write("\n") nzb.write("\n") nzb.write("\n") logging.info("NZB saved to %s" % output_file) return output_file def main(): parser = argparse.ArgumentParser() parser.add_argument("-s", help="Hostname", dest="hostname", default="127.0.0.1") parser.add_argument("-p", help="Port", dest="port", type=int, default=8888) parser.add_argument("--nzbfile", help="Create NZB of specified file", dest="nzb_file", metavar="FILE") parser.add_argument("--nzbdir", help="Create NZB for files in specified directory", dest="nzb_dir", metavar="DIR") args = parser.parse_args() # Serve if we are not creating NZB's if not args.nzb_file and not args.nzb_dir: asyncio.run(serve_sabnews(args.hostname, args.port)) else: create_nzb(args.nzb_file, args.nzb_dir) if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4438777 SABnzbd-4.3.2/tests/test_config.py0000644000000000000000000003271714625637243016255 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_config - Tests of config methods """ from sabnzbd.filesystem import long_path from tests.testhelper import * import shutil import zipfile import os from typing import List import sabnzbd.cfg from sabnzbd.constants import ( DEF_INI_FILE, DEF_HTTPS_CERT_FILE, DEF_HTTPS_KEY_FILE, CONFIG_BACKUP_HTTPS, CONFIG_BACKUP_FILES, ) from sabnzbd import config from sabnzbd import filesystem DEF_CHAIN_FILE = "server.chain" class TestOptions: test_section = "test_section" test_keyword = "test_keyword" def test_base_option(self): test_option = config.Option(self.test_section, self.test_keyword) assert test_option.section == self.test_section assert test_option.keyword == self.test_keyword assert test_option.section in config.CFG_DATABASE assert test_option.keyword in config.CFG_DATABASE[test_option.section] assert config.CFG_DATABASE[test_option.section][test_option.keyword] == test_option # Reset database config.CFG_DATABASE = {} @pytest.mark.xfail(reason="These tests should be added") def test_all(self): # Need to add tests for all the relevant options raise NotImplemented def test_non_public(self): test_option = config.Option(self.test_section, self.test_keyword, public=True) assert test_option.get_dict() == {self.test_keyword: None} assert test_option.get_dict(for_public_api=False) == {self.test_keyword: None} test_option = config.Option(self.test_section, self.test_keyword, public=False) assert test_option.get_dict() == {self.test_keyword: None} assert test_option.get_dict(for_public_api=True) == {} # Password is special when using for_public_api test_option = config.OptionPassword(self.test_section, self.test_keyword, default_val="test_password") assert test_option.get_dict() == {self.test_keyword: "test_password"} assert test_option.get_dict(for_public_api=True) == {self.test_keyword: "**********"} # Reset database config.CFG_DATABASE = {} @pytest.mark.usefixtures("clean_cache_dir") class TestConfig: @staticmethod def create_dummy_zip(filename: str) -> bytes: with io.BytesIO() as zip_buffer: with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_ref: zip_ref.writestr(filename, "foobar") return zip_buffer.getvalue() @staticmethod def create_and_verify_backup(admin_dir: str, must_haves: List[str]): # Create the backup config_backup_path = config.create_config_backup() assert os.path.exists(config_backup_path) assert sabnzbd.__version__ in config_backup_path assert time.strftime("%Y.%m.%d_%H") in config_backup_path # Verify the zipfile has the expected content with open(config_backup_path, "rb") as fp: # Do basic backup validation assert config.validate_config_backup(fp.read()) # Reset the file pointer fp.seek(0) with zipfile.ZipFile(fp, "r") as zip: for basename in must_haves: assert zip.getinfo(basename) # Make sure there's nothing else in the zip assert (zip_len := len(zip.filelist)) == len(must_haves) # Move the current admin dir out of the way stowed_admin = os.path.join(SAB_CACHE_DIR, "stowed_admin") if os.path.isdir(stowed_admin): filesystem.remove_all(stowed_admin) assert not os.path.exists(stowed_admin) os.rename(admin_dir, stowed_admin) assert os.path.exists(stowed_admin) assert filesystem.globber(stowed_admin) != [] assert not os.path.exists(admin_dir) filesystem.create_all_dirs(admin_dir) assert os.path.exists(admin_dir) assert filesystem.globber(admin_dir) == [] # Store current test settings, as these may change when restoring a backup restore_me = {setting: getattr(sabnzbd.cfg, setting)() for setting in CONFIG_BACKUP_HTTPS.values()} # Restore the backup with open(config_backup_path, "rb") as config_backup_fp: config.restore_config_backup(config_backup_fp.read()) # Check settings results restore_changed_settings = False for filename, setting in CONFIG_BACKUP_HTTPS.items(): if filename in must_haves: restore_changed_settings = True value = getattr(sabnzbd.cfg, setting)() if setting != "https_chain": # All https settings should point to the default basenames of the restored files... assert value == getattr(sabnzbd.cfg, setting).default else: # ...except the one that doesn't have a default and uses a hardcoded filename instead assert value == DEF_CHAIN_FILE # Check filename results for basename in must_haves: # Verify all files in the backup were restored into the admin dir... assert os.path.exists(os.path.join(admin_dir, basename)) # ...and nothing else if not restore_changed_settings: assert zip_len == len(filesystem.globber(admin_dir)) else: # Account for sabnzbd.ini.bak in case settings were changed as part of the restore assert zip_len + 1 == len(filesystem.globber(admin_dir)) # Restore the test settings for setting, value in restore_me.items(): getattr(sabnzbd.cfg, setting).set(value) sabnzbd.config.save_config(True) # Purge the backup file to prevent collisions os.unlink(config_backup_path) assert not os.path.exists(config_backup_path) # Call the original admin dir back into active duty filesystem.remove_all(admin_dir) assert not os.path.exists(admin_dir) os.rename(stowed_admin, admin_dir) assert os.path.exists(admin_dir) assert filesystem.globber(admin_dir) != [] assert not os.path.exists(stowed_admin) def test_validate_config_backup(self): """Validate basic dummy data""" assert not config.validate_config_backup(b"invalid") assert not config.validate_config_backup(self.create_dummy_zip("dummyfile")) assert config.validate_config_backup(self.create_dummy_zip(DEF_INI_FILE)) @set_config( { "admin_dir": os.path.join(SAB_CACHE_DIR, "test_config_backup"), "complete_dir": os.path.join(SAB_COMPLETE_DIR, "test_config_backup"), } ) def test_config_backup(self): """Combined tests for the config.{create,validate,restore}_config_backup functions""" # Prepare the basics admin_dir = sabnzbd.cfg.admin_dir.get_path() sabnzbd.cfg.set_root_folders2() ini_path = os.path.join(admin_dir, DEF_INI_FILE) shutil.copyfile(os.path.join(SAB_DATA_DIR, "sabnzbd.basic.ini"), ini_path) assert os.path.exists(ini_path) config.read_config(ini_path) filesystem.create_all_dirs(sabnzbd.cfg.complete_dir()) assert os.path.exists(sabnzbd.cfg.complete_dir()) # Create a backup and verify it has the expected files (ini only, as there are no admin and https config files) self.create_and_verify_backup(admin_dir, [DEF_INI_FILE]) # Add other admin files that qualify for inclusion in backups for basename in CONFIG_BACKUP_FILES: with open(admin_file := os.path.join(admin_dir, basename), "wb") as fp: fp.write(os.urandom(128)) assert os.path.exists(admin_file) self.create_and_verify_backup(admin_dir, [DEF_INI_FILE] + CONFIG_BACKUP_FILES) # Add some useless files in the admin_dir for basename in ["totals3.sab", "Best.Movie.Ever.1951.240p.avi", "Rating.sab"]: with open(useless_file := os.path.join(admin_dir, basename), "wb") as fp: fp.write(os.urandom(256)) assert os.path.exists(useless_file) # None of these should appear in the backup self.create_and_verify_backup(admin_dir, [DEF_INI_FILE] + CONFIG_BACKUP_FILES) # Remove the extra admin files, but keep the useless ones around for basename in CONFIG_BACKUP_FILES: os.unlink(admin_file := os.path.join(admin_dir, basename)) assert not os.path.exists(admin_file) # Generate fake HTTPS certificate and key files cert_file = os.path.join(admin_dir, DEF_HTTPS_CERT_FILE) key_file = os.path.join(admin_dir, DEF_HTTPS_KEY_FILE) for filepath in (cert_file, key_file): with open(filepath, "wb") as fp: fp.write(os.urandom(512)) assert os.path.exists(cert_file) assert os.path.exists(key_file) # Copy cert and key to create a second set of https config files outside the admin dir other_cert_file = long_path(os.path.join(SAB_CACHE_DIR, "foobar.mycert")) other_key_file = long_path(os.path.join(SAB_CACHE_DIR, "foobar.mykey")) shutil.copyfile(cert_file, other_key_file) shutil.copyfile(key_file, other_cert_file) assert os.path.exists(other_cert_file) assert os.path.exists(other_key_file) # Imitate a mainstream https setup (cert and key present, but no chain file) sabnzbd.cfg.enable_https.set(True) sabnzbd.cfg.https_cert.set(DEF_HTTPS_CERT_FILE) sabnzbd.cfg.https_key.set(DEF_HTTPS_KEY_FILE) sabnzbd.config.save_config(True) assert not sabnzbd.cfg.https_chain() assert sabnzbd.CONFIG_BACKUP_HTTPS_OK == [] # Results should remain the same, as we didn't fake the results of a startup with https enabled yet self.create_and_verify_backup(admin_dir, [DEF_INI_FILE]) # Results should still remain the same, the startup data lists only bogus files sabnzbd.CONFIG_BACKUP_HTTPS_OK = ["/tmp/no.cert", "/lib/fuldstændig_falsk.nøgle", "/etc/存在しないファイル"] self.create_and_verify_backup(admin_dir, [DEF_INI_FILE]) # Now pretend the program started with this config (note: full paths must be used for _OK) sabnzbd.CONFIG_BACKUP_HTTPS_OK = [cert_file, key_file] self.create_and_verify_backup(admin_dir, [DEF_INI_FILE, DEF_HTTPS_CERT_FILE, DEF_HTTPS_KEY_FILE]) # Pretend some other files were loaded on startup instead sabnzbd.CONFIG_BACKUP_HTTPS_OK = [other_cert_file, other_key_file] # Files in the settings no longer match those in _OK; no https config should be in the backup self.create_and_verify_backup(admin_dir, [DEF_INI_FILE]) # Set the full path to a key and cert file outside the admin dir sabnzbd.cfg.https_cert.set(other_cert_file) sabnzbd.cfg.https_key.set(other_key_file) sabnzbd.config.save_config(True) # Now the files should be included, albeit under the default names self.create_and_verify_backup(admin_dir, [DEF_INI_FILE, DEF_HTTPS_CERT_FILE, DEF_HTTPS_KEY_FILE]) # Repeat with the "others" removed, so there's nothing (but the ini) left to include in the first place for f in (other_cert_file, other_key_file): os.unlink(f) assert not os.path.exists(other_cert_file) assert not os.path.exists(other_key_file) self.create_and_verify_backup(admin_dir, [DEF_INI_FILE]) # Make up a chain file chain_file = os.path.join(admin_dir, "ssl-chain.txt") shutil.copyfile(cert_file, chain_file) assert os.path.exists(chain_file) # Update the config and the startup record (mostly) sabnzbd.cfg.https_cert.set(cert_file) sabnzbd.cfg.https_key.set(key_file) sabnzbd.cfg.https_chain.set(chain_file) sabnzbd.config.save_config(True) sabnzbd.CONFIG_BACKUP_HTTPS_OK = [cert_file, key_file] # There may be a chain file now, but as long as it's not listed in _OK it should be excluded from the backup self.create_and_verify_backup(admin_dir, [DEF_INI_FILE, DEF_HTTPS_CERT_FILE, DEF_HTTPS_KEY_FILE]) # Now it should be included sabnzbd.CONFIG_BACKUP_HTTPS_OK.append(chain_file) self.create_and_verify_backup( admin_dir, [DEF_INI_FILE, DEF_HTTPS_CERT_FILE, DEF_HTTPS_KEY_FILE, DEF_CHAIN_FILE] ) # Same same but more lonely sabnzbd.CONFIG_BACKUP_HTTPS_OK = [chain_file, "/tmp/foobar.exe"] self.create_and_verify_backup(admin_dir, [DEF_INI_FILE, DEF_CHAIN_FILE]) # Disabling https shouldn't make any difference as long as the evidence shows it was active on startup sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config(True) self.create_and_verify_backup(admin_dir, [DEF_INI_FILE, DEF_CHAIN_FILE]) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4439611 SABnzbd-4.3.2/tests/test_urlgrabber.py0000644000000000000000000002024714625637243017132 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_urlgrabber - Testing functions in urlgrabber.py """ import json import urllib.error import urllib.parse import pytest_httpbin import sabnzbd.urlgrabber as urlgrabber from sabnzbd.cfg import selftest_host from tests.testhelper import * @pytest_httpbin.use_class_based_httpbin class TestBuildRequest: def test_empty(self): with pytest.raises(ValueError): urlgrabber._build_request(None) with pytest.raises(ValueError): urlgrabber._build_request("") @staticmethod def _runner(test_url, exp_code=None, return_body=False): """ Generic test runner for _build_request(). Arguments: str test_url: complete URL, including scheme, user:pass, and query. int exp_code: the HTTP status code expected from the web server. bool return_body: whether to return the body of the server reply. Returns: (str) response body as utf-8 text or None """ with urlgrabber._build_request(test_url) as r: assert r is not None if exp_code: assert r.code == exp_code t = urllib.parse.urlparse(test_url) u = urllib.parse.urlparse(r.geturl()) # Verify user:pass was not included in the URL (should only be sent via HTTP Basic Auth) if t.username is not None or t.password is not None: if t.username: assert t.username not in u.netloc if t.password: assert t.password not in u.netloc # Check path, params, query and fragment match for test_url and request assert t.path.lstrip("/") == u.path.lstrip("/") # Account for urllib's handling of that slash assert t.params == u.params assert t.query == u.query assert t.fragment == u.fragment if return_body: return r.read().decode("utf-8") @staticmethod def _check_auth(headers): # Ensure the Authorization header was *not* send with the HTTP request json_headers = json.loads(headers.lower()) assert "authorization" not in json_headers["headers"].keys() def test_http_basic(self): # Use selftest_host for the most basic URL self._runner("http://" + selftest_host(), 200) # Repeat with httpbin, which runs on a random non-standard port self._runner(self.httpbin.url, 200) def test_https_basic(self): # Use a real HTTPS server; httpbin_secure uses a self-signed cert self._runner("https://" + selftest_host(), 200) # Repeat with the port explicitly specified self._runner("https://" + selftest_host() + ":443/", 200) def test_http_code(self): # Make the server reply with a non-standard status code self._runner(self.httpbin.url + "/status/242", 242) def test_user_agent(self): # Verify the User-Agent string assert ("SABnzbd/%s" % sabnzbd.__version__) in self._runner(self.httpbin.url + "/user-agent", 200, True) def test_http_userpass(self): usr = "abcdefghijklm01234" pwd = "56789nopqrstuvwxyz" common = "@" + self.httpbin.host + ":" + str(self.httpbin.port) + "/basic-auth/" + usr + "/" + pwd self._runner("http://" + usr + ":" + pwd + common, 200) with pytest.raises(urllib.error.HTTPError): # Authorisation should fail self._runner("http://totally:wrong" + common, 401) def test_http_userpass_email(self): for usr, pwd in [("nobody@example.org", "secret!"), ("USER", "P@SS"), ("a@B.cd", "e@F.gh")]: host = "http://" + usr + ":" + pwd + "@" + self.httpbin.host + ":" + str(self.httpbin.port) self._runner(host + "/basic-auth/" + usr + "/" + pwd, 200) def test_http_userpass_non_ascii(self): usr = "유즈넷" pwd = "َอักษรไทย" host = "http://" + usr + ":" + pwd + "@" + self.httpbin.host + ":" + str(self.httpbin.port) path = "/basic-auth/" + urllib.parse.quote(usr) + "/" + urllib.parse.quote(pwd) self._runner(host + path, 200) def test_http_user_only(self): h = self._runner("http://root@" + self.httpbin.host + ":" + str(self.httpbin.port) + "/headers", 200, True) self._check_auth(h) def test_http_pass_only(self): h = self._runner("http://:pass@" + self.httpbin.host + ":" + str(self.httpbin.port) + "/headers", 200, True) self._check_auth(h) def test_http_userpass_empty(self): # Add colon and at-sign but no username or password host = "http://:@" + self.httpbin.host + ":" + str(self.httpbin.port) h = self._runner(host + "/headers", 200, True) self._check_auth(h) def test_http_params_etc(self): self._runner(self.httpbin.url + "/anything/test/this.html?urlgrabber=test#says_hi", 200) # Add all possible elements, even unnecessary authorisation parameters host = "http://abcdefghijklm:nopqrstuvwxyz@" + self.httpbin.host + ":" + str(self.httpbin.port) path = "/anything/goes/even/params.like;this?testing=urlgrabber&more=tests#longpath" self._runner(host + path, 200) def test_http_invalid_hostname(self): with pytest.raises(urllib.error.URLError): self._runner("http://sabnzbd.invalid") def test_http_no_hostname(self): with pytest.raises(urllib.error.URLError): self._runner("http://foo:bar@/") def test_http_invalid_scheme(self): with pytest.raises(urllib.error.URLError): self._runner("_://" + self.httpbin.host + ":" + str(self.httpbin.port) + "/") def test_http_not_found(self): with pytest.raises(urllib.error.HTTPError): self._runner(self.httpbin.url + "/status/404", 404) with pytest.raises(urllib.error.HTTPError): self._runner(self.httpbin.url + "/no/such/file", 404) class TestFilenameFromDispositionHeader: @pytest.mark.parametrize( "header, result", [ ( # In this case the first filename (not the UTF-8 encoded) is parsed. "attachment; filename=jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz; filename*=UTF-8''jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", "jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", ), ( "filename=jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz;", "jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", ), ( "filename*=UTF-8''jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", "jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", ), ( "attachment; filename=jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", "jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", ), ( 'attachment; filename="jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz"', "jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz", ), ( "attachment; filename=/what/ever/filename.tar.gz", "filename.tar.gz", ), ( "attachment; filename=", None, ), ], ) def test_filename_from_disposition_header(self, header, result): """Test the parsing of different disposition-headers.""" assert urlgrabber.filename_from_content_disposition(header) == result ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4440942 SABnzbd-4.3.2/tests/test_functional_adding_nzbs.py0000644000000000000000000005763214625637243021517 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_functional_adding_nzbs - Tests for settings interaction when adding NZBs """ import shutil import stat import sys from random import sample from sabnzbd.constants import ( PAUSED_PRIORITY, DEFAULT_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, REPAIR_PRIORITY, PP_LOOKUP, ) from tests.testhelper import * # Repair priority is out of scope for the purpose of these tests: it cannot be # set as a default, upon adding a job, or from a pre-queue script. # "None" is used to *not* set any particular priority at a given stage. # Define valid options for various stages PRIO_OPTS_ADD = [ DEFAULT_PRIORITY, PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, None, ] PRIO_OPTS_PREQ = [ DEFAULT_PRIORITY, PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, None, ] PRIO_OPTS_ADD_CAT = [ DEFAULT_PRIORITY, PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, None, ] PRIO_OPTS_PREQ_CAT = [ DEFAULT_PRIORITY, PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, None, ] PRIO_OPTS_META_CAT = [ DEFAULT_PRIORITY, PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, None, ] # Valid priority values for the Default category (as determined by their availability from the interface) VALID_DEFAULT_PRIORITIES = [PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY] # Priorities that do *not* set a job state REGULAR_PRIOS = [LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY] # Priorities that set job states STATE_PRIOS = [PAUSED_PRIORITY] # Needed for translating priority values to names ALL_PRIOS = { DEFAULT_PRIORITY: "Default", PAUSED_PRIORITY: "Paused", LOW_PRIORITY: "Low", NORMAL_PRIORITY: "Normal", HIGH_PRIORITY: "High", FORCE_PRIORITY: "Force", REPAIR_PRIORITY: "Repair", } # Min/max size for random files used in generated NZBs (bytes) MIN_FILESIZE = 128 MAX_FILESIZE = 1024 # Tags to randomise category/script/nzb name CAT_RANDOM = os.urandom(4).hex() SCRIPT_RANDOM = os.urandom(4).hex() NZB_RANDOM = os.urandom(4).hex() class ModuleVars: # Full path to script directory resp. nzb files, once in place/generated SCRIPT_DIR = None NZB_FILE = None META_NZB_FILE = None # Pre-queue script setup marker PRE_QUEUE_SETUP_DONE = False # Shared variables at module-level VAR = ModuleVars() @pytest.fixture(scope="function") def pause_and_clear(): # Pause the queue assert get_api_result(mode="pause")["status"] is True yield # Delete all jobs from queue and history for mode in ("queue", "history"): get_api_result(mode=mode, extra_arguments={"name": "delete", "value": "all", "del_files": 1}) # Unpause the queue assert get_api_result(mode="resume")["status"] is True @pytest.mark.usefixtures("run_sabnzbd", "pause_and_clear") class TestAddingNZBs: def _api_set_config(self, keyword, value): """Shorthand for the API-call to change the config settings""" json = get_api_result( mode="set_config", extra_arguments={ "section": "misc", "keyword": keyword, "value": value, }, ) assert value == json["config"]["misc"][keyword] def _setup_script_dir(self): VAR.SCRIPT_DIR = os.path.join(SAB_CACHE_DIR, "scripts" + SCRIPT_RANDOM) try: os.makedirs(VAR.SCRIPT_DIR, exist_ok=True) except Exception: pytest.fail("Cannot create script_dir %s" % VAR.SCRIPT_DIR) self._api_set_config("script_dir", VAR.SCRIPT_DIR) def _customize_pre_queue_script(self, priority, category): """Add a script that accepts the job and sets priority & category""" script_name = "SCRIPT%s.py" % SCRIPT_RANDOM try: script_path = os.path.join(VAR.SCRIPT_DIR, script_name) with open(script_path, "w") as f: # line 1 = accept; 4 = category; 6 = priority f.write( "#!%s\n\nprint('1\\n\\n\\n%s\\n\\n%s\\n')" % ( sys.executable, (category if category else ""), (str(priority) if priority != None else ""), ) ) if not sys.platform.startswith("win"): os.chmod(script_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) except Exception: pytest.fail("Cannot add script %s to script_dir %s" % (script_name, VAR.SCRIPT_DIR)) if not VAR.PRE_QUEUE_SETUP_DONE: # Set as pre-queue script self._api_set_config("pre_script", script_name) VAR.PRE_QUEUE_SETUP_DONE = True def _configure_cat(self, priority, tag): category_name = "cat" + tag + CAT_RANDOM category_config = { "section": "categories", "name": category_name, "pp": choice(list(PP_LOOKUP.keys())), "script": "None", "priority": priority if priority != None else DEFAULT_PRIORITY, } # Add the category json = get_api_result(mode="set_config", extra_arguments=category_config) assert json["config"]["categories"][0]["name"] == category_name if priority != None: assert json["config"]["categories"][0]["priority"] == priority return category_name def _configure_default_category_priority(self, priority): if priority not in VALID_DEFAULT_PRIORITIES: priority = DEFAULT_PRIORITY json = get_api_result( mode="set_config", extra_arguments={ "section": "categories", "name": "*", "priority": priority, }, ) assert ("*", priority) == (json["config"]["categories"][0]["name"], json["config"]["categories"][0]["priority"]) def _create_random_nzb(self, metadata=None): # Create some simple, unique nzb job_dir = os.path.join(SAB_CACHE_DIR, "NZB" + os.urandom(8).hex()) try: os.mkdir(job_dir) job_file = "%s.bin" % random_name() with open(os.path.join(job_dir, job_file), "wb") as f: f.write(os.urandom(randint(MIN_FILESIZE, MAX_FILESIZE))) except Exception: pytest.fail("Failed to create random nzb") return create_nzb(job_dir, metadata=metadata) def _create_meta_nzb(self, cat_meta): return self._create_random_nzb(metadata={"category": cat_meta}) def _expected_results(self, STAGES, return_state=None): """Figure out what priority and state the job should end up with""" # Define a bunch of helpers def sanitize_stages(hit_stage, STAGES): # Fallback is always category-based, so nix any explicit priorities (stages 1, 3). # This is conditional only because explicit priority-upon-adding takes precedence # over implicit-from-pre-queue, as discussed in #1703. if not (hit_stage == 4 and STAGES[1] != None): STAGES[1] = None STAGES[3] = None # If the category was set from pre-queue, it replaces any category set earlier if hit_stage == 4: STAGES[2] = None STAGES[5] = None if hit_stage == 2: STAGES[5] = None return STAGES def handle_state_prio(hit_stage, STAGES, return_state): """Find the priority that should to be set after changing the job state""" # Keep record of the priority that caused the initial hit (for verification of the job state later on) if not return_state: return_state = STAGES[hit_stage] # No point in trying to find a fallback if hit_stage == 0: return NORMAL_PRIORITY, return_state STAGES = sanitize_stages(hit_stage, STAGES) # Work forward to find the priority prior to the hit_stage pre_state_prio = None pre_state_stage = None # default cat -> implicit meta -> implicit on add -> explicit on add -> implicit pre-q -> explicit pre-q for stage in (0, 5, 2, 1, 4, 3): if stage == hit_stage: if hit_stage == 1 and STAGES[4] != None: # An explicit state-setting priority still has to deal with the category from pre-queue # for fallback purposes, unlike non-state-setting priorities-on-add that override it. continue else: break if STAGES[stage] != None: pre_state_prio = STAGES[stage] pre_state_stage = stage if pre_state_prio != None and LOW_PRIORITY <= pre_state_prio <= HIGH_PRIORITY: return pre_state_prio, return_state else: # The next-in-line prio is unsuitable; recurse with relevant stages zero'ed out STAGES[hit_stage] = None if pre_state_stage: if pre_state_prio == DEFAULT_PRIORITY: handle_default_cat(pre_state_stage, STAGES, return_state) else: STAGES[pre_state_stage] = None # Sanitize again, with 'pre_state_stage' as the new hit_stage. This is needed again # in cases such as hit_stage 3 setting a job state, with a fallback from stage 4. sanitize_stages(pre_state_stage, STAGES) return self._expected_results(STAGES, return_state) def handle_default_cat(hit_stage, STAGES, return_state): """Figure out the (category) default priority""" STAGES = sanitize_stages(hit_stage, STAGES) # Strip the current -100 hit before recursing STAGES[hit_stage] = None return self._expected_results(STAGES, return_state) # Work backwards through all stages: # explicit pre-q -> implicit pre-q -> explicit on add -> implicit on add -> implicit meta for stage in (3, 4, 1, 2, 5): if STAGES[stage] != None: if stage == 4 and STAGES[1] != None: # Explicit priority on add takes precedence over implicit-from-pre-queue continue if STAGES[stage] in REGULAR_PRIOS: return STAGES[stage], return_state if STAGES[stage] in STATE_PRIOS: return handle_state_prio(stage, STAGES, return_state) if STAGES[stage] == DEFAULT_PRIORITY: return handle_default_cat(stage, STAGES, return_state) # # ...and finally the Default category (stage 0) if STAGES[0] not in (None, DEFAULT_PRIORITY): if STAGES[0] in REGULAR_PRIOS: # Avoid falling back to priority Force after setting a job state if not (return_state in STATE_PRIOS and STAGES[0] == FORCE_PRIORITY): return STAGES[0], return_state else: return NORMAL_PRIORITY, return_state if STAGES[0] in STATE_PRIOS: return handle_state_prio(0, STAGES, return_state) # The default of defaults... return NORMAL_PRIORITY, return_state def _prep_priority_tester(self, prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat): if not VAR.SCRIPT_DIR: self._setup_script_dir() if not VAR.NZB_FILE: VAR.NZB_FILE = self._create_random_nzb() # Set the priority for the Default category self._configure_default_category_priority(prio_def_cat) # Setup categories cat_meta = None if prio_meta_cat != None: cat_meta = self._configure_cat(prio_meta_cat, "meta") if not VAR.META_NZB_FILE: VAR.META_NZB_FILE = self._create_meta_nzb(cat_meta) cat_add = None if prio_add_cat != None: cat_add = self._configure_cat(prio_add_cat, "add") cat_preq = None if prio_preq_cat != None: cat_preq = self._configure_cat(prio_preq_cat, "pre") # Setup the pre-queue script self._customize_pre_queue_script(prio_preq, cat_preq) # Queue the job, store the nzo_id extra = {"name": VAR.META_NZB_FILE if cat_meta else VAR.NZB_FILE} if cat_add: extra["cat"] = cat_add if prio_add != None: extra["priority"] = prio_add nzo_id = ",".join(get_api_result(mode="addlocalfile", extra_arguments=extra)["nzo_ids"]) # Fetch the queue output for the current job return get_api_result(mode="queue", extra_arguments={"nzo_ids": nzo_id})["queue"]["slots"][0] def _priority_tester(self, prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat): # Setup the current test job, and fetch its queue output job = self._prep_priority_tester(prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat) # Determine the expected results expected_prio, expected_state = self._expected_results( [prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat] ) # Verify the results; queue output uses a string representation for the priority assert ALL_PRIOS.get(expected_prio) == job["priority"] if expected_state: # Also check the correct state or label was set if expected_state == PAUSED_PRIORITY: assert "Paused" == job["status"] # Caution: a full run is good for 90k+ tests # @pytest.mark.parametrize("prio_meta_cat", PRIO_OPTS_META_CAT) # @pytest.mark.parametrize("prio_def_cat", VALID_DEFAULT_PRIORITIES) # @pytest.mark.parametrize("prio_add", PRIO_OPTS_ADD) # @pytest.mark.parametrize("prio_add_cat", PRIO_OPTS_ADD_CAT) # @pytest.mark.parametrize("prio_preq", PRIO_OPTS_PREQ) # @pytest.mark.parametrize("prio_preq_cat", PRIO_OPTS_PREQ_CAT) @pytest.mark.parametrize("prio_meta_cat", sample(PRIO_OPTS_META_CAT, 2)) @pytest.mark.parametrize("prio_def_cat", sample(VALID_DEFAULT_PRIORITIES, 2)) @pytest.mark.parametrize("prio_add", sample(PRIO_OPTS_ADD, 3)) @pytest.mark.parametrize("prio_add_cat", sample(PRIO_OPTS_ADD_CAT, 2)) @pytest.mark.parametrize("prio_preq", sample(PRIO_OPTS_PREQ, 2)) @pytest.mark.parametrize("prio_preq_cat", sample(PRIO_OPTS_PREQ_CAT, 2)) def test_adding_nzbs_priority_sample( self, prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat ): self._priority_tester(prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat) @pytest.mark.parametrize( "prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat", [ # Specific triggers for fixed bugs (-1, -2, None, None, None, None), # State-setting priorities always fell back to Normal (1, None, -2, None, None, None), (2, None, None, -2, None, None), (0, 2, None, None, 1, None), # Explicit priority on add was bested by implicit from pre-queue (1, None, None, None, -1, None), # Category-based values from pre-queue didn't work at all # Checks for test code regressions (-2, -100, 2, None, None, None), (-2, 0, 2, -100, None, None), (1, 2, 0, -100, None, None), (-2, None, -2, None, 2, None), (-2, None, -1, None, 1, None), (2, None, -1, None, -2, None), (2, 2, None, -2, None, None), (2, 1, None, -2, None, None), (1, -2, 0, None, None, None), (0, 2, None, -2, None, -1), (1, -2, -100, None, None, -1), (1, None, None, None, None, -1), (-1, None, None, None, None, 1), (0, None, None, None, None, None), ], ) def test_adding_nzbs_priority_triggers( self, prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat ): self._priority_tester(prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat) def test_adding_nzbs_partial(self): """Test adding parts of an NZB file, cut off somewhere in the middle to simulate the effects of an interrupted download or bad hardware. Should fail, of course.""" if not VAR.NZB_FILE: VAR.NZB_FILE = self._create_random_nzb() nzb_basedir, nzb_basename = os.path.split(VAR.NZB_FILE) nzb_size = os.stat(VAR.NZB_FILE).st_size part_size = round(randint(40, 70) / 100 * nzb_size) first_part = os.path.join(nzb_basedir, "part1_of_" + nzb_basename) second_part = os.path.join(nzb_basedir, "part2_of_" + nzb_basename) with open(VAR.NZB_FILE, "rb") as nzb_in: for nzb_part, chunk in (first_part, part_size), (second_part, -1): with open(nzb_part, "wb") as nzb_out: nzb_out.write(nzb_in.read(chunk)) for nzb_part in first_part, second_part: json = get_api_result(mode="addlocalfile", extra_arguments={"name": nzb_part}) assert json["status"] is False assert json["nzo_ids"] == [] os.remove(nzb_part) @pytest.mark.parametrize( "keep_first, keep_last, strip_first, strip_last, should_work", [ # Keep parts (6, 3, 0, 0, False), # Remove all segments content (6, 0, 0, 0, False), (5, 2, 0, 0, False), # Remove all segments (5, 0, 0, 0, False), (4, 2, 0, 0, False), # Remove all groups (3, 1, 0, 0, False), # Remove all files # Strip parts (0, 0, 1, 0, True), # Strip '?xml' line (survivable) (0, 0, 2, 0, True), # Also strip 'doctype' line (survivable) (0, 0, 3, 0, False), # Also strip 'nzb xmlns' line (0, 0, 0, 1, False), # Forget the 'nzb' closing tag (0, 0, 0, 2, False), # Also forget the (last) 'file' closing tag (0, 0, 0, 3, False), # Also forget the (last) 'segment' closing tag ], ) def test_adding_nzbs_malformed(self, keep_first, keep_last, strip_first, strip_last, should_work): """Test adding broken, empty, or otherwise malformed NZB file""" if not VAR.NZB_FILE: VAR.NZB_FILE = self._create_random_nzb() with open(VAR.NZB_FILE, "rt") as nzb_in: nzb_lines = nzb_in.readlines() assert len(nzb_lines) >= 9 broken_nzb_basename = "broken_" + os.urandom(4).hex() + ".nzb" broken_nzb = os.path.join(SAB_CACHE_DIR, broken_nzb_basename) with open(broken_nzb, "wt") as nzb_out: # Keep only first x, last y lines if keep_first: nzb_out.write("".join(nzb_lines[:keep_first])) elif strip_first: nzb_out.write("".join(nzb_lines[strip_first:])) if keep_last: nzb_out.write("".join(nzb_lines[(-1 * keep_last) :])) elif strip_last: nzb_out.write("".join(nzb_lines[: (-1 * strip_last)])) json = get_api_result(mode="warnings", extra_arguments={"name": "clear"}) json = get_api_result(mode="addlocalfile", extra_arguments={"name": broken_nzb}) assert json["status"] is should_work assert len(json["nzo_ids"]) == int(should_work) json = get_api_result(mode="warnings") assert (len(json["warnings"]) == 0) is should_work if not should_work: for warning in range(0, len(json["warnings"])): warn_text = json["warnings"][warning]["text"] assert "Empty NZB" in warn_text or "Failed to import" in warn_text or "Invalid NZB" in warn_text assert broken_nzb_basename in warn_text os.remove(broken_nzb) @pytest.mark.parametrize("prio_meta_cat", sample(PRIO_OPTS_META_CAT, 1)) @pytest.mark.parametrize("prio_def_cat", sample(VALID_DEFAULT_PRIORITIES, 1)) @pytest.mark.parametrize("prio_add", PRIO_OPTS_ADD) def test_adding_nzbs_size_limit(self, prio_meta_cat, prio_def_cat, prio_add): """Verify state and priority of a job exceeding the size_limit""" # Set size limit self._api_set_config("size_limit", str(MIN_FILESIZE - 1)) job = self._prep_priority_tester(prio_def_cat, prio_add, None, None, None, prio_meta_cat) # Verify job is paused and low priority, and correctly labeled assert job["status"] == "Paused" assert job["priority"] == ALL_PRIOS.get(-1) assert "TOO LARGE" in job["labels"] # Unset size limit self._api_set_config("size_limit", "") def _add_backup_directory(self): # Set an nzb backup directory backup_dir = os.path.join(SAB_CACHE_DIR, "nzb_backup_dir" + os.urandom(4).hex()) self._api_set_config("nzb_backup_dir", backup_dir) return backup_dir def _clear_and_reset_backup_directory(self, backup_dir): # Reset duplicate handling (0), nzb_backup_dir ("") get_api_result(mode="set_config_default", extra_arguments={"keyword": ["no_dupes", "nzb_backup_dir"]}) # Remove backup_dir for timer in range(0, 5): try: shutil.rmtree(backup_dir) break except OSError: time.sleep(1) else: pytest.fail("Failed to erase nzb_backup_dir %s" % backup_dir) @pytest.mark.parametrize("prio_def_cat", sample(VALID_DEFAULT_PRIORITIES, 2)) @pytest.mark.parametrize("prio_add", PRIO_OPTS_ADD) @pytest.mark.parametrize("prio_add_cat", sample(PRIO_OPTS_ADD_CAT, 1)) @pytest.mark.parametrize("prio_preq", sample(PRIO_OPTS_PREQ, 1)) @pytest.mark.parametrize("prio_preq_cat", sample(PRIO_OPTS_PREQ_CAT, 2)) def test_adding_nzbs_duplicate_pausing(self, prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat): # Set an nzb backup directory backup_dir = self._add_backup_directory() # Add the job a first time job = self._prep_priority_tester(None, None, None, None, None, None) assert job["status"] == "Queued" # Setup duplicate handling to 2 (Pause) self._api_set_config("no_dupes", 2) expected_prio, _ = self._expected_results( [prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, None] ) job = self._prep_priority_tester(prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, None) # Verify job is paused and correctly labeled, and given the right (fallback) priority assert job["priority"] == ALL_PRIOS.get(expected_prio) if expected_prio == FORCE_PRIORITY: assert "DUPLICATE" not in job["labels"] assert "ALTERNATIVE" not in job["labels"] assert job["status"] == "Downloading" else: assert "ALTERNATIVE" in job["labels"] assert job["status"] == "Paused" self._clear_and_reset_backup_directory(backup_dir) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4441986 SABnzbd-4.3.2/tests/test_interface.py0000644000000000000000000002353314625637243016744 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_interface - Testing functions in interface.py """ import cherrypy from sabnzbd import interface from sabnzbd.misc import is_local_addr, is_loopback_addr from tests.testhelper import * class TestInterfaceFunctions: @pytest.mark.parametrize( "remote_ip, local_ranges, xff_header, result_with_xff", [ ("10.11.12.13", None, None, True), ("10.11.12.13", None, "127.0.0.1", True), ("10.11.12.13", None, "127.1.2.3", True), ("10.11.12.13", None, "127.0.0.1:8080", False), # Port number in XFF ("10.11.12.13", None, "::1", True), ("10.11.12.13", None, "[::1]", True), ("10.11.12.13", None, "[::1]:8080", False), # Port number in XFF ("10.11.12.13", None, "localhost", False), # Hostname in XFF ("10.11.12.13", None, "example.org", False), # Hostname in XFF ("10.11.12.13", None, "192.168.1.1", True), ("10.11.12.13", None, "10.11.12.99", True), ("10.11.12.13", None, "8.7.6.5", False), # XFF IP isn't local ("10.11.12.13", None, "192.168.1.1, 10.11.12.13", True), ("10.11.12.13", None, "192.168.1.1, 10.11.12.13, 9.8.7.6", False), # Last XFF IP isn't local ("10.11.12.13", None, "192.168.1.1, 10.11.12.13, ::1", True), ("10.11.12.13", None, "192.168.1.1, 10.11.12.13, sabrules.example.org", False), # Hostname in XFF ("10.11.12.13", "192.168.1.0/24", None, False), # Remote IP not part of local ranges ("10.11.12.13", "192.168.1.0/24", "192.168.1.23", False), ("10.11.12.13", "192.168.1.0/24", "192.168.1.23, 10.11.12.1", False), ("10.11.12.13", "192.168.1.0/24, 10.0.0.0/8", "192.168.1.23", True), ("10.11.12.13", "192.168.2.0/24, 10.0.0.0/8", "192.168.1.23", False), ("10.11.12.13", "192.168.1.0/24, 10.0.0.0/24", "192.168.1.23", False), ("10.11.12.13", "10.11.12.0/24", "192.168.1.23", False), ("10.11.12.13", "2001:ffff::/64", None, False), ("10.11.12.13", "2001:ffff::/64, 192.168.1.0/24", None, False), ("13.12.11.10", None, None, False), # Public remote IP doesn't have access, XFF ignored altogether ("13.12.11.10", None, "127.0.0.1", False), ("13.12.11.10", None, "127.1.2.3", False), ("13.12.11.10", None, "::1", False), ("13.12.11.10", None, "[::1]", False), ("13.12.11.10", None, "localhost", False), ("13.12.11.10", None, "192.168.1.1", False), ("13.12.11.10", None, "192.168.1.1, 13.12.11.10", False), ("13.12.11.10", None, "192.168.1.1, 13.12.11.10, ::1", False), ("13.12.11.10", None, "2001::/16", False), ("13.12.11.10", None, "2001::/16, 13.12.11.10", False), ("13.12.11.10", None, "2001::/16, 13.0.0.0/9", False), ("13.12.11.10", "13.12.11.10", None, True), # Local ranges include a public IP ("13.12.11.10", "13.12.11.10, 192.168.255.0/24", None, True), ("13.12.11.10", "13.12.11.10", "192.168.1.1", False), # XFF not in local ranges ("13.12.11.10", "13.12.11.10, 192.168.255.0/24", "192.168.1.1", False), ("13.12.11.10", "13.12.11.10", "192.168.1.1, 9.8.7.6", False), ("13.12.11.10", "13.12.11.10, 192.168.255.0/24", "192.168.1.1, 9.8.7.6", False), ("13.12.11.10", "13.0.0.0/12", None, True), ("13.12.11.10", "13.0.0.0/12, 192.168.255.0/24", None, True), ("13.12.11.10", "13.0.0.0/12", "192.168.1.1", False), # XFF not in local ranges ("13.12.11.10", "13.0.0.0/12, 192.168.255.0/24", "192.168.1.1", False), ("13.12.11.10", "13.0.0.0/12", "192.168.1.1, 9.8.7.6", False), ("13.12.11.10", "13.0.0.0/12, 192.168.255.0/24", "192.168.1.1, 9.8.7.6", False), ("127.6.6.6", None, None, True), ("127.6.6.6", None, "127.0.0.1", True), ("127.6.6.6", None, "127.1.2.3", True), ("127.6.6.6", None, "127.0.0.1:8080", False), # Port number in XFF ("127.6.6.6", None, "::1", True), ("127.6.6.6", None, "[::1]", True), ("127.6.6.6", None, "[::1]:8080", False), # Port number in XFF ("127.6.6.6", None, "localhost", False), # Hostname in XFF ("127.6.6.6", None, "example.org", False), # Hostname in XFF ("127.6.6.6", None, "192.168.1.1", True), ("127.6.6.6", None, "10.11.12.99", True), ("127.6.6.6", None, "8.7.6.5", False), # XFF IP isn't local ("127.6.6.6", None, "192.168.1.1, 127.6.6.6", True), ("127.6.6.6", None, "192.168.1.1, 127.6.6.6, 9.8.7.6", False), # Last XFF IP isn't local ("127.6.6.6", None, "192.168.1.1, 127.6.6.6, ::1", True), ("127.6.6.6", None, "192.168.1.1, 127.6.6.6, sabrules.example.org", False), # Hostname in XFF ("127.6.6.6", "192.168.1.0/24", None, True), # Remote IP is loopback, local ranges be damned ("127.6.6.6", "192.168.1.0/24", "192.168.1.23", True), ("127.6.6.6", "192.168.1.0/24", "192.168.1.23, 127.0.0.1", True), ("127.6.6.6", "192.168.1.0/24, 127.0.0.0/8", "192.168.1.23", True), ("127.6.6.6", "192.168.2.0/24, 127.0.0.0/8", "192.168.1.23", False), # Access denied by XFF ("127.6.6.6", "192.168.2.0/24, 127.0.0.0/8", "5.6.7.8", False), # Idem ("127.6.6.6", "192.168.1.0/24, 127.0.0.0/8", "192.168.1.23, 5.6.7.8", False), # Idem ("127.6.6.6", "192.168.1.0/24, 10.0.0.0/24", "::1", True), ("127.6.6.6", "127.6.6.0/24", "192.168.1.23", False), # Access denied by XFF ("127.6.6.6", "2001:ffff::/32", None, True), ("127.6.6.6", "2001:ffff::/32, 192.168.1.0/24", None, True), ("127.6.6.6", "2001:ffff::/32", "2001:ffff:a:b:c:d:e:f", True), ("127.6.6.6", "2001:ffff::/32, 192.168.1.0/24", "2001:ffff:a:b:c:d:e:f, 192.168.1.1", True), ("127.6.6.6", "2001:ffff::/32", "666:ffff:a:b:c:d:e:f", False), # Access denied by XFF ("127.6.6.6", "2001:ffff::/32, 192.168.1.0/24", "666:ffff:a:b:c:d:e:f, 192.168.1.1", False), # Idem ("DEAD:BEEF:2023:007::1", None, None, False), # Back to ignoring XFF altogether ("DEAD:BEEF:2023:007::1", None, "127.0.0.1", False), # XFF is loopback ("DEAD:BEEF:2023:007::1", None, "127.1.2.3", False), ("DEAD:BEEF:2023:007::1", None, "::1", False), ("DEAD:BEEF:2023:007::1", None, "[::1]", False), ("DEAD:BEEF:2023:007::1", None, "localhost", False), # Hostname in XFF ("DEAD:BEEF:2023:007::1", None, "192.168.1.1", False), ("DEAD:BEEF:2023:007::1", None, "192.168.1.1, DEAD:BEEF:2023:0007::1", False), ("DEAD:BEEF:2023:007::1", None, "192.168.1.1, DEAD:BEEF:2023:0007::1, ::1", False), ("DEAD:BEEF:2023:007::1", None, "2001::/16", False), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", None, True), # Local ranges include a public IPv6 ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "127.0.0.1", True), # XFF is loopback ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "127.1.2.3", True), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "::1", True), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "[::1]", True), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "localhost", False), # Hostname in XFF ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "192.168.1.1", False), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "192.168.1.1, DEAD:BEEF:2023:0007::1", False), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "192.168.1.1, DEAD:BEEF:2023:0007::1, ::1", False), ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "DEAD::/16", False), # Netmask in XFF ("DEAD:BEEF:2023:007::1", "dead:beef::/32", "DEAD:BEEF:2023:7::42", True), # XFF in local ranges ], ) @pytest.mark.parametrize("access_type", [1, 2, 3, 4, 5, 6]) @pytest.mark.parametrize("inet_exposure", [0, 1, 2, 3, 4, 5]) @pytest.mark.parametrize("verify_xff_header", [False, True]) def test_check_access( self, access_type, inet_exposure, local_ranges, remote_ip, xff_header, verify_xff_header, result_with_xff ): @set_config( { "local_ranges": local_ranges, "inet_exposure": inet_exposure, "verify_xff_header": verify_xff_header, } ) def _func(): # Insert fake request data cherrypy.request.remote.ip = remote_ip cherrypy.request.headers.update({"X-Forwarded-For": xff_header}) if verify_xff_header: result = result_with_xff else: # Without XFF, only the remote IP and the local ranges setting matter result = is_loopback_addr(remote_ip) or is_local_addr(remote_ip) if access_type <= inet_exposure: assert interface.check_access(access_type) is True else: assert interface.check_access(access_type) is result _func() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4442825 SABnzbd-4.3.2/tests/test_nzbstuff.py0000644000000000000000000002501514625637243016642 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_nzbstuff - Testing functions in nzbstuff.py """ import sabnzbd.nzbstuff as nzbstuff from sabnzbd.config import ConfigCat from sabnzbd.constants import NORMAL_PRIORITY from sabnzbd.filesystem import globber from tests.testhelper import * @pytest.mark.usefixtures("clean_cache_dir") class TestNZO: @set_config({"download_dir": SAB_CACHE_DIR}) def test_nzo_basic(self): # Need to create the Default category, as we would in normal instance # Otherwise it will try to save the config def_cat = ConfigCat("*", {"pp": 3, "script": "None", "priority": NORMAL_PRIORITY}) # Create empty object, normally used to grab URL's nzo = nzbstuff.NzbObject("test_basic") assert nzo.work_name == "test_basic" assert not nzo.files # Create NZB-file to import nzb_fp = create_and_read_nzb_fp("basic_rar5") # Very basic test of NZO creation with data nzo = nzbstuff.NzbObject("test_basic_data", nzb_fp=nzb_fp) assert nzo.final_name == "test_basic_data" assert nzo.files assert nzo.files[0].filename == "testfile.rar" assert nzo.bytes == 283 assert nzo.files[0].bytes == 283 # work_name can be trimmed in Windows due to max-path-length assert "test_basic_data".startswith(nzo.work_name) assert os.path.exists(nzo.admin_path) # Check if there's an nzf file and the backed-up nzb assert globber(nzo.admin_path, "*.nzb.gz") assert globber(nzo.admin_path, "SABnzbd_nzf*") # Should have picked up the default category settings assert nzo.cat == "*" assert nzo.script == def_cat.script() == "None" assert nzo.priority == def_cat.priority() == NORMAL_PRIORITY assert nzo.repair and nzo.unpack and nzo.delete # TODO: More checks! class Server: def __init__(self, host, priority, active): self.host = host self.priority = priority self.active = active class TestArticle: def test_get_article(self): article_id = "test@host" + os.urandom(8).hex() + ".sab" article = nzbstuff.Article(article_id, randint(4321, 54321), None) servers = [] servers.append(Server("testserver1", 10, True)) servers.append(Server("testserver2", 20, True)) servers.append(Server("testserver3", 30, True)) # Test fetching top priority server server = servers[0] assert article.get_article(server, servers) == article assert article.fetcher_priority == 10 assert article.fetcher == server assert article.get_article(server, servers) == None article.fetcher = None article.add_to_try_list(server) assert article.get_article(server, servers) == None # Test fetching when there is a higher priority server available server = servers[2] assert article.fetcher_priority == 10 assert article.get_article(server, servers) == None assert article.fetcher_priority == 20 # Server should be used even if article.fetcher_priority is a higher number than server.priority article.fetcher_priority = 30 server = servers[1] assert article.get_article(server, servers) == article # Inactive servers in servers list should be ignored article.fetcher = None article.fetcher_priority = 0 servers[1].active = False server = servers[2] assert article.get_article(server, servers) == article assert article.tries == 3 class TestNZBStuffHelpers: @pytest.mark.parametrize( "argument, name, password", [ ("my_awesome_nzb_file{{password}}", "my_awesome_nzb_file", "password"), ("file_with_text_after_pw{{passw0rd}}_[180519]", "file_with_text_after_pw", "passw0rd"), ("file_without_pw", "file_without_pw", None), ("multiple_pw{{first-pw}}_{{second-pw}}", "multiple_pw", "first-pw}}_{{second-pw"), # Greed is Good ("デビアン", "デビアン", None), # Unicode ("Gentoo_Hobby_Edition {{secret}}", "Gentoo_Hobby_Edition", "secret"), # Space between name and password ("Test {{secret}}.nzb", "Test", "secret"), ("Mandrake{{top{{secret}}", "Mandrake", "top{{secret"), # Double opening {{ ("Красная}}{{Шляпа}}", "Красная}}", "Шляпа"), # Double closing }} ("{{Jobname{{PassWord}}", "{{Jobname", "PassWord"), # {{ at start ("Hello/kITTY", "Hello", "kITTY"), # Notation with slash ("Hello/kITTY.nzb", "Hello", "kITTY"), # Notation with slash and extension ("/Jobname", "/Jobname", None), # Slash at start ("Jobname/Top{{Secret}}", "Jobname", "Top{{Secret}}"), # Slash with braces ("Jobname / Top{{Secret}}", "Jobname", "Top{{Secret}}"), # Slash with braces and extra spaces ("Jobname / Top{{Secret}}.nzb", "Jobname", "Top{{Secret}}"), ("לינוקס/معلومات سرية", "לינוקס", "معلومات سرية"), # LTR with slash ("לינוקס{{معلومات سرية}}", "לינוקס", "معلومات سرية"), # LTR with brackets ("thư điện tử password=mật_khẩu", "thư điện tử", "mật_khẩu"), # Password= notation ("password=PartOfTheJobname", "password=PartOfTheJobname", None), # Password= at the start ("Job password=Test.par2", "Job", "Test"), # Password= including extension ("Job}}Name{{FTW", "Job}}Name{{FTW", None), # Both {{ and }} present but incorrect order (no password) ("./Text", "./Text", None), # Name would end up empty after the function strips the dot ], ) def test_scan_password(self, argument, name, password): assert nzbstuff.scan_password(argument) == (name, password) @pytest.mark.parametrize( "file_name, clean_file_name", [ ("my_awesome_nzb_file.pAr2.nZb", "my_awesome_nzb_file"), ("my_awesome_nzb_file.....pAr2.nZb", "my_awesome_nzb_file"), ("my_awesome_nzb_file....par2..", "my_awesome_nzb_file"), (" my_awesome_nzb_file .pAr.nZb", "my_awesome_nzb_file"), ("with.extension.and.period.par2.", "with.extension.and.period"), ("nothing.in.here", "nothing.in.here"), (" just.space ", "just.space"), ("http://test.par2 ", "http://test.par2"), ], ) def test_create_work_name(self, file_name, clean_file_name): # Only test stuff specific for create_work_name # The sanitizing is already tested in tests for sanitize_foldername assert nzbstuff.create_work_name(file_name) == clean_file_name @pytest.mark.parametrize( "subject, filename", [ ('Great stuff (001/143) - "Filename.txt" yEnc (1/1)', "Filename.txt"), ( '"910a284f98ebf57f6a531cd96da48838.vol01-03.par2" yEnc (1/3)', "910a284f98ebf57f6a531cd96da48838.vol01-03.par2", ), ('Subject-KrzpfTest [02/30] - ""KrzpfTest.part.nzb"" yEnc', "KrzpfTest.part.nzb"), ( '[PRiVATE]-[WtFnZb]-[Supertje-_S03E11-12_-blabla_+_blabla_WEBDL-480p.mkv]-[4/12] - "" yEnc 9786 (1/1366)', "Supertje-_S03E11-12_-blabla_+_blabla_WEBDL-480p.mkv", ), ( '[N3wZ] MAlXD245333\\::[PRiVATE]-[WtFnZb]-[Show.S04E04.720p.AMZN.WEBRip.x264-GalaxyTV.mkv]-[1/2] - "" yEnc 293197257 (1/573)', "Show.S04E04.720p.AMZN.WEBRip.x264-GalaxyTV.mkv", ), ( 'reftestnzb bf1664007a71 [1/6] - "20b9152c-57eb-4d02-9586-66e30b8e3ac2" yEnc (1/22) 15728640', "20b9152c-57eb-4d02-9586-66e30b8e3ac2", ), ( "Re: REQ Author Child's The Book-Thanks much - Child, Lee - Author - The Book.epub (1/1)", "REQ Author Child's The Book-Thanks much - Child, Lee - Author - The Book.epub", ), ('63258-0[001/101] - "63258-2.0" yEnc (1/250) (1/250)', "63258-2.0"), # If specified between ", the extension is allowed to be too long ('63258-0[001/101] - "63258-2.0toolong" yEnc (1/250) (1/250)', "63258-2.0toolong"), ( "Singer - A Album (2005) - [04/25] - 02 Sweetest Somebody (I Know).flac", "Singer - A Album (2005) - [04/25] - 02 Sweetest Somebody (I Know).flac", ), ("<>random!>", "<>random!>"), ("nZb]-[Supertje-_S03E11-12_", "nZb]-[Supertje-_S03E11-12_"), ("Bla [Now it's done.exe]", "Now it's done.exe"), # If specified between [], the extension should be a valid one ("Bla [Now it's done.123nonsense]", "Bla [Now it's done.123nonsense]"), ('[PRiVATE]-[WtFnZb]-[00000.clpi]-[1/46] - "" yEnc 788 (1/1)', "00000.clpi"), ( '[PRiVATE]-[WtFnZb]-[Video_(2001)_AC5.1_-RELEASE_[TAoE].mkv]-[1/23] - "" yEnc 1234567890 (1/23456)', "Video_(2001)_AC5.1_-RELEASE_[TAoE].mkv", ), ( "[PRiVATE]-[WtFnZb]-[219]-[1/series.name.s01e01.1080p.web.h264-group.mkv] - " " yEnc (1/[PRiVATE] \\c2b510b594\\::686ea969999193.155368eba4965e56a8cd263382e012.f2712fdc::/97bd201cf931/) 1 (1/0)", "series.name.s01e01.1080p.web.h264-group.mkv", ), ( "[PRiVATE]-[WtFnZb]-[/More.Bla.S02E01.1080p.WEB.h264-EDITH[eztv.re].mkv-WtF[nZb]/" 'More.Bla.S02E01.1080p.WEB.h264-EDITH.mkv]-[1/2] - "" yEnc 2990558544 (1/4173)', "More.Bla.S02E01.1080p.WEB.h264-EDITH[eztv.re].mkv", ), ], ) def test_name_extractor(self, subject, filename): assert nzbstuff.name_extractor(subject) == filename ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4444268 SABnzbd-4.3.2/tests/test_utils/test_sleepless.py0000644000000000000000000000500114625637243021170 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_sleepless - Test sleepless for macOS """ import subprocess import sys import time import pytest if not sys.platform.startswith("darwin"): pytest.skip("Skipping macOS-only tests", allow_module_level=True) import sabnzbd.utils.sleepless as sleepless class TestSleepless: sleep_msg = "SABnzbd is running, don't you stop us now!" def check_msg_in_assertions(self): return self.sleep_msg in subprocess.check_output(["pmset", "-g", "assertions"], universal_newlines=True) def test_sleepless(self): # Run twice to see if it keeps going well for _ in range(2): # Keep it awake sleepless.keep_awake(self.sleep_msg) time.sleep(2) # Check if it's still in the assertions list assert self.check_msg_in_assertions() # Remove and see if it's still there sleepless.allow_sleep() assert not self.check_msg_in_assertions() assert sleepless.assertion_id is None def test_sleepless_not_there(self): assert not self.check_msg_in_assertions() assert sleepless.assertion_id is None sleepless.allow_sleep() assert not self.check_msg_in_assertions() assert sleepless.assertion_id is None def test_sleepless_multi_call(self): # If we set it twice, is it still cleared with one call assert not self.check_msg_in_assertions() assert sleepless.assertion_id is None sleepless.keep_awake(self.sleep_msg) time.sleep(2) sleepless.keep_awake(self.sleep_msg) assert self.check_msg_in_assertions() sleepless.allow_sleep() assert not self.check_msg_in_assertions() assert sleepless.assertion_id is None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4444716 SABnzbd-4.3.2/tests/test_utils/__init__.py0000644000000000000000000000000014625637243017663 0ustar00runnerstaff././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4445353 SABnzbd-4.3.2/tests/test_utils/test_cert_gen.py0000644000000000000000000000544714625637243020775 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_cert_gen - Testing Certificate generation """ import datetime from cryptography import x509 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa from sabnzbd.utils.certgen import generate_key, generate_local_cert from tests.testhelper import * @pytest.mark.usefixtures("clean_cache_dir") class TestCertGen: def test_generate_key_default(self): # Generate private key with default key_size and file name private_key = generate_key(output_file=os.path.join(SAB_CACHE_DIR, "test_key.pem")) assert private_key.key_size == 2048 @pytest.mark.parametrize( "key_size, file_name", [(512, "test_key.pem"), (1024, "test_123_key.pem"), (4096, "123_key.pem")] ) def test_generate_key_custom(self, key_size, file_name): # Generate private key private_key = generate_key(key_size=key_size, output_file=os.path.join(SAB_CACHE_DIR, file_name)) # validate generated private key assert private_key.key_size == key_size assert os.path.isfile(os.path.join(SAB_CACHE_DIR, file_name)) def test_generate_local_cert(self): # Generate private key private_key = generate_key(output_file=os.path.join(SAB_CACHE_DIR, "test_key.pem")) # Generate local certificate using private key output_file = os.path.join(SAB_CACHE_DIR, "test_cert.cert") local_cert = generate_local_cert(private_key, output_file=output_file) assert local_cert # Validating generated key file public_key = local_cert.public_key() assert isinstance(public_key, rsa.RSAPublicKey) # Validate certificate file with open(output_file, "rb") as cert_file: cert_content = cert_file.read() cert = x509.load_pem_x509_certificate(cert_content, default_backend()) # Validate that the timestamp at which the certificate stops being valid (expiration date) is in future assert datetime.datetime.now() < cert.not_valid_after ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4446115 SABnzbd-4.3.2/tests/test_utils/test_pystone.py0000644000000000000000000000224014625637243020674 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_utils.test_pystone - Testing SABnzbd pystone """ from sabnzbd.utils.pystone import pystones class TestPystone: def test_pystone(self): """Tests for performance with various loop sizes""" loops = [10, 1000, 50000, 100000] for loop in loops: benchtime, stones = pystones(loop) assert benchtime > 0 assert stones > 0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4446921 SABnzbd-4.3.2/tests/test_utils/test_diskspeed.py0000644000000000000000000000436114625637243021154 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ tests.test_utils.test_diskspeed - Testing SABnzbd diskspeed """ import os import pytest import tempfile from sabnzbd.utils.diskspeed import diskspeedmeasure from tests.testhelper import SAB_CACHE_DIR @pytest.mark.usefixtures("clean_cache_dir") class TestDiskSpeed: """test sabnzbd.utils.diskspeed""" def test_disk_speed(self): """Test the normal use case: writable directory""" speed = diskspeedmeasure(SAB_CACHE_DIR) assert speed > 0.0 assert isinstance(speed, float) # Make sure the test-file was cleaned up after the test assert not os.path.exists(os.path.join(SAB_CACHE_DIR, "outputTESTING.txt")) def test_non_existing_dir(self): """testing a non-existing dir should result in 0""" speed = diskspeedmeasure("such_a_dir_does_not_exist") assert speed == 0 def test_non_writable_dir(self): """testing a non-writable dir should result in 0. Only useful on Linux, and only if not-writable """ non_writable_dir = "/usr" if os.path.isdir(non_writable_dir) and not os.access(non_writable_dir, os.W_OK): speed = diskspeedmeasure(non_writable_dir) assert speed == 0 def test_file_not_dir_specified(self): """testing a file should result in 0""" with tempfile.NamedTemporaryFile() as temp_file: speed = diskspeedmeasure(temp_file.name) assert speed == 0 assert not os.path.exists(temp_file.name) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2348957 SABnzbd-4.3.2/tests/data/one_line.sfv0000644000000000000000000000002614625637207016604 0ustar00runnerstaffMy Only File ABCD1234 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2400906 SABnzbd-4.3.2/tests/data/sabnzbd.basic.ini0000644000000000000000000000014214625637207017477 0ustar00runnerstaff__version__ = 19 __encoding__ = utf-8 [misc] api_key = apikey auto_disconnect = 0 api_logging = 0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2399817 SABnzbd-4.3.2/tests/data/rss_feed_test.xml0000644000000000000000000004261314625637207017657 0ustar00runnerstaff Copied from NZBIndex RSS feed - THANK YOU! Copied from NZBIndex RSS feed - THANK YOU! https://nzbindex.nl/ reftestnzb chinese chars in resulting file 2b5683434096 [03/10] - "chinese-chars.par2" yEnc 40656 NZB_URL https://nzbindex.nl/collection/161828561 blablamannetje <blabla@example.com> Wed, 06 Feb 2019 20:53:50 +0000 60116639 alt.binaries.test 88 88 1 10 reftestnzb 100MB auto a1eecce5 2019-02-01 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/160588232 blablamannetje <blabla@example.com> Fri, 01 Feb 2019 10:11:02 +0000 118834743 alt.binaries.test 172 172 1 19 reftestnzb 1000MB auto e780326c 2019-01-28 [33/40] - "mytestpost-1GB.par2" yEnc 47708 NZB_URL https://nzbindex.nl/collection/159737534 blablamannetje <blabla@example.com> Mon, 28 Jan 2019 22:37:32 +0000 1202927128 alt.binaries.test 1678 1678 1 40 reftestnzb 1000MB auto 7fd8cda6 2019-01-28 [01/40] - "mytestpost-1GB.part01.rar" yEnc 34603008 NZB_URL https://nzbindex.nl/collection/159737527 blablamannetje <blabla@example.com> Mon, 28 Jan 2019 22:23:41 +0000 71092581 alt.binaries.test 147 99 0 3 reftestnzb 1000MB auto 60c9ef60 2019-01-28 [01/40] - "mytestpost-1GB.part01.rar" yEnc 34603008 NZB_URL https://nzbindex.nl/collection/159737533 blablamannetje <blabla@example.com> Mon, 28 Jan 2019 22:23:05 +0000 60689177 alt.binaries.test 98 84 0 2 reftestnzb 1000MB auto 8c901413 2019-01-28 [33/40] - "testfile-par2-stuff.par2" yEnc 47580 NZB_URL https://nzbindex.nl/collection/159737531 blablamannetje <blabla@example.com> Mon, 28 Jan 2019 21:51:27 +0000 111105829 alt.binaries.test 157 157 1 8 reftestnzb 1000MB auto 8c901413 2019-01-28 [01/40] - "testfile-1GB.part01.rar" yEnc 34603008 NZB_URL https://nzbindex.nl/collection/159737528 blablamannetje <blabla@example.com> Mon, 28 Jan 2019 21:48:05 +0000 1091705517 alt.binaries.test 1521 1521 1 32 reftestnzb 100MB auto 05a19e3d 2019-01-15 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/156768379 blablamannetje <blabla@example.com> Tue, 15 Jan 2019 10:11:03 +0000 118832821 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 896799d4 2018-12-30 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/151591056 blablamannetje <blabla@example.com> Sat, 29 Dec 2018 23:00:04 +0000 118827085 alt.binaries.test 172 172 1 19 reftestnzb 1000MB nonauto 60d38836 2018-12-26 [102/109] - "mytestpost.par2" yEnc 64436 NZB_URL https://nzbindex.nl/collection/151014889 blablamannetje <blabla@example.com> Wed, 26 Dec 2018 12:40:23 +0000 1175359330 alt.binaries.test 1655 1655 1 109 reftestnzb 100MB auto 480d78a6 2018-12-24 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/150801768 blablamannetje <blabla@example.com> Mon, 24 Dec 2018 20:25:03 +0000 118835884 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 211d6830 2018-12-23 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/150630723 blablamannetje <blabla@example.com> Sun, 23 Dec 2018 20:25:02 +0000 118829928 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 0d34123b 2018-12-22 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/150451690 blablamannetje <blabla@example.com> Sat, 22 Dec 2018 20:25:03 +0000 118843457 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 6bf10e7f 2018-12-21 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/150294775 blablamannetje <blabla@example.com> Fri, 21 Dec 2018 20:25:02 +0000 118841640 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 5b708b33 2018-12-20 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/150087842 blablamannetje <blabla@example.com> Thu, 20 Dec 2018 20:25:02 +0000 118825994 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto bfd71122 2018-12-19 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/149908623 blablamannetje <blabla@example.com> Wed, 19 Dec 2018 20:25:02 +0000 118834202 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 149f9fa2 2018-12-18 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/149733916 blablamannetje <blabla@example.com> Tue, 18 Dec 2018 20:25:02 +0000 118840895 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 096b27ae 2018-12-17 [01/19] - "mytestpost.part01.rar" yEnc 10485760 NZB_URL https://nzbindex.nl/collection/149543121 blablamannetje <blabla@example.com> Mon, 17 Dec 2018 20:25:01 +0000 27889406 alt.binaries.test 45 39 0 3 reftestnzb 100MB auto 1b8e7a3a 2018-12-15 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/149156974 blablamannetje <blabla@example.com> Sat, 15 Dec 2018 20:25:02 +0000 118836902 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 0476e713 2018-12-14 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/148946022 blablamannetje <blabla@example.com> Fri, 14 Dec 2018 20:25:02 +0000 118836626 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 042567b4 2018-12-13 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/148741846 blablamannetje <blabla@example.com> Thu, 13 Dec 2018 20:25:02 +0000 118837115 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto f1045703 2018-12-12 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/148550950 blablamannetje <blabla@example.com> Wed, 12 Dec 2018 20:25:02 +0000 118838924 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 3dce88a4 2018-12-09 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/148052768 blablamannetje <blabla@example.com> Sun, 09 Dec 2018 20:25:02 +0000 118836927 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto ad224e8d 2018-12-08 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/147882265 blablamannetje <blabla@example.com> Sat, 08 Dec 2018 20:25:02 +0000 118841369 alt.binaries.test 172 172 1 19 reftestnzb 100MB auto 46e46fd3 2018-12-07 [12/19] - "mytestpost.par2" yEnc 42648 NZB_URL https://nzbindex.nl/collection/147702961 blablamannetje <blabla@example.com> Fri, 07 Dec 2018 20:25:02 +0000 118836479 alt.binaries.test 172 172 1 19 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.444778 SABnzbd-4.3.2/tests/data/generate_test_data.sh0000644000000000000000000000152114625637243020453 0ustar00runnerstaff#!/bin/sh # Generate data sets for test_functional_downloads FILENAME="My_Test_Download.bin" # a non-obfuscated filename: capitals and spaces fallocate -l100k $FILENAME rar a basic_rar5/testfile $FILENAME rm test_zip/* zip test_zip/testfile.zip $FILENAME rm test_7zip/* 7z a test_7zip/testfile.7z $FILENAME rar a -psecret test_passworded\{\{secret\}\}/passworded-file $FILENAME rm $FILENAME FILENAME100k="My_Test_Download.bin" cd obfuscated_single_rar_set rm * fallocate -l100k $FILENAME100k rar a postfile -v15k -m0 $FILENAME100k for FILE in *rar ; do mv $FILE `uuidgen` ; done rm $FILENAME100k cd .. UNICODE_FILENAME="我喜欢编程_My_Test_Download.bin" cd unicode_rar rm * fallocate -l100k $UNICODE_FILENAME rar a 我喜欢编程 -v20k -m0 $UNICODE_FILENAME par2 create -r10 -n7 我喜欢编程 *rar rm $UNICODE_FILENAME cd .. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.230956 SABnzbd-4.3.2/tests/data/good_sfv_unicode.sfv0000644000000000000000000000070514625637207020334 0ustar00runnerstaff; Generated by cksfv v1.3.14 on 2020-05-25 at 17:49.33 ; Project web site: http://www.iki.fi/shd/foss/cksfv/ ; ; 10485760 17:47.45 2020-05-25 normalascanbe.bin ; 10485760 17:44.36 2020-05-25 schöne_Türen_öffnen ; 10485760 17:44.05 2020-05-25 this is a file with spaces ; 10485760 17:47.30 2020-05-25 你好世界 normalascanbe.bin 681718CC schöne_Türen_öffnen 788E9541 this is a file with spaces 24041228 你好世界 78938E11 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.240177 SABnzbd-4.3.2/tests/data/sabnzbd.sorting.ini0000644000000000000000000000052414625637207020107 0ustar00runnerstaff__version__ = 19 __encoding__ = utf-8 [misc] api_key = apikey auto_disconnect = 0 api_logging = 0 enable_tv_sorting = 1 tv_sort_string = %dn/%s.n.S%0sE%0e.%ext tv_categories = *, episode_rename_limit = 42 enable_movie_sorting = 1 movie_sort_string = %dn/Movie.%ext movie_categories = *, movie_rename_limit = 42 movie_sort_extra = "_DVD_%1" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.239855 SABnzbd-4.3.2/tests/data/random.bin0000644000000000000000000001200014625637207016241 0ustar00runnerstaffBb hr T+N}.\ &mo o_֪G7irWykRLʗ:Hr*]0E`bNnvx tN֚j?8UK,<_ .YP$jZO]k|WžJU̟vh;溺yRR_.cњa}E$׿vʊj ]V$`ŊɈl1/bl`9J#¼Au :c܎iqx5]~yU_r4Tjϋ+̲=4@P-3eLM-{!7ҡ0|LfZyK,ڟ#}m8H07JioJhBh/(otWAMC[&P3duoTBu,OեA~1 >b,CBͮeb%fSQ><B[O_a<`dϿ%U|A(*̛!߉&]sC"G=ymse{Vl:/JYܬoۦ'>MMǡu8ea<YmdJ Vדs8?pE.s9,XS,a00EUz:ZD5Z)vӱP kyi7{0C -gNKo ,XOoav7)(hO_]}u!Ts< rY3Bk1MAqJXCDp'(Ӡ\E/yͰ ;Lb?P0P"mܥ\hXDk)2cRIG4)b7*ܓ''EjqP5WP]7ϣkD AaRfBLnY MS3RN@ k`-6B:m"Z7JCMܺEUxc'?F(, p qս]m%sKa,p;M(6ݚr>X>rdm!nGO_~rDp]ZELAt6չ:1e P FHV Fp 9t(0Pzԩ/d  iX%x O@'` DaH(GP B/y@q甽E&`4/0Md+vÃ̈́רˆM΅tG/;@%r1װ#xz>磢4y鵁Vv]gxX &gvaGv|l ϣà 6'J#MۈMu|p^\zbNԁTTpU ` Lq~ݟ}awt{}S顦i@KXB?w(1Az?~6Kfzk+:>sZ‘څ7l33T4ɬe7wDzDQW|CH3B|Zpn"[vݔԋF]NeQYȲl\T;<#תߜWG+8US)fgi-xNs-]N9:zLl/3֣P=li)RxC٧4^O5dQ1ݿ6o?FR@Q$MzdwC,}"DZ}ڙ&WHh@[0go1՛t{m1.3AcMʼnC$hJ +3Oϋ-&c'x( y!9.>'d+6R"im/i7Y۹ GJ4U|e/*v AlIG\sEF.\b.3}KN&6a 83؉K^n,y{( $@EQD]&B]XJBW 3S1sj8?-id:}E },dШzZ+G5>@_@sXĀ'oWTWTLftZb/<bB>NdOp'<^5!y{,U#h;ic.,=s){'-6h Fc)R/'0Ύn74[鉷0B)ЄW1(k7ksKd8S %1\MߘhD[>^\g,I(b"F 9ʄ]ِ[aC"C?9MWw5@$JTh#IngEN^,CrJdd$s Hˌn fgw yQ~:vB}ˆvM$eB1^G$K"J'f(ↈ(~E{M!<\7%-[h蓝$ֲ,S$G~86sXcEZ:>G`XəL@Q/-182fbIdeSZc&Fe~vAJWj<ʪ3cdB4߬5X;㝣iN{|\l[*_`/™*yy5}oqD&3?Rhcm8j=/EK7ԴR*S0z{q*F:;FY~(44qGDjؙ7 o=8$ KGJiž>#+r==LLŶ\8ٛRHRNNs\ FPƸEYeQ1]fCМZky$ DXޒ7r YCm‘$/-} $+:zR`-!6kk=%:/)w)hb鮸s4rX̄5:IyrE*ƿQv$p*iP՚"<_m(ÒΏ0 ,=̇6ZEIls9znH v珐tcGg](jX4o~m8M⠉е}Wp\i`+Pɤt9,yGڅI=,L֪O*,LAّuGcdT! 9 g g6! Ly%- to?TPCf0#Ryn*ϯ=vG{l:@xP(2~Zt6[᳇El[@#_8-WV*. n]D㵸kyrr❲DM-˨ۮY8?P&7-Ϭf `[/hҚ稳16`K?{CHо$~e&yls$^ SaUfu[ҹ7#fGO<|PfWԦ(<EX<">:Yg0]Qtwlt3:f;Tz!Gƕ9x$duA #-VwM<Ig€dK53 ÄP|D!)]@ Saײڡ W^*剤HAtch1v0HQқګtkQ(> fٛPCQt{4JtThS(jDK |A #: G  >2 En|,1 / kDÊ .m[}m8šw~-yidЫLYERh7t`D%t\EM{HQyDP]TT,Ul AH/S\hD6 W}w~iQ`=#<<kMJI&l9߂ד)s K 7=/):;-Xeh9'JC1'( lSN-V.a +'lz@bbe3'w[C_t~n,[2UPAR 2.0FileDescs;@7u^0Lf#N2 #N2 random.binPAR2PKTdMsPs3~n,[2UPAR 2.0IFSCs;@7u^0LfKZP ¬4a)]PAR2PKT\;?jYϔIߝ~n,[2UPAR 2.0Mains;@7u^0LfPAR2PKTL~=Xb]Oa ~n,[2UPAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2292106 SABnzbd-4.3.2/tests/data/deobfuscate_filenames/E0CcYdGDFbeCAsT3LoID0000644000000000000000000001200014625637207023666 0ustar00runnerstaffBb hr T+N}.\ &mo o_֪G7irWykRLʗ:Hr*]0E`bNnvx tN֚j?8UK,<_ .YP$jZO]k|WžJU̟vh;溺yRR_.cњa}E$׿vʊj ]V$`ŊɈl1/bl`9J#¼Au :c܎iqx5]~yU_r4Tjϋ+̲=4@P-3eLM-{!7ҡ0|LfZyK,ڟ#}m8H07JioJhBh/(otWAMC[&P3duoTBu,OեA~1 >b,CBͮeb%fSQ><B[O_a<`dϿ%U|A(*̛!߉&]sC"G=ymse{Vl:/JYܬoۦ'>MMǡu8ea<YmdJ Vדs8?pE.s9,XS,a00EUz:ZD5Z)vӱP kyi7{0C -gNKo ,XOoav7)(hO_]}u!Ts< rY3Bk1MAqJXCDp'(Ӡ\E/yͰ ;Lb?P0P"mܥ\hXDk)2cRIG4)b7*ܓ''EjqP5WP]7ϣkD AaRfBLnY MS3RN@ k`-6B:m"Z7JCMܺEUxc'?F(, p qս]m%sKa,p;M(6ݚr>X>rdm!nGO_~rDp]ZELAt6չ:1e P FHV Fp 9t(0Pzԩ/d  iX%x O@'` DaH(GP B/y@q甽E&`4/0Md+vÃ̈́רˆM΅tG/;@%r1װ#xz>磢4y鵁Vv]gxX &gvaGv|l ϣà 6'J#MۈMu|p^\zbNԁTTpU ` Lq~ݟ}awt{}S顦i@KXB?w(1Az?~6Kfzk+:>sZ‘څ7l33T4ɬe7wDzDQW|CH3B|Zpn"[vݔԋF]NeQYȲl\T;<#תߜWG+8US)fgi-xNs-]N9:zLl/3֣P=li)RxC٧4^O5dQ1ݿ6o?FR@Q$MzdwC,}"DZ}ڙ&WHh@[0go1՛t{m1.3AcMʼnC$hJ +3Oϋ-&c'x( y!9.>'d+6R"im/i7Y۹ GJ4U|e/*v AlIG\sEF.\b.3}KN&6a 83؉K^n,y{( $@EQD]&B]XJBW 3S1sj8?-id:}E },dШzZ+G5>@_@sXĀ'oWTWTLftZb/<bB>NdOp'<^5!y{,U#h;ic.,=s){'-6h Fc)R/'0Ύn74[鉷0B)ЄW1(k7ksKd8S %1\MߘhD[>^\g,I(b"F 9ʄ]ِ[aC"C?9MWw5@$JTh#IngEN^,CrJdd$s Hˌn fgw yQ~:vB}ˆvM$eB1^G$K"J'f(ↈ(~E{M!<\7%-[h蓝$ֲ,S$G~86sXcEZ:>G`XəL@Q/-182fbIdeSZc&Fe~vAJWj<ʪ3cdB4߬5X;㝣iN{|\l[*_`/™*yy5}oqD&3?Rhcm8j=/EK7ԴR*S0z{q*F:;FY~(44qGDjؙ7 o=8$ KGJiž>#+r==LLŶ\8ٛRHRNNs\ FPƸEYeQ1]fCМZky$ DXޒ7r YCm‘$/-} $+:zR`-!6kk=%:/)w)hb鮸s4rX̄5:IyrE*ƿQv$p*iP՚"<_m(ÒΏ0 ,=̇6ZEIls9znH v珐tcGg](jX4o~m8M⠉е}Wp\i`+Pɤt9,yGڅI=,L֪O*,LAّuGcdT! 9 g g6! Ly%- to?TPCf0#Ryn*ϯ=vG{l:@xP(2~Zt6[᳇El[@#_8-WV*. n]D㵸kyrr❲DM-˨ۮY8?P&7-Ϭf `[/hҚ稳16`K?{CHо$~e&yls$^ SaUfu[ҹ7#fGO<|PfWԦ(<EX<">:Yg0]Qtwlt3:f;Tz!Gƕ9x$duA #-VwM<Ig€dK53 ÄP|D!)]@ Saײڡ W^*剤HAtch1v0HQқګtkQ(> fٛPCQt{4JtThS(jDK |A #: G  >2 En|,1 / kDÊ .m[}m8šw~-yidЫLYERh7t`D%t\EM{HQyDP]TT,Ul AH/S\hD6 W}w~iQ`=#<<kMJI&l9߂ד)s K 7=/):;-Xeh9'JC1'( lSN-V.a +'lz@bbe3'w[CHr9aQ(棆/:<K~ɊM/ #SYuw jtId\Sػ) [ !!  aJ +My_Test_Download.bin jRT ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2314117 SABnzbd-4.3.2/tests/data/obfuscated_but_no_rar/bf641bb5-d0d2-4914-8418-fb13d5c3a6850000644000000000000000000002400014625637207025325 0ustar00runnerstaffN,"9[ l Krح#&z}0_LBh:gqmZΈ\* 6aP[cbH[POV-mXkU*vuõ4W7IPYB|yH]KFAY狣i"o,ǭm.YBMx> ÞP35p7p*fLĐQ`kg :=~&pGJTCOo߲|.c5wK¾}1;FZ# |o]Aɣ$DZNkWRHIOukqRU!x׹մ_' WiGgϲnYs#crS PLe;arͩd#h\(ʖUkA1|; 1>!,|Kglu |]0|qt)3ySsC|"?|;:J$k 'ߥ䙘>C6w_ZI z[Dq3pl,Us'IYCxH~ۗnM:`oW=n @k&cV~'GTg܌Vrڥ4|^ ZU:E$cJmjeu9F~)2x2NQzȪ8vS8\"/$jĵX|Rsـۣ<"ٱTeP++) @\4`uuG1IJyxz衧* yE(ʍ嵷4Hy3k˘5Aj(X 0㵿Zda}yɸ ?Aq.L Tm.ـ@.-VCYlr{d J)?o(+g؀"@@ eOf6wPD0Oan1F_޽1F5Y='%o#1V/1}e75[L Y}QŸ) ~ [5P1YAR2NS0<͞#}.w+lKzJۆ;0>_z_ܜ̈́Y HB$H;cQct mf2QĶX7]^Y{K+/vV~nP+Ax?6ᗯqa]+ `%ۍg v ID t1 uD@EC?Y*"v-ח8[sow@q$ QԨ! DtϴW{*vz5ajIl cдR,QwZưmx[shOyI'(ě_VO/y'(^_mHr{[f.$<-CCOFWnnD:K?>v lR9 .uMU9 iK,ES*A 7p0WcHϬ!UH.~ʨ^l/2Xe>Zpg*\elsC菊[_T:w7TkWUX5p 5CSTjR z6fAJU[z0zk>jLA~jTSx$mhK7a`DxPLPy)G C[O(Zear)HgZtT.T! e#8܋Mh7 OBI|'<|"`̄zyro1"@ ɵ#ItR(3E!孓5Hx`Qs`O{XpXbΗXUxKÙLz\R>#JVtG&`24jF߄HAwZ޺":h19Z]POdkXѓ ;u{L3䂣-!LM<:8^@s}KgC $X(|:Ed?mvQ=XoNWOE Ws|pT9ܑ߭t z-"d 09ߦLU#@r=1Q\c=qf>vˤ$LZ?0<>% v-PcQu]{RFf5yE.Ԅ1E?A*ON . km_pIʝz# rIu}t#1xUJe$j%Q]eXc1@Yb)O1 $r)z55]o nMQmr –2l&q }'hQg. Q{y0<mYx)Q);Pewips{%(Z=^u맒0.D 1B̸:Xkz΍Ycv7yɻ V'Chp$)l)z]p`ozbT;/7BP1;".c9 "!1lb)tB+k#;҃ dSCJ B-뀩yhe m܀wdj/Dod+(_#uhҁw SDd.2s^Gʚ/E]}^ygJA.MSgSoxrt{9 s'Z1}VSQ׻Lv01HW8d3 DwAccz⤟q ;H E&mNX p `Qx[R1/"uLԯ8)ϙFL_AP'F^rf s9t|YuVtRAIuݼDX~W`kY19-qKbEXn${b͚dÝ!M]>Slف!s_W2F3/uGxh+^X.BYbD!#%vEϡjաn*j aƠ-Z)H,¢D5_<{'\QLjJ}j2(ӷ7ݕ X.5(zׯuRs#*/kSoӭk÷߂,PT5v0\ =@vQZyt7+f0:qh5SoeO<'x5'B!j<WWe&D@@ %] _Iam%nXM*c1qHM$eM97o@mj|Ң[^e[CdrbrOF$R;:2Q}\"x N%_X3βeտJ{qI$>I6mQ7Diۯ' qGHY#/E -\fX*|VgB:pt{!x )!\ K_t+-+JyviC+,l =D*ȿQmBH6t}Sh^?W0z|3H K*nOp6毖UigP8q=-]w+ik^r'SZ+cEVԃj` &R;]sу71V.|܏R_yWL]M6 KJ?^sQq%ڛkd}ޞk2UҝO::`i'Wo!+w(Ecyo6D'q\d2H1߽u+3|GƤJB|~,͚LAr抴5#]qG?ӄ{0!Pv q51wET :nr] G8sρk=-EPZ5fT x7"X_^#B}]Q7T2ElqkYeڬ vAg \_ !PP!I?''6e!Xzf?)7:-65t?5Cl.]'=)qɽܩK{TȝJ"z3=ct>,%ژ<'Sx׊w(6+d\}S ;!JӸ`'p Ϻ/@O&f-M֓8kCC.vb9`}SS>”7$\N˟; Q,riBA4PD@/.ZxͲ RJ1v`@^Ik-$o]oGW +YPOQO9NnPⰠaC.֟Q3WWL$ؾpkIͱm3ZŻd$İJ›dߋN(v} <ӗ/{Es;!.o>@452v A޼ȫ6RC);Iiڮxa7P 7`6fjn^ei9H %OSBsk[hK4,ulS!mVF~`[2I;+#Ua[@Q&o5߭KCP{h߷(4G]Ό3~ Vdt@"^#0C~FX끥Fzd.XLrv0YKL2CEe R&2[N+o "5ua;JzI[3>1Ed oqE) Fk]c<)}M%5.aQrapY4B77ƹX3JGٱ;DK7XЀsp/+t_#i# Z׍ ӲwF@K!䧺!ܾF.tuX^}F2n:q1%,Fzl-6[Xwf!дB̋:&tٜtJ⬢Vʌ9f_I&з!C~ @$J>e?QiOWvs/ў;UŤ#5w(ZlOHBtͧ -  Q>ܠG٢]m_SH@c+zvOEL j>EatsN?FVyѶ( ٮ(Íͺz7GiN>+8' W.ի5ajiU[}!U]ɦ*8K˜Hub`m#XPMLj1\s^OyT G쐹0+ka&~ȕ?U Oaفs!/*ϭkp@a}=`eȕ} a3BZ租,`B'"'.|^6n5JLw_ID҄9D)OЭ{=ab& WK =Uy},c"٢K=eq f5t=hc^Yl\q߼gQ$lCYzk MͫpC0N %z=R7B:U(n*n,+4%/PKi0#Vò]2CuQ }sbdU(C`pKֈ_cX%ޭܮO lq!bY<傝9ȑ˦F' A0Vk !K1_] x5i,jpK-7~,"1- (zi1B0xia-_o&`pSoci!,os3nb ̾$+f͉[e$J[)0zsW#_phR V28,<k>Gft]&_*l7:<,jsQ-LޗŶy)_p]}2u9ot~ZBEKsU6B4:aBgI]N.|ˡCc,||Mt>@0R$܆X Lj}Aᬽ6zXyh*{Y0qsAVBq Wղ+o-dki%#]-=FxbԆIP/b69:nun! MG uC gnnv. V xNpd3W͜T8!J(Ţ46` -.CĭenNcm%.8jW(Q_ސHq7C;6OֱL.RCXsKTE_3 Vv2fCsG갲S{=Lk~waLZ9P(!d̏h5TۛJ ~eK."fc6rKSvh!?ۧ ph$ {s UG(XA K.'G]݌lE,MZ/>G$1Ā-l :rуs2:ˢ`H3]f&9#bNE_ZauEd/#h7l0y?ebdRv././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.231064 SABnzbd-4.3.2/tests/data/obfuscated_but_no_rar/39cec468-cebc-411d-8494-ccb0c5b2158e0000644000000000000000000002400014625637207025551 0ustar00runnerstaffqH[fR/hqP顀-6zG/tNd-z-/Q^b$tCy_B$"M vNo5~aNωqՌyP㟎ӍCJZK+o6O\j?=Mm(XߌR4ܧ, ,ڽѿ gGC4(ƹq-Dpھ[ RWKsBƠ#Fݗ8gG(>4jr5. y ,zc`I<\A}cq[\2iQo!o_=\jcj>:Y?0Ý'\3 q?0 w@ZPklk=Zeq5+9O_3qx4*nYv CדOl+a^Zu#}|}^ϫoIAծԝN-gl9?ׄF]-H T qFg?Կ=>b5?b8$7j˄F6H/o$ (sH FҬ]βu`YPp%ح2!AeVOrůأp΃A^?PBGZlgr.#p[hHTe~hi f媜Gkaw`b 3SiDֽ*Kds/P kտV.;.񜲻]o\bHTyvA_j-p-#bOQd.~xv_Y7u,2s sPENTz&DPpc7֪9no#k\k[\!:#cVj5Ji(] 'w?Ýѵܮԡ/9Դ>>q-(en=u ? $G*I貯בA ~b[#y Y&2 (_$}u)IiE-Emeߦqj; 6_84f{>N~t=nj)@z=UjEX*wĚ @E> PhvpTϧ7@qrhp_9b&"`MjFj k`9Y\#VSy'MPxo n̨g+m4k~>VAA=ޭܪ:j-VQf$i+)_E3>aai`콄+>YƧ W@U뼗  ?5ezB HY~`+LM_=&acz_-~gv0\bH)d{SBp3Be\Tvq_Fp+l !&T#̫U6(sF]!P3(Ie.1_\οE&ޱEH`G{]/wu'9!XLUtXy7V.#dO4w%ꩊl gl[UBd jj\8pG o*fґliჱ芻;+)|x1@RνY)p(g['(|!6BZb&6j~n׸i!}M=룀F1ÜWɚꏽrn :N%˽԰L`O4rRx9d!hW5AP&uf3ND:HATMGR)#EEM~Bi 9-J@fs9N#$[)TmdnC:%7ǚ(҈IL[Yy:7}!T1:J1Z^JP#{[)wwδW!QrfKD>2HvyA/tc`cŴR2֫?G=TWgt7r}W YhaKqXYb4]>1)v47o3*ՓE|( I-q?:\L r7)n YuZ4Vjd7sEP]<-em"=bb F 9)F`;oR=3ғ_'$WI,/y[:6 r19~KT_dmRzGVtzܶ%ɠnVQg80UK%N^yg3JCs>^={_bK Zɖ?6` ݯ^u3Koh^ Xfd7y=2%{'nKIA.%"V؍YsGa^F@yML :2>~97 B \S.IyZ/C{0$#<a*HȫjlYl8,gH…`kiƽ*|D9/#3D3[6%8/aɿc m(< m?I\e)hhEav֤O=F [U?P0L?ao'Wv$g$`Mzͣq<2 [։?9 |D&΂zT5oO\Qj&i7)fxJ7ދ.O"DB}^Pۇ# _9@k*UO!1VQsAyU(}Vr}s);@d}ö3#@ο}yc# yy麡~$[oj*)1Gl9KM]Ǹ  :(g1)T~s J6ݜ+qGՙh4='9ѯ)a(%JZ'S"h%Ja/Rdy)GYPl#]k٭sarcslxm5v3- c 0&ʞ0j 6\{gMjV, DFS27+|DA^諭vv+F&km,ͪ`U DIڥ-@RkuHM3i%,0<)i&o%7!'j;Z"jOE6׀2 hCnٱAqdUrC;XS]]ɀ;2.adI[S1 /,9I;)3i{jݜ"y$!թ;D.ـc60BuЌq1V>#(fzlaT&:߇ -s߷i7iQZbvMA֩Ƿuqdh0g1h5'Yݐ6)D=1"\+ v*fF7KQ4[\cWnH^o. %}QU߫Pv{M}=-v#|Ϫ1yѰQ9JT ?a# 8!o`pK>*Z≠47oO{˫!!G#U֎6Po6>kp v,VTuqBS_.E3X@|l2E$L!ӡpcMgo*/x;/iqW-ׄڒm @i[NGGM}=&&E{-^U>CFCa>V#8[L9[SC<xU9i/r`O @&kZZ.ZˌR@4³:(;}-]hWN_fR wk{dYg+Oބ^@4OﯗeHϠv h0hvsilu 1;=ꎏ Vd2FaKUi~1@YNA!I`M~+%2-^~Ȫ p-!j*;- vLGq6s۩St$YĨB @+_%y |qư rݸu7O8ah >HꎄI#ݴ6M7OfIO w(zNL:})3dd,T56?cVV(9\E/ZFTZT `r7s*$a޸*rhM`[Lj#vxr(o$Я*E02=Y2r6>bJ K5j4 !p`#-EQs,[] d(> b3LT+Ke~1ޮ&֕8BsWۅs PыP$rFZ^w'3;[8%Î>;4E A#^8 i0bR:՘;deJhf~#Aoc\#dq}tCQ@' \@>B h0šz62bHt> L2q9>x/&xdHF%/U^KٰW ߈9 ]U~gƶ꼲 >m1ϑzxΈi,Ξ!m= WiH</-ࡕ֢'UBD~A÷fLN3`nhVR=YJw=^UyO K޹%|,;^suԖ8vmYxi~$zyd #ȥu#$?F<fqtrPPCj@G,T[;8 ["k׻-yF K *PnF_r̛U_Skik$/~g ˆia\EM*4VyPZH7NrX*,rgeIxۄKQc!N!Vg2G/VhS4ŪW,)FWc +H^ÞQ#Onxkq7{N$XH. ձ~}QS"뺞sÍ?*ٽXO:Kc +0 B9XXA?KdBha@C\r.!Mn#@) ʯit̘2qؠ+?Cɺ!>%k(dUħOH-S)yi\S^6OƗlQ/Êɏ\&U ;ӤfOb|]pA| k a:Un ;]`c.~;f8.x =dޓ~=ȒS9 *QKd@ӈD(DϗZIeh֪]HFz 蔵!WB[٠hȳ0aꄥȦmlM:Adn*(^? D vWrv\)eҧ|),)Нpi.ۣ Z ғ3|&>!-џ 2U` Wrk7h8$Bvå{ab iPe&Bam< YxiZ9/J/#n IlطMJQ tzmΑ^K4#AsQVv\R|$3LW[t>^25cc=L v4Z(.󅹈NW-6Sq.*|uڰ埠?IxN\l`]tS:]L{^GYJ*[Bmbnq?ʣE5`dk.B$Q}nw#;3jϤs?C2&N,QJSDt I(_n/yw-/II+Y \.;y`6`#RQa,?妙l|1>XF\m|?֟]w$9lfFD~ >5$b* e~锋qx%gg/ʶ7K^i +pEdmUEM$6En ezK*`Xv<0d}=n<^K#PA}sز{V{S-m zЌ3A!AV.!}ד60yQÀj\t٣{K7J|YЙd+]Orq'Bb4% NKMp÷&YTDo"mC5f+l݂~f\c%vRXPy]gi@V }vƎBtyUT-ljI&aqn\1PV|fN+퉵+$jZ|!2וdrtMAK1r`S16VP"M'hbvtq`AuWK+ KDHp hBIOmi/4{V/ӈz\8z\Vׂ} m:ݻ"v?sAU ]@}J1aj ͬ)=+$Yki ڔt_{8"kUՒ%l:As2<ـg޸4]珻06Q_zQRq(+e)!rR+ H\V\aONdf't"zRY1UGq܏*_~<Al_k]T&-_#֭SxY ͛!)'d|֧ "'hL1ђzb L 6H r7ֿ@UL$"Q$:?$o tfKPra$$`Q3z1p}p>%Q<=lYxس0ÿ kTjϝ`]+=/1" рr_ܘ(XA)o~a>z1ΣBSgF=KF.ͽCP1h-*Ry!i {S?7V.h?Fhq_5B Je>+oF/!ZР+k/ \tAL"l?joSHD;qU;d}!^Q.$MLDǭk"a6v/[l'zQN!U3!Ac&vϰ<)5Ezcs*1#) iܦs=`DiAZ,n n8Ͳ @-_WHVjN,T!pVw&OBWp_ w8NvS4;2`+$JFp&#S~&iɜ%e ^2QOzX-]PoRVG\PoP#lښi%7oƖv>ؚ8  ᄼy;t[L1 nE{>(.}pveD Jx# -jCl! 7j[::Ԫ"NQǐEdO܇W/(^i/ڕCAe1j)KԐ/ʉ=e_#C4;= ۏ#yF4/:wABmʓc+)]_^Pph()4N祚ϞWC?)ic|˼4NR5nHY#N[44/xff>cIgE@1Ǣ-ЍwX-פfh1 Hd[NГH?,G-6 B*+[;I/~{bYxYR̜ g C}M84(PގV`jTԂ!x䟸x'y$M:f S<܏ȜJB+[`iBϖ;Ze:ýWw?ފͅ[QV'uLtOU1f^z<-@{eW$f&m+E.LK:E&Na#.LC.?G ND icO LQ 4v>NGE01÷²qL&%>R+ht)C`)a%}Au85xFW|k[ zF.X"T>CL$cCarzD:,.f<7 e.gG!sMh CR轗FQA__˿o3w<$s[/l&!72U5.%DS&GbֈdnL!&vkˀ,?6R4/XF@h`: ,p1h8=Z\",/UvӐţpZ9q#&{ܯQyi8>x`E3>xqfG$ڷR8(HhkmU`֥*/"\8@_xo%jZ~h66,9-B;Ei vxὕEg;`L] zZİ0C%s*88492Rׇ߬jYt]8u^-$hڼ(>p!QrW2{-CnOi`m_,(]$&d2Fw/9T!(2i]EjIlIW]eLrn8=R/ȏ D 1;4w?n ݰG ap[O02ДTak}丐\,8Ճϭ2_SM滖s_vC916NF7޲#-X&ص#.s yƯ\|vR}Hŏ.mu`\y0nZGPmYuS@Q"x(/ٶA~` TsGm:"Wƀt?eg*Hynz(`-bzӅ+O/";St j% [t[d!ɁP̭?g.?&&4Q0jp?ptIdҝ1[hghk7fDn(ԏ#z8?o Fr( zvq1!2~kmK>wƔ.lEi#mK6䩆m`En=G~ә;Vx'wr~!A 89.wk;˦y荬r7p`Nn'V):i1;t酙~|.*rG7$6u>Igﵕ8茭=^x.\:μp-P[H]ď+ "!}| wz-lB,)9W%}t1~-2N Hf垚G>f+8|(U^s[:?7sܧP0jaP

v9_5[NiN^Rg)z vQCQ[4'8Wnm6إy2sT%¾ )֞t"qVCbDik#?܈ef>b1VW2_ʼE5pmqLʚFy:8G2 &rwqUHjx)O#( ʼ:[Ǧ%_^a09g e6lN9n柭PfU.xLc6|Q l9"f/S8#|BY(Q}'g2HEOæI8 ;FG-`y"*W_]Y'-2.dzP8ai!Utlno9sX֫) :΃#1{?zT6܉ڒ弒+^0tE%߯k: Gp%6#ĕ RHaIJfuԹu‚J}B+sIiKU@j,poW]SA, W: ֮юqfIƶp. Yi9nXBv@(n3h7eJ\5q INsī3+Dea!=pXXu ^z:Bј}811٭'ᰕgs}EVruAkMR|]&ȫ!2*9q'Sܠ長xKK2x.Z+NU[[|ou1%I `XUЉ<9W~l6 +)#>'B!Ʋu !ꅊt TAq}c2gGB0XW+@_k$W4br1;2Zd2 E?6=C5 ]}nh䙕%È3rr(܀0­D+CN5ooDp*7k:O F-Ar4@YA.T;o菿U1cDq6Tv$eqv^]mV14QL%NĭMRU=el*~ļG _HX6!n^*j'(~7sIAAimc3nVku+P}pvػZ- ký |;9{ ]&?cD܈*NxJn)4"[DCg_~I"K:ic3ǸoкgE*fvύ~uO^m2 jhՀ.2ys,'d;Aܵz]:}޸AvNY%VYEt?;V)6u㚶SP՚̾fOCbq>1L':mQC$ qbgQ01`q 6]֟R9;i9@VD5m дH V'Zo \_yCbϧ$Ti,qw(Hi:O(9rзT&Lh_m!sSp<;0{}c Z5ҴV}W}dvOc|տgHG'%a~<K"׷GpI)(qFրNt1.)?#fOQkEPȟLf0:;=M7:ҊK^iʧvNd"c0渖#m zE9?F&k$fI.uUsHy}8 tᖲֺJ)5ԚzHRpJK__N7ʜD%1_לRʐ[F{“ef@ ,}A_GHrk?V7b(n  @94ELg'9P_?NAlyjtɾ!TlyJ|޴݈U.KƋť r/O#6k.[^SW5Ҳͯ? fHC;P庣2*2m2MҜZNDNsb'mgMtX\nXvMN_fYQN 9NwŻJ\Cg)S%`R\Eu7Kxa޴Z_fFPX*;qkV&ȫx Q$6T(XJoFFҀƥ:'HO:D^ {eV !LP!6A3N^VhBKeS3Yz5N_2Xyt$v<5@*N@lDaNTfg&WjJHݥ3+m#zMZWN~b gXмE~kmߒ'_ٌ-j Lv\*)CISR/FjwH?w$9W { .5?pi+  AVҖjK|yʝ=`zȆ(:q$8SJ=y6}gNQDSPbSqZk2 [#;F4uO~Rl{*1c4KRw^\CuQ'fyYgwF4i-=%:tԨ]11fGk[m ku}XHVҩ l𻺩 A}&ygD}r :tj#Gêe$u(H kF=Xm{hah*"J^PvR#u9J;?o>b_'Ne[>Mvޚ*IWa!G6:9?y1N hJ?ȸwF6&Y2A+p8#JS׳ (*e}5Q Xf]œWbtd@, 8T˽tD&eCXPq:w_qv}×^t1CŬi>E%{5AHvD,: 3Wz s \D/޾g87 ys^$A  kiտD Fo2UqJFmfqag^s0TT(g*rjFA_f8;Kos`?um3F^k>ڐѶ(3P?rD!B/wn?[ՓЦnt^2ECS˟LjAPD|BJ4GrP耊X7B}ΡrOghOĎ谐AznƑr]<Є(l+臕'6"܈>̒L- "HiCSI~Ҡ.9.V}QCݍ.HW J &vR?nw. :_E\] L&|*qGXm \XǨ6*M!V4tHx:\{V:dY( t "Cc*&b|VMpHS:|,m&5mrOPEe\ jg< {TfYHQ&?LmEJ29hA#wc (RI)S;%a96e\`=k_ͯ^^J^rvAJ tv02JyNqk=KO2! ˤۢJݻ,{ **7"ˆ'E}BQj-7&ΗŘȚ@b+o5|).vC`۹~tnn&><5(if7zҢ*aoE|>xl"_H}2-6,ܳv@N8O]w3׆-@M [I iWS,+zǁq_ba:ƒ#C93D2ś~j|[ H9篣KlwWV1Prpoh!"*ㅔ֒AJ4-%&Cs#)Ólǘ(wUu`Gh)$;by1_ bm<@wT47odZc/rҫFY_8L8XJÈA$+]| 62$ :7}Iɣo9ϲm~T"a)6RA7_,똬B\Q%- p|CU/r)zcڧՌ[$lzr]I Ep:vN)x;櫛LtT-``=L IS x 7J3&MG!OkgV/"ɚCr@@uP2DoXo0,uv=4^<@?x(6]e})f@rNmNyjG@0AT2>W 3̓Pv8-0F貇f Ai*hi/y8b3ɠ<ѤBbrFtKY{@_V~*A>Vsށ6 H)wi_[xZBlψ+֖q@czQmq(K{қLь3o(YQ\;ebOf3UpV>pO/-^GYA JЌxK2x V gDy+pujJg8W mu`<>.['Cņ1*1$֯@t$Xg8g*W]ܰL~#.:N)? }CALQPj>wϹvbb-"'LS"$ko{1YWnp.a50JvD9%^*1Yl&xW0,V3NW1!Ș-ღN], HD/:I,'gD014\OنT{I?bwu2^onyXT5n.*mbX?Ŀn߼62*juc'HwZbE9 ;(*iNN -7 7k\i>C & 6$c5aI(=EQXۏU_&y@GY/ R҅N{mq(=[5$N 'Iʭ"02C`ʹ{ez-̨jHE}x<$) 5龳W%\ڶv/?UYZjQ.sqۤ r.$:7yfijC3?MGWps<ćՊP ր(a/oQkwU-?$jR̅@tu)qZ49^צ,g6ܶdH k- @I6+%9ھO#7W8C|ˈ\!nUE^*MYU; );"I?pRj9>"/5(\y+MKE=Y 9\D:n!l]*8)Ndt eN]V|yp[4FbۉC 4kkmÁ&B^UU'FGޫy.h e$%`m@g]]-DF'ߍGEN3ջJ> ^zaON۶9MrvMms" ˰+P+Yb>B9F~tMNK 'WAM7XNԟ(E7q +qE:@sU21ʋeg2TO0]&hADFB=쭞Qo01Y{X2W҅$QU([RYR2Bw 1ì$jup Ls5pX" 7ĹgCV%7ܬ( J^aū\#E$ 9lhkKNSoPC h}%PkoJ1 Vz$. G,l14@{äw5 RD{g. f&bpͬEGBݔ۰;[F>,ڍ1`(#2-SC( ?%8}:qT?am,l/vD#_OAݏ6Z>r-[T[,9B_XHmD(w)gAv"bUsNh&cXo5xUZYxcqv1"Ogc{< fE">'ʣWt&I_Le{4tA%p3Z O~zX^ Q{d3;V[m{<<ni/0LY.9:Nfl詮pYA/J +%$x/&ǬF>R&U ڧ94uZ[0l nEͿEgOOї]~F,c&EA/d<)>sh =eC 9WԬX}b_m8LP NV8bXlɝcC 0R$ 9Lnk0/‡H`././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2312043 SABnzbd-4.3.2/tests/data/obfuscated_but_no_rar/71287e2e-988a-4f8b-8fb2-5b1a23d1e89b0000644000000000000000000002400014625637207025431 0ustar00runnerstaffc^VH1-\[#GH'T!TץI 9*/8O&fa? w[ĈW[ ~"zSB4RC[ |\sZh[W$-f[7qt\6H/~]D;]@P9GIor0bO$+a]Pt@נ5Œ]Z$b+xzqM|Ϋ wBζy݀hQ.z2*Pk#H o0IՂ@P.kLcis)HOpqgN Sb! Q6YMjQro^.c ,7{Q%+ UK'D1_S| - >uS! Wf@H kvls'ܐ2;^JBY5 :nN!qUxm!W5&Y)c'+NV`5"jƻ^?O\ү: CjZEʈ\㡞Y^[6,m'd$ws1'gO"6aS\f?p൥H(&~nLkÐwL^;XdбITӌERҘ'8oG Jq齈ݮ2h4`N}ʕ,-'Bfh&QOT5H# LUOV zH_`U J؀rxNdӚfEibZ2eiۛ,Ts4MՈoK-1<_*>S?ZG2:x҄$gMմ02lαeS`aW)hAc=msxγ.F?nq+U Q2a"_#িR`~y 5;;rx鷭?/O= 7BmDVNVEP˺#+, hf"|EȘ^ K'8]wedg>fՐ|N/Fs@Ha#E7О *a$:2.8ij@W;J-a|wlI=Z-yNRߦ3⪸۹k9 '<tCɑ3}[ z7ƚV]AM-.|^bLhz;)4CU +>cmF5.PrpWZI ǔ[]*]e#Ȅs+dF+0 ATf;r˪+=c1kl{M"?~ Lzhl5[ ],@@F\.ZaV'>x!z(azÃ.A\w 9zə}܌V \abao{+ɌVySH1hîFgL]LWdY Z &͞Fjx(6?%#IPwG9r^:/ 6zuB<6/ BB (/&j.FDY2rGupk)aDNq#GDEdWQh -JWs9'vC$ZXcg),4"}cKY e%dz:˚IOK7҅8Ʈm=הvHFF VDJckI[b5|K'O/cO`apdk_4o"8+uY )ȝ%#5N ?0 J*l.!.Ԓ[(GYT4u] n9OGǕ0RR+Vd`Wvy]xё _u'R'Xn_\@"8;0iN%8:TG7x=Y2I^?L'Yܠ`." g 2Lϕ wPA {,'krxnsE;R8gQ2+&jx&jlbbNyu Q:cJ(S0@2ly_Q%YK“'! V&k ,NX,Z}A8FCpx| N!J^ܒyȄ*jl,|$Db"CDh rނ0Մ5Y?4%R@_HV;DZoX;0MQ(^ w).[Ki2Ɛb&|J7$d6"F|ۄFa׮Uqc}V@:kװpBhKCai/i*"ib j0Cdo_+!"?b/Ƀ4A^=9 ;*MUX p04kSnG\xةK/ԴPWNWeufNO/\VmJo0øX~OG<92lSt*3ZǶ?@TC&Ϲef஥>M h͔ds?hc(\WΞw }6oԟst |w %TE,nn4EC姦g{aX2gZ'n߹w]?e BCuvLjJ,f|٢GIS5''fKˁooP30寄Փ&HN:JuZO,B8kŸdZm.q֏|&h4Eks(r~ώ=@<>EŒBX܌S@ing? *W7?R'EY%; Q+͞HeΡ gH~5 QN1=LUJضeMB§3a46VkpG>DiySC܋N N$[I'sCۯLנn½`RvQL^ "63%h]E}3G=O~`~鮌W,h>ϖc@r#v._c?߲*&&m }μX*3.Zzk fAB3Bb Q%߸Do9",X/d)LU#L'i!WKXi= ӕmCHrC{ulx,k$eȹH8VE3r϶ Dq:vl]fkI VV%"y_P>[[}m1k5!Q~FدM 9}-4A5%>mB>i3LIg#r5my7Zӷ1C`I 0xw}QN^,O=IK0^­mt+Է,g͏E$_$uuz~yF}3:zn&bɎ,zAfkD8y7&e[Q+~)meI"@BmFjb+{2:f_Ft1[ZJǶ .R7K[N$xAvZ0N2up.q Q2RdVaZ:Non}&2A*^_ bwMA&1~D\+ל42^@Yy,toCxC\Eo'xZ]SɝM Y/T)U:2'r8'P Jm2+;. EuГb}MG,n V6]s,"́\1Gcz;.jV@TTjƝoFSى wƦ᭐pǭUR>- T@T[s1$/օܞ(/b{SptⰃb)菒]"&Xg~ڈ$fmGHY!r ]8U?ݲh=tJIX˛Wa`o:3n<$k@^2P^BHzUgp+Sn8< *g`?̸sgCM[_Z$J}U#l'vZlCLi@s8rh60-'-}Ip}%w6Y: H'NFcgE=)`QG޴1+ë6]%Bl) <;jKO_헪<޵++q_f+j1v̕kܼDS X˴wR U[;ڊL{$ _7+bon? `]'qc$̴W[Gg2Q1<&ݝU7f:䗐  BFkķƸ9.6ț;ό!&%$:I,8$S/bj֫a$]I^tbb.%C ?螰3[lHJe $?"`0٬"'mPdgUKD@ bdvX(/%=Xpίl2xnJK@}c\E'\Kh|eG>FV*!B3K\Y&#_eJ \jF6xή`jS(M:сA#vWUM'>Pt&2:ym]t XAf <+p:kxrJ{ +!+4h~bR#*t0 = ̥V_Hf 0dh[Lp_Q+Pfz}Y\i\#PF<ӏGRQ$~FNDK]NQM-ccca0BIJ_/)Y&ϕZW*^`/"56Fo0+C)NA}e??]6s^TUQ1|V Ts0lE\GYe[¸jj.Ч@m6dyDU L?qLU^3Ҽ,TMy^I1ecJ4Z!.֭y(n{d&\ nF .S/qMqͪ}`aqF[ }Rhd* CƔK%X+F p53k[NBvz4 P1 ,yuJox (:%1:m0ZQ=eea#8d%6;u7f{ Jv|;VH|9YGq\ @}gM<#g@?/퓾\9gY,- 즾P{8љPK6/-Cvj8oԯ>r<ڼ1_^#rYֳad7#?Z ֮Mi#JMa <F& J8r:1@dUƗ 69؎٤/ V\x" 0,`CK\%NsC`wއZeGHnnv0, L]8f/J.+9^$秡)z:6l70FZi:abޠaa_)85 [P}‰Zk4 (g%̨=?W):܏O_'QHۭ'Sq3 xގN%u*$'E OǷ.7%y{]D }}z/ʅ~dE u9*4K1PM[P>3+꙼^f s'p GTʲ.7GI]!|q%6;Em`6He(4N$w7χv 55 pRG<à@>a8XXnIG X\ND^^,Y,JtF[ w'THZw[g4봠dj:'qBqD|ȱ԰x{Q&?zOͻ/z|fHȳfLAz7o>i[lWNlcWp~ŵ ~pveFi`{ɧtܽ^cbjqR%Pd]W9Y|ѧ׹ףvQT]OYFa7ڢ R#e89DsJ8(U¶ _Nv?f{j.ݺmIA@97#S@dd?Q1v0N2&^C\,E_Q4Tg'q\0rEySPEu+*sJᜫ/bJ0ӗq#]˃ 6 6qVa8+zTSImY2؛Z@R .xkQ^w&j#7aEWGhƇ] 'Vؼ>蜞dw I扔[p[^!^1FUz7 ro!>pXl36̴F)ak#`lLAǴ7$E;anp+ Ն^K~.܇ceY3QpBpu/V\'2~ѿZxcR@Qq:ҔӶ Re;c_GzIF/-qXbW-T"wcﵡX{/k};حݢN~q}jvs9㦄r3RIAQwDRԹmcTZ,e3F& yT)̌g} T8"ԁ1F=OP/_̄a*ܦѲysga+( XkUJ,M[nv&VUNi/+lHW/&DYIPS}4On}9a/@] }nvͰ+}L˟zjE*b'"eVnsbuT{ONr>.;"룸G9O8Gq H6S\9նo~( _^۹^ Kf{ _%r ߂ ǻ}?;g d#jY$ 6=lk;Xo^wdVWnLJC#fq90~G&9i.`ᅒt'7HhCbQ+7Y5Ο-yej #"Sмaޔqů22΍=?0-L~;UHݜYVc`R)Z쵢\{nn5l҃1w$2ϞD|hr(HWb}ߵ>J5kK/:fߞ*W_JdɰY9_RZ˹4F^N7RSV_:]y?A; R)' l*  5_%Pbܔ>Dk././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2311413 SABnzbd-4.3.2/tests/data/obfuscated_but_no_rar/5b331515-eb3b-495c-a9b6-76983dc029980000644000000000000000000002400014625637207025211 0ustar00runnerstaffT2~-c5%ҹvX͉%*kM&@W#Ð"V{ڥбp+B% }K$*\7/BRΈ\W\IzpHaUR.NSa5şbqB$宭6LuBRnbJuIs!(fG@-; vÝd?Y Ҙlv$ ?np*8[Ç^ >vBH7UB_n%m5bz ; răbYH!g#A gYDWьNUVLW_e>xa djutZ}߼ItB,)4BN}(wd0q4o(2KM6鏜KzP8ve; 4]D)y.ሬq\ S<`'7CyAgʂK]avK*dAj];ma[Om2` -&d Kf茩Yl3u=_4vF*y@(!G!‘xw Z-@ӼUD9^ZkёCʕr_h{hdejw_Ԕ:61_B6YWqR\O69 pmlٷyN>~b}0ޜG@(-PA*/ n#jsM&B`Evzb3lZ K O^`|<:S|է6.{%"T~@E~iH_G%  / a+Z54(bW ZVyZj^NŨd*Ewd]T Oz!qI4@Z<1u]1ȫnu.`=M ]9U.ժt>~k9`8^" 9T609u ĭ7iOj՟#@obkkri0?QNj d~JLVnGcP[D Ͳ47u)gY,[: R"K(zfgՌ{[7ҧq#{q)8+r|z|HRCP*cMtv֦iSm髮W=;ᄎKG*5#RRX zfd Ob'wKyV9/70u(ly(z22F, m &EWPCWfד-.E3jӁ'O$$g E_0)oӞ8lw].#ddf_ :״%f,@=BDUm82Q`in qMhjȀUc;MaY59=+Vypֺ,j l"ttgj $;Pö_`l$C@tS5 Sl`5WsE'.dyLD᠝]E6P&,8KCf'1!n]P.aMzZ}%@›¹/Xژm~ S SWВG4Ff@5eCvS &^.G^[!l³qBy0,8]f>g}ׇղ1gdH?o~_VbYY-t.`bTp֢ςAyJeJkC%FT\~` 4ު؄8!Y%X|ҔP ZEd]@7U}E`0ȹ{=' 1Z̫-u ~U~fHwDXN܊N:2׏蔳 U<+򓮿HFjX|*ޖ?u<#yO҄ȗ6B?Rr 4W n.xLZjv+umA ZZ^Ӏ{ E_"kf60y푩2 L zf4oD,p9dꜵÞ7dDt-0C a;zrc;t+Bsho3ۓ>@uDkGjH+(+Ev߹ m{Bc>KԖiSk5:x*@rtj*;#gƦhH3eY|K^7t$5Pݻ/(RN]ɮ8J3mbĥ2ltn}5|lJqL“WĘix(U>dW`i΋#UNAbF2LǯzM qgkM:!} -qΟS|)y9*$@J}VT; ׷Xv,2Õt(JHYˇdXjۮKrUV6e{%Y4h:5VRnJ-.'௶#r4{~D~P܊@]7@5۽1_iW#J xQK'ԬK'Yi5iH q._q1yM*SDEd;'xՓY.K+Jз{nY8ۤOd(*tR/KcX~Y{ҥڽP(C U|pK3P}2X.M8k>Q)\*h+Bx:Zgֳ֜S@[EVK+/:D= th,Bd#V0@ 8 U] aաÉ8ި:҈4aKeW;RRd\`g5|Zb&\wObL,B~Sh/QEL%ʥlWͣ@$|+ QΆHes vXG4.PmN}R:k5M+F=-Ѥ3"wAJ gx䂽1~ʷy[)۴deC6k0ѯ)rj?1UoXaQ+[NLaN 3'I V,ҚZ; ZJD ulm-?L8鹃n cWUq62gT#a4]#o*R~.=\R'YVBL6JʝuJ3ʚ>M_-C]WĀBԫ7#ϩq4. (_)+OL[}j$c[I@B Aij?pV+k#SڞCۑ;RiýҬrŸf@q h*y5N%Eh"# =M15)/XdE6 R"$i?& ljϘDt% SERZ9Tι-> 4M 2!bLAo|6_PH? a@c(zWF*̖Z-dK؈{#Ũ9wΆ)IXŧI?\tD C5EljjVT f͛5 fFY&ǥAD/Ƚ`ĥT*G^WVtwgP++Frd*(pjngq65wT5@b$[_iU]Ili=.<B4q+8iSMRx}9N$ Cߏ ,V&S>?Buac''ٷ ydU8ݵ^q.eq2Řཡe^U3AoC]6(F]Ͷ~C.⬶4Y m8-q9ae{Vui"ݯ se$ G> |;g)di/=i$<:Vc^`NNw?LW-aJX-<0N@ 9oj ho؏NЖ0)t'@v4_Ost_Oc*׊N-ݺ-/[vS̘$@G;ڜ1Y\]s^e$"z B#Vh7HUM*Yv-j#t5ډ CdkDUJe.,&nۖsa/ hvlk/5QZ%:LPbjz( $j]õ.!wU(5)56 &+LWMȈ̩ùu3֎S_[VoaX{@VAo)ߙ3QRK?vQ|km\WtK }ɄV)Ki)'YYwW!2~}-8!ܒbA !$xi#L+qLvl%ď :-'F*( aWÉ<.2x^NN0@(U6|.7 UDJ9R.l|ҠRCxaOjŇ_mPHR0sd#0}C-OQeS4EIje½+HDg[#|n@Sf r OY'F#QE' ,*vՇ>w`$,x_C/DIض`a)m$Rq%,BJlKFiJQDd[@DJ((@ 7Ҽh+m4Ŷ{=HW4ua>oLN5~kn-(䍋<:.}]fe(hOjfjBUk,M)}[UfA4#+Doi|ޭB$ഫI oOWU蛀˓Vjn[9pXäU j$niyJ*ͩU%_E *upj-\W 4Udܚ{'t-^]g>U@gg?3}Pt2>0y '8N uFpe\Lt/F2ʷ1uZr[롉.wW0P#()fnȠN_SnwJ/@ 3 qcTIrUf|H-Syޙ z3Kɷ=*r{]j#}(vb6ڽK,])^WBx?A-eF>]`جޯ|&C#0$\ }dP+ X3`Gb8uo|cRfbD]%86B_\>doPͯi=jkjҡA ~j.HZ\TIJrتOJ@}t$ah*]\htZu<-.|r>ƼYOtDޖHMaJoNk2%[UAic6bzbSJ:^B0kctjfs1 D(se=ֻ]oQZޜR35Ь.O{kǽ#!7N??c~DYK*Qzж :]kϼR3(9=:~~NcST7 w: N96 Ԉ 8f/2( |h7Jc8?F־ɚEl) nI-І$tfԝAYt sBD0cۉ;L;ح~:ԭΤ(3 /$Oxu$$18oq!-}҇+鰢m)-QM-lkqm0pNT;ԫ4o$lSRl0rޝR7;H[D_x.Ѹ*F0n UOԅu)URXRŷCSsqD0z" ϐo#;7o315>pBqtMBLS߳TXFH%p#|(t7P MBLHh?&`Gq"u3Ǟјk#:V?C#*kɸ_Aт>'y9ڈ߁yW3޶#C uڔGep=G[wLg{rno[맖vdNR~GDi)麨 ǻɓՑ-ʃ6z鄫t2o>ɛڮdjl@M%3şx*NkreVSpHvKqN !>ptp Hx-V'g4)A%?HCutJ5|϶svll3To8:1B"NkrNa5)"h}|#Sck"o}ZjO0f-~f[N5Y8 O:fY' RXα9wvb05AO dJO&F1P 6ar>q ڞ2\aa :R\a yfO_pd8> K4y^nD. 9Ďe+qdOʏ-Yg(hcL<kf^D?h4(Qw$y0 0|fsySN/mR{,pyaCQp-N@ )C( _ӓ=pt]܉e=3B 7Ѡ!jk Q0⅝"X>hXȏ疓P5wB<"ユa#8Ѽt7x&'/-|S B(i^Ay pt,Ӱ5jscoBC.-j>hbW< zQLW}~K(A WPkKIxzL!]± Auu]HwqK+<0P^^ѧ3 4j|nɔJ }k5'+ڠ˚XgVu (ϝ+ߘ?6L46N:ԫ8*3H^HqR<^ =q<& `Jb%KC͵cwѰ|Vhs!BFpQc_˥ C~KS܈zUӱr| %10L ;Y;sI[zΠ A&XK&Јѹ?RNjX;-yEXYz2>X');6Ѐ$=d6’8*Maa&>W `Ct[;,s䅨J$[kc7:1z3 H4/fkP `p1U(ƫMBwֵӚC5;= * >aOuYY[$EhWHJIhO Xh8'<䒂*  ӬkArs-LwXN]܍ĒM@K( !śeeLe-pz2Q9/7EZ::.z؋lEMV̈́d+SaQ߄Fy=w`yS";>d\}5b0bz%b_'&xZPZ͏gr2vE0Y-U .M?S`5#츻ZʂKxUA_8ǩ F3,q˴2PG}8SeÕ'%[~FJ?F3h wPR]jYd/F` AXZvjd6S =f3"U{we(SvըO2cEtxܱ؈Wivo6ĦjOti4v1r=Gdo{sJ-!fnW -ZrwE0ZK^N^r.9![܊uylߊmk(Ox2"'DK!O'?,C`g/.@58D\$h b\"9$DyYI&eR~^# 17X}brTG0@x!9Uxe@3.X:M%%W44s@ڱ 8,ʹa{ VH"T2;J #{J {jc B|V ,Dn3.- =[H0BSC{ Y'NpG{"U5#Qwօ\@g}Ds{ߝv'HM $5<5<^-yе *7*0EA*ϛ@G2U=_@SKGcH]P1Umvj )]*݅.%]+H=-/ZWn iq>nbɜA혆Y D`,O1NcmL ɸϙ T>W'HU0@3<>wx@BCGKEmJ [A3ڎk[6]%$^I5tfNDCnOD6yOAa˒X¿)pY}J1oCa'd-1).l"tzmi&&Ħшáw1!d`y@dG"pAk4BĻOR!5 pV?{IWLN`4Nd ixEa…v5v̜Ba}MLnU|O[[Hfd&Pe^9=M8H6K:mf=-5ZIV:']ָ*~ش!7F1#ei1WIYs*x$,B+Sh'R_p] Pei`QWjb`I-7X}/{w~EHCA mzD]?u2 B?{qQ78W+!@(2؀Jin큙њyð w-.nԄF*t aB&:M S'09NͲ@^9}THD"j"a(4,:97nΓCÍ/Ϯ"2*]ujE !aMאz[@6jB  7=ٰoZv4)jSF' huĴ<yfaSZ'Y^JlV*/7rxAl_凮sQVde Hw9&n&h9Igygd@ c%oBL{S2:%zèR|V0> B.kSʪ*@֪-Fs>gr!hQS,Z POw3>..P<Ζo t 2,o7x^Gd)plf3!Q\xo*&r_>MԌЌΉk\H2Da5 pWߩ{6=pwrL{~)Scʛˊ 56!.A^kՍhg%Pq E#2:/|z-%{` z喇WDЎwz Z1{E!% L׿ c3XzW, Ev~F;rHNi^UM~cVz $p=. UA%f7 2Uft2wYkN& ^pTĩլ$sQ57|ctV| 51Ey^J+g>zqߢ ȻQ)Ŗkh8J  0e_I1g ]ț-\p?ݚfd^>fE&]v~^g׾_M/7.h0=~~s;r&\]묍08[- \$%0w!؀ 9ܡGIKujΟʼpg3~YLd=gJZ˺t>M#uz4& Sx n5-q]]3:"9_h]w$<1ģ_TŰ_M`,M"ކGZgj쥉dXM hXDȡB$IIzF{Le5tI[6Ic\v1CPwgӂsN5ّm$9Ec[ HpQJh? EϾJ8R'qz$a ;"y w*TBV8?7p8gw_>oWZA;ޖ4< ^TIيQXG9Z76i``aF ^1Ǖ1vw4 &)^k=itF)+΁i>TЌ艿ӳ Z9p Xt:UYWi FgCνk54S\.4z.iKxn6_͗ Y+s"-!BDyXY8e.E`KNn~'M]BPoeT"[9goǭL"*ǰ@x02ZRLs~8PRw j1FN}=S2_:`&! ͥ\)Y0$cOaT,@߫zN Wxe13Yl^l>뭭Lue:@2z\X<w!vtZc<)@I}Eaa ;=D2Cs|UJr63RW͟vb[nbCt)^ GN_En.T v. 89hLA?lM+Lv2d"<\p&gn;QȤK<5V6o-;qh 6JW~6eZ)}U$\ܪ=b4j 8EٜEٸ Ak3848}!| zM2$ bd nm\1xdG> { z{N1SN!pB56/ BTnFR a LCO _o;ty6:3m֥gx0 זD{E;bD@KmVhqY' )b$Eh99[0*"v0Biq2C#`a+B*aK'·YY( !y>"U9cJ}S:Pl mW\bRq]_B68#llÑŌ"z8Q'Ggœ0[ĄLO&Hx\8҄ m߬d䊉ypDvIFS+xŮ7^ W 5;!6>(7SiN?uJ3iNuխDp!BA),IX]6-[7`.>vTP ݢ͵.P27JfAd݆'LR*4VꜦ/ VPq{}P%sBqfq#Vsڭvs Yp1L5L[d;H|ڰLQD^:}oyЈg'x#t5on ;SocWAeDiMT>Q2AHŢ d(9#~ ?]dh5Hz1*܇6cIeX?ߙsd3Gfj~"CaYG~8G/(_ zԉ_~PoCR;fb%=OH'E!x#z'o4+ }G ȑ0օ&hќ 4\n=ŢS;F)!,IXHҐs 0̿fL l~SzjtӎC,c%%E}\4qA4c@( $Vb(+9ga*xNPx>g:YL)"}&ʹ]n$(bIIN>P ̸=Q"'w6+uoG"2oyI=٘d䕣K"4I 8QX0:R+$6!ĭdݢQsiq2sFyjD`bj.dgx^* _]-XgWH;J*8Dǘv;QRmcC !Qؼ&R"1~:9!ܼѬWhJ߹WE5&㇂{ J21Eo'2i^jЙf);Nz5F/)Yw7|yP}?qt;N &{6;HͥpLq5jVbo)[ 0/\eߩF(ZuWdIleXySQC=D }>pț{Qg۠tp&"~0tWOgq Gu@ʘ4Srl]\M`x Bֆy-RczΤ]KY 5, Y)n-bTc߭dlTq/, ]{;9jAsB@aǤci_ƴRYPS _zv [mNo?tAv\ ˠdͽ.v2q\Rm1,v'~Lc_jRx5$) iG-oh8' E( ɕE8ۥzz{v[D[`pO^N;\!B,E3/1sZlvd"dˏ 7S80t #iʡmײ~a /+A͕+ _hW_G r/f +44i ./ڋ 6BMjk3v9I|ˏb-f7!MDtZ@c=sm_v|pL !7 uWށ`U.$-PGꦑT;ZMܲe-l+ӊv+&ITp.#*crkm3|k3zycaޜ"Dj>19nAaO0(,:iQT&I'p3YΨJȿ[%D:v$@8[xʱ`ABj5N5HRX$y c+Kk-U/X  * 8<411&KR!KhA/W踼%z}\67籝ƫOQtx闹'4n!HLoS<%Tp/3㼠 @=f)4nFuD*~M'Rd. 'c0 /M# kmi*== }t[!k4qI]J //D}hs .hk?'@򁛰D4OIcmYz`\Z"=-٠-Zi cЁ< .3ڬCRM` +&ܚ-!űRWA5ռVD#l`V"Þ~q*Lgo*D̃)'#WM 57=Xdb8=u"8eQ,eYbnu}+W;<hm&G\W& ՂNV\z e-ݦtknCC="?łbC':Q(Đ޷x2ith%q dP9HP&{{;m8tka%,)nxG6 x|OJgkZj[ %Tcp'$'_-׼(݈U$-*c}@ p!R) GPCYD<\!ˬ!)Mc`30iCEĚM,\]:{@Rj)ꪶhhf :Dz9'~HZ@ۋgrXLc͝ {z+?c=3 aƧmoCzE$O$A  wGA|)$k,:D *Uγ r ?TEESG:LfV}y8N28\N\d香.FH &HZi`)@yYFK^ EN.ȿ[..^=<lPfrOS]T)`;/ MP/{G mDN?(qfWFN+&B<0d7ONA?D˓oС<a@O_o x ;=?<&[k$yr/z2n`uW3Z澬PE=SFMec|:TLEC3pRbo f_E:g=}q kiqՎ3cotd= !;.żx4k{Y[Y6g%u~̥7{ r2~ n/ -ۦýpqf ͌ĭJc-]$YS0^" J5yxqo(jdLHA6u&.Bty12{m+kB#Eprz|j"Ǩ T`PzҬd}x\w\bpPuMhOj:a :|KAkd, "ќVCLP)B׍=a\FF$; N_s9oszލE(l,f'z[櫑  RȂ ?WsU`mJgW]{\<%pW{U3py4Jbi8?(HO;1oo|I(veR1[͇c3'J,p1#pJM!\4´ tCs>,NŲ K,m9Ib =fc6KV@_9`J-ͽ_6Vyr n݁WA7I&5s^ClpgUVh2⳺;+D!IYA c;LM~S[œdJ<2pM7Ңs~d&&UuO"n~6v> ȅ3MFO7~F~F]ny'Sպ~ Wnġ{E)נ9ߑQ|+0]{'̔2ipuenRlO60G*jC$`iUU%%(71*ؤDoRHbZB~'Fw EWZ.WItqJB В uB.84ʷ r&d ~gFjm롉ކо ݁hZƮA%nܓ7%D|,CP)jx҅|C>߄w,F~<1sP,J|O]?wu}iVQ^].˃lc,fQS:\@xnS;i@~Zl[ն^$(>~2,–jjON6g&l1[**tR8u 2E,}@c_5 JpVytHjFe![>M:Ã֧^G-d쇩Ͷ_!\FP.^KZ*ok5sQCa|;vFBu$3i. KYMVuwRBEPoL xDv;aQ'!Ԗ\ EHnxJX냽)%4M&?EihS-6lcvvd\j&g>OPX ]Ѧ֛*+"nGt"=7{ Pu7~P=cA[*BU49jK25ק^ikbxшԜ pL Rp-P!UDZ*g ټ FVzox4֧|˗备 )j?hC;+s8W(ieKE>XNMY k-' -׹9EiaZ 859-[WxgRF~-p. 9XAa+5aC(椝(H?q4xZ]W>2L] Z,././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2303264 SABnzbd-4.3.2/tests/data/fully_encrypted_and_obfuscated_rars/032f4c17-50ec-456d-ac02-e118e62f5a550000644000000000000000000002400014625637207030242 0ustar00runnerstaffRar!$ s!1qyJR1:޽*Wqs"8F ̫~kW?'u?ہHZ34t.|H/{0վt_p;TL5+耪 7zEN+auO@+ *ݍl;i{_5i&POt-%ppL?h2&(-CP^2 GysCzPhMej>v'yuU\|VzkcI" p5rpM%]\'qh[^{߄wO&@1C BާExuݺ/fRauIZesoAŐ$ĒH M,2KU0@ =,˕iZA^ Z)2bhlv6)_Nr^0lTRZuB+fC;Io< م'(Ðp\-BXR@9e6͗UuI?mtw,l&pq<^j֛z2Ґ-f;``fզmn* 0rFJvn:]ϙ\;)9<\Ȓ'S!Aယœ8R4d: ԠOZWPJ Rpzbҽ];Ѿ++~Hh_@æ~Rҵ}5 ?@.&WpW*#+$${cH皌dzBɕ,fmq-fT X?Ken54Z4@&Lhܭ)qFHt+&ovޡe%$E :a+|/qK׽dvx#" Komj-6#|{_Șkw,3KJq%>/==w49/CUXđ(˖Gk井65zF"ݽY$pFT}|JGc9J#!tuUSkQYވ˜hOޑB\W(5?wѽ$rbEr ![w=*64$E$ f:ºςcBSd% tx(QNVcPA1pƠ~?kW"drQbv-v0u`XB m>Bt)Lsf4Ia؍d(aDDq 2gVѿ1]%|uB`W^( ӟB%xXy=ÂEQy;Aۣ}4lg4SAr[ EJ vb>iSSFg_>Xʡ_Ȍ2 A^:?YJq5QSSHA+|4 b+|)uYhI.;ETU~1T^}˳qIT7Y4w@T28,l9=#yJX "v/2$_n.(Ug=` gVqƲx=g$&)NJV{ܻf/Bɲߒo!>6d.0m.uK22|&ydRic[ZhI7ߢ_}TŦL=utZP<d5Bf]d)ƍca ,Ŵ"RQ봘h8)HsDQ:"[3SBc'~v+ `MDd@5eϤ{ɔs3dW|eV4 !Noqp vO]@o1 뺴PэUy,aLQ2lo-;U#~~͸f±_% -87C) x"ay| @ "O?Z%qfLg]5:V2J(Pq ۪Ϧ B{dYdN&S.ic5> DڈB$ x+^P bn @[zG>)w:&GJ~tnֿ:rk([AC 1EձPE:ӟ%Aϧȯv4ѹ{ [./ct ך*gR!@JJOt٣f˼Hl,Hsq*gJ0y˧"-W_mAqZ%ͨEƊ&yiUe^l`' sʽűɯVI{ u 0+ k ~\S-hne"G{bf!}+));9B Ge*2vl>@z 5;aI՜2FxM}HQO$,Ӽ=DeC|cs4:ðWQvjG8=y;$qCjQRoY|/uؠb1wJwϔ^JI[`qn>"PA8Dng7?}&~_@Pp'bQ7nY&sT"?rқ#]q㚆'OMY!hEhʡUNf}3p))fxK-)J iȃPbBU&iߐWYC9rÎ^;ȼܶjOͶ%rm6ȅINvYd ^Q]!MBQai׋1I`͍+V,!g_(rZnť} % mũ4wj^M_w{y:\kh wM?wql2H*ZV-Ճ>o~P(W _wQ3Cjl=̷tG2o'('L"Duݧ%5EuqaxH^EvK#u*>;m.8] ^ѪZ+vRq.!'޸>C&9ז51?+B2;$4gʹ7]Y0v% #E\Y!m$üBf{mjԔ3;Oqbdn(hQb)QoT&VG19wJC/Eِ !jjEF~*aR5 ʟ&'XC PTX pCUJIEY%FyԡzD*c1XUu}}R!{9+]ˑ,ڰ]d}=kIZv{g(Bߟ|VRӂ/i n(3+ls=V GA'N x&,^Cd\ -LC~&!g]BwsTV1W}X ݴe j\jkQt6 I8-4; RP\yW/kR" 4 WeۻTRl_!|[i#D`sܾŭǹs|u 3 >llSaXɶjb۲V@-('i11P o *=ey8-"̆ v`6gbH\[R7AE)-106. _1.m`9CԮȮr\2\&kD‹VfW5v"Lh®q9~c{뜊Rl$=B E#gH܇44YsDPI6qnd5'>#7 [!53s,K/l@FS٠, ޴Un&dwfY]* yQ *7,z4ae۰b7Oe[{ c~x ѓeF} E+~&N$!=0.ɥ8N%;+tiN>X N+r2փR?S>Q`8h"y0H/rTvVg3riDQE2KW1^GjVy&a:7Gj/Uc }u4'n}EYv̼/sъ혞PE-2;ʫ[;ٳ蛊|> )PjOSU.۵&_0$h!8 =$N7UD7ph>0X-姈=X9]̈T< ] _mzNbx;E[S~ɵO!XKDWMm2vSNtsZ\SB7K5Vh2d61b°jgG vݘ0,'ܬ7dӜ|Ɗr[ 1e&(d,pK5kG:@e|mk$͋CQr_ެgvg$11a"ၟEG&V)#dSB{bl pd.RehʁsJr&P$YDW&C:W(56&v-<_~$ɩXBH`,uM/P6mx.'~}/w>jpT Gc`&`>.s&X5 wtU~%:RHZK 뭍T:TĴs@HKb6X9K=Ɇ/]qSKGJ gzŵ QxZ֭d GjC-mL#{G]Arr#7ACxX z^/ň6ݦ/"wu N'!phKWJ>&-ѐ,lW) Å>MbBR[A>hyc>ꀜ8"gɎfEng闚ohn{ |ijk$&Pr ~uX|x=bz}auOm/R)S 4]q;%LB G%i&ePWؽ$Jʔ g8D344 [ 1N[fMN`IN8l!_fQ?KH Lb35 逕rC\_V-MV8n$ r?_߫}FUJQ brஙz{,&C?K>$#)cHo w=xG@t̚9TB~K<Ø8%VX}CKJrHv\# e 3%>oƭ-3!K7X}َ m`-2Vuv[A5MH4g-_x6c;8D描FyއHR91 MHLj@W6Lk(U@~")$ɓa;' eOnjT猌k^49:Nb #ui r{h. :ZZ\1M jQ&y$e.Tc!s#17T+̤W'hò7N"ņcq £_ Lz,_ֽIwQ(J1)Pl̳a"Kw]hA&lF/}/Wɓ| +CljXF^m'dr۶tS]qmV=ҫ(TsvTY݃[\wZ!dC K'2RJHSC,GJ=αq,pxr]+_3" 飨4q:n;aveQ׍ε ~ ΢iՕ,(+Ovmp>iSHNA_yR-}&)c J ߼bga_fs$4InC3󥹎:OEHa !5pI}%wXe=] 6e9Kw3Ku'Y{z?aDꄛx$,I]=2(Ó/r*&;Z?ā#]bo$]1棚~A!ׇ'=ɞ$}+uHVM5RD"~#?@r8Qݸ] sj]kT#+)0Gm"ZC2pˀZUg}&{fYMv.'n▧yè}ѪuiB{x }8iKdS˨G~< 7f5ҵ{3ѽl( z-LyZV] ePcWUFzGY.pڡu0pBc82?~g3cc95ՙe%v"_Wla& {qSF5&C]YX01j*$JLeH@ׄ"yؒH#/$˩s3M/"_v 1 H': =-X.!#9:\9ꅴwIiCĄ7G߈ h3EXi@"$Ur VR@ 6kj__+8*7M&_6CBcy/,O|Va ,U0;uRڡf*l*DV>Z Ruiܭù֦$[ڈ I,ED[i{<;h2#k>R$6}m5s^!ߑU?8&Af눟f1TNMme[nn(Iv谶rxOuezKvuU*"_ ?,ȎWjwq7c2 U퇧Pe1t1ŧg"QĩP14׮UvCyC^11ARFrBV{qJv/K\ -A Ja$̊&AIH7C5ӘǕ=Tь6T\\gߟ+dv| Ԛm&:z8I$ҬCR(+fBZe ǎ{k^Ϣ:ydd/9 IʝwVU{cӵ# ]ftx@9ӱjhs L&)B aS)D/-+؄XVVQBQC/ N½q'ZN 똍ӶtUOHqӃ+%D?p gq< ;4[UL gjkש}{"ߙuEQ]5yS<\V_Fty:8Y-NJ[kl 5 4^3tdI)Ul']ӞQ 9qr:w@EsH8`&0%bwT Z~]ؕ-@QcɤT8*nYja$Jeq^FBgU8xNwƽVw&6kK_Yq$m9]}[ :ʚ 1v;5hmxԦ ^sp~ Զg,8%t}2i~0k׋h"%3}?fWǝr5 AbƇodžғuL7qNĿ;, ;nqLbJclIx ֨''sN蘆DS4ױs2S ?f9r}tQo4S孭j.<+|v/`|>T RpкK0Q(JM֟wFҳS#M:-2Wtfc Hӆ&cԸ Ɠ#pM|[,6!T^ϔXܓv׳}OOe܄x[4fI–}qhxHғa=}qD'gxl훉o[7syNI#"g|amR` .VE?(*p jlv17 [:&'4HO,K3}fF$iHT_pZK qB~b6J}bH=x}IEØ @X}9n!Ix#mu.Kh!XeP2?6ȋ{qv{(Qz̸({w4L7 3TL~5k󟘑%"ܬ4ZPWߛ#a:\UTo~d̻[~8 tO_G5֙`+R*䷤T)IGxv#-^I1].L?4hAC 瘲/t-:&q:agc>,&|&Tu51P /0Jj\Ґ*Nת4z././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4448626 SABnzbd-4.3.2/tests/data/fully_encrypted_and_obfuscated_rars/making_of.txt0000644000000000000000000000023314625637243026247 0ustar00runnerstafffallocate -l50k blabla.bin rar a fully_encrypted -hpgeheim -v10k -m0 blabla.bin for f in *rar; do echo "Processing $f file.." ; mv $f `uuidgen` ; done ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2305553 SABnzbd-4.3.2/tests/data/fully_encrypted_and_obfuscated_rars/bdfeb75c-c177-4efb-8bc9-764103c82a230000644000000000000000000000507614625637207030517 0ustar00runnerstaffRar!$ s!1qyJR1:޽*WqWa Ԝvj-Cy\}#c`$>%w!ӻޙjH/aKfn< p6rŹSσmGEHdDk[ uRC-̺ߢQK툨; Gb#iϿS1ٞhMNB<-5)sjB={D 7L:HBky.Q?2UT(!JNHG\lA a"E":1n 9-U  z2Roc(yQfA3e?jIU1DU_4BԷ̧S5jt>xrД,D <saJaM%St|n!}UzquU%u̝Oؑn}F}H4=~u}@( M ),MKKw~*E|KӗFæ97l'M}Wa?T%=:b@ṙ7cYE~ *dv{x*o,M;h]67O5qqwaSҹ\0!4Ԋ_sR蜡U ֶIІرM,đ"ȁslvlzt4u9! 0xLuuwo> ($M&;7f`oH0DYzBSLԬŘGZgܕAPOl0/g*HPP%g`3=^8X=U!1 Yq$-n5oV( #| WEK`ւ֞fǠ.KsDDY+5ېko5b'ġ>L(sJ8D 5+ﹿ92doJ|m]?L Z>z\ IN X 0~J1h^GؘaG=eMs./L' O^ڭop6ŧ/D"#<&||vAJPڸ娠~߈9A{[TVK,9Dܬ(HfwzA3= 8V_q44SẞBB{ bAԅ$ ise?PGgjw|Wrx8YDPF%V!.iS}iF>̷VG+Xh-/, u#[Cw#%gGfgAL#bCkFщb+44˰4YE<<%C?e1,9(#5vI4Ѱ5\ww@NDʅB4hGfv_B`p44 aIRE:O`chDr7`d>I3֝q{C~WL2HWɪj/]_RS|Bԉ_\-YMApe6s.?>`fSCvh\ZrOV}MdV~J"C?g $i2ɬF ʨT@4F0Zx0j}r h>FXa-yZFF'jU{e+{,`c0ƁR1]SQ g2)=x[#v _VUM2=}ڍvCvGP^pƖ]"Jq۴H [#b`F#!Fx39Ϊ{H! "]\ ;]v͌CPg35 /JuM\66μ4׈x0Qs GԁH 9V+@lJwsr(\ R tkB/=`d_y0a**eP9jv VF VʼnJr,oqFnm%}/VqzvJI~1ˢ9x߽8QsiKW$R z g8fM8#1$bƒCI#Pb>.ч?73 -wznQՍ)hٱW`nW6`p E͙SCIU9<N/mİPTǏx6"-vr]!bB{ ~m C04Sb::/~9޾JRaZy^/#(SʰxR%]Y"y"Er5Mrc/Fo5X@%/#$sVzo;$yuogN&7;:=ȋ^9$αZ$dL]C S GuVX|?0ϝ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2306225 SABnzbd-4.3.2/tests/data/fully_encrypted_and_obfuscated_rars/dee6a48c-c443-45e1-a7ff-e38c31df60c40000644000000000000000000002400014625637207030563 0ustar00runnerstaffRar!$ s!1qyJR1:޽*Wq']֔(p62 JvkȌ 6kL?䪝[&V|_ᆟgi4RH[`sE?s-[gQ4G!3M]˅/#8=jKFhX26Wx(̟~N@ع"$bw^}ɈA3hV"5t ν{OC b)$(^!M 4}"D(\`ŗ 7d^ _2t>qJ-hӧA8hH,rl1^W[SƏ8\6^Vv/ݛt3"8Z8"oVr2ZL*T)wu0;Y,cYK+rY$-uMhmà.2y>0'.BWkYn}FBLj r_)##oܾXQ*{0”~gFY=(p A".uxgB ݼ|AjLzti.v~DE$DQxkf Ӟg|V<8{맋%ݝgSL^E'6r X"K޽!gA24I2=I4Y -]9ɩܧ3fB+j$*h`-ZX4%EoyZڦ}5;_731_J2 #Ͻ A[ջ)-+S-O7=tkE'O!Ӈ׈V[edyGKyLn|+6ty`wLHl >YjVLV T:b@̿rkb:!,o1`lK.|`[@ ˨>'B$s# ܾ1IOeN-l&;GzT[gvԫh@ r8*ʩn1ZQ W\Gw{G.wBl,Nw Y#[$I0eXv]l)XCSn4v]?u; %{zA% *A^*z^OI CP/wH;C"Tȣ$)ʇe"Zᭆe5_ = Edf)^-U})s=E/j]lwfcxP/hAn^(%\%SPFYfǃa!J j^=aSuV"m6oܙe1q4?}1{iW| c/ڋ=NOj|=QӁ21bX&9yYz K~b3hƒ_ېv ~H/gDV&A;M:n7T5)zU/r᜴˶AmJNj%˪Vn٢F}~nkq>?|k(*51i}8H쨳YkVnU\zp%TpV,FGNMZQu`p%< C{B/L8i֣mNJT&HsU")^ZI+vI6t[gKpwpDo]>&]q> $w`Rjr|yYRM:C ٹ3.rs"LЧ;_gx:#o=Hr3nv :r_efd)%'T7JaIR C!+lm3ȭ:v 5Z x9ܴs:_ \ %w^5-M[l\u^Dh\ynEL׎ 7پjkaB5~ 8&s6?Z*\,+jX3 e]>u< E- e!J!;~to8n Y .{F\hGR'+z`y*A~,'l|g,r"z ՘瓲qCRmen|O좛UQ8nN>^t,ZJ@*>q)O\w,e tGɮpBIl^i-FA(|vB/F+shb:dC1r|DVMD8;|xP xE2yG1.#50긹l<6r~A쒡"^V7|Yt +hqV{2ZtˏbXiiR*zM.[Ot$/`;ʟܘ!ⲁ^wmu`?ŭ[(6RrS&O$VI$]vk~d4 _ Ib .oWR tLi Kww|8R`YF[/8$DGj`S͐M֛S@kޤ݃[@hfm.?¯>.eQU<~"wZ<KD@=F&7/L^udz7 ?c[c f2Cx$߬/N-عРCG8OQ ncNH\_]můۏ,cQj %&5LcNqem!Φf\3k]ON p!Ҡ} {,pr$ ixX=# Kl)'ZaY \xGj~s!{n/7yjR6ڥ귘F`eĺ-~o*:WTbtg}jM{\5%7oPA (mos>"T9PGhj:| :4mGKȀOd黬Ƌ0O3OƮBlfJ}'Ѳ%Wvrxc $9 7MApCub36!&fPdh7*)$*10dY'I6K][%|{ap&0CVWW5kA{>qrJ< ZE%q0p3GbH2H` ,|G+vqwʻaHm歡oo<¸RV+yYiZ9(@g惵:%,Cǯ4<}]CH!J-'>oVKjDR.Qw$J,v CVw.÷p<]Ws:ăS}8'q2)unO3_mt:&9mԄNyXl Gv&VbL1LFw :WX!m2Zy wZ.5ftckv<.ʂ{1{êJ6uH1DnAW'T(Ov!f\[.GOrkp #@TC|ZxpZ̷;b:Sb! 6i‰NPnOfdJ13XК~6[NJ'~5o)Cnǽ6prK09ᩲMCY#{o̓CJ2=:۰^[|#@w(@4i- G]~XVA>MX!YˆWf 濡fXh GIkfpF)3vm1?-ޜ1'`2.fzN*z9*@]7_B1`٢F] |:jFxYkyf8Ϋs ӒV7%L90O=xҕWg+DԍsYzbBmmUvn"!\f{|lقL. 94pl3|z{dgKE;('!t8l(91PI.; wgҹM.:Z1zt#izɕlj?x;䪊n AS T }\QBf'ʱ6($ .PIܴ} z=3J}|ק*Dd c:f6莀/1g)L"艴{A?9~OxgoeϽܰ ϳ!6M#O4&=~QM"~?Jjf{0R+9 bP̬CA@BlUjGbeCiyUy0f#"]jD LWD{ыm&)=pmZ+4zDFIҏ B3lҷ (߰'IGډQµH~a5+UքWX?徼/F$yiqP\%n ]-z1%F삻wMg !޼ȻwkHB ὨQ6JiN\;d h4uiNJ}K&f10MZ9[$Ԩ+ԥao;3QIFTN-t:8k`pvO6ޚ-K~e]mEMQq9Xm" B5O یhu+4D3 m\`hR LDifz+FC3.1dācT*T?SΈP9G Op*ۊa<=,& ‚DSl(-ʬݡO{eHbV-8?Uvкa[©ç뇌N7N#BnРUKnVHvk?٬.ԙo͹qCo0p="FV bG >՜Ap( )G8?o= FՌ+%Fe{QS/B7_)N0N愽4-{ {w~nb}昪-h0=~K* Ů#-5y}de]N2Z^[_g0zP\ {d#f}BV>YZsg{T![z.Fر52Sc#3ÝX@ʜb"J~5ڽPFOk,2C40 `o~pa'"4t%J_H宆(8ZpG<ᮟ)u_2b9a]YTCZp케q!* ڇHL^P>tz yރP?upRly 6ro7zc"AMԁ~h‹gwցE+(e4Q cM{j‘b #..jAiqk.,Di^[-4eqzD7{4Jsa֙5'cPv]z /j*e Qq.r5;0ekxP|9cIj`qTBGtc_U`| '*vP" S}sC sc"̷BB*׎gy;R `SIE[!T^1l/% Ef6 __%Q;6mEJ ^w O{ZqX5ⴷKUB''DS|'zY'*mn$\çO6l?{KDWŰ5"Y֟AEةj'#?eʵӴ71vNx)u"W_kgu*Rq^ٍ;ik1pNű13>Xdfnt} NA9_؏:r7 `d һ%@j1m4j``PK%mmIꡱ|ؼ%ٴ40iǵcRx3_=LVJPqIU L=1KzBtp~\uWéz|(%{IRF!k3}^Tm d_3V(`:+ 8*_RY*b,Br.+GOc4h - Rѩ,:ۙp+>>b(U"э*6gHa%+ |-;"?I!d \V/}(u_ӮNpd:~O#BdtXi:adY'*K`S(a+j&PK}W5tԔ{zI8vV`s;+2Rq]*sr{|S gy?40ˆ#j-Pjd:q@(d'$~98{,9C,rw|~UE_o1ӭP|7rΧ7 4lq,LH9;ЉĴ,Z*2㝢MZ& eIpǷߎE'tu$7})F ;PUf).V{?(7(zBk\\WxQ[dm3"ƃ4o5L*^%˩%:"K]{s׿ss qg{ EbJa sMgXetx(E:}XȦ" b{ʮBA`G9-Ψ2]`z -`5 w(Ad&p)`$*_Y7'"M;3W͒ gF9L-W'I yŢ 'gj=a7DNә1ŦU(u"&ƥ ̇OY~ܺɵ˚̌!ƈG)^]X=^7:sXH?Yx691JCע1߆Uw L\%I[xG{*>!0+0C^VLʈiPC4 yTX%Iç1dz287>tzsR'SiOR̈́e0././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2304773 SABnzbd-4.3.2/tests/data/fully_encrypted_and_obfuscated_rars/b0a3af52-165b-4285-af12-8f3952586af40000644000000000000000000002400014625637207030176 0ustar00runnerstaffRar!$ s!1qyJR1:޽*Wq)#{3F.jgKIc"j.E*iG\2p9fgʷV@ 1m"M/#jn}!'d-xmi`9{eڪm>Ir5k` B)s8j(W!H")|iKŒ cz9G߯B@lR%d IŸ*VޟnLiC6u8wIq"SZk˻B^ں&ˋ"skvbB @YNt{ ~X" OӚӕ(qG=uYYn77;\)%R0U"%M/xb5*bHQTlon3ZQ}KQ2s9e#`Q> v2*tug/$m5*( E`jЃ)9UO '`3HJ($FT}T~ Ct$qT*>89tʪ3 KOPJd>#b_&}?)u+儶|p׳HhNۍ<=W)VqD?`voR0\X {ӄ<[-?YA1ŬDOѡ2wfj{RrEp9ַ6&En9R!+QTCdE*wCA;]J[3EePR>PNrbx@-Ewq3腪Ys\qK&$pI'QUzfj;H$Ꝥ4 w ]#,8tgO4(dC՗=.:l<ܗLW*{aٍ$ CmgxbbeAG4O>7;lEP ̕ZO-yC% ;#K[p?kx<ݾ/',ﱗ/O! $#S!qzb4\*N> zbX!؜eخaZA7C#QY@G6}iqzӴ UM)MͤIL2 tw}̥%pG" GuQŬLqgrFԡ-P䗟^ɂoB-dmX@vqa dXZ#ЇIHo_#;>)N}嵸dSu殹pF$>xFhleŽ!~`EϹ<x z~/L(]W]ȣQIq9)8A^A<)]<Kh Y1=#[S+91o| G-= aV^x:o$D нLt{׮~ wTGh DzxFr}#ƶ/!FR,/P9p~ZfZ(VhcZ9W [qV)dHhGk\FHRȫE'g4fD^ \"sdcѹ.' EZ Y'2n{5wD @܈i g:8`7twg" VL9?#gsazF!~gGWBuqLV /œzsOK!`kl3׭I_C*Ns:DLb`Έ~.,Lxovppr\7FAI붬Os&vn1ie? Ipr1o𺭥 dnj^Gl ez+:{[gm.oӲ6fH8T|VܚNh H 18P`,-W "5<4k8^]{ $I,ᥝ ޿u鯾/ȫn(`}ͮ_0( Dm!n4c8ex;V[rqڂצ"=R3G.H(&r!GKOqY2l׫F_S7(?W% >~H5MqK_RD^ K)]CP9?!Kޟ ԣjF J|*tc{t٨DRҖRZy69%x#@ !2}ΝONjoU{s_?jC(݂hmRM%0OP[T̆0Ꮜ09[;CmҡM,\17̩ i(yrh@V(9"<ɑavL\ͷrw< 99)YH@/Bo]=>\~!b9 [C7IwUDI4$7{V&s*uJdt1!"'"BU&)XjheSʀ"zN;ZvmruҀVo'Dr>ljhSюᮄ&:,ulؼ"Sg<U*gANmȇcGcC ~"zH.O'7OGuqli:(쿆M i 9}1" ~E :$,g Y:cpQkےQ7&}[U!1#'w mpf&CF&/ /&#}}: :<(?ӌ9Iae,˨yV}"2 j1Vv2%Dw,`+-U%OA+O,oz)MF|3 `cъamZϜk pB!6Yr tC\F<_̽M71]l2)YR!D ЙM:tsg<-pɪJJ-ĵEZ_"x w)#k1J 6Mlc2,G+U]#d>\G |^9)$c07#` 2";|H=$ l PL \m7eU?niھ %tdSzUx,_K/XOg3&7"g Ή5^Gr[i~:4-wI6 DP~QYsUDVJ賚-eIꋷ|4Z[Bb!^Mm5LrDfmEF/(bh2eˊ+LA[_5#U,g@y4(gxcGxCT)j P mnqqbZY RCFRxq4"3;dս<5`msCxD>& ,1!E/27?:VO;@=yPQp,c8AG4tc +j]1>[2K=2TWf`1ǽg잷0/s+M`ysQ%s4ZX@7E'~2s.V!r3K\mp(ޫ//;*]:E}ٓ\& u4x7Bԙ54s¡^;M>_ B|_ 3uC@H49RGǒb2F؟-̮֯!Zcr{NS\ɼ#u`儝M)F#<;2IeLtsɥ-O:sPe::8>a}*P %C`1f.Qcra(}) *ÈqIVn>z+TQ fB1yX/m%[ckH>֪le[Ȅ7 ɅnyA{(x.2VzGSאҜׅ5|I_8:Ii~P?}ÊMm#NAcĩ,;i<1JYX,Jfe,K qn)<%/\RTׅp.ھOb:lJ*1&Xn0DO#`Lc%3ubKR~+YS栠+MW6ʷP,lq?0kؤ1&>r8&vq6=|m]4Ԛy-s EIOvcǾer¼ddgE¯Vʘ^YA p[.3 N>*gCkwB{ȞQaqgC;U7c8U=- (F\izЪ?3_'l KvTᔳĹl ^:kq{ xzCa-QjHɡ4dU7HTֻn}B;p:Js-iRm֟mj+jS/:mǶҒwtMWڽ#jFW0Z$NI)LT0}s mϽv)1tZN6A4W`u@ԽhV\g|Pa.Lx}n*_5Agͤ=Gdo[co5g!nƨB=ڀ F {<7dUʲkӣ1S1:r [pB|GBx'Ldx,\/e yMΊ8`Ra^Nivj.ӸV7vEНVG-J2+. ,83Zfs)h {!8K[۰miv=>D-$_ ._XUγ;J@ !S\d $)F 9 ]EtR%8єQ睇4Yj{@  ]^`"KJ;픴{EKz,.Bg'Pm6ud n@ _x1HͰ jhO8PGRSZ>w*I&.k) +yeQ7 lnj3focE˒O=&a%i;C9cEQ|RQ12څڧpw@ݸ.?+yI 5ZdY߿H:0^'!I Jcr6kKyО^NQ R:/ɰw{u/@`DiIJfdnj/F1whߟ(y&SWqHV4aCO3 gwpk.%G-է[6C=Iu/wu:FUTCTf!Wݍd8ٚ-uRtJ*.? CφH!펗g'=\$F5QTNs0;FM1#j |ڋU2 /Wee z TgJ1]0-~NyV0O1^I)PU"PE)eFpFVT9XTO"c9T˸'9g㝓]Gełl{:?)wZ t8!LeNFZ rGXu9 +!=0% G(bD̨Fw,Ey:]}W$9Vd;t;[2󺡶M]򚷳©o7EoG[?I8 IX=i5ŋi=`̐=]:m?MiKVk_ƅOFСVµci{aV7^5fWcn%zҐe\:^ fO&Ut .J>,j6 A^$uvōkp,Q-B0//T C]xgE3;ž1+OC˾S@omdC9 Z]5B(6Ƶ;*ƊO_̅5nH8umCKG(i܈Sf;hgy'e3uGAoRfaWț^stzLWI;9U!<䞀~!* ^#t>NT5ƹOA> *a@U=0$QQ~u3|ĺnsoAJ% mWp|˦c% !O ފ?Qz!;dsID52h< p-\lӥ|}f"@l#w\įPNjV b#|gX%8Iԥ-#U}rN;_wUM I#Q\IFin̞؎4T"%rʁw23JUa샻u(DWIUyȱO"ȉbm=cA$M۳Hwq=! ZYzTˁLN=Pr#Kb-?}WbY;fY6~xg,,^dl+sDms~9ASټ<|́JtecJM'!ZU)V V-QI`z\Qn8VMj'-K 昞RP >!8$/z/eFWQ ;1y2L;*æ,؄Ӱ̡ʮ$$&}L؆\y[h,q),GӍMmܱ:#Ů+cU[q~>/YF8QK?d#jWoڰ|V:GQ2KBhedρ >t*7;OBc>Y%WK-qq !N"HEv}ư8OqaX!3;Zn0)]ϩ#tF PMN Oc[V*j5X)d}JPW-j_IDRO l5qJJr@Xwc` cAY΍܀whxG q$Ӳ1)w#!rڱD !g?71L}WQG0r|lQ7/)_25xN)VOqh^f]3rƽPP7{ӻ>mjo {Pƍ$p| ^pJY÷*~}BUboX.3Ksw0|*c甛4Zyh!:F+*ŷKQ$Z")_1/^:[Cg[ Iכ1č  73x#/[WP1`g(+r80wN2u|J$ Ek;]IL[YG/e?O60$TY (8,IX%quƀB2u˽~;G ~Fܕ=$y+uR}5pXg{ D )Mn!4 {FKE=W{L!! ŠfqnlMH$6HWU%pm\ Gū~CJmIp5e7Th$rxŪq28vߗݽ욉hZ.Ʌ^O=jG ,M/VA2Q7U8?Pq IUl,#y -ȁ#*4yWŕ{_ ߄q&om5WX Jծn4|a!y)5Nل݉Q&|sz,7|y wo#C"WkvJ[jj*bd*G.(GtX8*bNȭn -J*o Ln~KLUv:6J@^ѝۜ*It֖c60FhM`^dSnc-Ad_ٌ.7*Jn3ՒܜS+HUoٯOK6`řz ~-?3$e{h,A:wSm㿔:s޸Dc 3e܂~  `bꥎe|O7Lt\5ʜcm?.S1E(,^1K20fmܡ3r3w s^,GlnAT![dRMt}Bɽۜܖ-yXH3W\ͨ`@ŕ|.=qCT 7Q̾ޮ. PYVF@$z<"]Mx"6ؒϮt =]cRh jaOMf[!yQ.B"c߉rMvridC c/k<(Ij҈[׷B{򋀛r(x}~dOH;`|4 0k@cX+tϪ])lIܽZgC?6Rd'#8%-$w_2/@!VYHI"ᆑw)Fc" dRY~”aRM_'ʪ^VuIQ wnL歍ѡ.v54:nm^3asBcHy :Eދ9lZQ|&Ew~f-]Pɐfo["cr3ύ"aG|$&~ j`)b8ekHtTUfȤ0g)RJI ABU=h!baȘI?:}U|sQ7*էse:$w4ꑋFk,JMRthc`z`-v=M.!Re;}Jχ}F?Fbr;K@Ɋj]o]G9x/; L=M1 ძ-LEkrXg1+|Ur4ݖ`QeF4?Yc¨ŐL- Er^_J~nG׍{@xd&h|j qTr9.Tx-u$HǞXÙ8)C֮Aг\ 96TьTt2rCt`"C:$6t}eIDΓSe5sS)񌢚[YiVLE4J{ b8̀+ &U?8BF-Y:_aA&AQ Z쵮ra$;Q?ZvjKhQDL#tl3/X g,`r}65MVy|.ayzEl#WgXQ6h(==K61TGt.+$jD=Lc%QfeKbim 筿idM !).߇}!TJSkºyZ1_%<ӥ 00k椁s3B?oItpm.Pp#[c#ZVב4/ʗoÁrˋ+k53@2@7 i^5٢)nk3v1Z| RQ3ߊ 8ҜTP42ϓx|#, 0'i"pj ]Pth]px*%D@l+ҫ~`)W EY" …˥E hkbaG\L\Ƈ謚xyh0ܑ4QhsK8xIaLY4+~1vl Ze^(Xvc=6pwmyJ?MElbʺ;.~Ԇ8G9gfxAG` њUJB? {acl $~npr U|HK{ڠ3wb&86 |ZęxVGwDrw;v 3<3mn;ω1nhq_nВyr׮G ` A1#"en\^ i!>"wÖZ6c'8x<1\uMKog3F0qV[ѬRjB@{V ,#> >n"m O |lnfAWCN4:+?US2;JE@l/1eB.8a-tWT`R!- ]]VSݸ}nw'bŤ@ '(^/+ B*+dO<(zc䝨Kv^L 5&HT=#ߵ= 31B ®WVul*ͭg&,Gͩ;Ko#xKJ%tx:+Ye,WMF2oA|a;MW A4e~,b=}:KH j=2#vXvӴ\fFl,Xnqz^ j376fH^zf<24O94Nhm]GD ]ЏT#QIq03ݭ4ҊaǏ􅴁Z,brĽL^̉ Xx̗mPFԠЌz"띕pIg.NjVJ:q=ՍMOױ~E=6EqF{*/V({w ajv(I@_@2*~}0E9lr A5:NJIl]hV -Kpq ɿX" NsM3Ⱦ̐IrؾhU蚡y(.9 &vP4ϤejbW> < 5S!t2& (&:bPN+7+7Pa;p28,f}[Q( čYl3(H[=(>P'gqV5N;!3T- E<$ wg46+FsD.<6g_PVp(Qީ-1Q[5fo̼OD䫶 #{^ 1iC/,++A`[vinKB<N 40vl]Gh+2;؋LX4r5eOD(`V&l,5}'toPMg$jOr^JAfa);ϭ'^*B. Y쳰"ϜOF Z8روX0GGZ Y} h7ON!QZ p#DvuCCa89C_o ә6G lZɎ9ٷQxK%wY,mmB\~雪oRQrɚ"/dwD}]1>?*$<}e`j,ԉLAQW jkzs%} .KYgZmɐIiW 0Äd.;'d-+OOіn8 $Ԡ|Q_pF0(e>9æ.zNqR0xbvq62zj[KJ??,(G_QbCDĹ5%}1-q_Ƕ@MS(x!kcjr|*MԺFʓk>d.Dàb́Y"'xeW)| ˥w<֞æXil5<- n[E#(/RĹ ElT=vX(K; g 8(zϿ:VRB@Svqt*en(xvڴ P ch5(ӎJz{Isb^W\P()oP0PtY.GB2:KGfz:q7| SjLոa$6!7 j14VwoFUHjǷ/[}0nh:+ {XKj ۝fu3OGBϱKcdȂ_ r84N&r:gu)/v_o7cT-zz%q_1Xq ;PEtgfkhbKPr҃ڂh*~)Tg2:Ruկֲ7VA偙^d>E/ g\"Im4^ -jAoy@[XDXa<|W|zw^dhV%.鹦G o_j9?q0#NvWF$#9\' =A&>%ٓbx5n "{O_y2lq]U97 w›Zb{X_׳үW<^g!:ywsvʒ`w)T3Q;;@]H cI\#wۏ'޼Dg}0"q] N/t)8E;EZϟ%//CJT'`y }`I [V̚, +vt٫4%NE7-o#\jsQƑΡuͻ,^pqjYW6g}T`||DK0ÝM/W^.Qn0MJ||#̛)g HQRsxۣۀr%w@+JRq( աm9ZG*W24&6 s! [2Xߍ9N9+ `y= l%]llx=wӬ_]d=7'w%oDZڻg1 tnE {m .2+QpfY^H~N"!(1a[*0q0\_ ;`7+ E'Տ~V0Nz vp崤FP:vsOrh@| zw5B5r3K8i#e5`T1"9>1#$ l` qgԍ/ywDYfWX%L<ۣ)Yt :*8k@lmO)a7>jt5[s.4?~WI-g4BI#ʹT=XjYEbMBΥR/&m+?Uwc[ԅYK&Pzan}s .=!\΋)HSh3=[#A`OvBhc\Рזt\->|K;@CKԱE2_yJչu#{u72s ?e6ڨ*Jtlw`An:WWcɭ=bՎLb[<7KXС)Q︐~Gp(c |\K"?G6酊Uާ5o)eD{Ϧ<]xbイ\d#.L݁ t>'ʾdek(lޤ }͡pqmt ]kN`h.Uzkˢo2/u!@/T1H2G RE0O&UMu]/>V}f;dtQW-%\̱ bTۊ d*vRE:k\=eM&_3`! p#]NS:\uLjMOPSMYQlW®3;pha26c)4AȓFɵ6)[l/g|FhP ) gt,Pֳ|&>QRULut@lk dyPJX?@G[0n)5@AYke.:GQ3]KhYDHvre|X5}O7>xaʔ<;W^y??+GW"K6z44'0l^"3e$3|N L"%"@H/y3cެJ~y.f߅^pIi<CNT?rH\LԆ:hR]=> R&(|;#9XIJ̲/>.:yיS q{O+&*HUw jA#pSDk])&_4* RĄhIr'guD&BMs @;n F}We~&Ul`r ܽ@_)qdB˨BrG\)ht|rH !̎])C"__Zcn&0|8f إ=P/6w6K$^(i)ł?3@0(&od3g%I"#.2½gv/r/mfhؒ9J w?%g}׬$ũT_st{0eW:EG>6 OW(ۙ+v)t/LT)!'D%降]pϙL 蠆R"")bhʓGj\M%y*2j7CuGBM)UО>`k&4u vQ:@w]T;1T3%zwoCaK!a~`s=N#xkW hO`|Lʞ3R [+n鿘)NCN^貜>KY4y~VGϤ)^4* 6inCh\j-v:ju[JzJݛ9'N9}RR0K ƨ,c fcKB3bJ~Y_ k|>'$FhqfKR9Va/5K lEҲQ7/LxN8v= Yo7A퀂<\ө࿀>Yk 7[#JkpcßҥkTJ8"20j|X<-B-,K.ã[t+Cڦ,8&[rpC[]55ɍ~hW*"|k2+:!AP_yu.w[y1ϛ"xs|[qT^Són k#7GtDqPH<~[HUfØQOZ{"\J h$s״~Ʈ7g+L'CHl</Dą Z/RH$"1;xHi1r:#ia&Vr]QU]5"././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2304084 SABnzbd-4.3.2/tests/data/fully_encrypted_and_obfuscated_rars/8a5c1f24-55b1-43f5-8407-d28d2c0ea95f0000644000000000000000000002400014625637207030261 0ustar00runnerstaffRar!$ s!1qyJR1:޽*Wq`gS?)&i/DadnE3aX!Ö2 o!GfmnZCv+2"ݏj-z}s{e,71ߖb2Vy]d󴵟~WW5? W?qB]^tuO0DQ+"e6ވoUtq{Zpzh9lE{BCBqOQMtWDY$?88)`% yz4i4I˴>cxC-詾no1rk``j_qa0q / q[r^R*g!k}HI]@Aj'aC|7ܾW(lCDVC/:\ LH `Z.ԁv:M/nE7 :4w]+ؖuC+6%d*tPR7`*g$.O!vM,Sty9sq́Hv(7[TLIȽ23=_99/Y26N"UկƝaA\ xjm ;1q\C*bD3fAr(7ܷ083F1!xhnr&QApa!&=WⰦ5.oܳfq^a`v{SH6? f&K.zSu5G~zTIB YvW,RAnM&F f7|24^-\9 &y _K *k*I MCO{5 2yA#M9?7 <EZ=yK_C(h8Oǧr.ouXïqx{wlɧV/o`jpì.)A=*+=?fE?0EϾeO9cG ۜ?|+n7o(Cj>{S "fQ.`Z+_cVYgCc0IE8bfRdG$<=%?w_!KEF UC*?iCQq& LEq`.2rPP6Q_rAɟ4RZUF-3`E @w@u頩H\yVbҚth&z@s屉kuL7.Ɣx0>B=: eSQm'WiU||oxi4UXC@Ud)0KX7[H>H&#Daqy/{ }~:'|3Ua)v,*\*J-`ICcs*2w鹙(;P龢Yl d +cPj7ߨ:)>1!޺U[2.[cK0$flD{9zRa89)0MZ|Ȉc Lp+9Tk:멚6l!'Qxx(^Uهk6{gU+v v ubҗQr-Ze⫛v[J+Ey}2eh-Y7nF'mlB_)ms8ˊ[U`ɧxwΙY-CS04bzǚ SVUC-@켑}4X_3r棰;z1%֨Uc5CQM?㉯9ڗxP7M--g,"_+1F Ʉ|M!:;nQ!5t-I&AMvVZ} dBSS\s-|66Ёl 3K^u,~MI;L{PuQg *=>{ږ #9i-4n+,(YfAV0y,9mX#bDaf륱K3/zUf`IZ6T*d"S5OCvI3&>qţMypf^B"@6^̛eƨ* jMX~x)]"zQ!Ze~(>U:;l\-)Z'bmܜ<9$b&@+:Y hN` D4#&^WoL{| WI߈̵$e+pƉJʔ.Eq%Ą XiG1P7z(|xlӹ qy,!h3hBc08b~Hzhr-9da_loCӷjx~")ibAF-2x3rPs[pVs91;wXP=ZAVwη-0[β/.3:nȾJ3-g6O4j\/ !vD5y[3d>Οk~-]ӽ}]x6EQƘZfYE*vzK9'Z@_ %:`fcX,#->GͥK#EI3*,ƴ=!>q"%;y%0yrftKfR}ۃq19**q$6JcJpu(WCg-QfqKF2 HN! X|87xµ4yPIv6q}G0KFJ~>)䨲҈wE-vRv/[\;{h2$|$zCj5+($E]w%to̴̳ə8˗Wb}AXL0W%DZO~'v̮b-hHx9s5uWh@% gH6:y6abC7_HDMК4phq4&8 qZKg` <_go?Ė: QQ!O3BK ]FϨ W~/e&'0 9^-ά6EE 9cZӖ)k5# ^EC sy+cp+Hf~ST j2g cVT')E C?p:/n_(#*>25XLr^6UKߔVkZāK|R^MӭBIڿL8Y/z AKm7/ ֓# G;3xwNkϔ (N-NSu?;bO8lo񬑛EF YM=a 62fyCϨIVMI?_hǽ!Y 5;MS5*]~G{^0lȴC¸aB9uUW׋% =4zI;g1[M,%Elf)C!TʥqUS-i'`腋u>ΜxmO@D[˳/ u0?I#5!`})x&, (dZʠgW=FnI=CWA3^EKc=7/wDMFMIS&Lg+7 |p6/}r_?wM$\{ a{blaӠWESuZIϝA@݀,=fx-]5h`1#T77* j9nf$E"cyq{ѲꞼ:KVhI`˫ddž)D4IR.vA>jJdEo> >Y2(+wQ9 GqDWŸT‡(a܃-VxK"Bx 8^|\E\G/Z+[V|Z-pg[ "pFA%tɧJa<>ja]7{JO@T ld kD9L9zĦ^@.oa3]FDM6qkPHj$Oѧn@+CgKQG _y>"d:TN HZ;:;s[Vylt&>dڸJG#?^.\m(%idy,o^݋er[).a@îvjqOJ(̓G3ˆq53,U`5gV kVb iO2NVf!fD8Mu#0Sԛb'Ѱ׽O WC\,x 5 z (;S.B4<]h@j#U/]ac$8̦q,8/}eT]U< =[l;7*CWYHUmv\pQyp$( ܰ3f[ ]+o=uExpO)mcS\z6tB n3xx *  9&~-r;Kbh{o-VۖV$EVoa |Na jdkaBh|tU㔝}B\r; D( yd؟tns` xƞsQ^["ԆWpax@d-`2V}m|d(F6ᗿ`T(huؓaqF=bY'Ȁp!=JL=[=2Dq^=T 5[ &ҏY'Yt+< >"$ Oqi'L`&@1D,Vy N` |tߡ 'R_m=8+G*Unx.Pg1%c0 tRh` ?|z6XG^hyK$t6w4KI V64s9;Ξ \7fV$Gϣ<A/Gua né`q<Xk 6<\*r>b TBe ;!$t /xlTÕ)0:[4'@ڌeт~:qw*OB=/ Vu.Qwj -sA[p ldѸ3k{)O!Y9p11 '*gt"b 3kX@-~G[6}JBEiݍշ3:@>~0v:wHh kW&?}A%-<<+ rW$|M:.z@l7$p,Deh:+N S;.s#A{6@" jHtBSO$]>jp7+Z`amI߂,sqEi m^L@$x ~${cXp@|AY6 S9DJ\}C PlxB[- /D)k 2ʏ à5{f >SMl!ۧ29c_tjBT`ɟZcku}[ȱyFϢ}m0ߊ,;)q`XFf$BP"Sl]'j1m{=*Vق#%_w$_B6Ed@m*YFRtJ=" /C3 p'kzkʢZ<"wU0NV~fϪ(3rW'K3/p <&Q/$vT_<4 gRˡݼSέ/scršQ1/!U-tAhh5E7c<"+I3k[|/ل@_m0q Zןj|a`svCx!ƥA$]R-avw[5_HrjTa1gUFFU6y>be'zIDDKn-԰$ww^v)T21pPM]G332–X#7:Q} FU4nqB`,fTq6\X~hm'X%&SkEf9jEe *0X$|>U(ܹ7q|T"!B!eQd+E\,_ i.l΋.~;$(7AIM̚MV`8G:15%9LJ9ioU7! aUY/5Qq8nCƘLqk[A//.~iy~f$mXڙ;u mq@*8Ԁ+C]^5(?"4X?h+`s$]j𦨮#@z9^_ݡYv{"e?SMb;K έL9rw/C0I+9[ښdeTa)[ <4{K@~_ ;F>93ϬVWl]ŃgwM,"{[$aV&:㶶 <,R$ߣAji>1H# g-ry)*ǨH'ȩ 1`)L4  rpbS=oV6D#by45l8N#/0sv0nWѯRpؾBbv`Y&iR}u+m!F΋uatߪuW-4a5 ;xyu?:z$66GbS±sKϖr5QA;ly%9XՕI0Z85mBf*@ܗ]ȠWmIܠT>AddxV]$T^d,tׄ#+ygٲL!Ǧt "4 RsRes]29XE !hZ[ԣ0,cCB4;. ]H%0UmQ| Cj:*^ϼ36ƚv?Y*\'8bSA~U1T3yo޹O*?qnx˗rMl .Dl9sL%%Z?=5ovd@PfקVKo\yXNՃMޡq gH2(j5 80u vZGsTf }Ht1 F/q5 s:,ocKU:Pӵ lH}MB >m))Ԏ~@tIm]v9 7Ǩ>{Z&OܛWk]TMD\>v>yJ@}6$FU ݿꨂ6'=YKl.lt "h4Lz nP_E̕V }|05XHY$U4Cl4jjgؓRu"-#k:PgnFXr,m%ʰ\ULcӈZשL- &ntЗ;ӝL|͈3{f*"Ҿm7hI} cEl]OxnJt%*Xi<3er<Tܙ @4 KVW͸I1F/wx0#j]y aǮ >Xֱ;/Mڶ)FEG+=~+n mk“L%ܭ9C-eV7qd@ *x /ͫԍTMǻ =LzԋGN ޖKcY9%$bx3?}ž.9+Q"m/tB17~Co6[ Em:5fhr@El%C}O(&û!Q5b4ZHjmB ?oid,#8mm9xZxe梧>Ǒ"BrǨ^Qtܔ&8=^ȫ%ʪ.,dGx7j q-x"xW Q uw:ZfȮW0֥{\R5 p^\'^_PbCnk>K-GYd8F/dnֲM01LQf%$A[m]1#cbMe&+tҷ;dN0_D$cEy=J%˵%$b Z.]LcrdKTC8Iϲ]c@ U,=]`j`Ǜnv}f! r2C/!h}PU\m0p r}eA h0 оȨKsometestfile.bin _r5QO)=9?5#6>0 оȨKsometestfile.bin _r5GQ&././@PaxHeader0000000000000000000000000000021700000000000010215 xustar00115 path=SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/b5106bf5-8054-41aa-84d1-370695fa8534 28 mtime=1716993671.2330854 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/b5106bf5-8054-41aa-84d1-370695f0000644000000000000000000002000014625637207031067 0ustar00runnerstaffRar!:o #6>0 оȨKsometestfile.bin _r5QO)=9?5#6>0 оȨKsometestfile.bin _r5GQ&././@PaxHeader0000000000000000000000000000021700000000000010215 xustar00115 path=SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/b3e4bdd7-d161-4711-8d6e-65d9d4070b09 28 mtime=1716993671.2330241 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/b3e4bdd7-d161-4711-8d6e-65d9d400000644000000000000000000002000014625637207031316 0ustar00runnerstaffRar!#fa #6>0 оȨKsometestfile.bin _r5QO)=9?5#6>0 оȨKsometestfile.bin _r5GQ&././@PaxHeader0000000000000000000000000000021700000000000010215 xustar00115 path=SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/75fa7ec4-8135-4f62-87f7-ae4312c6627e 28 mtime=1716993671.2328157 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/75fa7ec4-8135-4f62-87f7-ae4312c0000644000000000000000000002000014625637207031247 0ustar00runnerstaffRar!Gh #6>0 оȨKsometestfile.bin _r5QO)=9?5#6>0 оȨKsometestfile.bin _r5GQ&././@PaxHeader0000000000000000000000000000021600000000000010214 xustar00115 path=SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/ab1282a7-b77b-404d-8c4f-9d2e69ecfd66 27 mtime=1716993671.232961 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/ab1282a7-b77b-404d-8c4f-9d2e69e0000644000000000000000000002000014625637207031402 0ustar00runnerstaffRar!o #6>0 оȨKsometestfile.bin _r5QO)=9?5#6>0 оȨKsometestfile.bin _r5GQ&././@PaxHeader0000000000000000000000000000021600000000000010214 xustar00115 path=SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/a9cfc0d1-1745-44ae-88e3-c88bb0239a36 27 mtime=1716993671.232903 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set_missing_first_rar/a9cfc0d1-1745-44ae-88e3-c88bb020000644000000000000000000000616514625637207031412 0ustar00runnerstaffRar! 置U0 ~U sometestfile.bin _r5wVQ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2389445 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0110000644000000000000000000004320014625637207022701 0ustar00runnerstaff1 v3̺%?tCY0]OymNp4KyYQ< s {3S2 v ^T:yy}we/xJ\b ([/wxyb-B yTF*!67R0셋WZhNUM\i&0A=h ~{ΨKF|U_SƝRB3t㌂,'7Z4 !&JӴRkMqg*EIM{L̒@*iaS 60kI39ǔwdOio;V=5s@څR2jдthɆ0>dШ oqnw>SΏ8@Mdg\zO )s5i7U[=ק{gH6]!ѭmLё)ZdlϜ!\8ꥊ%݌) hV_Z@#7Cqu5N!c;}0:~>U9x৽0kq;晪 (\$(syٕE{`%0@=}g/%K?5WBִ@A\Fz:mceУv{֥oZEx'O`pK2X㑻M#Hr@C}~ &Ҟ+[BIuX(úwLaָjN$ڼBN1Tv!EL/Ad|d<&dx~볽cRfZ:C56h*Uc]`i3,m*)&U;< ,0bEYEO:2ْk* ,kRd99Tpa/"e45DZ”˕7fe P>|xjQ._2K y8B-PmS ѳ9K£_ .`k/iivɆDRЉYScEo.K)E3Ɂ ;:M epVٖ|IUR9 .[hK,K haݚU{::'~x㔐\tgqurZ-ȤX=ͥ@8>"< G V3DJm=>n'ױn*p.a$lMxP.pvİh!9qQtdZP΅Ȍ\RŽh=$M-1&~QMN^#י*30f;'.ZZ@s'ޥl䨷|䠖{u֝m<Ťim"A#μiWGb%Y6]|5VCk1&1X<(CףD1D΁t64tQ֖>J&F\c*V+5N^ol:~9@;>k3b@sR!%#b'!7jr;pL35GUa!~=zvQG;R4[ƍTl\`܌1X ^=g3϶Y5@e%^ Fݝ+Ʉy w/<8o/83fbL@Rm:>ڳнCs>b(SRq*- xM5Ep'M5:I: `7RT:m߷SIҸf_Un*l'J9UOP ;Uw_{qmd~ OP]yNxQN[Â#3y 2A"]p[͑뢒!'U[mN 鹊DH񕟘nm;~U5ǥГ՞d50ͳ-^p3KСWӾ6iq9׭yA K~w/GHi~Z_bG[zU:wʉvT4)ddACu)uL5<؟8ǫwrI$LY0 vCݙ}8"Up &fcQPShWcߡ=x)n X-17~m4ޭ$vW,Jj ~@5Zzh%hQx2ҭ>*c7յH0yg˶JigM)|g"$vb> T ?DWwx,~{lKI~Eӽij@U23ϧdgh!-ȁuat0XL8."ԑFT]PJ*O?]2OʯA1+D:s ql()R(] ]9s-IkfwQm@RIABylbrƈ?+"ë@Fc@ r8%> h 3y*#L7 o;#z:+R3u KAMMjdl틿!5{ ћU;aB=/qCDF0j=WOS]$2n x>u3RO< Kz0j)={DHX@J¡Ou8fp 5C\Pmt\Y( 9`q'59jwTwON͗؜-lP݀S')A5`e. ~>%%usY]-{$-/Ybzey3lt"25;< \G7t۫]ƴqr{9yOf2ܠ,Uĉt<~}oE* b2f,rk^?qu䍱t֬A_G[5]A>o 8>rQ3SA;:84Iq*3}*ǂ=;Txej;"K/HYwV:ce9A"٥W4+xf~$ DZO:UbKzJGcY+D@>֮X2@PTAނbjKZ$:3N~SUx}g<\_27=R0C pRMK <}hIR0*W.m|3%=qH1Ͳ*5%Nxc w9017Y96ˣX$ͧ,+VN\ÀAgv0ռ7+#=5|b2N<Ε H=jrG6#\S;;M.tIRVMobNƠvSN^& >v5@Jg3΅dv5=,mϑG=vL Ez1ʫ)pѰ'ӓQ£T0o@AU@ч&K0&vE(]U o,$(?h+v& zS]KYSU2ߢ} 5P-wc-]4&W&NI2Pi#~'nDW9w5Ku>b `lW"_h?̆&?,ڗC151 28aҪx:D[^#E5W>*j~/̟L~z/wG4nU(w.m ˋ&WDI.o"ƙʹ+ii;U׷U\hmzl}DHbwಹuaT}Gч Pz˝,l @İTTsx/J;sF Fx15R &WU]ԷP(\.Wd_TRށ[fW5XeiL92Kn-B9Fy'5:Mwb Gb tVU&'#A _O"dMVNڻ_?@'K*[W2hU,|8T(To|.nZFL+ZdGgMSR[@sUٿ9OO7yp _!_7Ɖj"to{[%f~3cA2Y+F%Sg ϙIeg7k`ifC}j@Vlʹ]s" u Q2v4*\u܌KܕYh5' #dr-{ȐڒxZHQfh)Bw"E+yI?7 2lF5ɸ,b "j 'e:`m{'&FLbrmxϹH'zÎ-iZNsqZXX3 q$Y<V^<㡕PD9ӲИc4j>:yBScwwG7כFuO,tu݈l5u|LVhWÎH`qF$^@$1dMP?|"al{^א ]^䅕/d"ĨTp F,J5:QtIG75/?YNLfllf}]it9ʆ޳S;|m(x>;˫=n|VogL9jXBhp(&_0]5Ѣ`=KnuIbNJS9qZ4XY5|DfցQned*STԌ%XMb3wmMn!]wT8{}kټ (|<\xd΃zR+ FfPz-n])V/;eir.$[ݍq66o4K\;;-zuF\ߗ/Wy *S;[;:FC}:CN:k <8]:)ӟ]ˍDfX@#nYF~]0"( 24$N6)xL,Îs+_vDc3hsA(઎tRdt I:u ?(?CZPSF[_:S.z@ &N`0'KaQ]3t<}I=J0_S΁t&tXbCf-FV:݅C-7?^o\O$F%:zxsu_̺^:k 6\fĥj &*5(({Gd5rזw.XgC,,+HL.&-~~;B=;mKxvV啫G%,@j-;Bfۻ%d[L@3Ty40᫽J`3~7wFRyZ a'___SNaRj>% ²"q+wMqYRsϛ{H^C 6QylW:%4x׵@aJtXKZIBaOI#={ .PQ OVuڠ}nP{mՅU(f4yPSE_x|c5RyJ\m5&'_*b4 Rg RȞ4R{@̢(Dqcr[^':Ǿs k.6`b͙0역%C(Yx@I3P4X ċ D[ZcbU]|&Xl VppҏGNlwW>bf_IK_8 S?5 \I앥AճJ`ΐ]r"V=\b@@MQlS"O}h/q[*i͙ƺNpxLpxtl2"!':;\ss\_Ѳo;C<Τ[ S8Cw!g0A6{Zt$`[TYɄEHu2ؼ4+84iǎv#KQ1N/էwW!Df+ec?fKc&O~ !jifKGڻo>4{>/"MLG2-ё>^ZD&P . BR=3o d4)X6zEXrzX!hg3 f=GSaO-ǧkfyK=qXgk֤ھl Y>&gg#Y+ ƪ$ I:ч2mp8]|b(P\ҪO/ߏlKۢ ),z׾||M]$%?( ij?7<^ل'.}WNȦۡe)qfɕ0qCdjGdj6#ه9WH\k>!ϊEMNTг Fw[  l෱J)|Qڠ1cΜ8oo֔(BNfkHÕnS*_?]w@DTL*uWr>ȃKŴ8aKP΃DX|Y6?fu43<) hZk'mP߰@fJ@"<Żְ*8!U>!UqBh #ot.#.NP'Sy֮0KbPNHEߛܘΨe(:Qht cVX>A,#CF )ϚZtj5`)MV"y ]wF4nv4q6]#Lߒcq nyTۻFhl#LyٌH,rJjS'=fHl]%wzW׼Mz25\pс蟠鯶#I_тGXVTב"?M4N,5jam!h2.(^-Qqc@2;}bF& Tߚtzoji1 CET֊ԻG_բpR$y1$2B!`Qe) b? |/&-lknX_!">Ih=\D-& #I+$ G h0anlH|(K5ct%r}j?I;w+$p \yW.GxgҬ5OBCo;|Mo"~Vr1'ƏB_ج=ЅGz1W5擜xgFZ5o0{%jvTL7&}jYaJtfdd~&';N} ljvmž G] bko#K4H$aN~t馛Yc8 @t1 *x4J\~;FCMM3|3kL / M %{rl UMmEyKcpXѐ&::F38wjjR!D6v-y?c7UxyſA >8O$x85 8%wy5tFS97}58#ۄ'{HI +Ihʜ(kF MWJB=D F \82hK/Kl7!8rg׷dF#n1?G@)tRUѯ.#[7k>\~|X>XoVQD̡C4NfM#f/MO!2 t ,N]=yZ# (G=_9 J\J/[&?4GGќǬ' L6-[e`v>? *pjF++ڳYup a"s|Z7tS'а [flgp=͌,VSHD0ĶԶWFQUh6Z #&S\_lLSv(Bλ N=]DJdV{q[,Yu\Hm魅HV*Bx^૸Ef}%ɭv'WZcc1Lmjm9iKP!'bZ:%&ljX >6HN]H@aT4V {%bMv1XM\7 ָuȗuWۨ/qkSWR;eESI /-m KXYM*} ̞lY(&p !Zۢ;>RhGK1\ݮd2"k$-">]EMW{s2WѯLx22C4\j1p e9.(*zG~ x9նZ1Q1Aq}I0Y,W{~1ŖpnK'PC%w W.c&'miatkvx͎5V T߮_?HO̷3[ǽb)j1e ?߁&^ 撲C#VWF8$ӛ)!#9Qrc wSa&cϠ )-XIJ%4xf֣<4. **ķSŞӾċH/BYh]25уа9l#vfqhag(`CTߨ\z-(!7~Kv_땈-f13RoDB':] @k>UUNwnmL:9FJc98πk2j̯҃$BJP 0oY!MhVmaܟ< !j C,SXwT)B Jy"㙯Q a=DQ{~8 C^ qb -TRux]u򊒡 )1LjO:|k}{tAY|`/vn$2-ѢpMO;RiM= dzk㾇)x! :ۑڣ>x8'mZP_bQ@&ԕrUvU l.a ŕ]EC:=ԏ\+Wv4TߨEO]!o3C4!pwqݷFa*0+->Y~FShX]֡ͳN#Ȅ޴<2'-fg&dtr2P-(GYGX(g IYrZsf1O#y >,#\$qڠVx;~irak S|Wqw EO2.t444e9oO=+cϿ:m:{bdZʏ/ ̵$oyfݔf Vx`,˟\71]V0le} iCn[yJwlu :3q#Sdחf I˭vv;L& Q"¿| ͆* r0s@46"L4ٓN4YZXK$PbGYh1uE[$ſ֡vҐc+b>p5||!1t+y Y0BĚp> ^OG%Tqrp2ڧ BIH*(#9ax+X_JE&ȃsBidJ $UZsgdgġ?5D߻GQ@Dܚ^ `=lCf/+$$MeWߵ&p]ӹ׍s>*:h;*6bQKf<[>a_sI]Cf#n _N^%UOHr*شN5$aek*na8$ -OaWDZe1m~f#?[(@}o gsp:ǭLe(?/Ȱˍ<%'4dTE=8m?&]N_V>O@>fU6zU H:D,;nӞ돭RCɢ֊B"`\R7Odݮhpml*tE(/Κ 0yPyGkl^% /So)T E/܁oeA|Y^B_8d<(ķwÉWe:9T9ÖİO0:~SQx|UCIJ+2v=+wtJcD^O$㾪|30năTGTQ[Π.dzV/1(tj;JUp.|+]}Ʊ] %yuLun))`l {>x2=;̰歋MaI) R%X*mYS P$>Ab^%*BXiq?xzʊG:s*M~SZv1ʑsjVqL:.YZFj6[?{-a L{w0ßHCwnaų/]0vn=,Ea}5aC=ܪS{Pd[LÑ+OtHr=_qY? DPGܚdA@z؂8$tu bmHՃʝn+F(y(O8 :X !W4LȹĠ.lPjȸ#Rѐ0V*7)hc`HS ܫP?Rv p.}#hcA`$r12޹mE07Q^yͨ 1+7 R}I[Vw.F>H\ז硌BT8՘[OJx+}4@.,fuh0eoq=E bLRN ;"GMoMl\~o%'t3ij_ ]|k|=vaOޠXjwȐi|7sW3R1E_5 Tzײ"-h8eZC0 e{(X|2ֽ'4lܟ9C-kz <{ERa8ڄD1mg'yUǸDiqݎu4&K ֽMERPYgA17U_6=Q 'A)W =Gw E̼(Nzx_թ0s0E?CGC6-Abj+Ë2u0#JS@ aHMmP%98t;N㜤Ms3=[INrNJ<6= k\<4K8<>Y 算I`Yώɺd'';ֵH>N)ߢӭOeMݮ8k]VöT]F$q(qM.L#hR?"e ]ecG̈́z;[ F&>R4=߱*:,ȷn *9F[_^9tly綶BJ;U%U]Ln4ar139c+!93 [b0x2(h (lckJfWxR oN8\ͅ}L*0L("l ͡oxZx'e1H܈Bu'jtoc@:{ E(U[^| _`?"ɴ+`7񏅞dqkT,sQƻ:$e.x+%Zdn^<"/'(r)'Wx1—=b x -C P"R=KB -! Z[!#zߡwo׺<(K4hb>:"'y.wZWL+ow]ƊY7#ˋU/ [Rw2 9(./Ca4[`T*C[ \@UYFN.wI7k$@q>{i)3a`. @^;5bgbԉ5/k(<70P˱n48M7pO._|-'g(W84o +$9_\gN}z HHECOtgƶF6EK 7Xm*oR)'fKq TaAhV@7S,3{!+\#cӌIK|-6ThR+\`p!؅`..:VdiW\]2⍴R׶uUe3x䦣U)&[G!|E YMJ Wwd@ϭ4m@QbSDNg -ą;iU߉JO̧=]`Dp0W@k)wt( p{~?#bbvǞTڰ@2G->?Ek0 6dfC1_z]LWh!*֐ x= |ˎW0hs!i< ,E6g(h=(Ci @#SRS/]I$9sz9ro~p!Sk5!cU!9 &h/gZᱏX3^c~K"e3^S~ ;fOcp7$(퓂KYqS<r+z;GwT]>jse2 rޓO9mڹ7qF(`$AsXк?;*9Oj#1"TI?%NBfǮ.{=4#iYn?ei,Rk2 ?;3/jhɳx3ݏvȉȧ6)5xw*hO"i(v ,&,oI|f7ڱ썛!Cz pFOkYs,"Xc)y۝g_^q[7%H4F|Vp:'eq<8$:)r#xRa[lN[`veFZirz1T/{G]qhדVQ`A2,|iQׅ /0Fq1fS}x )]hP4SkG<[kVb6{Ϡ5{8+I-#5>׻9̫Qh I7˫.,;D/aRqg}溲 yԐ_ߡᢁa}Kw#?E0Mw:^/87$md$^h+n,>VgC4+g /1 F:jc](c Mqɢ4{ "^i@ܰ/| RpM|o}1]9sOlyM}΄^oMR@S9b{)$chݵ~yLZkȺh_d6 Sښq>"ֲMz뷴E@P‰-G2O_xuqm]<@.W"'\6yl;Ϩg/| v8Lb3J秖ZT1] mY29ѿ67, 1m[;zQxHnA+&66ťyz<@v#h9Y6N09m\73X?0|n\52 D0EXy f[yz ѳWOr mRTILaw-v˝U| F΅ya.#+d{ule4o:>C,F^ Cp+WJIQ\7NPV=45`NCII6n}nE'O1x#*KA(c?/x ^t慩P9vq2o-JYaRk41=tB+zZon1lPʤf J.ך_yT)$ i^"8WH v~̍6Q LNm^08-DX;҇Θ$ZSM>ץ.%T䳊bN`]7ܩxX~2fk> UyV~aT D*5CAb* 8q!: m|ǧ`;>!̆܌4+el+|m1zf[Ucewe޷rmؤ1 o+O) 6o[uKy0'S* E};6=8sujp>h=G3&5!0q[55ffx~.`E<3*'*wkw'a}U&>)F9e"s;Y 'FM-(ldQ!A;_8lYkK'.HՉZ5L0N _bڥƩbFh*T{Æ9d|f8r[$ ? ];WQ२ƌRTJ!r ºHz%c Sy?}FB@K& 'O E8 &5s޸'1 ^@AIWlI/)*q՜<-@+}W`W pp9/o_ "8dy;Kmu'zVp F3HxNB9"޳@!dD*f&st [tLsw<ogktXH 0n<$uq!J%=oNŚ~$e*Ml;2e6^]EO0.s4Z 1yJ =}" l#h'"tJBfk'_FSk<*Zl>7IW,UȐoks=#Jp fߜ8Iϒv2tRF-u.-wf]d>GK  -fD}30LC&C$rOrҖc(?D89Ew?(ܣ,HNA@?q^@1A{z W7[R/~[ha=-^.}Uciip%F޶O[bt`mRJd ULUAxAU7Mb46d[kFRgE,dJ#~ O):ΙO]?9o0Yon Un߅XSpGx{dDI2@;_ie~xHק)b5=h''nV-|Pm<_)X,`l*Ȝ 7nr„ d-3ĴS"Yhk<-/{X+q KRo#2-$s?:OLXݼ'U*i}5;`ʆ5Wz?r IqqfZD@ ѿ| JuM ?`ڡ ]&f y'tDY"=eK? O٤X#g\̢Qz)m%wƃEu~0]=BmyJ]8Sn#@2/VŸnbZӧ.P{[Ek"a$9Ha[eRہi_Weֱ 7= >Ϯl&1C6HgJi_V[F*yq^ϔ`PGs|8= /4LूT94f4ϝt f.ļxYUB(F]|J* nj4~OQS[d VdsAS>ڰ<M$FU9 ڽ=Iv їމ ְ/R6āDuogO oJV=}7z'XdԢ vsǯ=c[rRF,~c3_p}±.rUg4Nuvi {Op9D|>wEhm-\2LI^q0ȥEDxѿ՞*v!aq叚M{F.H@,p >o} _>_QY^ z{pC\' IPzh{c+vUWghFÆ>w-w^D׵dܦ@?xdi$T#e;c(Ewc0KiǺ]JlƛfZڄz:g ' *}P.{+? (? >ߙW_g_3I9"sJr$csG2̇=LVv![?53C& xM.,Z9+]a0B޹+z%Dgر⨠ 3HfX = >d [ޜL,@R:m)ԩv'=F38d]c%*H׊w`ߩCmqk5PmMkzk0}p, V{H'\Wgud'_ C]NO1f |2QB&z%"}(=^8U>2q.cOcTHOlk;?i$ (wQOwCs:(zYB 1Z ^[=.աkx=co+U mfvb$K)z}F~[W~7PoA FNDĠgtdв=ƴpsPTEyW }Ca3cټPPu?+r Ts{*p :[\jR^!;*+Nh_LPbϐDsTo ?%Z@B?0zt%c n8'1!POB6Jt"/vwD3錥v!P#XyPd/_g IkKgQԸ*~Ni.{}$ 1A⊥jy*-57ꫪun Mp8U.nA 2QXh7r>v¥ntNR#OJxEp--aNq'L=y>00#8¼Gk⨌|ar|ND㋿t_PR6n[HwU$J#Ԫm3pE$ u{z[ˡPO |l@ug"e؂UFᜅpwv 6pN^!#U/nxE~7^<]vrUYP\Μyw)r\ ! {0TXE2\{`~ɬ9oZWE0+0}|*qj#|-M>Dj;ӘFɬQ){IHW'I̺f'37b dغ[WB7*-oM>jh^wb7|"=: %IeD E$ABQv1` bׁ#=yy3%@c1mC?ZCҷ` WXK܇Vea٩nH*'CZ#.g'e5X(KT ^vVhXqp)Lٛ7,f$4K۾c aBo/A.'|咆Ը oInje\\yK T3kaA%ꄯ&-ϼՃ/.Tlp"^S>0&+gݜ6eX) WȌBaiөdh?qțKYT zq8+_;|@Bgnqic6%ht6{=;b蜻n&K#"48({92onpfxĭGFF6pnFˇ!-s>E)4S‹8ç؜ET[a-E!3fFY9Fѩn 36]艀C5)(K['ԄtQS 3Q0$XMbMgM̓w$ϼBٿP!\IX֕#GPQ&@wb9cn#̸y8&X9~b ǵ F,>@Iu 4Q#eW?yvef,WD6Tz2yp LY]{!aLSt `شt%d;yFE6)v"U[zeC «έ2teyzʡEO:RkLf0 Dt̸d}nE #<;20SIٿM%uBO귴ȗ돁܂ӶxA9bOs

9CU GFfq҂#͇-Wg;!jp%E<ѣ==T)BBKia8Czro ?$Yc9JOzt{., 63"_w~H*A+ohL;UHf"֔!<,jd+uTkE7[^ [z#(|Fd q=vf̺(0jMoHByyܳH3UVCfF?1g '].V fkdfE/M5 'B<SOtUYd!J UY-Laqj5*IU C:@'t^7ӉB4:z VF!k?Po~ .A "!e7Ad\C:F'd*y LF1*oβjz3Ӻ,JlzEWRsAS*U L8l]}ٴ@J9jYwQ)@;ho  \u A*@SYѻ|~0c=Dom7Yr 3|>e+H\qAmj@gBvU1 F뗌NKO<I|~o>-M 4|vZ>gS=GM҃oLF.@5#Y PJg,^(Dg] 1u.ky\n}6eDB\^]~|np\Tv-MG8֙6A$aMTgvreϦ <yCRl>Fe9%Ue ! egk\^s:RrbɈRubv;T0h۾?YM,LCn<pv%MG$ZZAvKL ¶z@B/ V݆D 7tCog?x`6UF;Ó%~ʳxC[[KACm.IW,Y\ǬbZ)Sɽ"X܁iٽct:!4D ߣ^19ti󶭋$MED W5NJ Bu:\o^/F3L~4dzGLYl G!.ejxI4щtB5uƎS 4Ǵ5 ʠ;4rY⫿{Az'?-%|4 귄k*R%bcE4}il橋Q[n|mǃ2#S^aPWK5\b:<ʋ)z 56/GNâjFs?;Tɗ$.HPe&2;֣JVZ€s!skl(͸iBt'fzq|g% c\.`{!eg|f ~Tb_*f}߁-Xjï0zM lS%4˪+aYft4,q弸am5i@Tv\C1JCJ f4qc;DV&*} |˟D<}{o-BLWv+fyx%'U%͌z0G~)Ɲcvd#ȑy`>>cJcY5Pb2Iԧ!(Rv`Ipy0o,U֧$o̞פ"Fߞ/(yCk:񶹂;M8;ொWSwd+5JTu=ϒQc ݊םeHqB |kMghU,M|VtM)|9B}%?@$ׂ է*+EÜKbBzjSK8-W)ZL]rfɋ"ԙc`yQ[Q-uch䙓&JZUd7 j?'ߙSsܲ1(GA6bWRHGUe.H)/]m7%ݓS^~xa"iDCV'ZC?OH/*TZ%?Gno$@\"G} #ibI`K~aqdr\zw}ڔ^Bm5ln \p"^%9`DѴHct ݝ|H\;8@14#&ⷀzMI=9>~Ï'Gkh cȯb_[h"}PʜX /:#[W_(b YW{3P^p )gT9fryn|8!(~YKZQ+2]Z¢9A g>X*Y?XB.aUuAʸcRdm^ 6&p }:`Τyse/1Ruڬ&_v?2܄(v]3;A [NĪr5ϡ0xjԛýr|@tMni/5JK=)¨ [jQ*gY-2mNx/z O!H]3ǯ{ Ҭ-ČD$8Λʓ< z֙)}]Ԁk*tl0Ȗ[[ueU"o#CC;ہi 3 |Pc2,\෪ߋ:z*ORNV4II'jfhA὎l|@lk1Vf}]t \(B k7ʾ$/MPGgA%K=!+ý,@S-kH:b#RW`@`P`r_BGkqN =4 ~YVfbzzT۰ AUzl5ŭ^>} t0:X mi4)@קoO/Y?Vq.~; VT41&~=پ0P\Xfّy`#a KAXNޘK)Yg;wu@Օ)kzd!Hׅ Ea,ܿq2pRCO$񞌘;3~>iCmKR6}^ȪT#(MGeVnG~ʼ4#-~PQ SSoLP?FQl̝v=KgGzJ <{-ܵN1 _N2v;E0 xoEḡ!emٷOZ> '|menqI;* IP!0 Iq[) ;H=k~^\_55$m^ްeQ3E~+…Z.F|qkE:籑#G+ig6FriA J=kҊh&Y&LJ( K.|jx/~OuVσK&S)i:s9̰Q,A$"'XD9(cu(ռeA˖Ȭ8 N} J|)Bm1'54ULLqkUKT/f >/MyLcbLVCKWU67]–n5s V ve;t(&wyE 3Fp)hJ#$0.oKWÄCƩ?dĽje5%AIؽdӣ!#ߥ=BjI{(}HiYBۍsO)Uth/&nkV^> ot[I оř{}gU dfpVyP03pxdНʻ֛!o."F6Hu Je5%W7.f:T fW5Q'LrkJ%f'c\&.t*Օh6oy'̥r5r?[fW49=~TkCCSYXRe9B/4k+v͔i;,`ܒVʳ@ 8C*/ d74Vr?4mH/0IN ga>Gmg-R)K3w r<=ljKe&ƥЊ':oXs=Zg6mYGJ1Ly,AÜ(Rɘ䞏zT9QZxXJI (îԺuSf?0] C =fJYh960k/҈NPjQytCcaʁ4gt0+Xhe/u.$\GКa) /TnkT"F ØI՟?7 wu%6k`{9ߙ;KjhRa&qoR%Ѳ$k`s <:kl [.8tx|P̱p.lb M/SF?Aͅ؁Ix9ާAͬ}M.'/zcE!@)|\.7HWd2P?`Z`X2f,(%5 4Nq?;#_ʐ=+ce~m}w~ϟy_t` nI n p-E&{D,rv &QW=)d-S+"XN|0TUQsG{$Vjmxv jaqO4 Eh'2e]-sm! w.ag9+IlPzijS%ζɂp"3Jj@fy-VV1lcCۄ\z : }R}DQC FИo%\\izE*өlE[pIY4zE0<ٝkٍ9QO| =zN:\*kj)U[G44g + C^M=Z{g:屼\Ky719&TlTgfA>9핎͇UHWKȢ4ny"D <"&*5NWl4>?WzbP|ݬťv7OJp[[ +Kmd3t{tMZlX%n=[B2 ԿͿZс k?=LzPĄF njy@hw+E[NG !o)d uCvQo7JICM<:j|ٟ 1cuL`#I7 v, zx 釿Ɏe ;"y̓e@봎#fǑU{M#^ `m7-=&WJ쏭Tt6 {b xXuSm60Ev`9"H#`?zSvԸؿf$K~51VZ|1p2G"-_1h'oj"I:"x:Z6.D" 4_3x e&xCNfmNʊ4} )UVU_a]m*"|1JTY.VlWјɽ"aLuJg^OKQSa -36bb  Ͼ5{ S M*Tf^ud:_o/ ~Jjq2Qw}R]z0-jfo!F ]D9=RBv皇N8Wm__~|y $rěImbjtO~4V+M@/g@%4̏v/*9\W2A0H< [E>*ݞ"|X:;"p`Zo/wfOyVǒqco.E~6'NEU 6"YyF^ĥtg` `O!Mq:?p@MiX.&VJd=ߗC3ccS#"7A U|/f3kE(ֿdvy#]j#Ty#_B]Ń@NG)pJة![Uav b~JH+8QDEFw}<C޸橐é3 ;@p[[ý OEKa9{pY4Ff m=MR˒$R "O";░D[xXC߱=?(ioa8xeTea2SǾj=m)j(+n !=~#330&oI"hED”'U٨ߖQ?Ҽ~*v7} TM~^d֐ڭYCX<0gXP{ēLBRw;<1i}_} 䰜՘:zҝ-Ԙ}^̝)f)K,EŲx+)14FtQj!C]pAk:#Е,%Lz1EAl>3]}U5$m}RgɘrItc6sU>}wA/ C2,M/x +M1ȄIx6Zf)o=h_`?*8QaH!<ظ:CfݪTuzI-;@ΰ Yȑ,{HH 8x8"CDAB k1Z؇9p#BC2mdg--Qb;KgFqsko0NVz8 m":;r ZA:+pa6nVeZb ۞cswܨ`/5O'~8Rcknkn/֒1XF"% V}tqǷ1͖M N}I') )*ѝuB6߶`䎕J+ؑ;zubA&^Su8qyəɭ˨]v_pу:y Bm &j}Ӱ #>~AlV`dq?)\,U(QXUj-p[\qR'h,! F: 5J 窐eQpis~Ƚ7Igc3lQjbwO#e4TTm'^]EPɓcU謦?nBXh;5`Rai*죊۱mŧ/fر44g ]fA% A6,-UK -e*AoMe 5[<&tV](O'eys% ߖ_?}Ĭyii+wzͺQ2A+>%d֍T. &=| D?w_kaxf. |=g>i=EKaGsXs4K̻UV;]ݥ?R S#-Rƀ>`pW`zvJZmD}g+I'Xi 8{F:ZsɣU-x>bMFo1Gb+Aw5vFBQ?L:0O8ĜW'/IQ;}sE~ߵiq6ri$8gVzq9OV,εw9_` V4R!6hOpsxu;*t>Wـ>8.k`AsO6 _c 2=5nfS㠦7tBtY60΀L-ժKo駇|.#JuNdtu_F{pF i;;@ *pFdm00qQ۔zql:ZR?ܙjl1YU duz[ng k_f^[R# b&((zcznjT?i}^CY[WC"^)(IN08нSҩB:p֏D-AƘV%I=5?֓Ra!=Oz ÐO+$RŦiC =WuVzi6Ϛ;Il\Fc?߀H)up7^Y"E7PT Рlt+Z`LA>+|Qôk[`,fN<*zmӚu( .S9#ig kϴ'4Ut} 9U޼5r2zS8AԻuG}\ySsyÏü91xd_"&_Wzf]S\Hl ̀IA3ލ n_8I^HaA(p<:2B8fhA!`jAcjƔJO ,i!N7tT#,:M.wlʞ@5:ihkYXє@ 9!-mAYiWXsiQ ٩t>Y&"{˘Ià raU!E5ORY1vwI(Z4j4mW.J#,pߴy3[x,聳fBCg."K97J"{aPXڀ4To#˴^MQN\N2>ýq'$KB\bYG-`_f#-R3.+.B^l돯璒yCWpeIxp0`#|Ko.Xq6`>`Ile.H'9ox1z#' FGR:]#ܐ]{0!d,~D_D4Ji,vh D:G.G wVUeVhWSJPSsx?[Ol~oh,j4-ZenEɽJZݽjt# ˶2._ a> svR9%tQ.ZW+[V=+Onӏiܨffz\KP@tvyn<(-u= Y/mD)a|F=C0#B^R'Ordv B6л}N$+{R=%}Mj_<;F3 hN@=zЪ>ۖ6thlbt˹CA*/ɴe K.˚"T*S3PJXyy|A sA(urӬپ ;Ҹ/;o_, 4:`i!ɔ?#% ,Ag]Bl';~o !lyV؍`BiGCɷAخ^駎;}@ɱ2t}?qܡ܋,!l6>883$ojW ?QnlvlE*AϗS$Mˮ ˄Ka.xu<83mƐ=(g;a! ~/iAg[4맣Q|[bEI5[&^a ȼ /.ӓbLܿ$}PaCpÑmǢCOhM IeICQgeq)z1@ySv Crwpnw&T&XFdϹJc럗}~n2~c9%RLmZz=d vQ5a7sJ&1ـSyW~r}WrlSW]cV0ikne-a@vڠ#KW{)8IHƕIٔIgXM)o@靾4ib=ZFԞɜOT_R"Sp{* y:jPb;6[qq_F-G'Q$Y7Xڌd-X=-%9+|3S᎒- ЄahlP*Q)wV}Y<Ewxh5yeO9CWr۔ VJ~F5@XFٻ!Q֓WDQ=rKdk2(sXz K#WJ (b %k6]n⯳90ƆZPeJ(΅UAՖ|Y!ټ SvIwBFJ)]&1 p|O[G #Kj;C%ٺId 0[]RHO|YvƕK9S7tL[1n:z=xt{݅lm>Ǥx|^:sj Tq:/Rt…P)u&Zar$}D)5 _M%ezn 'L1Zb*ݶ,M/;|_qS*{D'9gh=(O-I;Q%1 (B =PJz# b"/*lV~':|H\zyl)= IipA_[Ee"T?%:Ix.OuTq&`u`._- Ῡ $fl$мGk3O ǝ.vGM_)s/Y}T^!ɠf:F*!,Ɵ=WYfO]D mc:NNO/jsá%"|Ԭ>0%*v\F5 R޷HCMU@4tɲOF 0"*@8Q-iP0jޮZ0WEu`?P8vur8fe[HF0F{C(YS?ƄPYSмQi$/TCg/)uɷ,Ǵ4 j?`vp.m۩OR|E6MK#Sl>ޖTB-zYi@{ Rd[qP[ [$pe=)'MI9E(-D~F/1$>D"2u#>5@cя;k&Y"mI.U_?2yݑ[ S'5k)Cr<2SĔƐӨj)tNo:B|@i fZ5)_WՠZɀ:9"ha(.j 7Z;ݩdYc5|L+UŰYvK(q`(֙# |߷i*zcv]fydG3Y'Щ.,ƿU҇&^>$ytr/0!{!cv26sZ \X B'XlHWw1p+Cg@ΟI>d1b/h ۞jh6Ҁ={'`@cK'9о=] ΏƆ1T2f H(stлa)ac)9r}%s~~.1_ݭ,!jE%O7 oV6:9iԕe!*DVQMߣP~( E&Ukҕ@/R2t`Kp% QLOv3vmG$%H` ܷ+0V`I:1K /4KWuU8*Lf4̐{S%[ ib>RN.ZAi?x[Y[$pM$R5Qܴ>NQw5b"kwbc-0M'E-27}i]PWr^`c@O{Xq {%>dT&XȋӥJC!4Ӂ1(}w7$-?9w(A\vq 4̲+ɧOqFe>SZ +j/s*y3rCaKA$>OSD4)lK*`"3tcl{ 8gSې8M- A !δKՋK2dC< kǵT$ 8Ok px>uA`$7/0jۺFN9A& ͬ :0]ӝLmi,blpH~-dw/VĞ`xchW)C b8)bv(=WH5V:Y5 >L(}&A٣t-%~ dE+KrI1 1ZyDxQ?gSqJok=U6?yacrS|U;~"{s@eqaَ묒7G~3e~Dˠ_jqCTt\x٦wzST:6kD́U@+[yR⊱ڧ myTegT7>]TLKW=ݜmFz,lI>?5?cX o\;DejeռJԹ$́ Ñ3慛0~kZɢx:^ >9$Sj+UCuQ ~: >2TgkT㗋l0^/m T+rڳi>[l-;zY#22ehB 6תc51Vry`j ; `hs^z  ถBԀ)NeFz^Rr{Sİ+NNzKLė",=1TԊ{jG!Hhjt~v}ƪ_'Bw{0Z~nWЀ wD@2L/G?J.jXڸOz_Eo G|:eǵp5DH/Ĉu(: 0=kt%VVKp3)| *`_xibsٮ8g:J94-[RQiCwZ2~41d_iF>u]-^ _lD!;j2Xr ,[6'f1&vkc혰gK`KE({VK:搣~rl܆݇/CIhJfT߄a=>"A}IolۈZ+ROAR[B)1R%ҘlC]p8Юwf x܏kݯ,Bb|x6D]oblt2P‡~MC ,W0oa/XG+ygzL3f=#@]N *C@fVeiZOvB&t5ccRxE*9w78W]!2xD`Q'ߘzC~1=gf"zz{fV˃3dG] ez^ vJ'V;JE10Ck}B.KQ v lnYu&@g ^r=ėqzc5-0Žx^KF :߰dx.:spQC)4 \;ŧc?ΨJ|.0:R꩛.T;.F?펺u4/`ܐD<}ꊊX+<]wnu)I;L3[Ԣ2~3hn /9H&\ĺ;;0mmܻc1ƁzH4m5bv?$al6Lԍ70QU|NZX@7ĕd'K[K~eH3uN\?}w "  f݆Ҥ,$'hP?kɑQʉ2j01zGٓz5h\A(G,MQMo4!#T>{vYodg~@/@ m)->`!9ZUwp<[aO }bG_% 5;nWєҡeO)×+W67EKeJged|NIfYlYb}:oCeb$y<X#mC9 _b7j(5s,WZ8#Eymj8"@O/DS Xޢ[YTw>v!曲,D93}ށ<1D/jg},%YW{'lFomBYZ=׻.$b%%nPͨ_ Y=;$6񲊭[@N"|%ӛY gԑ r)"v 3rfv7YږwtH})"q kṄvg!TnI0~qB5Uf!q2(rk-"' ^]ݦӷE`7yQG8{c[6e=NeTD QAJ;Jd$'\|2$0si[u"tz$*b^=1+CNa =Q̛6hȮn<[\<\[>? z=W9Mf"0?n;fs3p]qsL􊌽 ™<Zm~fde3ߠ+)e VMnu,cAr$3._~Je"x?m$k̶d89&)d+=萑Y}=[< ϹuإB!ɋ2-Fy; sd(` aZ՟֤^Locɓ{)4DF!I),]o zTm6wѺGq/:TH+̮f2ZM4٫yݖ{:n]j˧˸ 2Zw_6 ~zIʿoqU}l(Oñ`L_vfcsLSri'ln.>bf$3 =66{ W4D\J3d}6irhnzS/Xt֖<$|ylC@tk9pF$ܿB]E&\) 0!INm0Z! 9La23Poך؏b@ +Oۜy~0ݼ, 2LFhRH'i62CQuYIWÐլu^8^J{vRUSa2JML8,2 tʔ/rR5KċRG*Kaz)9 \VVWxQv8oMLviŨmV -3@~9fݿP]+تb1} ]r#X0ܹ?´^4+4}$ #MCCKRb?-y$c#a R, SFkHm7I~Ҝh 7'Hڲ鹜aF|1r!vrk>D\\;=9*zOSg'7LmR@5w?Pe]*Pa]&2MO[2uV7F wvD0ͥՑ; 1l,bƄ.~K$2x!yG,XD)jez\G~8:.26c!\1K$!4kJJA5Jܸޥt oƢ: wE?b!"N#N!fvgG}~{d [\M;2sE{(񬵸5ojbw=, *"XK:m<ŀ0]?`J-)~R͵.-q\{$$n+35#o&9QQ<]&&Fkxc!Dtg$R' wG~w),(\=)Gwe_tPCndX#ne(`=5()dG2@.yALO>"R6Ժ3ni -?fWֱBfC<K6DGFcL0`~ ƌXbL>i1%ŸΕ(vz0fr0k@>Qڨ=LȴPߢ% HMSsZn!poyfkvbPg6Y6gP'/MC1vIuaOޖ7\`9{ 2T-n?+r)g& ( ]m*d0'/R8Ub¹Pƛ8< WIEwc@r^M#*fP8]=v-_VoVP*/}+qA"~ȽQp~?3"*7hB[,hr>^#=YzOa-kKt9wM8Wn~7ɲN>3Qb2$PY;C]LQP&az$k"!cշpЎ w\+pmP5_pBH`cq Gsx>xYw*m͟j%q׼ZOq3X inI91.Omd<~X6q;Bri|d66^Wf&lʛJrcp6-tfj%4,g$ Lo=MK*C9KDD i DŵĔt%=ƍ5@V,jI)>kkmD~È&ܧ_T(s7IW`;n#4*~7ov?D,{ }~g4<O1v=/&EB?󂕲juA1^Gve!Ko=Bd:*kթp# N^04dPe'U s"J{$3=hԔ~6+)|֬MW+SvwͣK)Kקדܦ-?k^ H+tEmjG濣  qe|7{*Dv]kOǏS]A!Āy|;?)JcEɿ{EΛ fƬC=vWA+Zz Z 5wV0|Rm c?Y8p_k@dvV6h-t\Qd[~ v--$7bK.ɞGP(!98Z]y5v@x 5daVPEq1\Ox*m4{ Ez I/hUEâa]_ssʍ$_}gĬ 9ja1 a^/:bQׂUMTW=;&*!nu?zgO; s{,Z,nH_a8Pa& ^Nw#kׂ͔Vr#6aGRCR&bWc $t$p c*n骚  ?ᗕ ꩀ~ I3cTb'+ ٚSsP溷l4[W(^_ =7kG5pc✕u}nO,jʎTJn+ƠVc^Zd9v}}:$zA` b7Ok3ACU._{O(L"jR53h+vQIg'<b&RN Js&7S_;.g[FP3<4_Od,j d :7XzE柵`&Lt"ߐgkkBb ]3lЮzi%xsI[O!vZUZrCkQJgƣ^ȱY:* ui[u_/ĻpOLH~kd?d?2ں9XY7pMۮk7Żlp6#c>CfJu>m:E˝H&* K([[,gR 2HJ/Y2-5=EAo߅u yjň&>C{&STTǃa>(ʶ C$ c ]PsREb=LH Yk3'+*,K&yu50d$)噘fpU !]cMj|>ٗ/r4 le~Ai=:pf odt¸qy䊏yj"']ç"AI| %]qwh!xPYzA9!dm@ X2n D xA +g,26R=>|HLX:;5/i WwflѽY3 h "< fe2)jp{I}KFwPwOvw3(gJ\ ~O(`j@ $+=ӥ VK:D?A/)JfԱy쐸]rF!%m '{9 QLuexD+Do H`Ǖ45y1z(ަZC%؎>쀄i`FD CJJ-dRCom"5$>X.n3SV?via2D #|6"VCJ UqŇJ(::~c*8- Z;iFjFS­rо({կhyT%M=ẹdUQ:luR0+.i璌JCwʛ=f-]KW;"i}4| lJl`)*J8 #u[LB6aC?p*kFTq!+ͽ`WE|@ ]tu7^% OWݔ9ܩ   TF)ٲz{x\WIO2IONpZ&jq}2`ۓ5_PL|Ǖ;߆[)sŸ@1Af]zN@{?[\8 K  iE4!egm#_$cyJ Q9ls@r(oZԕFpZ=V9v7\xǦf(ٟyr@0}HZ{}e8RY $T'JnSGB@ZĂap¸!sn=(*~8˄"H s*$ O!{?= ʶgWo@Ƣ[ێ͎ƸߑZ@i.d* mpДI CUӳuXZMhG`L%;Ǥ(xzD햗LRl)-wS1h4ܧ(W ا]va":IdN>xLa޼Okdb.ɶ` ރqnreNjڭ=)0fmpr[#4D0lfwS4y֡{ 6;=M[vd5i9 ~$ݽ.?,5GsMx`r+kɨ*0O12 ܑ%[hRe:?WW6L %) wf(}xW_YS֟|j?h}hwIIC/zP73܀cɈ@5XK67\d ؾ, Nُ{TOnaO-]Bi;F&ϴ8:GHZ[2Cyv=eYb4@ [-C]- Q.|/IVO*x?_bHsj66AL4CoXs/MQXCQEPXjH 'v[b~3ă#4~Tnc䖄KRg2Ѥe( ^p:n߃qD]Wtm;鉺/*6ٿl-kWfӫ,&O°O׍?vݝ{-ߤ}Ik=g;~!cT NmqP$%7 ([ K/sf>6h TMz6qwȃ(ݘ5^ޜf6dw> lX:DLh[Z P4^Glzn=ЧܷA(zx~D ~5jt Z WRevگ+Lz!pP[Av+sN RlQITJհUnGC\ˍXS5Y:9e x'0 ?2[\};5l,<Ϧn 6󄻜Եa8w{+{oek^_plorBhU Kd#khM)$2A%՚ZlLbQT>sO i&6wG[:19s4> hf; k=0ۣȢw3!mVmគ*÷_Yx/OI{ZmF%]L3C7^_}j)Yr4KV=,H걡is)%Ǜk-aAkgJAD&0cDM'!]od= NL}\56?OG{]?"!k {_oOT7쥕Cb(@?U#?[gǿé[8,0ل҆$]=~6%ZPU{FbO]"BGy*`hp(5@JRԔ9z=>ZoL%RO[ $sLnaԨ*3 w" jktc5QCr۰%|C°~Bҋӑ*gI=-@s%ϓ9g$THz O:uxm!J7r}r# 6[u;pFKNϺ*!qHw* [+̭4fe"0)$hWuUHe+ '&#|VϦ23P*ƺ'~6*Lkm5< rNlIp#K|@HE & M5kAt9̙'~aº.άDX@S~m(J6ynʤ =pʸ%_1a[Bܻ;C ^ly^eHܨ*o{Sz%&2|*F.BtOS/A,;Wَ7g9pzP;'3=B󅯱8a\zUzq#خ^ ?d=wOMG)59iGN|tymd'}ϡ-C_m5Uo_}5:.7݈wZသ`9;޾] k aJZ4~A"g  D !>%ZPRZ\_>`ҮJ@/L:mbq YNKͬ&kNR) eNI6⫪@sL_b ܚ\k]R)T2i9;@\dl INW0X5HxжKT%i20GWE+-`a Λt 1ĮWy]|4 .Ml3>|!nC|˫EnGB.cH[/+J'"FY-q9D(}xK3f&o! cDQ,vO܋TrN)=^z5 :t)WHZ^u~(G XC9}M |OS-m{M71+iNY G+;~ LZ73wcAʫA.5cZ8qg/SWi> Bon##7IZήTi3,j"&[keN֜" ~micZݤWUoTZ[Th|} ,|=n9vDPc*mC%#yS:!~N 1O`q I"em ]s^Pa;л $(e4jpo$'lZ9:>KVV>a븸+=c˿Wr@嫾*C]ʢ߮4nih PeOhhlY ;RKA {SAr3X7`1#RE*QC//lssR5KJ"$,mg)7 {6` }7g6/5bG"'5_)?+(Y A﵎ zVY,/Q)A#H6q̞Y5ezC,V3#z},:A rx([%Z[?,YlotMb9mO'/x:`po sRwY[ʹ6eA;exܩ]>;`>昣"tkhΒ_v:~FT~˽|W=D֚FIsݖH<9_>~Po~I#1 H+ܢ5:]4mbzG#.~'ull$\EY];P1+ C4#7u   (6mIڼi?ufS1TϜu>lo<_DWz gN2NbOTV=VʐS+A(/b$ld{^> #ۓ޾ZÞw<}/#5lS'O`jqϸn4oQ=nj&feYYI óybXS*J#W:Xra}_HNː)V~ᲂfp"B9FYj>Aw][W]-JiMfjQG/R#EC|V+kVtᙤS]!6-S tZth"z9U +|݄j@ ;IVF’L A8\1fj_+MO YY,IH.;aOe:1}EY.E:YO[/ރDxk& `ODe(0T.U1\8vlT|jk`{\*5ܓ+yx@DH'/wlZ,p)=L;w/ݨIQ& L#XI&qNq+mϟ+sB|3(|6{v7]fHZ82m<.Il 0 ]Aiwg4hd红F]]Uv&:IqeaO\ l.u]W`H٢1I͏b=;QW,_M28SYJAH>P\ZOLE +8#A%e֢f|̛g*r|aΰU˦9ahY3cX/ [(z$'è6RiES *-&:m"*OA)m>mv*' ?Ԡ5|Dݩ9/uwFUjRTn0:=~wyؖYg*SkT Ղ 'h|M((:7W%;Hpd(ů! iـIOkcŘQ%[Sݡm3SgI֙EM6/n?Laj[ ^MS֙ϿoO6kP#Ux ɻZ4fpEn-юzOa<NlنoZ_Y|ҙrjH:q ٶqa0K!p #쌼v|j\BS=?x 3Gȝ7odXWt ӴL93H#͍t@,W":B@4ڷAoXT(mLp&&=MzӴ Sc&XL mŐIi7sz"-ˬt*XP*28^{LIJ^iZis ZU9Ҧ0AHHxBg8jSg3c7dMvѺ' -sinVgvW1+nzfxZk=D@x0pjtfFZ2&~Lek@mT>ZTL/gZv8tLr1Kj)#W# x=6X^D}pmv$3Gs#5~}Cc(ΫObQd<&7S镦 3lB?aQnLmfĽ=<%A[cj k>I旒i]F*LR99*[)zcAה9JR.ń)݌Pˤ`4%ǒ/[ )UL^#ŏUn0ݱE/ Ԛ1T>FlP1ksQfMo8U$\IC%JdN |(tp`[i#?!92r]0(x PC`I6T.b 3{ G};z9S8r4~4}h# "sEe/|ek5ù@r^}vࣰ˷0<;r&$T 5*txF3[5H2SfZ|r=hkق6hqCI~%7cLsMy\9aIGlǿ`OQO%k1Wn7Q0z"Z Guu+8 wAv8 b<[*/n7w/42qm> ,qke/-!7f1Pij4 D@ϏQfidƞX.i+,(G |5E͛I$tW+B7 0mbwUW}(m}C[L uaMݣv" !aFÈY$,p8%fEf BseRm%Z?g$EGyj=m=4rS^pLTcj~ltkU1.B߬:^&0a/_`[O5sxE-]SR!qFbJ%ue j8-K^?"?+>F E=& F e<^ٱ&ˠ aM'<ĉŷ[$@9UZ!(sASʹ%: {7Ġп`n>s'c. M PNf鱫͊3Ǐo " |MsB 6[c:Eüi고 \Ģvam|`=$t4]k'YX(ƨ(h8t#a Bgg+ulSػ1==8d`] L!QEv/FJeYGGǗZURhENO'UrgՖ`';Q* <-QiV\}L}WYRD{$ yEq 3b+熑쫳hrq̎m$6=&N"/llф# 8ױ4* ؁Gt7 cdI9@v!.ӆ,z`wQQpey#Wj*1\o4IQ0%iM f$[M/Oe5D;Nyt4`oQ sσ'|om:skOMC,Qz%'e;QIĘNk6IIboi!(\D 4? #͌.a]ϐrjh.{#?FhS.V0Xn뗓FdߐkW jjwJnmNj\̗~HirR@x)}>F_ך\2WԃF^Y^އ@l< n+ZJɛd }fGrU+ʼn&|8FЏ (ߟ)5 9HB1|l4Rw IhgFb}SVڋOؚKKϳ1 ȚW]t xye7ǎG_uHKՈ?eg)lH2` ˆ&D#B5qQ.;aQ GɶnBʵ}ȆS2{+_yU/OX1LHXk2D~V5A7Po!#p& 6[Ϻ$a`,A&S+"BtDίr؁qvq3J:;eܳHfbϒ˫48\_@ ^NŇg$̀[:τtz{P ݞza$ +g:Զ}m^]?g^H1n%)0|fBqdWwK;V vE+K2wЫXTNHJJoTU5ы@,9? ; ?etP9BHMwλ% $gY3(6!+`u WXѧSu0k QK\L,JkA>fV˥j뛭(f' gZblm?1𪰉Hܒe( :}a]EӪ2}z#YC JQ[7Mބ 9m_u^m<7sN„W/D!-Nl1|_.0M{AhU\4 ^;h;2R2B*pj͎%Pq<#osqq3Kpu/ A3W ~i[d\#MJppN'Xx{h*P@ Y%7Kk tit}kj/Lz(݅Գ'>@ӠrvgLM80X Iΐ{7բsq}.euyLV\o"vN8zM `,I|Xo\R[*q'u']P$=f{ڦ:W0(B9:J³CQWsk/60VV2,/Tb۰1R7m?F'4"RqE)4r1HH6۾!O|F={ywsi=1B{mZ) OC?`Qdc"[l* E>x+0PClwRZ&_n鿈דּs:~h츞Tɷ;j̆ӵ+6bAcb n>==Z.`+m)R8!Zg@˪_㢖ϸ/ejb1ހάM_0*|HE(LXpʼ0#ICV`C^`_vHk W%: /3nUUZAڗ?2 8yl=5-?#_5*ȡb!.cՕ*e-4sFm].20@x3idP<?t<)ls) ^|&R[ψce]į+_CCFB!Ruzvy|t]0\3$U>9yZ-7 pgY8ߩSv|y M"@!0Qdq׾V skFԒ*md6\ʭw!2p_p)OYӼۘ[YSiza-Kr1p{R9NQb.7g(~A$N7J&5z҈=D$ffޗ0gmR-$|23/~>hۏkO@_c`*3)/}nMX886t S6}->|*P,uOQ\yWŪ}m$_:wN޻jv$T;N-Uګ9  s]lQe?Ĩ,#XzOOR.V W9:23ń"(Rqr ֯:`h-]Z%$CEHE_NhA&߳_x(|4Et mx&굗U !L\#\Qǘj#)&,`k(W-PUT$oo+װJ/_bZ^~f3IR: Mr?1Y6UHkJBU`ٍ njr_ɣLZY/w &$o5R% q藕dpxͨ̊Pȃ2 QI L^/5u-0+fgvqRMG Bl&+JpiYtl~J& ?pQDDwH z%^mWd8 QLHbkvtBH]DeIWS;HеPSʎ|AzeӶg> gE]t׸g> E t۵:a'sHA S@6S F)PIr!fqlHA }R~2xtF9V2ĺaOukhT$Li#8ވN~"XPeniҠ T:Fm=YūgYsW a+-j=Bymb:9_V#+FM$N}`i ARXp lCSXd!x8  /2߁ Ur½ۤuOa7:SwJ4ܸXRөµNCsMBK@ZåE%9} m?73QSNi8{Nj ⌢RMmAH,, R|Cu9^a 2?:NH ZDm6O$7vnO̹e~EC{eyuѱ 3W7ݓh?Ỻ{QEc- {v!bm$Mr Ua7WkGb=|K15E@q$gohA}8T_+egh(Amш)/ d8"}4EbAI(h=Y[7>'$3 TZkd~eZB VˮSgx74~xlұ[1@̾ a((5eߍCEod,晆)dH8-oG^kFph;zlfG:*?uG"fÝ+&l 1U pjnov+0 9>?C[lRIe3ɤ3Ƣy2JCR\ރS5׻j %5Eֆ.)^ 1rwT@B*(q?ʂ BٍDN> 1d!"aK(;h qi8G^H;֢癓j6fRtJm"h:J7F/7þQT a-B.[FzS}1peOL*PgoO}XpI'~TƦ:E|ը [oJP$zLв-ЭXbq\ HWa*mf$N&\7Q?4!kiOHa3i & b4ƽ KN>|sw9g`2pR]!cqG/$Ond j5FdN^ Raok1{FӋ'"lh=OgEK8nWX^8i/['\E$X]08h^ovey+)^轃ů];D492]y ($D*a@5!%j,QB'>̨ҌAd;^CKQ_2q[W_^QAS0Y65:P G #f)D3)G1e5 /@I (G >foz#ucDԛt8rzöDU@UnIPcoEC6;^= +]RAG-B.=mwǷ;.SEorhK `/2X"&TͰ3b+51OgϭmP> ëlN;=‘0IKX{S!DLZ)kHn>DiuZܣ^_QrW{f7D\o+,D޸+؁qj3"q5–&HZVz{LJK2g\$/ a ˌƋPf1o޲v0#i&NlomLgZ@oDZHN#;d?JyrPa} ,RÊ+aٸ? Um"B}Q  [HdSrjcDA߃QȚ͍+2e^uR+[~(a;8h pGu cPw__wmR_/m#찥t汄rvwJĿv@vB=0f1hoܤyn`v~idǹÿyv޿3ЖR&%"a 10 Lvj7Z!:­vק`kJeTfM$^4݅yTvF$k\e5˴j @(Cz8 ]2R"955Zɋ=*ȌD;O3K/ԙ|qnBG|ϲW鉶 PhqF"$6ӜhoewtK,kd``jmU 9fQ +)\ 2HWGKE0y>jal(gd= /Btsr۴fqw!-hN^ uq 6ex e7s%)O}7^Z\ͥI;[pG[>$= L!ߞ)r~~h)OϞ[˸տxƬrk\2ZU4) 7,ev~~Oj6İ|;43ׄ6=w>>ݛϕY5̗睭fw<Ӡn&bqOq/L)_~fvSq0z ?H' {??nr& :!dbApM8kBQd&̩Qu g*)ْ<LjYtM/?g6I9W׼j Xs"p 3F"֭R^rΊL\ 3Ö xܺמr][&AFblP1a^{9u,NJiYaa@0LU! "-;VU]L9@ OBO5$ 4.T@Pn{6A,0 \,+Y #z )l~⏞\,H >wﳍ^ILAXl g! gԻ4sB~wZݳ܂AhP˟,S%8nA.>ڈh(a<90e ‚?5DybƒIKN dװuWA+.Mzθvk)G:}Q$$wrZxlҦ450zB4Wbe~ɸ+sOioPc;Ȍ-wcDseKʺWZՐO߽pg^T+#+ zvVűEÔg̲xEO񎚽O߱PI 9ɟa)LVr\&ζX?ۘ< :T TDQ1ʇImw,\W4 DCUa]׶X \D,|4r=W!aե }bzL~p/ҹ+JdE/0vxx aFs*qViw vI'Fyc;swjh;3b)Bx)A'"r_br`$\G?Mx|82op)@7L_?XAs3?4* s8a@0(8yi_C a$#P[/rEof+g51^%pAGo,zbirRm#ԭ'3Ulfl}QRQ`Ka[Ϩ9K:AA^ܴ͕":e]Z;-e<֝MY/ 5_ӇS}%+o\yԠ(8BPSx*0HL (h+U]4б=u8dB0!2>b@x}P5ztʒ&IbB"ri]"B2k N_, u_𩋞pڄn\Fh)_.8pZN32FD[9>|p11֧ʵƕJSU]LL{WxRq`k+IԫB68 ^ Qsrٱn"t[\DK,yN>He踪ġ zQ""4gbm8L\ *|7$gڇx:B6 Z2VWpPHksG+SOXP,|OQ`~/H͙Na D ڡpS07]FPViLno8/iMrx%@7i8tyt΋ >'C!x\35' ;#nLӄ޶)5-RW%Ƃ0q4kc%iY;&eÿjw|<˺Jpj^c &5<\HAMi?RrQ:[8_4ь<.N 8k`ނJaJ.\ Ϣx^S9$*cǬvYqݶzG UCjn.~L5h u`pN}_@~^PG>GgUXƫ`J&wd0v%Z\՗\$CW#~O\k\!. F"gP9UOO-gg\4euzxbj8ZaqXs`w]qa7"$p2Y@I)I:0(!ԭCA$z5azڂzp+OuA| ʈr'eJ@|̠KO$?Be 'pE@gXgJŗ F*sAdBfrnpgT@j˳G0qv*Rбx)q9dz5ų1XGZztMu O>1$q&$|:M9lߺ vFC/U?\Ce'kXH[]VJ8 ,x;JRwr|9 Q0Ọ,Z+3HMXɳD<g1!/S'b 'j[IgXD14iz~F*u?Ʊۧ)'ľ#;w}&^p&Qj4Pԓzμò NfU||Q ޱYPVX0I==w{:=VN-;wxbŹ|-"(M,$vxxۓ&3M :ٺ}GL|p#"`J]5n]~OȉnqHg>"QɨP'ӍmxXBټS廁njIq]U׊0ә6U,],m),^?wT@!!$Ģ( #d~©'V~wص|)_?ϔ\OɧϰZJUߞXHcQ88%jZ.=DP׀˭V?뤼SsʧjX6 ƗL NMP,#z#%A@˞K彆3_Mk,ӠcT:͝wܣr-՛kjw.\Tȶ %ݿsWQ`y+W5$$Zl2zC#ְ;|'Q[OG1 ,1ڊph|#AYXCI>wQ\5r>$tV3lGk55[M_UAXW9 pV,H #A&.n*pʝ[ё zYnGӭYU3cUpz_rױ)ƮDSS2txk4_AA RbA`q#Zgv~e] ~^-Yu:̌ tmɜϋPVӆWļ P)"/Dtz2$ItlUfs^q=O^@~¦`jqѽ/0uwB泩i8;xZn\|fmZUn9, 󚒙vS|9nCX;QB7Xm0?:;b~212s661/? 9a*GN4Q^ M_V2@ee?h28` =LbVj Y͉ -AC9zp!TI[aJN ƫ`zs̴^5&*j=dG/<̦qxEAH +H&ɫzPe#oK>h\^(X"vTGި` ok=Rnpl2LM䠴)IUd \97L֕^]K5XfBKB6#q_/pΝЫMwZmMWN~kumi )7{2 nPx5SxBFjBGE`mT'1A*<_n,mCXg}2.Pv2:3-he2^Q'hztgY!!;ޅp8ѡH9y(ΫUeJb/3CZaͰWq4SyEE ||Y@< ~T}9^YK![/ P_jjq=RN$=HDGX2yJP߀DN$(DUjGԚOc=o4:mbhoey誁˼(#kEaZz/(`|uW>:)_㶬RCN_vb/ߢ( i=qY_}> [M!߻T_ƾOԿhć܉V1D1ߐ JEGh %5Lw*/h2|{앳ݟll™*Y`C-ߞ>gņĢ"rS? ݅@ 02G4!L0Wb{|6\ 4N d =K5$K3_'D')j3F;)oS\YBJKI">aKZHwjLۧ3tFdL92`lmM6ϧjBQ$'='bx2x33<2x>΂`d`1leؒg7/n"x@Oi\6}XEd}dxlFQ(4_ZF>dc#u O,$)Ͻywd Vcw3)t a7r$#Mr! i++sjq©' 6Rt5j9lkj.P8̼;ժšGЩ"To1<aD.ӋmCQaZS-=S%  &\78 q2rE v%_ ȵ֮$=dC?Aup;i WD9r DZ?> kN߮!Y<Eߒ)Kb}2n[)Wz|kJ}pnN_SƓ6y]O:ͨDW:^<5Kw->/4^3# ka@}K&1A+!b_5|Ow}>q"+*کsuUp JKOD }ن"Ѫ3,J[/Hv7f >[|Kne؃>c+6:HkVܑb#]l,my8 qKPxVkL|Pws;VDϏ%wc4 0,ظ=S a?eH.9QVzoOvyD[`wԢG_78'*pS :Y0l!d, YCNmV¯EQeJ ~WK be_AY[v:uH~Õ<5&~t1u?@ jmlT8=Z1$'*G˧~,v~5cTlw !i:neoEI8-qU4nIsyW8 Lfh L8z *]{u'RL>S\Z$K00;iʈTW6qMt5FVȯ\tƆQLb+1ŗVXzlͪrBfUx\{Ozª T5Pp@?mR lUi&sG#Qn qd--zGV;5N< `Xn"lRKnҘVg]s}>L|GzxmOqCaj e{m礪hOxNSD]c Cڨ(Ɛy`*v F{gdBC;rq+Bhfd 0uYI]CcE{y(+!"nJN9*t|2e a39(M:Qr 2=Pk^W1ʻ< iyT`, vtIj\,~Sq/0_9z nZ0ʠ;l1>6wi{Ԍp9RR&,V8=z2ސ]kOtH qQ Unp^7{ Dv~/`d8Nd/1Rd)-ziHWYTO ȥi=H Uå&MF`,>Cb'Fn+ +N-<WX߆Y,cKW-5h *DK@>ÞoaJ sת$ ^4ZAdT0X!CSENT[Ɉ#k#xh9X%eh(a/kzՠ$n.M"0Z=$vMDqo9,i%eUd2|x BBoR&Tha8-C"^dM>`2K)6WN:-uXYKQ(Cg7ib~1?nu.XyX ETB/nPYps—_M!V*/[Xyf{acE m~@"#4f'/.PQM2eՏ^G[42kBpZ%nuÀ GSЁTƇ_7{J*+IhF(Sj iܠ42n'D-∋}{X gb[zMάҧQV)*#h5BDž+סZSIS6a64USN̲lϓ ؗMM'y5H9w-A&;Y(*M)h3^2$it4z6hw u\]m?r~y v:$NX[Ú׬r}!& n crlxi T<@TqU*C4fy(M@W hHHIn&t'Mae۟' O`Ϧd*7y[EVGD[% 4rlϳ"69sNobT"iw9SBFj 75:0ǚ_]ɶTJIOoz6k(& 6GKaÖT D'b(z.pACm#b ](6gnU=a`jᑬKD(BQIH~*k];5H"uW1SEmB ]wN&;3tsvYA]*֚7kl9D0W?2Я^3خ*)ћ\ +C `$jgC;)TIz3Ei|z\k,?7^cw6MAYGNMýxW󘥂d*ppo~Lb׉rMw=p|5XK95϶Jj =ۃ5 m,0 4j4񄦅N.q}Q%+K+y`.TftNN|jj7uv`Vhq-eqm< ͏\"]%y9%%3m,M[kr|{Pc4Jޒ14Kۚ(ѾۚfSJխ8;p_oKaݙ7 eWjC̹U 4tlsKΙ61bd/ ]ů1:4aW{er>,D9* [%|"P!mKlr.VЧʇ>IB1r"$_toײ(|կRz#iV5{0Ɖ ӪY Pm.򻭅ǜA6'k`My}ڻOQ$ @@әq9|V .M2 Z([Uo jgI @Z= !/UJ5zPJ0(YE/vP塚(އkǐI[Pt&M9o)YL82oG㌹&4 L~y}Geyh>ݺRO<[(mw:r# DO;IEa؇JZ\V44hrn|PZjQ*h|O##i=<3 /w@eex/YNVݒqܐ/;UV.ZYze%-bgkc&u;҅ dUy9DPPbD3 /1٠jh,,ݭ-" 0l1:ĝ T 6uhc-uE>n~, 5`*ge* ࠃ8Y~FmΘ^Ghv^Z3%W+O?qD,^MX hP}iOQ¡8P3MbY4%ٷ^!j'c;s<=#|FC1 Dش%餐|YxT(kou4dI_2IYD?`qNث3~)y<[т+{a&Fz]hМrU*R̜Ҙl:1xȴY 6ϭ\xP ]ݹԉN}ƽI?+=3nmkf3PT 瓁6ZUynW^',d}ڛ0]+羶f3J ],lV=8޲Pţ (K7RA|, g􇼁kʧFORȯd+eʇ N]jl,J ob駟54)}:)NMzJwKxBKF+&ЇI4K+z!TUܸRR|u-z}X/ƫFsHbL}c` mu*WA@"*!,4KH1j#qq5ٸхeW%/k%AKEb٥CWgٽ7ji^V:'!:kqVC P{ٔ~@ģg_z҉/;+cHD2 ~Ӣ=q7izx Kz^C>v3vO.YajQNQMaˑǵ0ߩI!reM;U˧VJ|뵆qMmi:rt~Zz:2Z(,f!s\CYhO5XF8+칇N{AB>ƫ>5%Xo_#ml &C9/hFzuS((EOibtV[\P6@^}r'ti.Iv'>[}/J0AOӟƜK?W5)UįDWR)jZO5Y׻;}?FGwT1(u=<㺪 ДkMd|šKS[S|8NwqJ1͚#7J&*LhEl v~XǓc45WͤF&geG%$E \0 d{֣y#We}N&q8,KDHZN{jҊ#J& YPR}W(xWsE\P|qɺFqӯIQyjS((Z J/(K-/ aLYAL2 e\r㓧jzk];CGPݟnF/I@Ӧu֊blLd/֔JC{_jQ]ڥp_:!+uE;7)2d5wk'_xVM 8I?Y0 w$R{$$^-ԩ$mU!}NF%J.`Z6pw׳3_l")o[t*fa6X{`x=\GY}3 io_eOSc5dMXn (Wo렬zup\ 4]u-o.\8eOOQ(Kex&{X,|_M~蘋*ng2)6Ln{R){(/ uMyr9/<*8¤Sh=a#-PR Rki ʥ5i8{l5rm"Kmޝ@)bQRGTjTiwRa> LpMaJ'ۯcXgTϙCh{A+w_C>ߑ/9{Aג-Z Vх%f_h9e8AMdna4L볉.䦼GɼE,SG٥mpPoPBXO߾1CS8NH2VD_W$*4d9B$* _=26%pF'-o3EJ!{9$ĸ_,q,܄yq{WF4w/VGtXMGYAw| @/ni/FF6FD^2Z cЉ+gA _ ^pE2n]HVFe.!ݐxwGyZ$KHQRܻ!9W>eP堖'{r ̿t KB6w\AƘةƼӟ:[R۬"ۻ0nT{vhWPg}RgKfE`iK,-hk$( =kjoĉ0X v2-1UtUQ']"$QAuT 1%iq}$p):Q˷*AZEV6&tί(U`Z%Ppn{ŀ8L\ K>n oM7gq? T+.s!UCsF_dݖ%@R:T+GO+ M_q3O$X8jt[ ptbsd9qVVl;(Tʂ ĥ iGsM}JӖȊ&nfUfBeR7 "bNe0ɭ[w`e+k38q@\qLwVѩ 4W䘷'4=ǜɧإr+[٧kVX͈I mD+P5 -}o:3kiCWv8*"k(1ލM~Ri2#!4n@1$iֽp6)Su)i HYੑ_Ry+J]ǟGke?U3N:+!sHjm#`]QaĩM$=x= n9 'C /">&fc \)wv%hlEʇ7͘edJcPت_&HpwDɁ]:* %% ]`%_#L6a_?by)y4ԥoe,jrbysg+ m}ClN9b&Hu!=Pd'c$*f7`V4S'Cb8ߐAj~o?b%}$\;dgQ"j;Fa]#y"d c;l5Kj*#I4$MѸh?/!7n5Z ݡg;6$Nekư ٚ=JuT 3#Li-ja']r˗tʘcC"ԔgB"$/:s n(Lưp:[V(XUeLؽmh/rje"fO `0}0t(!s y9̻E(Sd;QQ*! [b4R>T{T5Fx 1I }f/Nmc_1[&gMx՟"&,QmLG=u *4!}!&y: z0aKIޯ$0qsWDB5p<ŸzN.9:j%B;DSW=Ti1rԏ2R~FKJY} O.r{`I18Ӽy ^ L4@c^Ke79MIO~)9b3^LN̹;r]U@vʍtM-p̮Mi&^5 A«79#﫶A/A ayqm IV?^ѪHtDhfKtBųq6 D<)L3u>鄋sOf?$8fRGOM͕m2+TC?J5V14e `ӍR5!u$! =s33ޛTpgF2CIcPȉ{wr ͺlz_m/hvƦ3_૲:nt䜦ueƶ Ug5385kՙL:vJjV F#sPМT띰OVBW%AYfx +ZCsn<ߔ$}5C\Ɣccϩ4m?5JsQc]KrՈ?y_pI+E{ɭ"Yl]pUH $T [9C&*Cxz"e USVgOQXyGy'k PN:.o7OڧmKɎb{ϲj6n60ĵBfhIaSplicrj/( `@T^ߝeSQ=. ]J6vwX ^M*]l%lܓrl(>Atw އuӥ>L8MW,mt8)|Ǎk-a)Wm!oD{E[2a^+ʋye{. 2vpR"iš1bZʵ is.#A4jޚ>W8ܘOm.4<2S)dϱX95? 2Dqi9у ߨn4ka4ɜʡOcbr;? eG].3vɵCQthU?V IHquM.Ki#qFE­n^Bl@d?Џ/,4߰L$8 >?`s#W7Z^.Y{kż)fqmlT$JBAYL0ޛ:c}185.E*e:-S'Brv̵ FD7mCf$;i4*f2h!$\.SwyZ|? .ۥȃD,n:D&;dq+cg=LXo}( $MM&=krUWT=?iBIY$ l mCL;rYxQ!1fqDEԲ'u]oM-UeDnQ/.lU&`jKSyN&ʂ:%TGp }b> ߻x8 sE(%,[8S̩efW"ޠm1ջlr y.ـH6"U6BHZo`JGӢZVܰ;-@!;q*l:k1L"F׻_Ӓlx,4ib {|݈AoZ q/lȿ׬\~HJ%6쑶IdO#K*xz2!LT' Cͦi8#XdBƙ|o8بQAeO]"њ=\K$0UA$łA#;;:LK GtN81_Y5mQD"~X!"SN:dF :|f׸N~_'˚c 7Xp\~MgksiZ䣲;߀y6s8䡘D 9))9}RyK_rڧR+I'i.9js& ucA};fXHZd/ ] 53kcpjS~mEA˼WHcwv)UExX5"/'4wgQʩǫ0b~PHUj/nzR<)Hf|Jӹ_9|@v,I׆ɎWj 39x/K?(5mþ4`}~Ꝿl-Yws O뻻b JXJ pTU(cef)&f-%PDŽ֨޷XZF. |H6\dʧM,r?#0ME^%^Coh*%Ȱn/y~NlLWF0e˶=!lɣ`u_*\?Be4| M<*4PW.^̪s˺K4dPM#?Tq%L]u_Hݷ9EV,&t3H"dw^L?fj-O؇wV:ЁG1uiLVd"X+p4p 2Y_x 1>2 fZ$Cҷ{Y>bIƼMc0\%KCk^m7hƍ,s31/NدJbeJ 6Sj 3]2?_R07Bj ( Ӆ>͘!wm+xyC1Q-Zz(E'$tP8 l h="gt?>a-䔏${ڭ5.^eM^=t:uj^$?VÚx w|?,ݘ CtAoİq)E*}hFKh{ } 'fEKvdi% `ug6=*jjrh)fdf"KҴ{}iyl;%X 5!c2O+:[LJV{Nmo[PPN8g3>oj$ n=[V |(SGP|FƘW1˖&c `$_rRk f5n`lhר2+Q`* nkFLSQ F$PRԜ^!dĞ5+46nQøoQcf,!LS} _R<ٞ(pSquR4q+r2n=Z TWvKcaKZC4Ʈc[n8Y|&ng^7*k?Η M;Ӷj+2Uz4:iu`d ! 9/ T@2 tmAC'*$˖>;džPOiU@й†zsNO~0J5 =Ɖ " sMy%KHpů\~~tsQ N=؉ͥE!6bY.-撼םӥS4Q"`Y0 1öی@oQ/s=XYGkrz~Lx=9A|T7H/z4=8OѧX@ bZ7MH4cِ0Ia\ɟ2+20Mg^bgQS H)ט 6s]s JYbrg14=ZkVԨG90]r#n~)-C"z8n/+t$7q9vde&#oG W OouF߶~y̕h8C ! D#; \BL8`.#p= xʊoN)H&ҽ>*_r*0y5+0k(A"7BKY $hLݷ3d+ a3_`9-4E, $%b${9$,hY;$Ӷ0NpfZg >2!™+=deޑ@Q7K91}q_wdR#G@00"{#?.\^_Y\( F2خ˽3-" r '̹}!Zt푷("d7.Q G|x4a4e?$&:-dv\eދ\{TΒ'RW|񁣀7&ƿ\%lSH X=[4j# ?&aR@B}{hڭ_ܴoi6߿?stР P:Ƽ@TD w&?4`7Z&keBo9G%$e#!Ua!tRZfuex#'bg#.ŢD_mSwk!JBDn/^gx٬j9"NF/,ْz-bʙc  3t L8BswbU;Z+?l%GUG)y}PDv,7Cq"/暈hV:+] VɎ/G2Kv\'Bc;",sk@.Uc6n'EO (?!Л/S)A~ލ9g;Sso&jDz^'cDc J3΄cBq2+BPy@m;WPsٴjZ/8<@BʮN6PVY#@q9ȵ%5}]*)Z i'bUVs4.. ݖv>J/ k̘Cl8irLlͪә?@ޤ:/w9(IB dinT{rEl;J A3 7-\k0u0]Y>ip&3 IVD_x~_ͭvFdHn7Hm8# =Q/d}AJA >:M/b}uw#ۅP&Qrt7 wORp$ia16]j_ɗ НB9e!s3dZQk4ƶYLJ˅ \TPFanS M]ϮVߌX16b;R%Yv\khP9snt;؇9h o?FAD}1.#žTSGl8"GDt/[ ˛wў7E<1G"չM{ѫCj?&l֊If/G Z9ݺvI) .v )cN'4Qԅ"J0-~k0#JJ#XvRDcvjThξUn-!%mv89n0Lc_*E([=3q.)=T4Y 2 Ea&i\Bx1=8*uN[*ɠg&=N O<3p9cSDCe/L?MOe=X%p^KU5h/wH`%LB[ٱYbJiHenM? lpَT ,- heUCbs]c #LT0z8 1a i4pV\l݀ IB 9׻&qZ^8 s9pP0zI~R d \e5E`BO vMBsQӼf{B lPejT/ »S*#/r<}#&82Vw@;ֆo+wh46YMyC]qC@ә Ϩ觸0?E` //\Ϝ:i $Də)*ӗ.EHQγ9#9o"ARFvͽ!4q3 dBb;a)v xd (?ѮazfߌC`H8:4\EKTx!#b7ZRz9K\u%ՉǞh.׎ %Gó7p=1w*|cA*gb*fp?TDF~±?t`ӫGݩ-VF"76I5f%mTL?BӢ1@(|QVfjӌxVTPJCϒĔKqrHRHrJ[{M>696&{Yk^W-E-*DW78zSwB;S=+E"É?|};Ѹ/5n]"mKyo*>1rY D-E0/ 񬚼ԟALJlj$-F5Ylz#B%cbbsb/ ]rPiYkUS4Rvt#H @WqiV ?Np8c+K*\)c,&".C*=e*E p"w~gFK"PqUDOa4iP/[;REA2.3l(!'%EHB*ÑN ƳN8֠u+­͐3}qEζ3l"BcOi.vuML:|(L-_l댄3ԴdV)v2LVиGFAjL'_(50238/V`f6*epٻT Gw-<7.zw N$DtQUFd>F,SJSQP53U Į@ŸchE֦i= &<OJ=Gg!bmK#y+ޤd&9bd$wɒJhq^|RVuǮ81Y#a+XkOcQܙK*?^M~b a[L gJ57udRU('ܓh.0w#3J)JZ\ ~'-E2}wx#FL v?w"TɽCgnڪ{((by=9=GvSB(Vy]E|,=h д_F#FIw pd)97ݪZ/یW!)޾;E bxՈ(1s㙝m~h fA,FKj7 FsA+z$*k-] aMy\z!J˜ʏہJ~On RYZ$閷_Sj`$Ep o1xHl^D\sZP<0@9 Ӷt0DI%io\{Z~P-[=o(c#TrO `_$f@KcO\D,Rq BS$4qde.iZw'ߝkH#$t]n|f)JjܢA?WַFmC;αT'<|s8&]ucG!GS (ijaHr!*ElȘ7 Qio1v&ga~q*"R,Ѵ@GGrطqJqB} :׃]a0֎G?W.mJ*-QCEiޜNf. 6CAL%,Hj1*-'u}UQ;9bP)plltaH%C`}3 h ؉ӿ+)F$xJ#D.#<&<{ xSӔ\o! '?>%䑬(P9ED; ׊ꬹCPAՕ5]s@*@l_C2PN}}* W/ rYq!;3-i?hm|xT ;N$e Xʊ7Vl#[gS.WS+ا<Ԗ,=}*2%Q b5>h`c <<+\\\'ps¬XZ) WL?ґ|IMȶ3|zʡIxʊT~w#7*p'T]׉|~.3î`o#Ku,e&$ =VS;)6)dGɮ cIT^uqr8靯XoϮL⇖3V},N5:uƝG)yvSZήʄmL)MR^`q`'Xt"RӴv6~4g2h1d1{jm<I݅IJ6B,-@ T, Ni^S);VFRAP{ɘI:E{6.Ķ0sT."&,e<߬g}A~0/@$L$ah${JM6~R1⚢_йrLe@B VSdD*/ `eb@i敟L¯d d'p5ebDԧВQ+!|N8'?_ɒ tT\?-$>(?z8$iUOG%2m"Zx|-qFthpܘѕ[Le\k!\*2ȟ,?pE_ ĤtnQXobk$HdX*"ǮJnxꆓґ` qϘNF1CCus\#DD@n"2 "&{٩C: A ^g-%Wi! RSCe[9?ΫGPgb/%eYC0g(8'mŲPE6&^j(h!/\P*dfBӿ`<2ޒ*te-mޅFp:Nytt+E4U!|27nﮚf@̀WloP4s)b&(ʤ;Rt|{ƝLc<1aYKD9%eB߯cǵ+ήZlr?Td` z '& ?@߫eCT|ê\t7!:CP} {뗶[.1Q0Q)m=(ͤ1mU6HEY;b޽Vx4fܔJ͌AA,?'4>g\ 7$uj˞[0~5]4 PMJ$p hSi%m|q}6%Bph{\\% \Z66![m\8? nr{w3.^m/&NM^o%vJV"QꖕJ>S_ͪ -JG%bڥ/zC\b*?̪ RZ깗61Iʊ8>nPN0!߃S .Qj~37DdPG~F4YXVGxDh2*qAe2= jӣD{c^PC;] kנg"2Dg_APaw:s2gND9Tm`CM%T xaM@`ǕRv!N(0)^kdd0HO.^z#4Uy+K |Ci#&W)p)ac( UȻb-n˪ir,!x+UI@+Q\]AfKā$̯7\g^׾"pW2LL?$dE.C*EJXVsaM;M7Š!'D/Ѱ=O h,@)+޸ ƃA*cAGVS'ܫm,9C&iS_V&!t R9sLHmv[gĹs'_.[?ҩp.<ږ$bXIlf1m/!tZ`Ƿ|[p^T&`AAwPEsK\|hRP'z^MX*FaT\0!o궚SkXHJwA-l8^[OIaSREEkƏ+8M ;}sT@.yLw:i? l&.wjK.=g5ը$eHM!%_/,iR?4f%}5 j{L+m)"=: X\=>!Or..JINb-q Tj#\|Ӊ+0liy:_]bbOi[Ы̸X3*xW;+;W{ՑзS)uZ8%'Ħ}%Q([*VYmf4Z`Az>/e>*i8|j~T/ nfԼWYiOx{惢į8=Ž֮(=sӥ\}-ȸ^YKT~K} gNᎿS3)wLui%D̕Ae$+#J{0ىZfGtάZ ?ܣJ@Zq0S=g;wF)/ +8I& z#{ub"ɡx쩤?k62jI4%I&~(uI SKSz  -Mҟ 8A9x&Fʁou0R4​H 8oD؊rl_W9WgF5U%S3n<+ eF݆Lm$'M3qG0& wwR8VA\:e kb$ 6a/25@ ‘韽x,ޡUSFIR#jػ:R|m?3}[lQbȄv:cY=b[{=uwYIrLxp6}N,{ͅWnOm$0#Wt DT TՂFj,qf qK\4k|;L`puyԮ)׹o,목$Nd~@F¨nrQ…ݡVLcۜWW?P}R˪Gc4#^5[BۄsdPYCC_„ojj \W: u;B-KE**9shȉ+Z6&BpKth᧌ \c-'W2g%?ڣ+ Uo$T 8;?SŠȔ>3z- gU~`%V%j׉O{t ݛ$kj(gBٜt-9@v$=I>\~yq#t`׵D^oWn=IUyBpY"oL/(XӃE1re @!SlNIH-3aw ;ܭYŒ(j0H"IJAh4o5At/zS{v)B y5 LV FC!:).%, XV&j ޟX6R]a}'Ktkg15s=t{"KAkB ц;*F+)Lw[+qϰa3h{xŁ/SF~9E+As[_ z0Nǟ58T?2N cXAW-arWv;6C;Սd׸Px5残A%8yP b5zΟ-_6oQj's\ +Λi~2e.qAL2Q@ ɫȏ~H{?Ru-}]|YCu'RFƸM`<iW~EGH 3HǰD\a%.;!&m'9ph]|t}4U!@bI}BkX1L5m08F27f&L> $֨>^Kd-#aDiE8A[n82/Tn[~!i\q, tӢaV5g %ʩWMTr(reیSOeBghnPjo|Tȿ>]iO*!s@';ޓ W(M&V1fU}Z% wXj{LW_$ABiF01+SV1UK[ok9 kբ$PS=Z{߷j񏬌@J9 T&|exqasʗqwFB mo7hJ\{_rAXCqwN՗'$!R&[xM`Dǒ]bKZ"ʋ᜽h@4=R9 `gqSR6mq(feMo h"9+ރa7"h}asCcP>Zz|8!|U y&krϹR[䋎uƲpXq}I8?=f\mQX ۾! N:U~mU߹𩐀QUS'8 OoEϫQ)i͢ӽo{z~.gw1v tXStl:w [Y^Ai'~H.z $r̩,ܡXm!+G6Ú<Єj~5Em[YU>&>'!3Fk #(Ѵ5_-RC~bk@Cr6 zz?ݧ/i|gڠu" kw5Ċ1z'@ tCP@iV[ǧKRNWlՖ@;N"n[ԙRk0۰kij4fzkєv ?ڰgC4g Ÿf[`F l/E#106ҔOKEj.0$›C~u'Zx"T|KEnvjtRZ2ӡsu J#]c@88ŋ/%Zߣ.1bgt$АU ɗ1{QڳP go'P?Kxj[AB k ?גFeX;E[uOB~OfQomWkvð񳇢{V)ǎ-Ds&@-^S Zy_zvoaupV?| *EAUQG{F6{HjՏҷY>F9N#`k]1n 1㼄CGxq~bE¡Su' Pĉt V Il h 6t;Kx] >K~B[q~/@f >8-Z 77Yĉ 7{ Hۿ}%hTByjǒe#-[&aAj%Pc"(ҎԡRa}Ad`sdÌZof!6 Cnr&Gw҉g1֓;!ĨK~[r\ L/A[$gX)Ϭ?ՒPKz4xw>\ {2Cn³`AJ @KJW/Rai`ǃVXegUN>>Kpa-O>:́>~Iצ}\Op)2+럭xWl }d3!,*帎p793Eu5a6 &O] L 25XUou :a=$w3=kcpH=Y&Nڞ !ƛ?ʵ3\ri3KM5!W,׺°̣uNƔ֘SVN8بU&2?h|1i-\W(qrEI@ފ:=ܝ] /"P ~DGF2>ٸuٚX"DM]<뮂UَNr>a}zMz扭DG:)' }U_ mfcb:fa.(J/5t>L]aZ`NjUswKFJ9)_쫺*u[{7'Z4jBlCd`M﷐Q*H $wleI>:)!O%w;<)xG=l᝺ׅ&3,^Kn? ve!rQo.!g;eoěƩvV?9J Bk$f(#,O"La;s+= oQ632xyl;ʹs%K=U ёmjjqNkM$4U-VG遨G%<MӨ<:~(΀])@Q]S*bp`g0v6KoQ*C^o$&/1M֑)sN3 Vdxvt%y_]c m0f9C! 2ٍ*@Ҡ̥P*Q;VKM8eЙ`c߉t Qd4^޸:X8qLγf{ %,Ie|L-OIe=ގJHȭ+eSG$gQ~Dd* P^5H.,>VL) n32:Fq!!1㮩R0֊\iZqM_l~MGDS:["bGڒS>]k@úɫ*\%SimK7 hZ7*0hYpmL>U;Kn^'F徥O@ z#@D!6y\䫈{LĘ58jg8rEt.}Bv1]gOUXXI=!? 腭B$g|*Yx^+3>/ ͛ߣ2f_,J/JXM8&M>۶dwtlHvO|SFUg~(S2SH`x|KK5b{0AvK߼S%T\{JJ%! 몪=xxyZBڀh/ώRL'Ι~4P(Z"[AB/~nYKM4<5u,Rc!-(m]}ﮗw;JYB9?B\+6-ǀ^H5H 丌U+)WdA|B˧v,%.o΀$ ŵFF!" Ҷ1P Mu;!\hS suB75W%~jN$&+|<X<+qR+Oу}0 8&A rwFs`I&kžiХ5}>QO YOSs|2FWpmB<0%~,n#@21ye*c NÔ{ B0֑~v[!BuXtݾCߔ1Aw&Ilw`{%ҏo0c T%Ls =sykŃDQ'o2T:\Q-VЈg @S63% #D{{%L.t`6P'fg0ހk-GqOsxeN?1]XX`;-nG A%y) +qs"2Z w_~r( `7\#پ秥>5# %uuQ 7W^2.omkIO6d(f,~/=A`o~"L\ IQDKն `@?$B h5#Y܄(,˚|<@+D{cם'#mGF=2}Y%X>gv@7Ș}=EI* p8m!)|t845~9B3¶Yc&qݡ)8i8. ˲YГF@/3o W–O 2=[m SH[7wgF~ .2Mڃ!N4}E  uwv; }q/#o1'`3gFfz_1w_No й8b' ֚zxIPZ@>_+P Er\_g@ry4by46>+]@m"zڭ-* (M%Wrj` أ:?^:ocA EGuGǢlm!6ƺ2KL$A7s|4\Sq:(Ծd &Zb5  kҋ4wKCH' [DϨbA~8sl^{+c.<qS P%y@5 5%96KE7qj8,@Nܮk`3|1ewZ]RE!7PX~VK;u4穨v\X|xls#Z|4&kwL4DFֺt]hj;p c3u6xI3^< J^;/Nf 'HD:) Vyh҂y-##V |AQɡO7nW<گ MHe&o@_q]Hk2vTDy+7P۞ՙ",u^ |1qSdV 7in2|6Z?(/*<!_ zT9Srߛvm 9)b7e|7Lx^Ar>p lswYvj MzĨQ9+.6 ѝY:?T)_F} 2jЏzpP:OqJ- ŔԊEWZsgbr;elY, f6@Xzw F_؈ϿΥV֣BxdsjP6RH;OIpVd0@2-R6ݳxb~ԌGXҎ:(D|-TU<LXϣWUN 93^UAí)굕*S`zerWLf'\„MDQ eZuux oPعH;;uKnrB>[DOt]QdkdKbZuR)Cav閔]K#\xwգo}q% ޸>x r#~vj)3$mh(wl/K me,a :\@7B ""YgofQE%6˲i/tTneb ~pv|bBz"Q@+CUd?=9CEGi}L9C}\?O5MJXh5noR#z$CuRW<Ԏ|e1m58~gH.vC 9/HQ|/qai Hx j[ [=gxU!&9K04Rz*GnS`]I0ض{̲H{_*NF`4NZ>9`/_j-jnp-̨tLũls"ޭ`_J1Pൺ5q֬ŭ 2{aR%͵+=L'yzKt@BbJ!fg|IadG78*{2P;1zОZyY@M֞Qh̝<6#n*IL#B ~cg&gGڄMP׋+ЏB\մ0 sOy3]f&7CY6c{ bBza#r'}>2CG.+[Pq%HCZ 4zy2ZUPb3)-ٮu֫/  ?1ڏ:iz7E5'Mn)1kKh=n团{:ՂCg WV~`K?h@;_^yKV];%f/ñ Dٿ#0l y~s)Gz6"{ Ɓwd94tMa6J(RD4Suǡ r{'@U9C1! a*j~(z+JyÂZ%f&#fVUwmmj18+ w3{{n&҃mpG$JɘIF1.Z50]etltXQ m \%!%Cnd!uzH85P̔x#hEJiWV ٙI69>baj6x8"x\X?fCےŰ)HsGH:}5bˢ(@E>/:a+!YspkӴj@Bl,^~h=-BΏ+GWvl= CGuzKNM!]1ʝ <2u]Τ0?L}rEE;K"gRbjQ\)9Dܹ$/97ѓJX %|画_][ 8r7、'^7ZzoL{oqVTKvf\.W[Ϫ8@R KWZMxkjM^(B$\߀% \q"D}¥A($"j} Qc 8fM D*/DSUs ˷sr|W1E|D5~]SWKyAӪGYLѨԹ P'UQ=I!m$N0$XF4?Vií]B2{h*GDc쳦:)0G>vl.q{戏7b6\Q9 vN{G(w-Sd(1} G% Sn͐ 6PwӀN։s+ʸ2c< id|tg4 -͗LAQ(F@F:쿄vJg&m@ ݀>_C5ٌ|@Ҽf Y3IGMjY3ľ֭"X*jmiTjZM%U nn%*!\>Ӈ+)FHaY<"\a兏S ̍Uׄئ/=N/!zdk2-ƒ~D#E諡]|lPN>cz3g`d_ (6h\7|90#d)ԯe٠xxB<[..yBGkBA J[z;G+YRr\E S709> Dz Pλ`DiLܧ|5\٠9!, sޠu}\SG6"Ps5>)n~'NkcdTƙ޵;%pK 1Gש$$21wSM}@0~'i+/CDБxݛ&E닍̓'W+)a2Vmxeq;f!Hr&dO `Ήip,Pv&n;|pX@YfR|mD,\7-gԖq@,6ב!"b1٪ *[iӲqM;e22n&.gВ_nZ?ݤK 3S I7G8kE>܇sޜ9;Xvg'D74JSqiKD]l/c/n ^~l!WF:0i@PG7zZfh8Ġd% ӱ셽R21B;e'NI'Ip*4SǹVy{4lgqy qB7@qJԦ9GAt +]CHh`@цbJ,i~gU'r.ӾtJYH:'[Kɐ*M0,/FL ZB(g%;MezL#dvI:m _@F PfE_]ӁA(~yDWVG20^4ìLC]ݚ1H(|Ă(yVx)lJ't%rW2 {"&(AMKH/_X '`kK|;'a?Bj*.o14{2pgjpYxWaA#6#@~:UNv%@s-[о7ʏd/Ckݺ+󁅮9e쎎A\ȳ5堼"׼'mZX'c،(}e<4Fmӟ@ySev:oUٗV7LgH'J(m1s Rg4Y TDyy/6rB_+Qp4pACf+檿ݦJP[PC~aS"Zy:PӒ L]xW[e8sV^`doVf4cPڀBpqle? B55h}ґCB-h̾`P >J%?Eo *;M],MH a ^BjTmN~z*\RBO﯐R Ix|>=_mܥj(\ncL|Y5~W`y$F0 i.pނQ nG$_U0Gz!wJp90*Y= 6M{Bhf2ی1=ZiYkgW2_9~s :LMTJ7of%cZ %1&V螚Gh_/5OaAuWZ Bw;xH]2 p<Gw~o!;6" C\5h *m 2B+83!8l%l64xTPÏ h?cQx]+OҒAp9g6׾` 2+m!`e:~NOZN6rCIhp7>Elf0nJ[RNT}/OK\s`Um{rE.Lz#7jzY MXxB)_bࠬmfgHt~)+@ݵ~}5 >T@-T8O@iQqv #p;dyhr_ 8=a:ϼ"u; X vٴbɦC6g&8ݮ.T@L :[ [pڅNa%Hu'[i=k\}V88߅Zgov %àȖ t$=wUi,[)߂C\BDN~Oex4ʔ7O fs r0( r3e.qz~jny:1Ggn/[X8:ɒY*Y:di>Qާ,pwi4wI&%J έjX>IUn/gYxY' ̻p@ zyZ J?UXG!BVL/CFwϭ%!3u7k_g:tZ^s걸(EC X@3g9S$9SWl6]~NR9ͻ[(7iǷh%d hCj' whzVyn3c5{sO*{k6sk2¯3b#> +|D'ɯ.k!r“=&@K\][PNWRoR\i././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2379103 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0030000644000000000000000000014270014625637207022707 0ustar00runnerstaff 7 i@YK(|R>o(E)ܐ2`>9 7^iY)&Q_ P,Ӯwt&/9F<C4L;'q!9Y"t;@^v#қTqI_|a?X#In?w 4mG*ʼns){Al&fZg>_êgH9@szh6Z6܅&$B⏕cX+$͗0ɩuճWlA+9nm,i죤&ſ{fD[, MH)jA;6^ZFs*`}`oh9|si"5nT^/R4dTO$ansoߜZ4x%S_">')ygG`}/Qn[|V#OƉp/5`L%c}3GO7F^CX Si-%o`G'ev(|U)E,_Z {CyB 4o8577STt3V|O8K!iWi(/S$bZRKÆ *nVF܁㺷KGetP}$VaY+C!'qm:6ll'=G!6wf|8ARgA һHa~.wWQ# %-W&;6oi5\GDq 7R˿,{7#&^[ ίщ!2:LFt@b;+zs^t禡k.MW+tq,[2m@)/0dms|þdv~7]K֣=>hN-= gCD$]0LKQ?]9kA'\v&F;"MRoءpb$[O2 Ie@5P8RD4h\t370u>qkT|cgXcjRU @N0fMqs ҇'J=>rd@5U1^<#aY׶cp[U9P%S=2h? s/;3~yk!g3TSd@K8dP\XşyMg[$or[,ỉ2shлuѷMf >5soY+c/ n^ؖGͩ3ؖն6㐲$b3aV =)Q)m}'WrC/!pQ2 %3|LmZ kJ6T^ V{MO76_5:>ַDk(2w|z\ #dV v2 -N55j??mJ Eȴ76тɎgLpQk)5ƁV:e}C^SP #S "6ݙGj x4'٪|nή/eU.R:e习2#6C1$ƽH4Nm=6sv_g*{R?k%aN5~@F8&. w)Ԛgh3?vzQ Zy!K_ԝ5"NV&gYDyݧ@Z hֺ1*Ylқ+O5~i 7D!S?O#,{GR }?g,Š.LS=!@VrI"e ؔUG#^9&I}{9Ϋ|ak_Ą,yltV  F a'ݮ~̹;"wyYk-s"ct3c`ZI2H$a5gdy*!.tmcO!^$8kR{ofLA8~ PO>u})-6W7O_R˒,?wR'ze٫ۄUWMU @mQ(D4oNLZ4}GY9yοÁ2 ZP9:63ڷd +X7X g'#|~f(iQ,r;طqlj m GM>!Xoek"aX?4*R QpUn`\NPyzs?ȂDT\7ƻeUwTqڍlOnٽ&{?Y~^Vb/XDu)*Oq7oa =xSLI\%(`1q6LF>rp:Xq 2 ~lOcLP^c3 ;'wXuX[]0ס(+?qa==岻Ү8I_|yû[s% gJ"UFng3Thc'C=?!"GʷC*RmM]z;dt.KI/M8Iwm8K+O.h8S׼\51tqw=RLkUӝX"|UP ^ m ӽ69PzAt\j;T)@RGOrӓ5Aͤ;]Kr>W1(ZA,~"v׳ꍩ*;t>,DQ b^|Ws;Bpۿ ^1fxO3 7 9?Gdy<~ 31^f6_Y,+ɓ\ ~AńA]R37tq'u}5fz(thAqvL:M:?n$:IA@@B9{@(TЭjSo$\)L#l %D?q@;9\c(j#%S-.;gCuaP8gHl`MI 5=*;ᐎ(*amw=4򾈼m|D$ j9ML.O g0CᷬW, TW/3qq 8WL`}FOJ5a(D!؄\e Qg}p܂m*3(E]B+DPB&~l"3?D.X6/DB_Tj(W(!r1 KD$lUxcj$ɼX -^f)z7\UkL5a\ƥ0UHFqNfJh,|{x}KLXv*g h<̳M5+6EP˓+HiIV8ONtYQXa!@Gbb\,JOrR-yMv>b<1c|(VOzǥ)eiAKX1Fۀl _ рB<2DUAy,#|J=Ghv& #r?{S/cwXLHPC!*^'vs{axΏe/-`n_,~23=37ZB:} y~Zl,,4܌ȫsz{П%EcfhBث*V<[`lp)+ ~FjJj"X;/Vp*:Pr>2DϺ9b6q.ԅr7+&G1Ѱ7e񙪫eK\Ơ }hSc&*~Jl-枱itО~Rd2IJvTX)kӟ;8[C"ߜG( )SAOgN!,lm|Wn!8 E!JIFCq *!vBR`}@T[iOOغ>?Z_yD֋{ͣz= u2`w<0-Exa=NhKݦ3V=^b{f"<8|(#rBbͷ ^]^V'w"y;o g*rHvfU B@RT6 Z b`臣V $mL7bL>čY񙀬^P=mKt/íq.MhURugh h/z{cW{y-:2 }dtcT4i备D KпF@ ݦKlHTwKKYFNtR7I?~Lfy/+궬?$O YV#%+lZ[ppI[X #1g:FۉmdBǝ֌ֆM=h8vo#xl#4÷WFcZ(`ObYoY_ۃg ?d0wJFeY'ߢ?u1CE!UdYu *!1b߶iŕ^TX^?w2+&𻉭k&}\Kc ~\Na#WJOJ֫TιXQ )g\PpUʊonfg>Tד,A(+~&?Z.\cDXP tM.Z>PW-sWϣ8cM6E␭<HZMRܜ1R2{4<x>WQACsȌ9}j@Z|Ufs#W`pQS`S.DLVHњw})[~BT9 .WL'òB٪ɛFu~p GaHP0]\Bd[L v$)Z4&<)`ywsXY/8s"(g/p58J}u-%zMq:p?:RF2P3gtm5aQB[SM6m8>"u5UؚQj)*}v6RD3=6 }z!F$>sn8Gzm13j2;rR -{ЙSR%Uoa//aGiZh87e6zg|,g~MPyAI_e9fNkt X)6<50৫ͯs&t=פ_~ae/#U?#k[ lU˔2PROEeF0wmu4brǖ"oܼ '7j~NŷR3%2Y$l$>k؞ة{E­fwIwym޾rOK_0PCpCapOT]NikCj:ߞG|-PTLˣYǣHS^}Qs[GPxHYdθb6ײz9=v|WyYb`UϨ سXp$<%.OmSοDxh]ŭ6pΈуt;BŃ98dĄ֣7}֕0)Lu@Qxˉ'hfK%5 Z.:6Ms ~OΑm/Ř஧88]BLNT.)}PDYTN8.^`I# 9vrշv<ުNFӔւlXV0Ǖz "# j˔[6 $Rr|?ReU ӂ_2QGU-!ꕮ*6[?ȆCp1y,@ˌf&瀌 ֈ( S5[nϋR*MYUak̈́>`xK},jrbn&. q{Y%+ 10%ج4u9ʾo:}O=KQ\kAtdb+G.;P>DƸRQ,#i ]w{-@~'`Wڈ>Ǒub. 9JNʈ2}WН6TVg64!x⾠4, u$ʓ4?Wye\ڒbE9^󀳨suq;=OCWYs4NXxH ;X07G) R'b߆*yetXh?)%x +Oi8p0%+ߑ4fF6gQಝa|ܪ|} M]Pbv<0$-I^sBᴽH:+ XiN +ŨZj< N.ϫG*%T_ y3DgbRw b&_g۲G\Jt]9J2- rÁTJϭpX8)$Ɉ%ޡYi 7:Ҁ$AA5ZZw2G6N( @-m؍bHDv)4 WRb(c< T=(V}Z/Ju Sj1ZOh^"0tZr؉:` Мj_t" $Sլ@֋s3ࢍEǷ2:~Q.WFi.0;߽šzێ!QѪzfrmXMk VuBo؝=̫rrdY{0Lc,41 2͋$[j40)Y\k;ɖܡW\rŏ/U\Jr+Ni{a5&l|L;c.eA|k!q9׃VGasuzF HjFZɍu3*!7`, 4H7l]t ȋRtЈw,dCWgn&ܵH5>gdr҇ޚJ "˃a=ƭ+%.OME>p@^ªȁ_&+ % y+=]U?ߩZm'r[b>}r^9F'UNsP (lpQ-9n6p^g\ɤuMwoBתrO?ugw~"T8ROʅ8,%CA#hi&yhA@&=ًh *Z8 t<l{& 3:Jo! 5m}n]&s.XJ1.S^,֟Ϟug %9,B`BYsѫdq换q܄޼@28d=q '][l\ E$*;"êILGjy{$h:B!-׾k#w`.N"dT{w.%UY'Q/OS?plfԴv4oM4L,e}!(^^(S>]Ru̍pJv`o 6Z̝ *P*ņhjވmYocNG2*-9=}f6-QGzNDNjxbnnMP D^NOE<\߶{woxjѻ~9"_do3SP P-G^gI~/umZSusc>]\8h|J3_]%~WӸR3(l[+(aڭcK.6bfD[ u k㐱4e cfn71 Y;h /=pʌP)ƍ.--*k=IaZq #? ѿ+yGH\9 .nC ս֢5Ǎ XW fq9v2& ޭnXM\0^5Î>vE4Mtޡly5MzF8ԴB @D,[uyDź,Av+aLKx>s|~ JoД,ɱ?@<;ʋЕ0ئ}'*X!:3gO@쪲ܯV;E%4zȽӎOc,PB\Y=IR–6ȳNP_TЌP]NcyV_j'n5=pT&\|QN$`/6`3f)Īm> Lrkd8b+HH9dvu ð4H1~ŋ1t8ш~¨=5[?'M>()V6rjUec7tțhHW_YK5Ԅz8/ K+i)+E+Ð&x[ޠiZQVۋ#euFP {4#mH7Q8 ͥJ IS zUmq#fc8_O9xk֪̋1 I놊/w% fDhlTqL V=pzQ uFgA)| #E?S~[? }滨, >mJm7)+6J@]XS7Z3_-u,\*ޡ@g® ngP1*2.xuf(C~O}LQb˱v@@c]zt-QӽzI96 D{^5f=Q%nrAd.8!pכy'bTz_؉y9mkl LI oE~v$lGL3>2N@+Bin4? &.ymZ%=8?)0QfMFDRgyV{OXȥЧC *N|*'Dg!BC)7VnCҞ۾6(/,n荞~ZF߆t{ވNր'N*=*L"2*|\\E}mQs05mFlBU%}$V u^ N}3f΄`+cB;w5㱲zê3"_=w²a_1x =`e4M`L}gd(b:r ^c¿մnՄ(_2lJkYR~ms Z>Pu?Bif4RَJarf 'jK!2A`gf" (۪/мVgZfÓ Lc0kfs((΃<.zwo@rMuy|WnV 7J[0¼ U?ن0Hӎ@zPO04Z8c)~cS$IwZUuIz0]暳hFƘqfWF& i]nVUYgi.[X J_2DlWJȝE9; &AlK(Qn>I+JNZtT-Wb/+p; |NpA7U\x1A> 2şszW8E*?5 'x6W *)|_ftkK`6O<ҴPF$O֐x)̮t(M~y#4#7EHZ \D") 8hV]3dSS577!H]:g.utEo(E[g=x BಂxQR 7q0̜-+'S57p/#-12e[6M~~w720ӯyYݛ|"dc̽aWޜiS~,9+l*Gnhi7U^85ӻ£Uȶ")sy$1AŪUzڇQg~:νqqVScyu٪5&gڦa.*ɼ՛~J-nsCD,89!Qiq%d?utd~.~˸ [P"ж1ࣦWNJ)(վƾpr[e.HDWC3L Bt)3~4VҏC6 Jj$f&#Ko   |bو GQ̢it)N7|N b8`An2IOZWF+>Wɝ~ vS|H@iBb&rB_lAn|ح9_f<*4`L?f%jWQ_Pz #؄4ŗ@sӯHF}خsxb#P3TJ>׈UY0 ,áKLx">@&zRNb/:X4VS -$wAY sɢDڳL[řS$HQ ʡb/@T]%D9L2J6!UXH+b`jJߞ]6}\/fJ-zwQ>_wF=[Dk;Tkq!$;c;4_Y)o$ŠN>POH2`Ѓdy*m0agLЃPh@Cn1lUP3tlA ]Jx#9_V{Ov 'I/e7 =~u0B'z ,4(2g֎L?NBV?ܕ2}mмhDO4pJ\ _H YI9 gܽ]g[YODAqsBtlhq[}1iZ-i`l[0/0ug>BپK7Q7>SV+IhY]mџBo SRK O BjcUw*Ex,IF/s7 !bJk4?ˤmq6VTg2&Y}> lLewdZjkZ{>%w #KBl4 jH2„g׻Aqtex!Xjj f%'qL,lF͖e&Κzߥn  S,Y/ȋo,%S }خx]?{" T2RY-AN}m!evA@oF}V4_'ُhG(dC,+ΰ#+$U-(AG5ZXQ ]j n2t/ -Z<%gF9ձ2wkbcIl;?10Iq Uڅ[sAb#4 ϻ}ՄXHXD_[zF1M0 wVTI^ppYNq< Vzvxܰ_q}9d!6bN5}=|g읮jF拳]CASҥbN"$:J;K} Vȯ [DIBBSf'KMҘGMɣM;=s޾{B\_3#LEP2_bF: ?II7|3ZZ9w@e> :dУI_0v0vGǜv^!E8dA)͍z<꟭Qw>EM_/+#jhF<k&HO-CڙJ.똒":X "-zTA9?m1>fl H<7: Ԧ7L`3p, >\k# BW;JwUN6'80հ Rh]>4<܀~2=ӕmR8;|<~ӌO &^`"9*"#Nr" „DWfl.nۭnuHW),ty81Ǧیwoɺ@@KѺB &p,7JQM 6"<D NT%y# ۝W|^*',ڦW&B> g=cCKi|$J8Mހ_íd1ppuX t f:x6cTj'HhթwX.B|)f°iK&f2#ϩtHiӢE )oSn)+nB 78>m=C,סU͡52=U}SpIxG`=]d -3^Lom$`s)WF߬m[̑ étom|B`V,R*?1l:%6B!v;O6T_r Ն9*!E@%1W"rAtqo/$=[x*YwfsK</CcO'ManEZjSfLNj v)ߵFh<Hߒ<5U׳:lEmwAMIuН\ǩ钥S @G[uٟ҆&d-'9CE5t8ĂX}E7?E` z>mow3\J J۲*.RdjW9UcW'ZD|Te-P=D`&dSTU v½2[y-G"!6txF y.92HTN+E͹m6uEPPxeq!qΜ9bQS;U6AI=ߞU%xqJ[ܬdڟyˌy_u |״ Õ9ln-]~^{WCiChblF81$ľJ+5*Wo8)'9'aMCEGZ.BKk)kh'@סOο<Ԇe_P3}ռ,~&%(3[% VB[A3YFY\PSdlߚ!=}).b>;օN=yAK6>>c(n8'1hMśmuݗynh_ARRQɿh[g΄ 75:eeju8 N}YX74Xh Rw 62=7[.£sngTa;݉$0~S"IA֗ C;yHU5tbh;Wc]iZmШไCDmeY/_GYV4<;F.e,gb\cNngo;aα/;o'6c8HXLFZtv|i@ǯȑÝVzdՋTh5}W`or΃R&dЊ:qn8Gو{>V\6𹛿M<ߡY+d0\G[dK.IVʙRGz+aI0{}q?@G#%m64G3%ʑSgHpg k#g8#?蹀hzSI ;t*\|5pS?a ?t12 Wl3Fqt*A6* `5gq1/He)34Q?IEMƊ/F Uy)2IMwp.[fh|Us9\&XWzEh#ug"R#-tjПJ BV4zd>H"BzѾ}bNjRomҹ͞S, kfIKV1 `+9r$<i&X~?AN= *ejK/-,ωoސ,.+Njd=$DQFlb4q 3N0Ìy!\bwTѭk/ûwkg>vypSJJLQMn0SWz‹rk `)|boj8Ϥ*GX޽km5BgUXr^Y" hGҎ_zBN6eyH)ʆfIQip],%ǯ&0{W\qA;)Fos- a/NY2\yf6FI$*?q)wAA.*SԜijؖ"2$zL:qjב?kJ ܆Qʩ~mq҉N$MPD6VVuӾ:wKMD?e'h^j+& a@D+ #hoU,>X9ac/>R"f<$oѶu#s+m5ʝۦKE=$NN"rM[V B̉N5l,CD9M@o@c9V! 69AC- b?a)lgK(N]Ӳ&$SY9i`RP+5fvoo'\T%ݑ ?n'W]Z˵l9e@Zaw:_6DqcZ3I 喾8BKu}}Dit5hN|=IN%\T*#4)OGy䡸: }MYLsbN#wNin/p_Ig(ex gFGj߃⟚z+31/l x62zƃ[}k uU1K} ?S+L2̅(QzMLQt/]\?l(SHί$ąQ* Q䉠DRoY07of»)R"|Һk#:B/\-ΘkhNzUZQx pDk!: -ݰ3a1[Φ_,.皔J3@eª}ԺqAƜ&XGAiB n{zTyevn8릁|^3ޭiհѩަ)A+ G|lTST7X6/XFcW ݆2:p6TGo.!O [ -P|T]tdZ82X.ļK(i#qOz.Ns|V ґkF*53(mW󈕌eψ-N>9̵tĒFk@CfmdB]%{N4yr;AquUƈF6҆ncB|Ǯloը &D.ٮ*J̊ )Eq)}I{0*DEL ZX}5cfx`?k(:H&oA%k~IOZ/4KS\PHJ{S b#@`5 Ɲ$AЗ;6h]4d%-z j_6_%: @Lp|el*mEn Û:1k)U4P^=7* GZ!Z?*M5M#ya#n^<#0'׏ecA9&rnSSإP'3ЎnJy?+/T0]U I38JLo܆)BL2oTf'toF2 l^ Fk  eց4淀`<݁{[Lsci!j""8;FN^' zvNv}…I+5 8;Cuiʘ.ju:{4@Y`H k]ζ 7N Ս>%O5 gӫ6/82,"bd u+.iV)(9  ?."8pNNɗȤ+yĒvռq ]NKdСeM¡C%!%"a?6?ik*8ӯ'z̢R&0*;uxil0#{cx/T[9 k$'Q]`rN 5}(ǦNߧҺ/y# t<6~!~_+7Z⹲K'fp IWҩeҘW)sdĥHZ 6;Qÿ)n/ K W$4%)oNی?0WJ /jf|}Nʙ&N9V(@ɵ.iʥȷ_Z@PϞTꐂq='H303GN~DMIL*s3V:C[%ZHfK^Q7z/Bɢ낹"8Y:"S/48IH% |+N@.kp}Ivp@5ٹR(~uY22i[t*@ %"S,¡~w@R W $npڔta@u[ܤS{D'X yQ}^0T0Up&锡hЀ;_A쯝XZpӮs_tkr=rե n3[֥4IO,< FYqrjoȚ22gfj4Jɔ [˃_|?ȸtӛK ޻XbN= qj$ &3e Fʶ6bQ=@Rɸj$1zO*d2`w2&Lyqs>L6)|3~P\y铬hcϔA>A-.AX0/WPg+= x,ՑY1}42!@ <ҬڹfE#^?WhVrGS2XpZ={Zn#Hpƨ>-s(B8$JK^86Ƈn}gI! 0tO؀!h[5Ioy~jAO[#UѨeG& bsd̝46un3l 3ǣr7%U !r#97X60fnN_0lUZ7ir NKI)S-C(:[ K1<ԤkADu岴7JDh њLce=0Hm}oy&LΓQPU8y9ڝt@%Q4@ }jaV]tA6[|A9*H$wmd 46^E x!U-wVWLO0OE2%w|,!1aĕxC%szA,ی%]?لup1](; x9j̶Ӕ[ \"YfP֝pPm 3o4Ωw|7ƎҤkٿPL١]H^ r?j $ BK|&#jQ!"<3 (\P[8C܅r#* *}:p@lE˜^bJ:C0q܉월:µ0q; `; Zܶv>\Ĝ>̧Q3?p*2'+ - 2'3=빴P՞Z/( ZZ]\qVU^l{ge?5}&=Mf'Kl$؜$>z[:hs]  D/kKotqV%k ?1TT&S@z 8'  YE$GlA:+h")^shiSZޫ( i9.% \3*`Gt K=O,<',܅F6%稢#!m)%BbJQ3gjh{BzUhĢltT̻,oBhԅHhyr= |!.V&cF2*'BH(@v&bN \]'Yw"V,G89+wh+)l(aY9уZjOxaL]E-azHlbL"TRJ6#μa-T+g[{ NH w )3jo$=F9/&<]gkQl͔r%qGQ<]}vna7y_C~|7reoB;FΫM`tנYN:>vGX!O \Z+Xo5>rj4bEsh:Ԉ\%Z7Y5U4$2I82eF>|AXQ񔊖DuI}E}P>r粋m{tM!SYwѯB~E@?o.=J[" g`xd#F[S-,XzBe"4\ԬyHũR1lqJ"/P$Ҭ~MK35<`az*-86U]̱#`Y7C$iY(b0n?h]q~F>&t߿>|B &fJXbݕRǃ|4}'2E`pO!'mA_/*M{X%S*|]j }Ҫ EI{=2G^71tbCGʜ&@ ScyCr]֐x]Y1~">RzP6EIڂ55XxB|4Zdz:!\!"˳JxIAA:xmw%`s }'|LXvͣFp<$Z?*?[{8+פUoRpR"wIPIff=z8+Vql>@l>w/88(XzIj,М7QmN~$3u}9ʇM|gW1OJ'6簩mvŝM$mUҺWΑ)u\Eg OtV#X=SdMԂ ŎVBёN]뱐[OckIUDI~Sx j:o"Ο 2c A_At/t13v`/8r֙W 6`v/W>pM|tħF\Q!MhgYݬr zm4^I#.[s^ \,8sÿ(ũA :ۇ(/ .POK7j>޿wuSF(_ey,?ZIdk9TfAh~J:/!'y@->v B J Q 0Oȱd3?5uVZG je!I@0`Gn&+j†}b,NsjIJXw6{m>U[vxEN\wŗJvdvs«oU\~/T3?WOX#CX;k> G3R> 0Zw_)`Ɔ#9X*RDdT!HR<5sd6_:EK: >jB QCdn:aĀKLIYԸ 5 ۖ])x LzqVcaJXKQ-u` hR}#q@ q8^nϧ׀^E6|\ȓ^|lLА ѐ+k jLm)+@K7uy0s-RGSФ@t*e?W0G̬HEat\u{ awxHd?( <Ρx-`DN59d* .0fH8ZO߫tDxTaX9>W)NBLi[p7:OeӪ]lcpP1|"{ [ l2Nns-bh.VCE.G{5 / V`B\~~GaKiLmhSHؾCt% "hΤ-84!a=?Y%DCri~.xv;% 3Bee]gCr1g s}Q 9҈S9Ba SNao2ʐ*})Kœ_V!A@SnzT`kW {大sWN$/>@ TS5OiD5h{#xhK,۽,/އ *oCl-ôZlOKڸ%~]v6|: "dL|nY :ig b@kmIk0bT!~sN8DXG4$<_!i4M]:$Cľ6ޱ>-ZmI\ zBdv0|v{s;5X!oߠf/GlfFHRh ~#GM5aРёaxm}Ajp%p/eaYoE169I7FMxjLda홡٦C`~k's|4wi$4 ',Uό#EyΝHy̏=/DfP  /_:>)k2{ lXφɷoV0Γ Ƥ1=ޘPZl;z4 \MK{xۮ|psćK6$7f C#Z>z%PL !*j;GtG:Vks``T4ѹۉնmuƙז!x GI#/ e^e"k޵ON5- K9NeP4qm.hr*[H>ԟ,C'vpk%̫ԂP!Mŝ+أ&sݖUto?wFdY-{qxTn HMn] 4[ue3L^%^79ࠟZ,:p<[/V Ea]\zܑeDjEJji?M'*=.Hw|XU1΂68w0 yNtX"e0Q1 y^PT Û;2 ->>RdCUr\bJO䀮2F" 9# &yv]c+9%I$nr| %{∟WCWق v7.Eܛv7̀BB0 ,eAikF"uTnOwqyaa5z\ulUl棃{;Oy65a"In9WX=*{953^~㒸#E-& VLR 7لxDeVٍZiD:K4_AN;>r6rN j߰Li槶^20n"相Z{JyYɾ\O@6 04]kyFz .kg)PY& kVD-yNy5Z=ZO7C T7[[4zBh93[6Tsg&[&E؅YQ5N_+vk2;Gw;~wh>٦ \~1C':dPP%/qI;űbO<>_&,] = {Uݢaz]gh56ߣgmqĽJ #yrMh K| $@=2V qSPh+ u J񣂥k9`wgmC~M0n!4'{ u9YvV+ˍ糵D A6,18հIҝ< sww79*f**^m0^N6}"l2aVYl 0$xu甬(eL4^spXAWϴZH׼8p|=Ixݥ=^ĔLeZt28I)0!=f܃v.YK)J%@ [P=U)ݍ?)F-%I%ڥerZ`oޓ>RZf9V4cˆȐ('B]OxJ 0h5 T ZTFL͜g)kItM۹eF1 fRFƂEɞJ{!2 2޳B3qͨT#Iuh LnIܘ^b>_:M1] c@ܿv6uLOrAآlJk<>c=,i64 |R}_[Ё) 1sukO.]Y9B"&8 Gv ~cm?T!%K9BpGЮU9DC q0l' M58}+uNhj:#y=bu*QJ>.P$ib𘎝$MF/OcP}e]UyPBN0U.n\q=~l7vRf>YnNk^=SWu#\NEP޾GWovEw!O{(?Qݡ}6G;`H:Ě5̇ԸH<`2we>1uR[&TQ)[R:ǀik'N.ҞO1ZpY㵟wD8'\:,Bk69qHՓF&Zv`qt98sOwic^ef[$̊p6%k3? H/С"a4]t==J+A7Z*t:F(~i(6<9a\`zڜUx_`aL/2Y X ',<'3j&c?=TBcpέ%z= H1.cK7\馧#-嫐rzI9>>IG aU9B6y8chTV e]":zL]y[s%Xtm.7љ6RxlY}J['c'Rv FeT1%wԶ]YDŽgЂې75aq!/o=޿^4kÔQH$!*ԍx$"o57nAG1MEQiǝxxWP #b9y>O\Y)[:5YutL:sB.wEhߤET[v='Ax 12 @ӱ0=}uëfHD?2t _Lufz%Ei`> /W0֗A(VJlEyA롯T⸂+*e*́l4lO";d"jЭB퓓D |E=D r#@A}&0FFOå@VpV)5[9JN$IudMƚ&~ʴ٧ig?U6cr'?hߍrp (O _OCyJ'?*kآѠFSٛ) /@ TV/OtsT){m5 l 7*v96A]ibk ~} m'Ln[2V5atX(d )EzScN\*H[Q.v}Vɶz[BW6-xv¹V 2lٻbep\ȧi_+D- b[(y3]˿5enkxchQkw :l﹑x|,i 㔮38'{&v(2dz͏5ك\ZKG6g-`WxwmZLqÍ 'v%A/ay6EO]h6_ؒWgOM7R5Yj&4J9D^M ' farue W&4 gtmXT,<.  H>CZ֑ډ1\q Ʋz- ڟS^s,ݸ?e rg:WF3PB$`f28TtlwcI asƱOϽzm#jsY%;O]b_~C샲Ss ذsneViw B'4)%0}?,donōI_E>[QZxې|o3s.|7Լ3~6j$Ii'>D d+wYc]; 1=\;!{݅d;ǓWS>̔;u39 t͞]o}5cs%<R ODeS1uq=|;W)k4k|o(!8.WVjPњ4xu`!Pt&x~lbql^0@N5jϵd0,L-Rz&3-e5rnTtZ҄6WnOCkß |tA(슌"md)4HC [ _9ვuV$ ,=%acJAOno*8Iv`!J @H36iB$ 3_5j0e1eECƁO|NmˆA/WLWtxa: ^Ty1{cth?}珙!!2! 0Rw6XC: x],@ᨵ DA o(qӷNxl2dއkM+fF޻5ߩJ& vA+MvLVwj 5n7Ӧ['[* ^Wu5Kb5>.Δ"!2$dI:ϳj_}s(`O؇>txX9_@[$e+&m G}"-:! *}&]R%F f]]x?)`~ڑU .uqS-ANߚDǜ JCP~05[9'JbrmDdfMdH2#8K/bʱPRV3 ]U[[c越'I&sO^7,r#]a_KsWHtC5L u:Vdupw>i@Brt19P=2kn3,>>%+KfI^wZ/suҎO#ڀH<-NI'ҜTfW\u}Ь_H>k?qވdFDkM_pNX,cńt啗3DQ89epum+b$ڲDp_[ɏ>a SXUa 7#k6SRI:F@rLb,9,.!?C@ =L2,$YW9 GQh§5jASg4.]SWL,K\=Lp.6AKl%q`XB1+pBjEo>Of]3KK;+EIJ@K^#"~^5EڑWB?%`n+CݼXhmefK衁?4K6xtí2l+:= r8袢ak+| VUKl~ h2o?)"q"=S DSVX{c}]ȆۼJ9-i. BvB1_rgڕ1ɥI, ͢ P cB(RqʚEU c˗=4f.cҜz,@)]Z`Qd@87EWWvJh j3K8 p \,6ȷZh/ív>Q9чyߔ5L\\'>K,5 "ҎSbb sx1Po[G.*T Zׯ9r_$fDO0R[oENbQ`?H6LFzRԨM,C~/WIvB+/=iOf'+EC<O+?kH}Z&Gv-' sRM)X/{au U>[(י?Gָ7#M%3eLx1JBnPf*kЧkdtY nGg>qL_'L1]"PUK2* :R[MORmo7BT "eՐ~3Sn<R fЅ@E \}>mfl|'d { F@#ŇX9]E0oLĂ'I-!Pѹ/:#0gI Ӈ7-.g dLm+Z> L{==R(yޑvgH0r3ކL _[t G ONYB&GGaZב۳9v1lT:ޱf kx Úx6\Pis 5 nCTNF~dЂyij{Q h샄KE^QB-o.C+fKCI3c:w"O0YveԈW{=Hux .ۃBwZV>h]qYgxSKKCɳR;F\n`>CL! uga#L K fY$}}-WJtdkӁ䣳H9G0N7/*ؓF-B%Q7{{A$1dT4"=cQ4Yi~`HdmҨkt[-ɊgR  2 ~gD,R ˥2u0k*L/"@,Zz5#v0׌XS0ϭ9 ھK9;$NDͳ)P׌ܕUl|l& NA}/P_k;"j 8v{M@Ntb~m fJyW*JHjKɟW|C35 x3FEӔg2QqM>ks:ݶ#/X-WÇ߾U xZ~(ЌIy⓿ fx%ìv|u1j!Sni9|_QH~)K&f]NQFHF"{ty2X|C5@.7jS`,5h׌JW9}kǸ Pde f~z 5=Z@}noXz }˴; GtL9#k&ۂFv>i//zrZ1|#e.N̩}f)Ʈ+> ɖS)@{t C,Ӱ8/[L2bSC$ D%\𮰯Plyn,RJ7_@=,WfN[7ęa3Eg)&ȑ)_Fv.B#ty bk!?q5*}!VJo yMqEӖ@[T3W": }klP9]a4+'IKډlZMl.՛@ϊѽF+)JrbFqPo9?ceY ^3.!SGO e[y'kG+sNԑp:X,G>N=UQ g)HGX >%x0 W  ZuU̅1#e Px\eZZ{N뼅 .6[UML:$1clBNj䯙\I,v!`<0g$"5 kyj`ziM :j'٨]J0(yS (^QgηDmg]h9Бx{`gDT.{f.nUÿ3**QkȌao"EW#Cs^*(- U; WfmTgk:j^QKV(SB=3zVƒT%W."v<ʷ IJsN()usvO`yEA<d[Eͺ!wVZH(9V(񀩲ww_б9`+ DnjW6`O&;6ˠd`i(4&L7/ŲuȗqTrE`] a-w@2\g)VE3;TBf!cR3TǑ7NBVj&uvf7.{@E?8cD]Nyo'Ԯ8󂨗VvշL vž>Jw- %U,SZ ^#X%::m/ uFp% ^Ts{aսPAo--'uR\qlv۶]E(+rg#z[חÂTԠ N?#)GX~;' 1j ݀VyX mTN^warE)IS[>X!m|wFl+v~7!a|5$(ـ}ɋ9حͶ'|V?_qd,)6Į׬) LvC/JUӬr3*S]<Da%w~YT4;> o%CwۨBTJCu)B :Ġ *&fp WoRsGX}iMQ$>GNOZw(Ic.mb*vNO(;C{ 0=N@v3 {ae#7NUP5=zpJs5o1єi ԃusT5 {lPjCp3;)1G}lZen6!q¯; b27xl'|[ I6կ>۝Z鋓ukwt*DiIL;Я_C8ZiY?M+yכM|9aբ}e?#iBsrݕ[K}@? 3On"'Sf !R!sހ.ܑ9gגyjJ L]Gjk @M㸒@,'4u@u9tŔ[f1Ԅm+&Dj-b$ Pu7t8ʫ9.f{ӽ!]lfpsDrܙ]wmKi{˯G!zIa~?}g C6s0$OF^Y\INMάW)ۭ[Q n)4N֧\{GX]ǭ.{~]ѻ* `ZnS뷆ZEg*(b35:( ax'S=a 'y{?3yU [ۉO:Z0ӱJ`F~H KvT;T"UQBčj.$cX}{U#b pcٕӺ+N Kgh+9ym//\Mime`cAWW{3}&YBbþ޼[T-C)BLԪ1 F>6JYGˇ(E[_ *rGԀs/>#Ud{G'[~Av3 zD(kix~\%G~X@QttNXy,.;bY3>H""r!뚈Tm,Z5Rf/eCɮa>3*:.Pw6{]f z ' ' Ai0f6 :G$zۜX4&brkJ|Jz V[ Zv?5AٟAܬDw0S3vg$j 2@ 2rQl]Y1toomS=ZPmwyߍNWdo}GHLdu' >7&KS n Ft,es*zܘ6Y v'UBO`yܢ~R&smD#T1Xs'IеJ"fӐ7y1YFfZBܿ 2өԼN603|2/߬``9rl"y}'q5ĭPR)r}UHm- ]M;xKmĂUO"L32B> n$B67s^}19  v+Hq,/"hC~8[3/`d8i]x(JG"%0ZIs 34#̰n[[fZ\v̯¼$>*Ӡm6Yl{-P#|(ߣr*+$2OT˨q2KNR;EsKy Z75RTᱷRװ1 <ỉTRy48 ?;HQUM0m H|XXTǨ IeXw 4S`VR#8ua\ B~,њ|a (X$II{ }SWM ?`KJ7 qiA67 #vJ{6 ^b8hFP,A;-ph՝x U@Έa U(dx59Hs/yh$NpOQH&C^D33Yi l $#N9!ͬUx؞A&zԐ{ŕgCe␒V\l^lA̶GJRд&1oq"5Lۺզ?rqK%~pJ&97yll'=@1G0icyt=J 0'T}>oru?!mdYs§*]6eMaOg^&IOqE&> r3iydTVǤu]9(W%/,*1oc)&] ~L2AԴDx$+&_OKE>v1N%A1bj*s%LZs=u?SXɠOѪ-MfQBۯX JGi`g@ 8'뉿#(&]dJ}5MJ0h:n2?y\J@4҉omS(/ >3a @M8J[#,ןwQlvU]6 }ݥn>!p?&kѝ`i#v c!tڝ-Uk (y_ ir2uX7 2NAU2S߶Hz|La'AȐv*+='\W ugЉK0KtXPX_p{Jw$=@rj)y.zv1[p͠h~p↧u {( 1CB3YrLEE15q|uf#zwnכԤQ@wgbr:"TPrJ1wۢĿj̘]UAExd f+/4҂jڿzeR":e6[F~DZ ;$vuY 8r*kȆ& R0r>QA Eq#"uz?bH`"u-}!\=Ѵ>81 =o^ł ([_sLR nm!:K-@A"Q2Ɲ9*FW#rMNҼË$wOj\' лk^1*-#/lfU'E~83M2^-h,,EM_r o`@Z&Wx0zTA@ BF:rkKyQPvY~nU:xhrvupJӋ)ҹI3Nx~uD#У!|E?hlWAnQjxƼ;RDkRГdnsݣZkYIy~tcb5׀0mΉocx;̡?XLBDZ'εW65nW3+ n qO"(K?ÂX4xE9/huWg_g,WP {ĭ|wC)6hO{[oS@1}pLg28 Ih8d*:n胍+~_疰W\EF̗U).4AL>wD0 )WCMg[4Kř1r*/I$*;ni;VD9e}X_T}sJk@@&|H Ԣ϶b NM;YO/U !q#".7 [jxTBiIW,A˹Ğ.R\-! ~>)8u6_"/_l2t:Adt@ጦS+>>l_.Exur=YmdPQyݛjD@jWCkŶ>:iXΜ$i_f}imz$O q"Y(@(gSro{ʎEGGA?kp*|fQ}SEV*<5cߓ$aԑ H-jDJ %RSN!'+Xt#Wp?n#75&.š%: G6Y`+ 3cpd8.:Ө,QEdrFB57% R qӪrsTqNi=8_uzeI* ȵBGyPI +/Mfq7Qok1!|0ff"(ǼX9#BI4`u' 鋁"vQw#^y*HjHsC%-fzh";H)[΁)qsߩXE:iփ-쐳uJ;p(0Yl?ȴ{IOjpN•FH uK,fae6TZ֢ *4_dX]FU.藿`1ZB-s@KL,<@/:3iP /,VUGsݡr>:ryI;6~h>뿯$4Vn$cy`z4:o*T{b>-G`WU| :uu%=rGt`dJ"Tht'׏=fxDҽb{F^Mdppym팽w g3 W@g53}Z'#jnD=E3<..NQ, ipQāI].L(Gql;U_ĸpP3pjy*`%p ]lʝqcXj]k~_’b/fj)Mr ؒa7&/GG)rD7ڠJ_q rK'lhmeΉcJBٟi+/Cm*@=.yB'Es;^ eޤ)k/h-1^FN#Жkf& /e9)aZδk! M>]IW/&KotV@'1bqpE71o{AIZ%}U… xDy-ψ-%w^h*d6Imi|G *:A)X-nhƐ(|ЕLYe…;d T!EA3 /hoa iYEHT-\C\9?xj|f-3&Kp=U.A hXz3 5#;!pJ.m>ssVɘ7ꉒ1pϭg~5[)R0<7hS|PadA8:}p' s^b.}`"O"4eYM̈NmZgg;A"= ADMm:vQ}RlA:%/mJ/6-e^s+{ϧJko12ap%EٵSӧ=4u;ש`RS+tDR6tXIr/(3阁SQEr=ͧqZ2U-ݗjm_e,#lmFņe$?˼9r"U@8/ gHݍ9r4Fer2:#nHxBOvWMXqbXN }]m:K(8_KTd`ǵy dP 0膫 !`K(Fif!ɑX2Î^GOqU}AJGX/bKv(D} ^gN"R*z$a9}ߦ*O.z/^FX}ƸT$Қ*~d\_I+k|جO܏Rgz8Q } ?N}o_rjz+OW0tK{k.jJ|P"p)"̲rJX]SAdk+h ax1'"snύoc9 -6m`o %ʋUngc`Pӂpʚs] 6e PVlA(8&5W{Aw0ߑzy]skMqL7f*V@MToLJ{'''(ٺMYƘRg߾&Oz+:U5?\QgZsH)yD# Ng={$@e_L1 N(]K{B'p:²TaϦK0+,eYPO0eA\~ /b+m?R1~ǩei Bb}eKdWVx*+^JyѲMFMٰ^KAyPF}Cw'NP9 Ҭy7@{쬰IWϩJ8j7QVr54cRȀE]E{03pO=^bn5z1ֶh9ZU @z/Bg;f~z݄ߘ Rd,sYjٳhsANurg8H'u!@V vyzNEX|֝#dEej/nWհ PNh*~ S~Ezؐ]9u^#=Fϑxd5ћ%'Fm_'B"ZLvZJDU%O=c#@fRtOe{4LJ|>Wp~:t4[@?\UN ?OQS ~,tA\FO"֡xo9 j-[8DȒV3GVEiU) (k"o/9ϣt:n1# Hٸ+֭O Wyǒ=lZqQkoRtFuMU >iOtʉOC Frukr1 #]B7OvBY7^C%';jg0LJ6 k\s Va=h=e2y ،C:N⾫dఞUe]hPWR q.Cz)5S<^l!_9`*7s}I(LqO,,,\lj'ۅ4ڍ:w:8QoCC(kص.~釁%4Dq7N9ĕ_홢bt1ʷx)RBg&, S󟐝}iX|R]Z~R|"qZ]¬X(  4=ƣѝ'̠FN!ıLHK๜!`Ztm,b(#h"&'s^6CZ|.z2 kͷo7R4hRO#/@,c~kÌ hs"`򹿄Y{.Ѿx }@Qy;i/*$\^eMl4Rۯ#e4rTu/3eRp0h,!֒`1.dĥGL;6\c(t;aD2V7Xfl ]ý&cwuu@XpMf\Wl1@ 8h+⫳b '; 5Vja%*/i _IqWH7y֬%Szr{{G~Κ_;ج7i{ip{.+#,SD#onפ”ZԱr k$޳Xu8Z˼s>)#I4}a`o.'ڇ֊@7;Ul+/g9IVxR)bIc١zP1D,`R{֠D)(<*^Xݕ^94Oz〖vMC.vQHowZ<%]qp)!E2(Tͱ`G 4M90 b* Q%?wDhl@A雦! XZW3J=p^P%gm~y ɶMDZȹ.j?T*Tp7,ǧyMUBsQqzL+(;EɽeZnW]<;ƟL>@Mp,(2'35KY-}Z`+rtPAX6|[Z4p,/u YP v98dWK˩`Xj%]+v )Z*h.v$?7:_bhѩC'Kw*2阶ᐎ䕻_#.>Nذ~->} Km$yt\*Tޮok2΅^ j3"h`;;wJ#вo֬}xL~l$d7AE1H'5B`A=v ]HJ*RI~ Θ Q.sy<5vrIf2;.[V=ڷsSbޠLr 6_im+1iKHpP{;{@ vC7m\bAfMYzDOGiވvܼ.y+o|ۤ=h#)Ayp|pIf͎k }Y E_dN;*SR`Hlxjs $UTp󋍸w\\K

z(珣~@Dit(6l|Z(TS4C Su9hr<߿_aWKqJ ^ŊnLL Z\e*/l%QXQb' 1,!&mƩ10S}{ `D 0^Y3 f3ƘC5' :4۵9=N >$O*:9Y:51 '~h0$Η4%Gs;|wي?Lw$P }ۮM^QN ikߵ1'OT]k"-LYYl7o5[hkR hoNe<pRPs[2 hU S~9:d6xR]V&6`ުxεte5 $|zrQOG@)ԉ1 LHk_lJ4?O*`Z='1MkEc!iI鞉*>MF%J}!ږƙWom82Ɇfcxq=}L= /mq&U|f9OKEUo8Ee3#PYw%@>.L6G-< vԫl0` 64x{hy~)UWq؃rY8e3$~U)^LЊ>dg}H/頳dZu1[$im Prz"2׻q fLKg%l(08Az'漚0Z_+"Lbpd iTͣOwmN#ɩ6u=Mj@ ~baI'!@OE b.\Uja,p 4wQvoKLk˴؝`{CNIOwzag_mP'tq,Oi ;$5A6(i/*7b] mzA{"u"ş _)EK &Tnl<S2V] 1Crr@;P>11JmM ϾLfB#^ iK"Y(dS5x{Ƿ޳WZ|i°N.-AlRLFOʤP= Wt>?sƗ* NRVӾ12GspY1 zwp$c$(#KDOL[uG ƻ)^pɋʀ:vGw$އ~o!yW@z)OhL)<f/k ME"gֹs86B$ꊳgů/Ns~mF1nv8O8Fh]cu?3wg|H:Dhxgjg4 ?+ &0و}f6>y}_ۀn2SVuU=oUT?xy{.p&j9s{14Ʌ}7ziCU1AO'ڟ\ϱ,_{Iܣf|_qXPJAkˌkNo-0cṆ=TSj]%&nC~8|jHӭZg%Bc8=Kf?9+$=.$MZ\ZvՑ -;J!94 ;w?ѷO~<EpC%ň=E|2s-bT nڌd*s wG.0I-? <&(ʜz@Ҏ"Q3*րp~E)ͦ 9M|/<^8!|Aj bmݓ >%Ѡn% խne<S\9 ; ݨuG\ΑF7%~H{;}g|nez4BX:S569?MC^F!X`0f8e#/P` &h ֓-1(j2|*+u~\t0O}t:[֑FG/AiU#w|w_Ӛl ̓UFޛ<ߦb kcb( f=* yXu 6*~Ԅ\Bi[\6 `q0 #cB{BS@BRO_H!}7#`SF#RZglrMz,(eBvhчzK#= zM6sм 6bz>ݽ$㊉>pЄ|fq:/зdzn/AU8dB H&4BW=_f.SHe.R`")32?B!ۨS\:IPxH6ȋ alOO$OUq{p#RNJejQkz#P }XkM::ݷfCPYiL~۞%f|K􈡬/zW`؛ " o_CdwHATGVSTb曘9\\w+)sS;2pV4yIEd;lZ w+gHٻUs'qH_0"w@6@ܬhF_=+׌d6?IqR3WB܊bn"r- '^eҚU0[vYEzvU Fgs>fZlG㑉"ûp5Z^Aczd#n/.p ?|d?f((y8,4YIjȒu}IkLJk\fSr _?ֲެ׸`X3kGZL=ٷu m\Lb:Zj5dUt!_Ffp8Yvq/dԐ̿Ń]h Jv4HW9Aq4O,k7!Λq-~ 5 akՑg@fM-!̗Q8n m>`'qx㫶ߏ:s`ڕab#ME{};<7T4D 2+H' TC_Vl {[3tϞ2fc@R:f =Q렌5NgqY~AU3ݺ0Ɲ\Kp\kTB Ẃttu4;O$Qə|N+Mv= :L2$/!S7~ģP;k?X[bƄs۸] \8+ FEoȞΆOWwUf#V!ޒg^`4/v )iNt`q 9ew#N08mp*wH׺hzB2T8cM@j_P6ˣI~uAiuRw5b }pY-^㒎x[+^g@g5H`d;N}kFCWHQ }_,6]ή5gӓ>{Sع42R=DYSHJdc yE9p/Nm\52ee9 NK:^9%vR!;?Y?L @Ugki'OćZ,7Hbi562'p`Z4cV cBЇ&#ТwL [Kcju'U&8by/^E$x+ҥ " x.?ap;ye8KCNaXeR"Y=eڽv˗D"T(Bt*bYT̆ѯӧ4$W"`rR`fTj|TwPP: UY;=BLZƪS lLxrhX03w5b$;?t3%Z% dn#r<3JP2~be*e=BJŒ5򼅟t¢R3b5d 2%/K2B?'?4zQ"ܪ<Y?{Va+A?EeP{6Mu*@{3἗lLH~W*#^oQPAKP鋑$q>\^]\&vg^=)x@oQ+C9^TQ~өk[JlV c3ųJ|I _/Af {]Dn L4`hwT-yjXD"f֍ŬC4}!\U<q/Ḵ182g{jJO6^gsDrI%Iܧ !Nw19O&Vo6i2-@إ#G'`*՗+a65/{*׏y6~L2zE$y q}8K/\-6$Q+)qyn7@v`+b'aX:xZeslsP[BF2Ml*9k| ' kLP߁pULY=%jnFfXdp:7_~|WNmĖ=NPRwVSH_(ht)0is`R*(bI=sD&WO2}dZ : ]6rqeSS9ڊwXEqq4pDh[2}K_# 0%zRqJh2 ^C.z  H[m#QMPx@[A1N]W#,X~&Npp+Ǡ7f.q'x On&G[8ģphB,qWrVs;V?'t%fNغ"=L2x2Ȳ̲>~}<!m?058Syc/vq͆[;ERA,U41Vtri'@{V*w<Vy ugŧiai[5k !lth"{焃qьc>E]c "JEi}KFO5):_|u*ESD| nl?tvbiOlB-f<"p ҋC"doH9*:.}.E᳡6BB2%qP1o͘aUT)3EI+^& Dh7=ED=)sOpȃcF&D1tG}:hF Fi?iVu,Bc1Cv)V K4L Rt fJD Ѡtz%_9=_{ [{*GR ,`L d)?@,+\4#_ٲ3Dpa)N~2KS .|_:K5w/%}C=1qW%b68^C0'uRx:WZBZh3jI.0@LzϦ/,q**Nv>e:xٗ醍{v=}j-*m?ۜư$!TkX,cVk"&j5P'wsoXdFͷ !1$AQANDeUŵ9bɕBG`oo/)RMV27#siXiQ}T+̳OukyNc+ gkĵo0J}iHy;ٰ@>4 "׊SF!\v;O[qͥא9B^E{g9+r.% A-*{eR1o>!V`nefG/4TKu'}}yBcBz!dFϬndLmW S !G 7pXuIݘc_]y:sDKea=ˀ ̛?=(t[o97/d2(RY V%>^c^eKM\K0T]^y3TM u Z@ǕL|˭ 1tOYgZCx+jyl ѻ64>;fzǒlc7!ϘhfpJM]3ȄT$q-8'*%]g]^rG$ۖgΩbD7C?؝]aDKjZ3(' w9 FkZo\QI ԣAsH`~[Yg7 6%VA ?]>Tje@X@u fL*i 1'A ix̝]Mj;!K a˂BIXL3O!?oƥ^ĨR zbBpct<Wޕ$tRr+{m}:?t̄#&!gPg~qKWoq`DdA4· 3h4]M3Ј-N-du=xvzǞ9@-p>^=&Lxk(5# 8M)-Eh6Ghm'F}`?V)bgDb331mARHo|׀WmRxXYZVE}X\? H^ q喲rA?(/XVi[9;ZOY6q4K++I3ue>(JM-]^p6 a<\r+$ ?dw8pRR(>]B5Ĉoy <BˀjI$ q9h X3$WHEN%`y'Blڈ7u K4qT Nǎ,ls"J<#=p)LS[>R}c=v?fLX"'QVBZzRZj4A$)7X?@T<}2Ӈͦxp1BJhS/ox$h䴦;d a8wbz0:ԝ؄8}W!ff?ji)` `qNEFZe4Qj8gQ0ZDW8-i( YN͵/vUVi.x0Wc(|) v5't="p̌ҜŔz,K4~ i_OQyIS$$J և k\,{1Fo̓`۠kّZ,0mnn~|,^1n-/5ikf3&(ʩ xgdģA+ˋ4:Գr/n1x&C yxE iլݓh"=cD94 fXzĂ97&Ɯ/Vp0/DtGiQ$dJ.HQO$rMZ.^]ڐe~2dz)(RCHk  URQ^yNۆ8z0` _ZJ\f\Dl)QF…XMRƃ̯q|_귗BUHާ*&"ZOK9YIx\'oGT=%ENeZ L^ 9oX$vRI] h_enӈl1+U+H=v.60+ SJ?/OK(Qm <[}\5X7k! W΁^"^E J$edk%#-}kG@l $4'+A'C{ (SDsp{>926F1\u'{M8}}/-"g|lI`݉b|5& 5hC7W-tޯjrP#WK|y9%a7L>wtfn6i(aWr&oˀIez-F a0e;PS(um\dn}Hh#GR5B> b5|#Lu/k PS'^W[8CyjԀ-Ȱk>6Z2:ܭW8?wE;%Ğ)`[LL7dC.1H[>ά~4msץa$rwgĔՆKfyS_=aKt/xf|e?q-pe~M`Xb_2 ra1htqROn}i!@D亽py`OTJ Ƃ&ti|ڥţ/\#eԀeU=x`?LZ\cʸ:83lbd8;Pb[nYN.u@}v4hkOS)݄%S@`V-e} ]{UJ.,z1MϾ$)3vvzR̕مٚ(® *-QS4 wEXؼz,`WlsKXg1&M(ieY7ӠH&&>ֹDĽ=]nɵkuT%'1@.1FxN|=x!9kۋ _\K. NuOmO~o7}Y, .d\ |x W qxzdjI%6\'|qv>~VԂqa4: gYSP4 RV믤ږldfܯ_/bb=CyCtYo&/=_;mmo ʗr`,[JȞ7Cc@֟}MC3k!7gxmb;*ctfBAD}Tr;9zIW=|WWI綟.ELkd=Nw4?LtkJIuJbie$2vvǑ;2 46(7t/-"l}=TC0iH{I÷뵲HXo LU|3+ 9]$^g? Nl- +tx^V.gg4!9|t, _F2Zѝr5I.=V儰re%5A UI)f܃ YM}6*ڻf("?_8-/tΔm5P^1e/Vrn#F!8 EMBY@6ϨcPtZ `)Hu҄$dm+| yǠu?JuH j5.lִp']v^ޙ-P ^.7q|qFיYl?K8xzt}NdZ-ї>PN(' xͰ659b CM>o`R[7@Jc&;x;1X]}ǜ5Qݗ/ KQͰFˊ_e@#DO]C 2 ; `׫rKHO$HRUh{9:QfR0^Zf-*=GfI$I Q$[MW0YbOy^͋j,)U&J+A9=PrτݱRDj$y0\. -03WWJu=iU>~ %;՟e'Æ^Ht+hKebuDO-,>~@>WKy37"I* !{Jb8MmvLxtDǽ>cUpKl 21ߞO.D`*_&\;OwzwN q4gU[Ak;h5r:)$쯥9QTt;PVʲ:!4˻yU>C|$SG=ͨz3o" ܶ.]l|q0ǩ#y5Q><5\SXYYX;̑ϏD?} *t\,zm{zDR6{!0eb7p3ᐷ5VG8eε'9tU[!m8{3dFI ,Of)~fȶ$:n;$g:k:ٱ<$m[kFH λ8,5ZϞEBۗk_ߙfU/NVZ=+ c6t-'3-P0.l_ֱw*-i)tܢ<6zn݂]6 'L/FI a=Q .I/ . tI[_qߎix.e{lxSi5,ཛ?2+8H*Ba,` ڏEf!U*xԟR1 R9M8jl5 G(}췠c̱pr˔nNd2񁅜^anUUׇ;4Xyˇ^1*h؈:58 CB;[G Y 8"bRp9`d7sU89~^*>tIC5p 0ׂP7`= ]M 8\08Yk4گ!pmKӐW'8.`RWog+AGWwZ-\Pi/1N{ťL= uݵwjfc[_Y@U]ìND>1zoVkimZ;`P,c$^Qc]Vm3kR+F[͕d Y檘 *H91.ϙUT1 Y+@e9IbW+C>zF>PĽCAzeа(!ZSФzNyga倔09hSJ)2ܵҤzͯPD"zBx-cUEe((gf+ ;6~<a2f6`u'YVo"QwsN @KtIZ AY)v`\W (91sVˈZANgJ*27nVaTCZڰY~%i=ZƚkÎ0ލ}'oU 45X!Vmbz6XW./XZd(j>ѣ96ug7B3D0|k+QP ?Kא2װ^,)Z:dJb@T2 פCSCmA+8 %24/GfhcXbr$8#\1dSg7#aJpl{PոW,ƿAcQ0.fRɷA|Jdf>eMS#@eu)DZ,7Xn?Т[g.fnNwz=CĠ֕0ib|~U!6X~ ظug'Q8' 6/_TJCsul6_iBG( pKYEq fekx!NtUxVo3“{,pwǘH4!0(R -rTl9vo"o4~TDz'a1B5GOd*ĮwfE_XqOpƷP;vX h`P0:yAdNEn%ϡnL%mfFi >.ZTE`f_Ϯ{>,cv,-'g!?]Sޏ9#ia+uezh:ԟ:M,qކzܼ PRN[@5;|fdf5BnRNB/? ?LɺR^(g*KS!m&tu@I,`ĄșP ш[v|oK4meu 6t҃_E؈ B ]͏5U;|aM_h@-@hi ' LK^umgo_1 AҼ_@G3bg@6|*ߓ |,rT%aOv-`pSSyp m7CVZWݙ ׍lD5,Fz(BNTlnS|pO7^k*]Wc|\ڿ̪tj_=]m0mwDNբ"syu(ڂGh )K W1;Lv{.9f,}ח!c!u^VԛU' Ӹq"Y؋򴸡MFQ{a:J@_=n$&豒7~ Efcsͦ3rvTqk,,)4[--R*Cc*3fKeyZ< /g }3,+V y0{NQ&To_t_^;ӂ80dmoG}[nqM'|oKX+/It unKm%k y]C^7-)*gt^)0yOKʟ%+</u=r479r9&M7APNk16B^xSǠRT5R5*XFSy#NDV 6Qa S&3*cH(c8w67(5ݾI%eTNsl. #>95Rbm@.B$>Mq &{Rf\L5%ޯyK#ǝ{줵cϼ 4dsXV[VP!_+7Ŋw4?x9J&2ooJuUq?^JN}3\,VFiEnJfN.!\.)90{q  tw돀I PU'_ x\;1dk񈮎R0A PC]MĶmrQhrQ" TE<Gf*6YR=<'i{MD VXQ*B!F+/$f#1*6:ՑG~i l,?QLz5h3*fZd$]l2@ mH8i*l'tX[)hWKMJ?'Ia|)x ws2Ed ߶rtk${mQLFFl}YիO`0b ᭍#PዬIH|>B,D :*zi 80;G1ڦӰ1&grLSALBU+Slb|Ebžs_x[%Y%~{@Y4gȓ;YHN;S2E[:Ɋ@\U8`tx}'Xc"| xii G}cs/[);I:w|Rej&(C C- [z #CH8mL\6؟[0쓺c+ѓVi 7WsГo鞎j@^K#z3|Ξ𐸠䇃l|ō?P%uD4Wn? h)fpXٜEc|ڀݡ2T{J)=N a-bbpSeHpTx@.˩M@)4U]fzbޢy0zd *Nʶ۰jw{\ރ ̀d>P=VK@qC;5 e=M#9#vh@B$|?فb?73kD(Pm}z-5`z _E`c NB۪l^LWYJギG=t0}"͠"1CwOӛNؠʬQ]#>liyo2n{jްcE}綿: \;MFgÃeI d`IRn:.S +N,Ef`wCG3Z}+}LfE29k S'~]HTʃtq?8ʛ 0 }>v-JCۂDUR,( W[0yG<1bl[-1ed՜|[?^{#;bG$8PNdK=h ]9ZEPDDϭ^猧AZ*n& N+9pҏ1HȈWY(@_u7.bv5̏V4!{G,I:;=MQ1qE1Hů(u' 3`*0ߴ窾B}o#`TA hUsko9;laR0}%j;Wҝ D'+4`w(I\4̗Q.3|lcdR|o-:KtoJsr&ȵxptm*m\3d)/\ƾ'({7%Z5O hl XLB<_Sr[UP 60-`g)p3,  J{9^B ŋqHy襜ev3i鏙H|,QbuXRhemޥB%51WAcRۿ9)bd}"^.Q)(+x}|F'hon!Mä)elR:eZga_2! W@mH.f c6m2tWU#.^kgVaHq0/lWSqC++qiWipQ/[A_Ade}j$:ê˚A%:U$= Hέ)KK*9g}j)Q.b,5c.òh(qu^G % $ztkzs7Ʋ8(A~Ls =jyi}Ǵ=;R{#ʉIyb,ڨAFUi玢\8+j$JjFwX06&dO0١lO64[W"[ַc|Wޜ{#v}/bkddCg=UCRĿuڸ}>+aĹV89FQ{"ŖQڂ*hSk^,/0ȩe5r-e-pC0-|͂9㓓&Vxi:|ARI?5i7K5HUN*y].F'M3[2^>EhO98Ջ|4 )̞$&CK$uE!.|]) #Br.kDwz,(['?U DR?\i0 Y?pʙRSYpN-"S&tT~dĊ6b,m)[fUFٿ+g&2LCL;(D62<^<jBͤƁdpS!qZ/|Br (' wKPE>؁/W{ QH83@}K KTwxew1z*[VktW0R~d޳8 '  :08@>@T'`%IoSͤ;*ls,YfJLXM[v鉻i(ad9|>{X_!ܧ@z1RJ{6(wg^ٖf<x9Y p,F<#56w~AnB)6ĝ| F$'SwՎ$ 5buW@†b^ٵ̿Y_Q^xf)O#=9u4vO~Wn4OO|' gq1g-懖ZFcȀpL+#nw)SJv3 AJLYDyV6ߨiԹ4]7@Iӽa*ԉ$ߪ"w$.J,}_[CV =k^m<=+X(T*]g<(y:?Y9>K[@,.Xl>8VȟChV2/! DS Mf#o %DzNŐSBg^hs!} AnA<:Xޠ5fᔯg8Vk߆Xa9ɊAVE @5AmrB*Cpm8B4SA^{wE9SUlbZeJ-791pVIŦhN/X8 3W);k* :Jʷ(tKs}u>6M_M&XqgwbF͐JohdBtB_b:l%hvӓN,R>^)\t5 6Y;W"%wd[%w))z.MU2e<1.MIlC<:[ miwS)'jg}e!Gy;J剮(tIQKҷg`۽Mo(Rf~JZ`c7[eR^y/%S]k2h1'^WxCj&/>R@J.slY ?l ;)@K8Ɨ| Rưz_{2yYtҽy~TN6,*H;*]6VIly-f2߅AִT'wELݗp]upJSQʴ ]AXжRg啻ΐR)]7n|q.HGDJMgT*c7(1 a3_f6Au1}7pUV_^l  ϯK3$(Y!QAzc}n鵺LQ>Fe$:y3AYta_t3>C%ߤ_͈ _MPKB]3c;] t{ǜ0 əWя2 M`*2I>YtǮ'vA4J әoBGo@׸y0csѽ: zy}d*yI7h#e7w!Bi1.C!.9iX72}1 cVlĊ/ЈTŋ+kxh-})22Yú+? b1n}]kI&B\bgkDC;@21:w#&\gSʧ&QܺĪrIuzRnx"bSZ vy# UBX(1`CA;0kF7uG 'iBPR"%+ x"쑥/R56R,pVrlz}CVQG,m6x/iH{7UcO;``ԯm-]l7XcWLx\wjפ k]Ii)L{c]AE {*ibTٸqKE-#2'ׯ7VdbɈ+8 2ZoOaѠU,[ݮ.1KkA?u8vR2B=Úh2h uᩧ[gm_R0$9-NCT rgT(HX_&0ޓ}$&ryon5]2Dkc6z~˴XO>zs@eQ]DlumEziU]svjNNBmȮaFA} l %mIۘ ,_g0A0e8קe>!vS;2c# U->-q+7䌢{K$ U{1'I6`N:1N*xٻS9H:>AҞՎH:m]K.#Ȳ}rC 3'qf™əur?kׁD'{#s:qוCCYϝ1XoO`#n^`{j~&u+{$yA~3y2[m9=pv?jvܠ881wi]j݇@>޼%K 륮0^g<7W`h 8rek.XouYC~6IhVT&y _.4/1[)/|-['qj wza߸2/B/ 0D&=a 18P^8mh&66Չ2j>tx|lNק=)<׸5CadAhSdV9?1b !"/ d!LLEfvͭ@-*~]"7ъnx{gԔ]F>uʖ!6.8s__Nl3|y9W/kå=EytFXoR;vaw+WF\ABNC>Sݸ[^f7KsVpM; ;r [+jҒ X.9".1Ere'1D| )'GwMV~gIXMSk;$Ube\4''oA>VsZC .{ ʢB 1Fbҿ؎%bRsS\ut4gdΙ!q6F-dFR3-Jg%b cR#eHYʯ[evV*7ӌ / ~ T{!BH`G,|bɘvJ6Å!% a_ u!>H]dSQfTӑFd"2U {t[dHœmj^TzvU?=N Qq~0C9IMO#ldֈ-W^)xa\%7ҙ~*`,Ƞ dG@|'Oz/*JmUY%Dʍg?dFS18eڼӦyS,{_/[ TI^W<ۂ̚"ڢ{.$\$^hϽ, m$U>ܿcFO3lJNؒ͡A9b5#At2vx[K *  {?Ҙe N`az@Ro1> n/u'8HI4hǬ<.6(S<)!|vO]cXwNNs`jE αyЈ6D!hJ;~){"VyDŽ L-BnQޖb{!2jt$RAqQѩBcwT $d ,.6[O1}}IJ*f*-c W;|:)u{.IJ1mSSӺhTgi$CڷRbl7eҤI!\̫BO>#ْ㏎68l9I^1?Sѯ`~+XkBAVċ6]%g(ԇǗ,3()q˩S v\eE#jGaQ`Ѽ4yLpٜJ8P>jo[ko9C/(=} ?ԡaqҺg;XWNɁW"¼GawzЧBoXdlX@]s Eq x2v^HrSe|i nz0S:pitܝw 1J0Pמ2+1IЅ| {K W wGʨGӹgΌP_uⶩze&4q7Gw:I$k {oH ?B^dF@iAb;9FNCȤ(4G-y'i.5ZذX#n6Ҽ4m.إga6(Pab%w^и6\Bk ;Z3(q [\\'1)gN qy9)Ԩ԰K::a Fh"BI4t]~]4rH|>UѢ癏%4,Zx" )! ~ߡ ӣ?IdD7ѡ9Nk }ɅZ">'lnBd)Zq*ֱ H#0[p./2JE:YpOl!/f?'\m{ e‡>7cKOE!vrW{Kf:W-{-f7޲땿MԎ!~"֣`boGYt`=b|ccG&JP %߰\/ݖ\JH7ɹ%NN^~:or mo7T<Ɵ nǣ8#t@JxÅk+Fcl"ju@yHxйZcVWݐ\FezwH6- Xw?&ibX9r5!C!G#+`Fe'EU+0e4F߄i0ӛIuF>Jb1>hu i5op+Й溆[a=g Ymi"7R}]/5b(5!NZz#7d3EӶI,eh񏗖Mo,qK|p=;wt3%.Eg|MFW₂d_:6XNU r[d$8 t}7-qIKlKxw׹kZ!}O"`hR-ݐe~ROaUgEq7W)= YiLrlnXF*m`vVҰ>U/7듻 2D wr}ow,~-rϷOZWU?PX*A5 *)cdAG{J_J<䜭}wsEX PaM$m8ZnRCJpJw9s/1!g &yΡfv4#a!+ &˧HfUG n&Q;eW@S"BNYg$!jWA7Pxo^ EukO$J2] fD:$Lp5djs;$/F#p0jtOj,m8.9J\?{!__YNq T2KBh*׆;bY|8k tqoq3з; ̉Z9Nc课P𷆨cvДf_YnZ'~o@ ׯ_I'?VkXZyűܨ.+gH;bv ^Aɑb\r x`9߀fYZaxf<`9a%USJSʲ, #c](yJ$z-^.-7<|+ÂeS/\$eP0Gỽ b%rtw}l'MrN&Ǹ{YZl1n70?+W5 Iln$4_nzJ<ΌrUhAr//X aT]"]%tSI"vf n%`AwE`$>,GYgp1`T,-#R͕{cJͣAwLU  Nj6 Ei/HҵųJHH'gfR._П.c{Rz=:.4(MBe1r~Zu׻Ƽ'L8JheV@-0[RxoH-a5%"* iXqɨzmxE$HFffDfPcKi0$gZгlV%E45T1 G5PVmo4ZN[;K_tt߁^"Hpm`,o%c}~}@hBtomwz/-jc6$Gk9X8Z~^&-I%(h r+ɾ.p@y lK50$+[]rHV7t`vp18q+gp ?15WU|N5MTl#4x O,_ʼaϛBO^" H멬Nj WrG]ʐΎ& >,"}Qh*$gd0EK,SX)!Xt}4!VTIV/F] V߫feb&18Ϭ7J y3kGj`#Ԅk8ybWlo?P@H'n"О@3x%/Dg_fPs-#7CqoL[S@yqؙ%nXԾo~@C[9.0QNE9cmY@rt<ݩy$!Nٰ SϠQvi@:* Ҍ )GҺJ/GRY.*/尒n"v'gx—3aF ŧTto] (Xd3a\ _Y8`^w5x huuf&QRay7 afrP" ͉2zkX`W {l|M aX6={[n$ XR߈fQCɘPMH>&g꠽~e*^u^Ƙiyb^#$Ipa \BՐ'QaAph- )OMոC3G[z8|#^9˚:͓%GlMtj2;bolFpطa;YLE} wuSWl\ûr]&b8'`&Uhj 5|".YYUqk5>4 V] gA[}_'S֜4Y į[LI*1*]oس⾘Cg 2rŋbс7?湪K^^n*5@nDČw>#uvd~.7thFOH)2sEkj xev)8"#%3n+X?c3`Wgx2oYܿym!㲈!5![1{u V5x_qfn jwB7Ƚf -$O ;Dr8y(RS. A UG8PDQ +5ίP[ϷEfDxAH>w^ӝ73&I+WWUyGKo}v踟$Jxi=wKn H"l=#IXhh=noZې{  3̞Z [<,T ftm AIX5: wȺFxkN??kcI_XW8KQ1)L6C.q8o>Pƺn%@ewNH+T7Z ← px$Zs;/d1{Vϙ Te#E{ÌTƸXv>ThHkHByؠO:2> rXE@lW!T |颱8* χ_3@]!'id郗(LԌKw DJF<C 79HC4Ȍ"ʬe/1+-C=)D(C6C޻I`M5rA LvYt8y=—(.eQs4 Cd@0S 5{s=nVlNW41'g]8βXDxU5L;!QkM =o]lԖBGo V=e)ީq iGe6)"4;Wjx>ɮQ\$^ ie\rw}9 %x1vY@O SZ`e5O[n}j x.צ4LhB]TV̵kܗ_j熾'+LLl4_ Zw>" ;h Ԧq3k֝?cT-ӉC}m6ȶP3$/qcZ%Ԙ6¶yXY։M/Wi&ԎR$VhGWQ?Ӛψ:UW3\VHV+ǀ׼>2m| Bqi/ 2<~6|5KͳBt#Sh}3/{<2+OO)cV ԩ/%E"$Bc֨.`(>;*c2xsk}Id^-\MDizSZwc, $8vnz>O=#.q]!9KO%{^_|H)V^w|϶DYy)8.c?&s j X*(NcEȾN -Ob"\1 WjĞwyʃb8@$Thl47i2LzWMB/\ZZkE֏Arg, #}$ɍT{ҝDå 1z~[X$ Oǔ^}=] BumrʲdNKn1 :ѼaE|=!VhR.,8P1f;k#@,\{v<|Ε ,hhʦ Sb^ 0joSBL:rU2O'q9H1 +__YOGtRݰƗ݇&r@NgE4OI Mq;wf!p-zz8 45kͲ*c]XNMҀ-gy쥨vD roAΰFUObCŝ#oABVB>V?Q/RF{EKc<"ϮS0`>~:t3>RY~f*%zlp^wbUD'EH|5:WO-8AczziCh~P(; 8qFAF)y]aTNI4>l@HB5׏#UY \(4V(.Wa1& a|L_z*Cn\^^=Mޯlk`)`B pD!rlbARE P,qe Ur#V2&dn%׺2:.^ާ #:MD؇r;7ʢ4kԯطɂ s?*-I[GdOÁ&-~}ٰ:Ѝi4ga&W՚Jԛ$/8WBYEw}vKOa*D$jIk;qKXl5}wPAP<6'k'fbI'XۛD50yo}_mnVs7E`VڮG EOKo6:ظE3#ג>RMI{Ybg_2XyUƛ\`Ų88t_2N= X߳;ϘYI>}i@G& 4 ױZ9,*EmR}QFk>!:c慭;ȂЀ(ñHv%J$2N |Jf%kSO և 8?ޝ ЙӁk(+xda/O)8ظq̊ﯽ&܂,_: = \ }%_bTLM؉~7ꬬ,GU 凳 m=[)Zh_sH2lX|Wˆ?9HgPAjkūq%WAK֎bm△g/K96M.16If;Hs ´~BL+kYn@a96YִgJhD.r(©mury4`[4Sϑ-F|ѹoma+ѧq7⑹86q]wWyfS?qZVIn]h9ìr/|T+ "80G7@Y/咖yԑ~K8j.II4/yWt/; 1E̻XczS9ܖa41ԭ4e k$8W)T5:Ψ@KAn\UɚcԔ1R&( EMh+^]M c\g Y0L J~"u0 NT^hWȯ8"nj4eoP-x(vDŵL ?)(Tjy{',v^d.0-" wZR2%}5l:*C 0?G =7mlM,`/ W>cg$b?3/r5n9S87G@BA%9 ݗ5dԭ-qõ\f?7:-0"PStٻG~/=AHC`;A_KJs JQhwoE0oD'T\))6Cy.~X(ɰoP .vԌg?y3ȗWOQ̳Q)xHB \%|{VS԰+{ttX!09s";NpӼB 4 J4+J u7!/[k .!+" >8׽6l늞6qӐF*i7J6 P lChVLmK fn׉&C'OupS b+&(PLνmG&bY)úh39س+dJ&)]ÔWnԲ8 "Ż# }Uz714!w"dUBP%6bOJaST|]J Z!;ӎΞ)*Fthk5ܬ祝V-BmAt,·*I-E蹅i; T͛'zgL9#бDq&5ܛ("&'0(-D !kG!\$uZ?0 %ZNAZд{ə7fx 8=b +gX4rc`:1l㾯e8'Q0H۔Q>旡:<ӣb<JiSUYF$5UFw6yKی7~Y~@#,WihWsuD`w&%%Z~ӽ^g_P7(K _G ?b ?yg FN0 +(m\䋘5%nPøzOGrj"I@ϫQpxC~7WIn8co[Vha J[gտLܓ,p8yVqvETz>0ECqSYYXNͦQSU28f5"^H@m9 ~L̛E !o']lw$W:xdZݛw^b; θCL+6*oU;Xs#l";Uה:) 0p5BH3j1kx]i!:Qtv5(j[>}"@#⪁SZͭio_ JeU9B9mlo~; kZtZӒ#], 3ܣ0HùS]qT9mؘ"C;<_:4"/Za_'>qۥZT'J:-vS3?٭xfiPԃ' ʧӐbkН rZv^rv?c]Ɨؽݿnv,f`HM[O{3nd m,9ɗ?zCHrvW~<⹊.kY~}P U˃v3>;3Ւ\wNPyNwYao4lmGn\H3b䉐xCV)}*H૑_@.8Fx(v$A׺д_f [{}+]FRJ9'u+V3WGF9Wi1ն$?w{,o/Pc*c6ި&~.yi4~5$5)8ƗbK4LI"4vA=37= G,2Lfr"ܟ6-B3kNHQqCg{N) i-k0%pB 3z3dߘi<{ebur+%J*gc['8z{Ԏ*{(I>gVUrjҨo0ZIeQ6 *]iKNKh߃`/I!9eUr!AAi o3Ȕ|El&M @]t Y{kuCpۚqϋtf=1#>54nPMj$$@_[^nM elԗ%2A(RjaO/Wb&VbMCyV!<G!ka~ h tq?vzL5xȤ #{'cCCu7[P8Zedɤ-% ѝ2@(ٶQ  49RЭrR^ɀNWb{?#Mh4:)Fh9@nn ޯB;Fźj*ږ,ܧߌsJy(A.EA ?ucXCYhĿ$HL(~ KiOb§u-!pc6C؀^tN/C\je^+/OԞyq0]  *ԑ?΍OJL1x9=\"&G1TK(϶2d)Y<vߗV!Wd>^ռ@jZse) G筩*nX꣺7ӣ8(jB{Fqa D=Y7])׷Nhw,8(c5S\L5*Tdjk0Na6- ;.+k)Q!2 u_<$UZAH*V#G2* @Hcf,񦘆0myĬ⎥^**F `i4Ĵǯf`&g:D:,G$.-~!pu}ѱm¢V,LlPÙfD%eUI3Wꢝ8#!9@ǥ gbX4}WϼIN1R%qanp-bZ=n0w}.Ni*XԫDe;#~wM!71_bբI)Lj @I]eӪR] ``|Tzp;Y3}I1GJY|1dY&=S9byju]+au[\c|GlwA I擯TOy0/^<֭uR7>2fcoSki!)l,~od0>=B}'oo4`ZT<h9ȈAGEx\4ZA.b+j4.N,Bu#:V6 qn*̄qc?9(bHQEE!*O+.QS{h>$-i(8;RgA.[C+onP$bR$NPfCE%:DZ}${`qV./ws|_$Z` zdĝeCvu zc%2rR<,Z܁XtP0A=?%r=Gwp&{0s>"9&k1P|Z葪J_nIh 8,)wS]B{^ұ'/PLι!KW&<*HIESLDžr@2N EoD(V_э!M{Yt|7#} ۴,Ŷmcд `K?+A_nGbL`lP[0Dj{C\+jL]!KjCQ0J޶o e#^p=CXxN٧PtoӖ記M%AK,odɐϕǸ^J/YRevG)9d*P],eq hn#8(J3 S4:$ECbT?RJ0m%HӀڳXHqg ?K+W^?a'x2#PvIJEtpVv.Q:*x|\0[Cٟ:Ez@\ ؅CB;$5_+,Gs7+W6652N┍ 05;@{=YHpi|C籍:hJ3kL;`:rį[=k&7bEW(U=~,C"ȲM:Vlw4PhytT(CO -0Z'nPz5j!N@^O;N#QٔHN_)0KEX*SJS; Fs{NDncR}B})2.ͷ8r bItSAIU<}yLnԔ[Q~ۋR4KՒ^ OU,#0=涔 ɒ %v+H^r鿢i-h-}2%.?w`"mU@RWٗf: pb@L:=e@) 082ɾw0'\ tSOtA74ndfnoW$uXEH&r"!}tk[2RDyKVPErפJǢkaj'Ic|kSfO5[o_低ق+VMq"@̪JeCV^(=R9*F?|e7h#輾@.+2F;_Z*ɀ9D:ZڼmJhC7tIb 1^ OO_3ԁG]\U"/dtUM0n8 P<-7pZ;Φ2R R4dPe~qEߢj$hSZYh2z0 DkgSMuܟ Xjo..5HC}WDڌ-te?3Fn:rw&!&hk)tjH5gSU+ 4hdzuˇDXHb\>W>?[͢-nrlYbPt}匳/ ߜ b-ĴET `P&CG+w1KAC&:ປ8,>$Բ7tp]@)Ji[ ^ŽҀԩ6q&Y Փeeb*#)l:y"{SHY>^άm B=aٸђp6rpf. {~Ӵy:-SDKR@m6U#,Z2o,$L[Lj c( TGCO7"[C髥.ϣJyWtOdwZHKz`f YಢߢH/^ݬCNvAx=Sv+5x(OE 7@?IJ]E ҹ$F |gkeJ>e)fi V k:(ʖ0c$l^vP`k.Zj9: <̽рybM YZ0\NjBV`!ܪbhatG_ɂ=~] =VqtP[ sL_Pt`voYcFpO-.V}#c}:keIԥb;yz4){z0Qٳ?vJI>,\AA|jUWkɮyF90I5PEsUGCtk( ڮP`oĘUթ@o3GΗ#O:X\v)*@K|j[^cp2kİF,6;홭(sx*YuLuFvVPwƹѯm*~X&c)WIdM:~;WOZμ<&+ ]! R}],$BjXF8E0΋-Uc]\ͫ=^{,dE$!]{.ΦO_4h!'Il2+oȢ2bԴ%2IgEPk/{ϓc+Т~p e* 髠;Hi|+797%k|@M^yRڮ(l>^P4_j(i}i% ^=@E%|S6CvGnZ(bYw5fa+ :kera*0ZΡ8`)06OͻHd+:|vRrIB[ ksH~IjiK_z|nIku0"c^OEI!9.bE^H/=vD(|w`_e?/߫B{?۟A%<g0€Ya7(컺W '>HXիm/^< ?- Av%DkHB顲:vG"*N -6Bf9a˧K醧ynq^(߶^o<;~YVP}`:ϗVZvWC8LdY@r2zZYxdk+ŏ0H3RgmOLy} (d{7ٔG3`rܔ~CRz]˹͕;G=FF]lé UD#z 33ϗA#DBu[ӑ{x;D"p0x2x4kR` 6$/&44`Eejuurwe2+ o+kԗ&FIS1J-۲KXOPPAR2PKT2ݫڸqF-d!h7@PAR 2.0FileDescQbx۳,<ܞLtmR,Onjw$s<4¸.Wbepar2test.binPAR2PKT,s _=_ qF-d!h7@PAR 2.0IFSCQbx۳,<ܞey94ET*}23ɺƔ-?oiiۥ 9&soӂVO.ro{Kȥ/1 =x2!eF41vt16bٰSv.xn'hpbttѴ*ߥVpE:(C&7FJ jE\ )΢N EQGɋ̅#_px`*PAR2PKT\{{p ~u>qF-d!h7@PAR 2.0MainQbx۳,<ܞPAR2PKTL@p~9Hq-~xqF-d!h7@PAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.237764 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0020000644000000000000000000014270014625637207022706 0ustar00runnerstaff7d數kxWqS%H=4M?I়ƕ81r:^C}'VҼ4 FŶFبM@@=zZOdvb8_D$ -gVUooehe$B5jzITZƲ mq=:x8ż= 7n6r)J^e?,2'G%R>X:(:\=wMSNW#yd j*kyDNnGzHLֽkwq21[?oJ>_0R~5&@nFTqX̱I:q* \JD \ywF)di 3Scn赇J+Z>MSn50KD&[m±bטF1+eT̛P3`wo\G5˿r^EHAF]*a #IrUA@¤2}^ʷ޶:Z[G)*uP͘.ZªX~L,~RL/>UQvqTKZeT/q:)l0߈[B>)AA 9 ̷X Sy:& Z%4hNVBD^vOJ}mϬ޹~({01 H"(o"!؁~>C(O lr,y舊>r[NN_>iڕe![}HnTN$tD~ha?o4HuE8;//_Z1&k`,xa sɡ=*^WeJ^JE kFf+  TZ|J֭x3Y }]W^u2.kPqjp-j/3q;-mαk,{֔~cZ0_u>}c* ShoQe!Q.煭rυP0;|"rIԐ~ x4省aLm3Ju1ӓ^p^rԂ 9~utxj7Q`'7{n'fUSLͬ+z L  ]ff~>%N#i2mAc< 7(|V#aKM[|sWaxuo:wjy-KɄ o{[0xd$X,hbJ=AF.A Q/쭿Zo^`'Khr!ւ68 &nc1[~aؚI>pg²w,,4aZ+s܄]Oy?K12r"dC,#x )>G'r0w>TswDR_7@qIeXYp-dgg>w_%e|֨Bn˟ -%Nx̎4Y3ԾAl؇| rAn+;UQtȐzQoz.i {|ߍ&hJ θa'՞~*,w!,+Q1o:$͠p3#EȫDOH]yYMUT7~"TywOI@(#ti$"ǟE t8xљ@ڊfl֙.jځݰe=<Nt lB>BˢxMa-p&^N`.Hv}sR9˿Hգ4՝b9n>3QBCxhRW }FrAVDFkcDfI7[T=Sy{:0K\F*+'䘄4Zgp ;GFm>gG} 伴( =F8Yr{)R%n՘pڥKw^e@@DjU_}6ff$ ` g^i.Ya wr wTrm7i4oMG!#zJڍa%7j/tfc i5TЬ`)1r~ۅF SVc/̈o-S+ų7)?l:fbׄX~BGEC@)> B\%L^(;.Iq#\lsC*A~\FBn|ܿb>\"eT/φ40<"1 6pK ]j!ȗJƴhrOfP@;`4&Nzk$b#Ы5wz9H{w9S> OFw.6[7eP:6ێIQnE.Tfu>do R e VM?u/-Dg9`K_SI6 L0 oxǎ ^!`Dp?8`jej +"1$BF'g@y@d*ɓg^4۫!(X0! cFݢ7Ε,+܆q#{HKF08pmbRn'H_MrF@ɚ@3H޻w,=!$<>8DX'roMRr[* ~4UuT^6>b+%*9;oaıTO^j!x%^LHz._ 17]RՎONh2ͱkYA:*Èu1?vNhe ~CZ";3|]YkYi"z-FGx*8%;VȒطt\ f\9~`jQ\uFog:Umq&L{~P\'x(3Y]nmQM{¨ch(B:XW{-2vu0_E룾dmLRoyqfˀInZ4X+RvL8^{~lKC⟨D6enP~X@^T^q^}%h.N&!:["#ZDn!Ԋ.4~mq?LwOpL~JFE[nyѐ(@I݅ɼն) Śŵn5B(2)7|Akx egxH_=MȄ\qBkd7R(1Ү 5D]a5J:[vF/P1=^>F,>.N@*Np8bY@J< k|J%c76DC<|'54)Q n,ݯPnwE;{TN?x x==;W)dqnA,A)%{)>s)X0zY1L)%򩑞6_f>Ibyv#RޝHPκm~kn0"XrkPWPxyܾfobs"6rſm@T0I{"ᚍQzoz_= V3@'ɩb!Vl;zl8xZ:BCr]cs3,4/ҹ3EBG+ [p5gBO`(CqޢGH\F1 {ӳ8?&?Vb}JE%EPgN b$әc'zY%n 9j +W%hOPqRU<bKyn8x%g#H!]I?^{`W(),dI\5.o~ eTӼ1ld}?rR|@%~'đUӁ|]gYJu; d$Uԧ&R|K\Ku|BOfV3{L^@iԮ;U`UAoL xLzp¢(￘O':rmnAqQЬIY?WqPǷpK L f C'a^k =uw_,>2̹@&劣ݪ?B*f_nU |-q^ނT}+Ww4a23x?ьa~-Ĕ: 57̎@?w"5a^.KASL]F򞓡ZmI@K%zjq^Cnܝ}_ô ]i|RG}mQGv3 O4K'k E.~_[@©^UFpы+JئI4J8P:e8]UWB?VVj<[rc5,\u5l[i 0!uɖ=%"wp #]WZ^;%@9,x`u,>RՠMm%wPʱUV!I{r>~Y; -@.'gsߒn=OBq@dMر*hڠrnV'>˽+6v:A o ,q"3~ ˿Z7ooFN2v*2-Zʋh(%([t[y& 2~c3|]Պ0 _ڳd!do=~ؤ5ޯ{<͙5Rɨ_T4?-joZUmv^C\w,܀!;YKW1ՁhK(Oo"!ہ?)Ů[ `]QA|֊ $mHz/8.ŽAJ^]dLMcNэǽɣDbx&c `2_/¡Up//<#= U@{0LwDsJ?߼6F9%k7~|Y8k8~S¥#k6?aw\C[ ×tZH:ڢ@Uo@ʏ$'l#eZ(tR6P fRFYթKyU\aoj$$ͦ Xd~,R:] to ▮n4]k#?O=ZO8Lf毅q&0MycC{vBF4B ~ %,tsw!+d0g:Aq6$MjzkkD (JD5c M y2cKxs .v} #-ǔAtk?Q'Hk@z>۶~쭼-H-$o}W5Ó;Z*`7 +4Ŭ鳁L.?Ϝ/ynyDX>3Gddt[,,PJ=KxRBjzٲrkd;ȼ$-t46prnZ'9sAO %I^%f8=:WBgK!_8pZMMw/'է58-@@}P&?Z\MWb&r鴻 x52PT K*, ,C\'%>}@Iʤ !Fk t>9\+UJQpJTf*EeR0j4 *0s{EU@{D.؏ި&L҇[%Z)7  mT> a'syN Wr% s\9)?tN`r7*%G9F:~LB 752x|9%yHi ]\-</+)xcv/P~lD`<#T]c gsㄺP7ZnmDn|s=`)bd=,/3,NɶɖuPC􄫡i|dy ][,U@c<" Þ@ІxxnI-lh,mkQKGa}G3 RiFBj4o 9dƫLf;4Nh]`rZy2ui~GR*K/ Ѡ12tIeh/#yhK*m8p8fx2#:CsOSFgBbǝE7(m7O@ѷJXA[6HvM%3pzM&Z}Lm1db NSp79YR tsB=m?% 7z5̐&sjhyc|+Y4޾ q鞚M!92 2:-xmͳ( E߲tMbtiBڲ8N Sń}ly=~c*j۬PV(AsOdhTeHJ3NswkT_\DHgTW U\Mx{{ōN9|5 RUt2;&}!D0|(R!{cp;{ D~a?\" yDKJ*oT.5* VAG`ɴڻ~GτlJQYɅd3U[r@'-SGaG(-3n&a KrHVMmpK_ljsC@^$ +:.ZT@3Jмu>τ,-%0ںH1qQxiy}B"H,ѪvB497#L}B<֠-} ]z";<HlT5e k(]AAg_'ȶdzaFYPM;ŧL N8HC<=;ȞW@?*6J pVaq,l߫}MQ[0QE]G"6 k !!i2K`66Imowya 7X^nPsߺ˥5d(]֢dyvxE CaE#d/ >V p洴N,SwH2چ^?NAܩ{ALlHȧ/jpkAښ~glHPCbb+"3N;F.¦*MnΣt!€q{嘫:V28ʶ<N[&^P L*uxMCp/Q~khi0vABU=޲Eo./6WE[MP8CwH+2}ML u#2;lyGvPRV'<_&6$ߡ=O,:ȫm6&*] p@xiV0&`kc0G>{WMw8\㾫9#Zh|ӷ͉?Qb{Rּ81+k9%@Ѳ55˒]|MPB9R Wb%oht>Ump4診'w$DԞW'9fjbO5֢r' t;#%2=sǷ2tyJGX!^bM+[u AuDRaPX\krb|;0.O1]J'8'1l.mqReePų GMgm.+iUӪ^I7MD{.Đ$kYc$D( ā|LQ"D={,1iޫо0x&0SG) 7j꿜t6(HsE:mԵo%W/A\sG i݋ALbM쮝+JkW4(aò>,A)5G\ےF3xdVS47aʰ,Xd#+pR=g!3 -;R$hV?xv|9gq_a۩,ejl`b  긺(dSm@Nsg7zĊ|6(Q^nBw1俞+ U*ܶzN+xt&hF骉)wCjC)_þs"—S  ">Kߺ։010A-\TdD7D?}w[acNC_ Y(踗6+֋י{5\r.=K~&H2χ"ud=|9ŴoMK-.8/G~\EAd!٥Oer3Mlgە5:$L8sB[n@~UlfPt# noFV-~d dDS%x3Yp{5dJk BɴQ`ܹF!-jDtj7+&z{_oEJIQPZ_?EV놨Jjk݈? }:Xe?D+"0/02.󝂼A8ӸUJ5AxXhg,LG1H*wbǕ/GY~1<xU;_)4h< leR|MA J^IAAqs||d^;<Υs2u,lnpT:ĥLcO3~v54dhHwȊO2(gmw. =!VZũ/2QZ*P1rFkEy y~*|$-+k(-[n# ]>*+:iv0黏LĔ.#>!=t[[16jlOҗmNpLE8湐*4h HūJ!,ԳٿAրjEV}1yp 7 <:0=hSF z!p1 ooJ!vA/_h岂=Kn)c*\U)"?uv => >6Xײq(\GPOm ;=tVaHj '^UX|3B}I96b`G (`Dr(#ZAR~gd-i(zu鄊@'G[86^2HY6[ YA$Eyo]=?($~Yb8l_h]SuOHV9b$,mOOOd` 64){ 40+s[_aMM9 nҎZXo&O_%xR#Ԉ /lNE \Bͽcmr _\[N+P.B%6)KGPThXh]F]M;zZl]sǜc _F%wc O狦Xg?B5s $Ք!ȿ{5pO?ËWDu$;ːM\Qc?_aܾf~'JU@7iPjtV3p}MtiW3GB/)q#_w?oXz { 2TaA7R$dPRh8I/w4U9`1a*ٙ0Ui0dsM弶n:r멏~d@/g(^\¡:$mZqiEc|JxB"qQG)X:b3܃™'a?XkPh/a1z!YX'GT6-kUen` xYHKXK_)=,{mhp0a%im 1 Hc1nh<\dqB=3 3CC͂|'mr*)=: AIS͞*Ә.+1;ׅ/-(=&a^}0')_:uZ-g-\R T&vhE|d *=^/=)2HI !s 'D !Jz|oS\$kR [‘c?yʔ&hUɋ)ys 9- }H ̃9w%*a  Kx-0AАCiLx5\zC"# c04m%D7+^LOӶnrGL1f*~RLSGhYrp}w)ֈb3aQVm,Mw}-6]{u_:D8PlG󜒅E}z׶,e5:J3Tx`w|P-_y3Րג+)m;$3td`UM"/CmKӕK}Ok<jSa/}m~ UF|0;+lU'6pBpWdĪ.?`.4U(As= g~, ne*aJ%TXՔo{FC}Vb.j}4RM)$& 32^# $}(8|&,8\DILQ%3A/:o 4|8Mlsq>+BoYֆX[x{}WB?ֵAJ5uK6.2r{K2.e7!?h0jV2|`JefJ=)5soA(ĥHIVA_^\]>uMa>I?9TOJ&( {_U?6GOP!ju!zD4XUYB}] c+dn dY(&$CJ(^%z@|<5pR™Q(W+T xahk©n" xF :hc}Q^wYo!i@*o_[S^ 2];~Zw#m#n])W C]nf61ҷ㸭gMHQ9gcTѝuQAh܍6i kLERm,sՀ+PWr9JR ڡb3|I=Z{YzdG49h!< ؛; # 8x7BH>EZPCN`^zg1g2?0W.s"2\ۯQ86M1N@n}4m$?FXN8c {<)k*Dw+,S5^Cq˵oy yg>MuH}?x\swk!靦n\:k yMk!2ɖ"ڻ0ϹWfO󈥂ŊokjK^"w]ș:٫I|aCbs, 59ZɎdٳ_cuA#aSUѹ"oR)c pr!Te:/ە|*}xlT^!Ì}B| zg=C>E[t^-'(5?jƤƱts+h:E#}i<0@y2aBJPmq7!w,iݒ3?f =c~-zF5ʽ\ ;@h$<3u* 5תU)eY+̎Eg*Sv[IR{ຎBhV Yr,ϙV cRjs0;;&nY/'fư@ڜP"3ŧhÿn58eF:YBKefno>EFS6 }K> A٧s>b U;ƛ}Veh[:x+<_])b@͒o|`;bp6^Րc t 5=_q*+]Oy9ІB u:@.K;a9&{U H4.(ɭYEqK.i;HvxiȚBH/3->槿v^&½H:}w.ImQ@ˮ#̍_1iŽ~xa p9D暯18PvRiP(4G#RRd']9`Ⲥ@edS+w>V_'|3>: 0|wX4ZXRCAS޸;g `Q%W!-8C5m XLC})#}ZA ,00 YPPHfޛ֏V; ݤ#:Cq ߈fVxx<߈@:/A{TQm["x]?J,p<~EbBm?:jKq+lԙt8;!ow$i9B>R p#;B6ՔVGZJ0nsuO>dMqoGm EX cv匉.ڗ#u{!_i1KJ_FoJ2LW_h5Vkc}ř0EqYPץmI Jrx|:4'sic8ƔEPM46|$Q1NULXu^A4LFG61]\T*θ]Ӝ iSlz+qڴh[ Q YUݳ%~ƟRb?mIN2 l.Jw"{E? Ց.'s)gSw^8ǔwBmuCRgģ 8QH*7l{)6K8 @|]y4Y8{x\.4+> #dLB[.*;8Z2#̪ g.ܒعZ |ЕJf1hvXzƾ!QT^y(7 5±בȍ g6@@|3W !XP/w9``e@}iL Ω9+E|=w# SΚoNY I%έ9Ȳ1j bz٘`! [z o|BewԯP<械#Eh=J׵bA> 'zd:!Pߖ,"/4fNLm_̴R.\WY7EyΤ6{9PrOs'ɣo.ھ0*@ 68Iyvvշ攈ws~'(phy#;G %{;SJ .BZP2V/(B_Βk-Z\qqW:6a?J%q33i}'0稲r4lXW趖?]5dX-?NVq^GDb_Tȇߎ2NVx6"c+n_LL77&j GM_ew<|>ڱ}~E8i62s^'\NX t48_FTD} /! k0r; QS?a{RG4Z779Z3ڱ\Ϥɉۊ 5S%W MW[&譀19Ef>&"q$- :[a!v %Ș4ͽAiР*.$ou l02,4GvS9 Rkxy1B_ݪ=b?pWJ +/ᬸ@4v χw~2[*h=U𽶏v+&'0Lvb3U=@Y_Rq-D" GMJfjZD.JG%}׌d6 -lJkC;~>iW>} AaoRɽzG?Dk. !x&GjrcoK*A`)?Xz1 WZ¥x=5ZAvMDCA+^r.w`6<-TU'Ț_D b=5~-Y {NJu-f;=_#'@Ă-Ujn/F'[&!z2KnX~:=:KMçWn ,=˄ օi3Gd"|pS1+t%M)2Zͻ"_fD5dR/h"й_] KTf4OI5 ؏@kMSr- l-Z fj:Ү Y)W}.i829B`) ^tKzOѫMI\LQ%4L߃9$˸[nfԝ9gw~%"$1e)?95F(\O4GIZѠ 9#kADF²qIDPOʶ´.ݺ;3ϽQiD/:fsHb7>c K#κ1Rx4`5HJ!8Cc,_l lrvv_ǥnZZ{B 3@jTG0+C;t|%L`y⚨Z6L 7#ѳomHJa1yC`:6;6u0 ݭ"oP#,oxjԸzGb-HɡMn0ٟe,qľ1W>9SPoxkO润dx#$tvṃ9AZn@Il$`rGՐUq/j / Gy݋"}#pMD un66ST@t/&< uD-SɋZ23c\v[0b,&Ͻ(~1 zw{{ hUoϪՈf'x32c4[I͆a9 gw|!1_8U[rdܾ}sMӲ#)bc9L^1zR#ȥ˞Bؚ:* JZ0sቄ=!Ev No!3cRfGb\{Q%3հ!b GVIE* ǵ[mӚDs4@+L%i*Q .p_!~s|)D(6_2owzMA#Q-1YF6Fʪ c+f H)D a8pr[>ctsrmKƞAmXޕl޼IcHJw+t`ҧ )pP I=+Gw>U{DpA)>?A 09*B`73!w1VY޴_+V.69QY\u#'1`Ϟ?L+:$9CR@}o#]VCad7}Uwj E ߇F8gսPZ(gB%\`LN.^'cq &ᐦ\sTBjd?Wc3>g "4w )}hLދBe)xy!N?lgPj#5QϚ4Y|W)'؜C}ݗP`/BlA "sa*ݸJ_1@h. D#q^D- t*h(4J͐N3诮C_!nigM~&ܦo' qJ*}wgiEd O{ȯ8&P+M/Xؒs׉O0$9"6QH]j/\Wʤ*|)/Q:P0TJٌLjPDgTB}(W`g"q)4l"^x`LhhD I#?aW&Rݦt =KS/kX N]6|\f@yIW|nѐ;VP) 8(m8/ϟXmsZ%t[ahoDn=Lj.[? [;z2iF d:tth{^3 B@C& hJ؋%nފdֆveH@g'fוM#MC ׸F]`~@B$WFN36xa_1bhp,lq5zfZnjo5-oO lڠ%9.grQg_]Uc8Lub@riy3[ f1EWz;Y\Ahج@RL/ Rw(Ⱥû-Z[ 0ZyyJ*coWdJC!Gc٬}>MÊ2|Br3hh/,$;Pn:$R>Bq l&j<$w% B[̇qgF6 @%E43'Rh2SiA6d =z.iw2=LϽKGu;b}#aU$)ЈPz㑱=E#4{9yJǂn Cwm#K( K+Xg|0v6;OƯ gUC\/n23**lYAlmۛ^ Vp!E5ޒ[)xNhYIZʀLi{&ǖVl!:P[# kى˕gmұRJ@5=?!}~RGS0{YvȸW?}wT+SDcU$Ě/֎,.4g~_# & 9Х/n{-KI>C 'M =~~!YCjɬ-u^Dc#26Rd|Zz!Aq7舓rzGTM3zilzo"2Ľ"hP'Dڠɫ3fpN^OЫ)S*"m?h[H#=\UiNϬ8! Zk->:b)"V4`a;)QזݴKJAfcU&-Gi;=G[h격hrP2]/&Ƞ0j08Cc̢$m?yA Mg7~$ X0]Ab%waս }D0fISi8T̻B|7)h%S06C JPȎ^yeވ*RI^!Ѭش2K?>A_CpG+oqJ&M"MiSA|Jv:)h(`2W͖efX2}}x>Mq}Daδr ege%ʔ/7C,+*ߨ[xA t?C7 ##'1W}03s=Kjs)߮h Ie@l4bYJSuxk'(!ޛ؍Kqf&jהZYKL0`SX*Px=v&Q)r}#b},4{5/է'p>3w۵*%Οi,rO{~lejo)$A##z1Ċ4⭼Ak\tt)" ;ה)|ܬ:y6ժa%oĈQyw2|c'NǑr.pZ)[fɅ̜4,{Kb.;ݢu7qVVB!a[t)ݜ)"f$,zvx T׭N3K|psB@Yk+p%CBl=(jEry=[RH{|g]}lua"("q-SRͽ˹V FdŽC7Է[WЮSjQ4mɑJ^AlẋI3WJSƟ8V1ԸHL%HJ7vyZE7T)l sR&ga_tQK;bT \38V1~c=9^ "s"I\5rDJaa;{W67m|`锆'A,-ؒ057xCkVѵ [seXCjQQ[޵}\hP?s$Sx.3q,|J'R{Ao mw'dήM_y Ўb(Odo_kZԜ[Z~NLu n*b,Z(@;?6wskkj/pm&❁Ӻiw"<@7pmT4M,P;NҺp)&yso'@O3vVEhߤۢ ٷxo=ݴArDw8ǯxտR:74rƳ!Zҷ<jc s`mTwnn]švÇ3#[Fʔ},$HI]DB4V$*9#/(U~ -x&RoSҦ=0 _8Ho6'Fj[E ~mؤ:(og09T1em?:bi XEG>Xe$!)waB(Kb̎"q%&al70o3i: sn3 2L^&[LjΰI8IUTG`w 싨o_~G+GR ?C|-@Xq q|?dmXv{>xjѹx]6B=v#{IɣNUz;He\qU]NdMp%wܷd88:Lzp''/"y[#ʤ}p`.ҠzATȋA,6{,$m 4ʏLڕSV$` k%~AA I&hq`?`¹+,PR6??{)|^U{kR1q& صlIƶ`P]KRuuqۋ4]ς$mlD60)~Zg^"tEт|*ц~QJ'74ҔJP"9۪ji-S:ׄk==c*2F)XaX*1|T x¯=ˑ\|TH@Y颖%cb܆$ƋԴ,ۗ%Rn}3gq)fJ,`Vۑ8U y;Y-'(dAΓsO*Ph?+rb֪od|+QAt.5SNpW?.~Ii,0L+G2>J1G :щ$E {"/bKqzX_ZŶof;Q=^`f&>RUgGzZ&Eͩ=`є.g. żIWbq`2o<՘dq= Bòᩇ8YVh(LgZ7q?qx%p;z/ }Z5m#D ΅|G GIgdj?$6b9HR鞏CV.R8pW5{ k#H@[(OOS}!P)[ؕg!Xzԭ9 .\ -wJ ?y(Ubdžfʘ# MlD@55Q '̤la-\!'x91%YB60A2'ǸG ''RjD-@0:ҿUN٩AWh֨4W;3Lwn0D:3H%<eQ'4 N.oߌob`g:t cuo޲9JEk7q&@){X5b$Ure .Rx7#Y T>{3mˆVMp`?m a}=fMR Ȑ/@n|X0A_: 6 D [۵a拿Mqq {(}e C$7oE)7*? XVѹmwteM 1B⍘=N4s- k$mV.Lh+ &?$#8~ DɊ@|)*GBÌwdVxB,Z``s&噵,)Tjpe@2!wɡS^YK8f^@40$mCe)SCp &%,мBFe^ӏB44ZELwHd):SW>Y LJ e1D1*#׼3nWmhP\N)KB'P ^* xiRХo)~VmZ~_ zۇn5AwL|r 0;ύOlpݗ?\WX%#'?aENN$1ohoKH1:L2rݎ k5ltv2TgB˵0Oq!9Rp"Eϧĩ}2 Ss#4eYY]-M r'E9D`j8 ]>>^-ȏp>>XCBsҙza%9l>u'ri$VApNYᾜH>Wdq 0UUj~jД.3tw FWJx;RYbKQZXY8H. JO3vXC"4."RT;輛[m: ~q~nM Jت\AuV[Mݥ9.E?C* ڞ[Om\VT&m`{c#եLق/^7W.n T|,ak:O7Dᬉx ʷ zeX^r&Ysl xtY\V dRޭ:RMRb,}`UY&›'BӺ&Lk>g1`Sh:kѮIWAQ¥SHlku,wk|`ZG@ xKv G~׻U9C9ke[ά>=]MgG0&r Bcl,)$˾FOA5hVӥ)₉L=D@‚ MWpMO`;ǧ TK[PSDPI?_n5= !b%X'?5kc{Γ :5*"CEB0ESi' Bas{-X9Tuz A+iHd{7$D:3RY S{EHjixH +:o~s0 mt1GfezQi(xSğXxV Buc8Uge OASQxha4e{ju\%SySL6n*>{A+Mt9(i.f4k1 v5@e!lu}0 Sl<U/w.=ׇK*bv|R.Ϥ# :uk71bHF'Z7߶=8RMU'oc^$ԡ9߁4e$ -QSiγ0t f r ksQ7&o"חlӢ.ݙ4`]Ypv_NR<*Bb>I p!3RGUcWn:j=MNz+>\ D$E\㱤_Ce|^+^5QeEck05w#1E-S2Q;xHB( n^ub+ޤB5I=@&mt.&*嗡)^zl$4eBO#H/6Yj4!cF d+g_hVRl<[rMWm{K[3 bq[ bAR@p%Q +5p".-Q5ʻiKsGH(oO؄M5P=XGˀ馼u9p|}ʣ4֮&+ԽعKX"_0`iA(xSȆm@N-cۢ@B]ՠo`SdSC!?W`cMvC7bk0 ٌG3S/$\RÈ鲘=mB҇{kP gqjDxevPB:+qʾ緆)d3p+h~%0~{K2Z!VYLg ( }^!*f!3{[& L;<3uf4|tBnObT6 Omz A١|$EHrip/M,(=չ>rd^^1&ڽ7H"%>iut7fea94peZ_RP0ڼ+ӋDɏbC#%Cg蘹KФlJPvayyZ:A)J#{_G__ OB,^P#YJ)~S?#:Nl`vTϿF;ðT՚XxuLYKYQ.DG\QC?_o9\? [m_gIī,wvl9WAb唝AK'>riT%(ʼnŇQ QضtV1o_N,Dyqß?r{=JWBGa,(܌%l9Hw2ΨхOI(]0Mi?L"j"2?߲C|{}Fw/я n)Oh35Jʞd_BιMZp"%mU`-S6 8̻f~ޕo)oR(-j?o3te$8D!_ Q1CK2l$|9_peDED$G*2wKR6ω Yi1HiEt XblcWFP@(3ص4fU|詟W/@W;]a!k9Z Ai:H BTİ-y'[rmV`~q}=BN7k^<)bD) ͋{"ѥFKz ۝k8t$e οNV.Q>er\>'V!A:YyDX;ާ9_(Dcwr[3/u3n9q2ˣܽm'K)ExrS!B)6a<vkX0Hyo=W~LǨ>C)sٱ,<#LF6g';l-hch}o!ݶڵϲ0.iwP@%6J1MѴu)d 2!O&E˜!J{\/="L>5HCӊ#\fY}~ e)D\+1jP"Xpί4Qڭ{=+j9ɢ8!wL1 K JE _0B7dmICw]KaڨT*'=X;ddauQ04M ~EsK~,$ bI?2x9;v6P_kM rvQm ZTS|Er&K d9iv5f= AQI\E68GYֺWu4N#ysT~HG,o*#[4Ww ? lvNF;-TZ=DA2t" 'g}"K92rG 0`(*ZqV_@3߲u㙃cU+M>ݴtOi}P>Ɂ@0H X0uyՃgcܮW|2Išu[5 f.Q({bҀ+gii47#*YL0VYWY)~5gB( qIeǞ: vR)6$#_9RpQw$e,Idwa C LNiQ1:;"٢S$VD<~Qn|Ϯ%EhWJa]9wDQ]}FJ& A#~/)&̴+s7BoR1T ؇W*AзoD4HѧW:Jwq %xO}G O۔gF{ he=$%\Xa'ӲcG["H{n̐\gī%&ЪDI'ixs=޴j^?SP'?`:W9L*|aVnЫD5"|VަnmPM gؓv?`t ff'2q}2O`i9vETT1GB"5$V }9kB^`'r+MjZ%*o)z#p'$;d c;؅{%jq֛#goH?#p1;}3Y$XSR/ "J|m8I([^HNI9NܫL«(u?jQXUgB?ݧhGʓ`M)u2>Oǜ䰙 +7s2N^faydU['ޭc?{y|1ެEt /_o$ff;{0t<HF0_2BNzP7~+]׭Q1t+ A$B p}:VR-ez}[4V@ _-3}*tO(0NG Zſ$.Rs+2̇HX(5u+ar],:((#?8JzIX0M X$óW>|f=6LŏGrHTµ1/nYd/ Ntw#3B88Dh H"|'}({~h#h7`!X96[o !DΏ/!G4D >?9n.Flj+rlKn$5yXx( o-˦.q:dRv<H ]lsmtkR VEg=3 z" m@Cݷ!%̤M X|>7%a" $y "+:9==n0|)RH"m@#Kepl g״[6|/ @o3yan)9̚| 9:ubt|S[a\%t nh5JLca}Uc¥l0Tk*׋̝1*]X^l麵2ÜkS5M 3R6x]XـṚ.bjQhЊt0k9]n`(/ȝJSvY?D> ݩ9`W 7%66[nyNw6f!LpԔ0NNXDa' }ڇ>To䃨wӭ%k=4;G؄r#wfM~`V0ޒcw-^H5~iQl n"K+kuNӀt a82}XB9su];¨& ('1]1[t^Qŀb Pm('lv2-RAιZm_+Z" #SG5VW!*X]?BѪEqZ !b1V_frkS> ^kiB3; 8W*NY*,pDTJS?v#YX-idv˾ d`k|TgW ؗoObtu߶mBͨ<&kɇמ8w4g*3e4UQ XR*ߚ[ISW!i-ƝDC's IwUK*z9wܒ=5ÏUȪp,&1S{vmb"m6s\+Hp~]"؞zՌ^p03YD462ǽA+^>/ jIG6d 3O׊rSWt=7h--^~}pطJ `>& QA-9@(Н]3F>YDW7S:KU a_Bot0ц.Y,&u: lJ<F' C$FꕎxNtpU4hvP\Ct* Y=|Ǚ LT8 I/o>;!t}z7"p=hCH 'mrTEy4+~16F&Z'~E˱O{o3ePN[v0lQ'ж9o!yTzg EQ_WxUr$y*i k3YfOZ..cf ֫?i~#hzn ˾KcG0ic%{oHHo>bPKV^,&#zM;ˠ !E:l8J0O3K**$XmhĿ =9`Kʼn QdIa5 1BSz+Q6g)OD!$5 |DZ|E&]F:o0sV,ﳍK\#!Jt6-^zV2)~R s&R]!A]c/Զ@e6HCmYf?)0{JF* '&Yګa8ҢM+zp|92^f]1BU*Xr3I`x X@ɚDՉ(#: / -%㢋t]1"Qш}dA5imb܊qm_R'Ȱ\'u6Fnq#`ߚmK+ nJ;WeЂNiij,VpRI#I ^b%f$cFz]jZ0iw%g_Nqp'g%EWGՓ`5x%EVPs!ymio*6w z%BfZkIw)c {9|)u Z$fHr`:3>Lg<_Fd0* 6K{Yyr\M1ܡݴO1i8(8|wn^im1i`| f?j2%'~%rG@rrlłWɡEmv[9('ҳ) c.iXKGXO Uɧ\]LJnlk?b9M}EN c-vXf'N) QEQx׉j?eGXe'效/ w-W' =wC/Ҧ.ƻ͊Ò5G Jzm$F1x:k$5 G^ʜ8}O16t}P.㤞k-s̳M$;CD+~'.}dKf,-@Nt3W@΁QfTkE}gw4WG?\ԯt)q -*lvU=Rd8f\`̜a{KCo$Ye0!HI2Y\>S+ FNaxB4 D+WM+#.a3@MiA ɭתn:/ >J]^q +hβ~Ǖ:[3њ{rA?Rls҂Ka){b3 ëb:8  :B-`HDm(G!ckPO8g30$ͫ,,z"EjS8t6e=z}UAED@.e07:Ω qyE27u!pR گWlz5EҸBO.S8J@ݑ=kps'ne٬ch؎ܰ7Ǯ+.)Dw1|&l^] HdۖE-!:ʱ:rIoi f머-Q0ZV@ =@Ml`$:0:p4uҶ8^:>kfSuw ku/ߓei+k椊S&7 &١69"y`u-LPG£t+';;mAQi!4-``<([٢,q-Z4eq]!ghoc$[`c=#N 0uldk^׌*o guX,ސ6ʠW_Þn|F*RKiMfGYbzPI6O9h J$ܑ';3VAqmf6]!.W{뿎)8]y!,8g&9 ; LP&KPK Ѧ^ N :ԋ3Lw yG;34;8\ߍWd))|ȽI*/-V3 te%Qdc}fmBI$?2<϶䞵m1I/o"91:p5c>lXl6duv/E(@wJch0-N2K{7nۂ$ Br.k\VU%A^_i4R^03b{g)b҈pXF B8/|^7 W)!&4uMmJɠ/~" ;[p/>Ypˀ-I8NtղI$@B[b䟪~bqqd람omK!ukAũE蚸yRCC?nR4~5+'DEDT^"|>[l_|x&;Lb$4h(;)l@x28XCm/HT]LšЩF W|>nH[/ \E<"UC3 ٤@#pvL=Z-](9}JFѩ@pj+V$Giq\o!=hABŘ ,^PaL3e $ڱr' ; lc Z$8QݑYeYLvKvy$h@ e(",ABPJ8aCdXܘc'tBi1';*칇Ϟ;sq*!So^0e 7şmh?ۗ1'v`pRyWx1RSg\!z}+B\"F; W_pAӰXvKΟWs+\_A݆?<֬fC63hp6~2N"?j.; 9#v{VD_8SOX;E y}Hg'PYYh='ߥH(Skl }'ܮcGPŜw.¤z?T`Ue5Lz㞡jv-8|G([3#@Q "Qb15e85.›_GD`&(^)d{髏w2AlUp3~nX{&srr$#4jѦj _{z+@n pI(9/q3y,ي*JVi"ECj51 QUc|N1-s))<dNJkNZXR"jlBERDc9"_e-Mr s85\FźĈ=8Ԋ2iTxOѷ=Il58_4i|/\aWt6p1Jw+~IcI3~n~w b͝XúmA#8U+3֣?;&eg11',p\MvtSr!CBb">!2&HG6Pe8wN̴fTӯo~O~v[9sBW!Tt"3ԡʨzw0m:" ŖxI+uONܫ9i%\UJ:H,n6{?21]wİl˜r2IB$.\̞V72%PdmçyxbȌQet w<պBiK0/n{q`ݦ7#[1xִQc^r :2m Ziİ40S!$ +k Ӹ ɮg4C9| T wn~SqH;2e_@yfCVYVӠ"gNnPMHκn|grczPÁ)/` DXgh;ghDOpܱRZ$T  N$vdI7Eɛ+/49z]aE/-T#`(V:;1g^ Y mKHt$76vl ~v\3cE* 6q]F=tapt2O9&8+pK@.pa@I>=f:V[S CCn|Ö5%0q Dixm2+D"aGj50 4.S*~c c{ǎ"w赆 ;[F?wqg6_ZZLb Z>G^2V(S s~fmd)?8 iXZ5ylmMܞ?M$PO2y9#'ftB}j9J%u>'`ł72sӗko^}V%'Љ$>Q"☥ 0C1--׊ ΃,:5IE#( ߶OӶ R0WI'Vl."=(w*?Ud_"@,o\>=MЃg)ef##1LG%rt-HJ?7!BZZwɠ1?kRb=5 wDX*}5l=n44"u0W|}8Lꮬ3IQM^bk?T"/+x8t>J1b9ʸ%mӧ[zj:#,V;]ͰY2ps2syNQn&eDG9ZNNҼ^b.t[Z`T/O pݕ\~33.@Hz.ҫ(b˭8?vtCB_g1Ck=I/u4lcpf>آ!qf%U1T?)&P Ixk'T)' F5cK<Ϛhu~|Uơ6_ T'cmF6k^BJԃY\+Z.TGt#$=} ˾};3K֕M3MEd;"* |NFpj YtnIW:;0mLɡkc*T2#8—4=ߖ{CHk/>~L~7z1/^𚟦j&N|>$t*&В&uЃ&bvj1cSʞ&#BkQ<Ԩ>~ZNdc#lQY{\҇uHT(7EaUŷ68DLjl̃tV-ͦ߃IJȑxĕ. "UWqLvTW ck)LD>fx ңͦ&krH-A_3x@75'#rKOaK;VGICi\6M܎ 7TqW)N݁6WB鴜}dOdqZMnң ъqVUS4 d28W) 1ôа獟KxTHlZr0'r3=?dx[IIe0wCIOL w}\<^0L@ wb2_evƮrvQ/ԝhIf by D]SrGwez? ~|jkY ,qߴ{ iËGMlCr3IEib%S@sGÜT&*7KLI^k\Gmةw!&#Wiq[E~Ʃj3n}ʳ6{Yx[$N=ה7nB[4&~1&tCnGߧכOv7>"J TW˱0 Tǧ)Hdhs@6g0Iw&Vbұz5{ m윸/ _2yuq-T>_*SRPyE{džʚ:D ьkyح}/Ѩ_FIɃk=R>awLY%tWtg Jn\ZYKHs&%m޺Y*Jrr/[A4^pCRxy̲ȡi=;|{uŀ|c*DZ,5bme3HSe-|P_aӢxN)w̋dQꦅ#4ص Ivǟy `⟃X8_IAT޲l/EfXy_Ua?B~W'a`BLy>3VRY3['x6?\2 #"&Ni> gT>j;~u*qB9i0hJ}(M/5!؜m{&BXhJ8N] ADD/ l ȣjƥ\R{b֤ԲUgA`5qT.ƙ%'mLc醡p9>y>RP7\ s!/&5.@"}d5{:8Jld8pTpѭ=ldz:*~Aa%N궘U. 5:Z~ 0 G̲Y:q? Xio |g ͨ<-HEpQRkG5SQsH]d1b)!n kEH#ܰpr/y^G#Hgs U>:5y ~҆\toGu@0e.y8>2 C`D aށT/\(U[qvoBߢ2]['|c:AG7?mZ v !tO1[%H-M2`]%01_w<8K9(rU# tjGBv0J%a"'E3Mf獪ȅm.b }2NٳIsmeV+5 7t;C*'BSЊȮL/asofVINNO|ԲdH;:DIV<3>[%UJ{ M6/O%†\X,vw(8"ڊ7Vk+37Yc4#s~x*4n.?ve觧t!=H-+jWOw *c?) UHҝ=77Mn&pjb!A(CQ5t@h/IT+R>gaBDۿ^^f)|t&%9_Z[qLԓ/WiPR%Z[mK( S_2D29k_FnV `Tt| zfcE ܶ. 5',2YJ~oY! +_azBid l#s)m24qP't٘Ш8&*i 8ĥddr>A<9.Vk6~F;`!:mR_{Zy##: p%@(ٚ:*r'/mA't(/F IUza95*!DŽ  9u180Qsj,Tv{oJiAMxfśB`IM%ڗ3JL VECfꒈ?njc~+oF-+.J9;^Ob_ؐBu)"`U-svjTNRnp'֜>f^|`| "Z橿hE7ClSj;xIztmYN+Q͍al}->Mν'ѣ5.mOgES FU9R(=ua:(uu4*15cxqѿpNlWF3i c*1" ҪtހѺ^PU.Yn5f AALI|7aX././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.238157 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0050000644000000000000000000014270014625637207022711 0ustar00runnerstaffpuW3Ws"֣ ZJ}@^N Ƿ^W-VN$l_ξ+ECأ|MuGwAzPrڊU̕/Lb>a^Փ56![ȯzӔۮ# v5%#i{a_r@+zd,;|oPJРa,2 H:դug9=\/ZcO'*G'r9zzT2AzJT5& yܥrS<.x0T:'> Dǯ(^ AIQKLӰ2j)Q4B9iBT;m) j'L+sD0%CAz^B7ꌢaN@WYx剡$)qJDLКɀeGUМWOp9 vq9<>q@X p3$/ "ÅnA#s G:#O~;!wUyE .%y蚒dNk93_8Hmb;Yk8e#KbS氘ho"$̟4Xʑ@qc*GxBb8{\ ɕ!9*֌璪Zb۪ɆqzM I:j}Ky-G{ʘ lATYJþZ'|2E̛Ve?99u<B"zBzb\xe|_<V& ma*`ce/2D17Lru7HO%~4_ Fգ3 ցH>DTR/k[H3d}Em7(m/W0{xPZ}%'2Q0r|qJEch84[ Q `n1Sޠd!&eS2%*"QLBA֍ T >c81|o?r} [>Ơ$gqY^\i[`Qs]VjL4%Jr]g7 Ϲ欶ຜ7x~%d &M&YAB{;JwbqF7<%9dqGJֺ;VRx͑*f|:mQ?Ɠx{h/YcLӖV%|SZ2~!+lb>B0g1^G +d(RR<;yodQB׌;9@.aD-T 1?^"\l@z,DIi=E`+J0/`&U}>?qdO$#QuUpU>Q z$?ہ1P(sOmڛ&0Ex; F~h3[įˡT.f1U -&ng8b6reʨvh70"+0&"p`kC/u3jsՆY:xt%˗,=aX0~[Lj|UCq"u,&&KIp S8-{)kN&8-yFZ?w[_+YLq2ևՋ zGHzP)ߚm;@C}wD(>ԉ ,voo$cEDdS +7,ME.\5JexuɌ1YYҴI#/tXSp/;cde h >"\)l"y̡EI+-,3dȻzMB(.F늲3C}璻&yIduǯ5á:m zR"/nݽ.Es<5@v-8+4S8FM,] nsirNX 4$w_Piye+*ߜ\[ߵG.rw:8x91AC\vO}yma@Wt:g`lIBh;ϴ^t'( #ܤgvp&5骸ץm\I{)tNb.'†1=l^y. VN+.wB'?x6ċIݸ YY96!87R *K;WO eCvslA u/P6foUYugϦ4s{/}Ɗd~m 8&7~9D93Uoތƭ)L=7&Ƭ{H2`pI=%[j+}Dt .9E>+koH5}/@&wb3N% 4$>^drsHtH(s{Xf3UU"]y0nVU1o#!މ)r=0ho f҅u21S;5_᧊|-,mpDk4o~|A㩡# y؎V&+D/7b|[r'5^>KӾN).6{Ld]%.?'z] ;C<"~pzlv#t)*_ЁVן<oy6\=ߖ= oSu08VnprЇ|_.w9!}gav]Zicr:&NgŠdnrhF">~*jgYtq(a#51d ϟ˸cYk< ^#,#&(kٙϴF@yh7<4SUlZ.kyE8E{=5*mt%*w~W(/0b{Q,\A0:[(Ϙ@v/hINu;A "w˔*6ko@4 P}IY8 9/e%QAzs&35R]S5{7r_q$5>̈Lϵ욌ref;(dA{Lܬn:.$&jڕ.8q4fަ&=2hhXovyszAdgkAMAܓWp';$kE^v[YLx@`(;n~e@DY\uX[-Yoaq*"d$xn;Ng/m>:d7PH?4O?D4+^8g%8`df38>UXNQb}XWV#[.Y2)ӊqxZ_hC21d m[cocElK^skWw VF.Md+^^27nYXgӊ/QK]Vo. G4u8gsmmxs ؚi'<$n  nZ,Fa簓Q" ZIKSVPg#huF}7,4L,HĝB;T{}~2''N˼pDU iQ6{w 2"HgL^`8ǀa ת*zVq@MufKAYk c/WHQZ UڬH-qnHXv/+LṈ"%Ux'+8tO'iaI$;7%[<6{ٮ;I~Ae a@cvoNd8"nHIKmл)i(gqtgVUeQᭃrÓ PN YXeHukbHȯh_4nYT2])?$-h|J~ھI܀.|\taFӡƐ*1/N\0 Pyʮ4h/nyۺz0 @niq`Ƹ)il%@{+-chfp cCծ;W!qBy$]Up2.=S mgdFy:Bd֓3P:;rfZ+<̼9iAdD\F+Y8&qq1l?Y4I@_[ EgD YԠSPB#g?9|:谔yo'I A:㺇EX1*jbE`,\ΡU">trܫ=OD|0̿7}Թ72#4r0')#&ˉ18 piڇ-xty(Z!ս$8A۱Gz nnX!\.7=kwzaeXu[R-Dqg*pLteNK̀\-MWH4~->`erP5Ur#A6Q<"hB',qȂoZkެώMh.(&o{&y/ײlQI"NO2Ul'V݆˚Mg fmHdNRZS)@NU;l̒7999OvqcϠEJ#1>$"/}&ӄ7],/ZO*Y62/+U$FهCWΓJt~вLJSźM:io+6_`Q;Wft9II1]8óDe{[V@#^A$ lIGdōNIhQDg9re婹8AEwT5nDJ$#^x% aG2}`A?bF9jr!`# ]cS_`'z9*e/KsdA |)bB{˨K߾[7`GYЅ#ƅsۉū%H u鉆S~zآNW]n3+wPEWrTs37ÇıvjbPR?⧐y.)e;ڃDPث }Kw:1,8h7>b<.jP#XSSnr>ٔh)o%69Ap=E;IIX0 cUjȳC.3:vNz#$%MB+ t2-Gwn Gd|ZΑ7Q㨴qɾn߶Yjd›s^nRƬJT*]+ -oM}-刍`K=c,k@?x;#zav32<ژMe.tw&XGDGmx K_VlEʄ.l {*/jj6N`[TWgRM]vUa tkPd߫I!f˅ r *7-=#i RözVzJ9 zzR8oaN{=F];7oLpv0݋oYRGlߢ@%B=S&;e%-[\t@+ )m!f}^v\OnYm0qu.6jƤChC@񛰙T$^e3Aj74?֑:rT 83dMy< %agoBdO-&nOtЈEhVr!ٮ&i`96 寫K3 !]qRi՘~EPd *n}k\X*Ip][(c.DkZzޯ78 W~+÷s5g'kw'gܦ xav0PVA; -ņL)XTM ~|uh KZ6K W#67MgqCy8FmZ?q*/ 8~8ĔZ'fqZjϲoc'( zaPWqdH*fҒV᮸<~n`v^. B{NDžoo++!L8/-7_lʲ NAă~i((~J:ҳuxwN>%R&T4f ֟Yr a$U^d?DA p$:en9Zw6(/ɨzX'UJ-f_'dïƫl%}6Kt/_% ~ "innFykox6EKU_qX" AjLy_.GuS}7I}ƚcd0\I#Cϔ5 Z,M]X3!ax 2L~yUŧѿ,7IۀџHZ !$|!/dT89j9`_;1r & Vhԩ;;>iH}ZD'*kKX2 3r2 øꇚ R3G>-,| ;5Z61!;usq\1#1鞒%R/>br\w?drQ?bA# _4 /PW^(Thofpl{#"<%׻w̺!U+7]IF]G$ݵ&ZHl#K4;c$QnEaހxMo&FcF>+dhu{Tw>e=3짲 R6IVUS1EqZ<]1+RmV V+~Sbڊ;\\ ';x NAtIU65j@R@ ٷKɪyV\ o3듗 lEM?H -~ջT-B>ȠD-\dZ319 2L*E ˜[.%k7bz>ќMK1[} XϿu +aEBzb _/$ vTz7sHB1n="ckb%CBɞfҒUii{K r2+ ( ]|4`qa;AO&> hI{[p2<_akԝ\1ϊ-Zk,Vy }Ԓhײ t\'ɑj# ], ot8-硒V{{fYJP{Cܴ9@L8$4]R=E|psc.1SGj,cQ"lu fn]ϵ K ^ß q 8e3vtnYUة+\0P K0նD,%5r"98 +م\o~Mq`*e~VRpJȗ\{먳5pnޒ'ڧ*X* jIK #b9+H q_ϧ0KW :zsJ}e% }48}sV˄->t+_]\ 5j=):$&k<_It9'ԋ ӌKMj'0JkвyP\V/vRyͨK|I|B5" ӷZýpZGay! ArB_t4eԱH_6^kNe;;kpҌUF[)IbLo.DkhN8>)]XhÂ>W4Ӯm)*1EsJ79D&Tś HʞHS =R fTsFIn2YXZb<2M| X Wo-~1{[;Wv~䪄0G7t.1Z`חߟqexw_ʗ2Zmc{هc T:;}Mse٨mo޲>(Z:8wA\#|ٓ?-{u ,Gqt[dܔBаQD*M\qoG-f"/Cٶeܖ !r7 4ojI,.ڝ-M E,"T+:W@f@M;f+'ZwV#g1#46&H2.c^׼['J!17P/is!cto5)< PA Aisdwc,4yH042;jb1@X!73 xl:5Њ=3g'AYb@#U; ca2G]ɃoE/!gg$k|8Fj/t 7taNkB1A7 jZ҆_16红HAPUȶ]x-L󜣅 [P9H:t'X(^%Lq3I/r1) +z,  @sf*q!zPC&^*g% / &!g0LӢTJeu&x *dfCW.iZy6wW4n΀oRzQpryGSqd #0c~n8*nd2r)rbI]4R[ŏ&@) tZB ewk, mnup+095XwFǾ{V<"JK>#nX@hDʭoaoY dفQL'K3g7{/;`~QqP8<ڼXHRg54ޢ6fW~%s] BQDf/3,C]C#T B:tEI9H˴0R ?VlYZ^=(=ѭ;J 8i8hG[ hݏg?Iz3_Qɉ˰_bn4Pf/#pu3]lCe&}bzy;{~Næ/>##Wl[l9.E|:GhUi@xV|gFy5q;M/ x_Ym26wjk *z źuXѰoWL(øQ+?Jߝ;|ƶ.7I c%0JGy:ʫ`CX `~W}bg|~9<) v٭^/PkY` E[R2J'R6U V'/3+Cya!E1Ns4eiy[SIth٩{#F6G!ߘyFAz_#X|֔sP"X9LI}P;$;, BS^XE.'U9p}V>TʛapxbKS^ g~,{>jB`.4b 3i63-+ݮq"켷d\i*gQ󁮍Hb =CBJA7d#@<0"n?]mȸ1}t;$o/^N81cEcoF;@N9P[aK-%A1]~FJh #=1! _Dko {އpg'.&,GpA*JE7JM`Z@_h {qp%y5J3~^Q񩑾[YB>w 2VwΙ]ۉ3|& 3~-5>  @X*qaN/ZɵvL^wO Ļ7> ?V'_wyRO̷"/Kcl|`: Z)4l )nq{1><@͌:Ү,=J@RjeBnφ aϔ7 p4'fU|Lyέe} 3Yc-_qJ =Lۑ76}xa`F?pRtMcG=M5bMF|Z-5g^t-'Kw˃PLcb(l7p uV3ܽH].f@$l#SGw[- _һ|.ɩ1j_kFI9Cbl][s4f?JܪMfHўTޏH}!ͩU%}5nQ.i艮o%ež_ʆR7 dJpom4y@0BD%%^ylm,X9n bJYFJ|nM՘}U\OH~gw]A=`UW@2ᝩrE^v߬q -w$fQv$5 11 O;w_4P#x n0Xyţ&V-boEݶi67cQ lccwcfjgH,ʢ2bK-*wl{rkN0Z",d8s<W8N(UE)+?pk`Hg𞙌YE A*cQX艎;=T,z5'`Z>\$w ( %[^G uS*qax^ݣxbF"~wOz(&7:cW, #DS-d?x@+͟ОoyC|\;7My^mBBIkSyŬg{*}L뼨guBekPa0}8f<AOhK6X.p~EZ1Yž{=B \qB۩yO97ktK8lEbW BycxipϏ.HNs{MQkd`2O5@Q3)޼3]oJ&YZt ~2"4AFNАzԉT9rRXZm뱞bҤ<^AVQP%To;sl3oڴt j>펤1Mq̡~>8OJ"{*_Jo\k+[2ӕbɡ9ES}+5%Q*wFTҕ6_ ?'+h>Iɗ 7YߌIKxQFF۾v[0.K d 2\-[+qFЗ#4`4jBX=2[PGY "F|N~˚@GWŲװ]J\;nkGufi7;B L9ʍ _[9Y>嘆-"*@f5/3uܻ4}d}!po&|.*؅}\4(Iz Xw[C>H6/vɖ _u ëUk5)s`yjױ(/ 9Tk-jl\2k8ǻ##%KD:|958ڏ u.n)ȓσ6=E@4-9W T!.sO?YjyLz$'3<:rFj ݷå-8Jt  ֖޻nlIqOCV%ׂEb| ´j!o$Dm f.TX"ym6pI_B: <>Ka${Sljtl&+R%QU* gBC#?(.!aJzP%=-X[5n5$3)"QQy*Ҧ¶B.4vܑ_wJ!7v´CAؼ7̓~N{|ӛВ[<0f>ή/ø`tPת9_/O&mUIz1;n"d "&B-|I0eڨs~sy;kfxr .VaG9 +8*\iX1`;ɍkdG=i[+ <7g} Sv9򖜕)!+$ /( 58TrF H~0"]ՒAܔI[<1-sn8fZ[EMo6X#&i1GQ81KOYBJwcHX"f_4xF؈e8VYS[qH Р&guZ;#.#,kˉAQʛjӴ7x~Rj}()D̲3qm-r2p'roؠ]9&#PE벵TbR1vPuO .qe3d1chH֯+a%ʪg}sv2 6ypkRq1.7E~*'LJ"y0[$)\W)EsO2S8Z{>mB䍥|EJv\SjB]@$JwmIf8Kߒə˃;2ڲ.3!@ocpϸ*osd\ﺣ .ziEt]ehhoR@~(nj޺o+XAۯ.XɮEfrx\.4AŅ;bi;8?EپçL+ IqqwD8HF}8UֶY!L)Mhف@fGzJGYx6v9 hUDL׮(P3CE(;Pa]Gqwj! *^[DZAvw(zz{S :N.8[) :ʋꗀSQ~'¸;J5R TC^W[D(amBe& I!rMwd <_LpoF ;QTm\?*I'C3~tYs/:/h`~D7_*P,`cegfSMv_iW_~/X6=d@#j&uؐiQ ĩɿh{f!U2$onuPZF+wFp\eUe OS3l`MIB 4p:Y̝0|7nԎ-qPœ I}={Ƅ ~Wn|(C]Zo'Ђ} L{QfrؽI ݼ1HbwFDA8Qg-?]:`5*[X.%)YDp}iĶ:ROFd UXڧ}3r{\0"KVB z-rN|Ęj(JVP>:[HV&lHy݇R ˉGV\5FܞJXz>3{8].W8b]l% KTιg39} 8' Y!n3D=WWwUҢZT} XV`ktkPn@ ˗+v աki.} 7&k +uW|& 4A糸Ag}MXUkBh ]u73;,YZ?0G%3KnGT0jj)=ӇO,>ى=@~~|Zg>bks/WLs4 /^MYrX_epPm!hwm:0A}Wd2 @>y('vV~<:B'{=7@`βZZV].9V̴Tq)^ G,g;G׫So?dgD銥QW_H7zc5$Ev#F6蚮Vrr2 R\f0w?0!-7 Șz<̢i;'cyhWIуX5qn"U-XtchD>pDR?Y.|\[jeB~0BSZL2 Qu\ ksU[ Ӄ$r)Ö8"70U |01^]m̷rx[Rj8J -aW*-%Δ PaJ Z b/}TuS6нkd``Xq&O=MqnC5s`t$>b(XPD5k}9{˘Y^\;mKjnmېSlk4p S2KI{0֌*Nei`^4 Ǫ5coQw&$3`×.RGF3~*TֆE 1LDB/(wMCoNR`ZF̅"qv :j1_6z fB70v%e70tA<:F%" a4fI+]-`aa\hDj@ŐY[-<+ÁoZ\ f)pf˫T2 Ũ3Jbl)KNPtaULRy&ƌxBnwO_,snmh~Wc& lQ^@@M8b]k|M_{w[9h7:# 3U>GH{{ nfHDXߋ>W7= sUp%wo_2|E8v9Vۂs=Si _0Eɨ,>Md#Z/ R&3J:hkSn= ҸlYiJ3D+(6qDR Y~>~vNJtAtƯXMq:R9 ~å!B6 SFGKf0<2U8.Jx ĭJ' ^ }-g:=>C"ͰG=[vVK{` sj2zO$yR-LRGLѪ1"HL-1r#w+;ۖH \R$ܘhXSrEAYyԼd席p"UȋFl$E?'(d$Ás tBϓv 14aIsޒAic7u*@6lW[xՀ)'d_{ Ck^ e+A;1]YYUND(LM}ec}Dǔx+ '(i#^.kdk<80QëD9L>}2h)oY4jf[N|f .g %"֛mZ쿙L8N4M1c?eY=C`('!]l`=ލR*9a0=/`;V(\XӲ)HA&0~zAs$,MVwk ?y!Ϝ>  PjՐ(|Rn Lu-l,ɹ4֛o wܰJe h/қUa;kn;ȪvȦgD&tެ.5zO.h<$yFB5m*Q?yOhDƿ~_s N%eL5O򈶺ۼmę|+^jᵀ>AGŋ7xPb@V4 wT?ۻe] pP+ K9scHl2v~pƁ. &&^Iױ8Ok`h@/D'cs3)m&Ƚ&I9Ş3Do,̏*p݃Ɂ"̲W>BnnWTF ǜ,c4rM[JrMWY.T$: UDO|x2!Pdz&f̣lva >DV DViIU"b&2Kg[X5__;2>r.d%WAI|)Ӡ {P@"kk,Ջ?TpJ*D5xy⾜l%ITףi2fL(ͱ;j<$ tY#~YkamXuHHi5A:Ў#(mN#uȝˠGXZp{U?# ֐DŽ`~.`i'P`ZOpt۹7e&nnM+9v;@In! U 6:DZE*q uGu^fƳc!5H}prFOvj`Rf/`%wvtÊ*)Rb #Mb =\Ak%L_pD\L!+/xvaV}Կ@>nł6$ױgS@ӑI‚zڵ82Z K3玌)bEȻ|`H>]nMX̬|k ~GrͻL5^~fz_!ߎDz5Qӟ3dgx2=4) Ŵ P;x~ﲊ`# L0'#*ig^n*~1ьFwACSٶ竬6DO4űƆc`O.g{ٷo$FD?Χ̠w?]1t(w!w v3PvZ,UŴe8wfW y6Af!(.cK,!=̓}w OP}g)x؊X0 ^ vgҙ&=Th$L3IrMsda+¶T1a sK@Wi!D6ӐIx\<Lr/W\إ\(4:+D=wlx⌄?_\^tslP? 6\~mtO1xqo'ᗝء4h%)FCvYsk;\ަ\?[lxAq#1Θ=e;kF-[my^H'Or1=wY6p  b7:'SZ\@=?]hzEG y!vfD%;jk'C(TXJN_Ǘrma8Z`6yۏ9u̻bL'i|py.@OHkkp陇V.S/I: d) =&T#GV*'˨h?SȍJCV cc9M#z^ {@RP{ÿᰡC'.u-2,~ @Xv{(xx;39jeyfhۖGO%8p+뮇!\'  $޼ @+HCFcPxzhvrFxS$l%P`)UTUw{Syo@`+v#RK- o,HWN4ѥOD466PE ~ J\x"4ؘfsտ\ \o :@ׅkjSqcZ5q2=~A~,,rgͿe6r%e#[ߙAR̹V=.tAt̛oAC7TN?1ri͟\CvM70*[w(B EL,oO@X1ɵ(EqCrQwu+2弳w P#T8xdx,ݣbl-OvL(V H/^DR#5?6Cx )ky"a-l7=l+?cmI dXtNk .yz4( ^P%,m7$NH|E͗C#l [y\ -@Q9m˅,\l$YT r:@t+Ox˪~B{,=s bFA -fZdDJ J<c![U"j:H+, nWŻqoKt;ۢؐ<@l:!؇[ UyfF>tx&E޺yQJx870r$dB;ŕG0s)7biO3A!M B!8j1<iɓΠ>f;ִg]lwle J9bii׃9ʺzySq{PP 2jt÷ndS8h{ A4F? Fa+)l%HK-wq6mBϬ\?&rTUk \ğ&eIvqծLu}KmFU0׻ gx$[fLX}?G&ZQ-}Ϧ} ` &3`Qs0rvZ>y*t4-cŠy [ 6F2b#Bc2"W7(ƚY_F)rݮimBT8m{t1LF)9ɾ}_@nWi3G(u{R]tX˜{B? çPϝpyLG|Q4hE3K.*KJ0%jڝnx${칶H}0؈Vo)h+]2/t~QeQoZ-NniP)JnЉ3q,Y0^TzRk [ k Ȗ0 \'\Z,7zm:FǷYt']܌]t9 t)"0K& ns\lƘpM5N?O?AQ" 0騣Z}i :PIxw8"o9io@PoTG:L b,k{9Pc km`֧ZuyRuaI{fatLHWR\{{]2ps8x#\P9"uQRa[J i_p->e9ۄ88nf4a+dpG2HN0͡FՎp )_"1m bsX,pw;MVTn[]|`m}˵@Z;,REujfi]A(ro;|; &n7W*Z̘o*0830?BO ˲0WbRw;qKvlQpy3/#!-$#@? RHm@nq cAːi ^Vw7kQGA&P3N?o\ƶٟF43jTFl:1宜WHQ +fP~{3Ai>@w=x'Je p YZm LEzA$c5i50|#.E4_|q- )~3 }LJ|֙qgJql|%Fר3XU,7Oob/(S>jaϿOZ QxEpp8B`=2rB\0ƣEn `O87O T1lV]%s>ȅsV~H'B|lv"?׍UExaS _<_,;+ Uɓzk;"H? ޺1L#XD;uLK]&Tփ~9=yjG@rq9?r 62$HJMV%1ϿdY 8[Q_WM;rWDy/g$FynՆ2rU~}Ad?38En~c*$=eDoЇo ݣF) ?xc 5jFVê)e˙)qlj"]99dJOM#SЕ`d,>{Z5%HӜ(?|d#eJ 8k@4[ѲjԻxkl""җ |U>sJAJsPU>ϙ\Ĥ8kegTlq1 NؘL8UV_yԨ2bxXqdH! (n;hh"x XX@~Ne(TG]/`_f!6&rvhx[Ԙd5inNUa5c˸Ikg.gȻ} A/) VK *b!ۉ̉AӨez0Zp gR^>*琶_G~؈Zvn]n%'qj %B4o~4Bg+J9Cհ5%x~ҽOo6t݆lGq`)yCX'M@&sdS?NN"e<$C%; !C$eqW+q˒#:P$`錘ldt\%*S&3c=Do2Bi 4h\[{FHw*\J%R8eRk 6'UrC-y;|{p3P=V(O6ì ZTV/Ne;RT! YKܓS`StATdGk/c#;ŀ{fDjlk'\>VP ,o:YlM QKo*L=80p^E?*F +bc'Rlz'A'4ȄyMj640H;vnȜqpm@͝Ijhx(ŪzoV]4fhAFK=h#十lO,rp/Yh}ARMb01sR>5¯<1Hq U˜SzlB;H(՛6jfwEWM(+;OaۻꌮNu=_S׮x|۹GJUN={@tY!ȪU@duo /-A#r.HsT_0\ok~Xe,HmsM W z]={*g+^>wLH>ڢa~KPt?o*{mR7p]H7w4\8AH,0qQ R`ܬ0H=FUaN|qPPŃ3uzR;8pXR /M*\OYMub2#+z)Λ6G/ v d BU IH-3)r'B%݆bX9'DDtO6NegD52 ٕM.`Vp 4%'cB$I# <1'e2ͻ1\a*A}gnwdBhscpo΅U}Gl]K[= :E_mg #:I [V7ItHQĪepjRPseJJfQ:]5^BsDΣ(^+JCnnX}.W ?I(z͞-fOf~ l\&d՝]=IJHCRiVl} 17&K:oj5 yo&Q'ǯacIJe!~ S;է#kGѨLv`BKA^_K:=ؑ {_,&aI?袽>PVW*YJA*,z{"+'Zsa`/2<@_8tMq ȘqZ~uYj^3c$6V&*OǎB`M(^4[Zro>üV,.d)8~rjEͿWD#n# qkE+)A* \10OЭ by~O{Ci4?,7ܒMY+|Ɲ3( y%n2bThc5ͺdkq?w!zeWV㶪sT*⋂4EFGQyk'ɟsu>gv2qhh:؋ó̃HD>hܔ9{̂h{,1g [93K&2o_3m~Qh70mӼًcZFFX Cdw w F7჌i\zV\'pt-T=z#Aw˲k!aq́eV)¶>YE1ã$]6^#U̯^bjfɗ"淊ލ{'+'ÙI8+-k x=@|9;#L*+9-MS5bS'8 ~5+Abv(Փ v.67@b;6rsrc j')RR$"~H\ǻ- J^EωMߘbl46!YJR4f4 \0sk , ̘z>pGס2Xe ~hC)BMvȵܽt J ViI ADZ>#s40ehtg BjAv"(H"9w7흌@6}oI\巕H޵n}!W 4Bj4b~l&zUDa͋elnm(gI@V1js^ #/M9GEvv̠#hǶV9DNb_ۿqku4.bA vcEtQy C%/[hrOcY^HJo SBf3vb"{tO'H2"7Tf Sh6~O,ɨi Rd[7zn3nԯU%FD>Jؠ8Qv; J1oG;s`ܹC}'cy20n[)Nք %Z$Cx_%^{܏`֬4Q}BA1d:4+X^Fb*?1ۘsYWLCL*/]nzp!_z} 8ugU'i&22ơ|JQb bwd4V6աU  S[s;H,ϢOkejtUR=:/1~M9X14*놆Zڒ!n{Y#YVe9V kn4h^*7#}NK0!0T:4iI2j_J4:/Lw",3^~;TSr<V nJ 3 pɇoܯ(B-CX!QB-h%"Oֶv:"w9TzE[۫tm sh .ܹp?M PhRԡcAaG4^]n2{rUOg[ʲ2Zw&B`ҹ_0酔NSM3^]!BLD@f2osp͎ZzrB>G{Z #ϰ \"~7paQTml /Xggvajiǂkz&d3,Wh·DD5ݻ71YńEɄ Vlr]lq9Y=ƛA*~VyWq W j22ײY=8p2k;l$:\)MP-#Τm]uQ0g-:&'8  ^78OA9A喌 Tgix/TʔxO(jJ_XyKWy ,F"z(+'S,B;.Y~FPY*~#brXc}>1b7>U"+h|d%eNm;~xK{n7duJrŵ黼l M[Gk lj==9 DL4Bzi1}j B#Կ9Jg`BȗD,i, V;9Q?mi H6EU$2 2c~\)pWVg]K!'+ D lT>dmaSˎe}.;%Fb(" =z]WHYtq,__q¦s񘠛X(6.d\{Jr#)$,c&=V JHq٤)M5SvhErq7c5 1OdY4'S\ДH/0ces;gqJ5L`ecNkTEx;x["ld:V!GUhl~,4DٱkvcX2zx1C"f~長Y`2p+DТ(hq ꢎ//= p(B~"KݣV Fή1w'J'QEgU.w˃;RDQ3?N"ֵ;4=\sn{Vzwl&fsT-}%6WW2&v۵ZEH2C:hIT>u2PT*)*53ιǂtN'M-T8n 1 j}EKmȕ/mb5tޡ~PV\S9BA f{tL]KY8,2+}Ѐ90?rS >hP$ƗMV"?3;d;zVHrocDsr0 D||O,KWס$}d<c`wߟ_+{Tn LLRKk_ c.icdV~Ƴ)jh_ @x[i-ȝk!8Mhm((0y[e-P|)"輙{4_}?AY3˽1SwI ,c =J$gyqR ةѪxW&j=4&#GlqN)oj<=΍cTtv:W^FtbGI(LAPn+>Vݭ$XhogՇ®_G9 Czk< TnRKrlZᾷM E8K-F\*:p.k҈ZR~Ќ/wȘ((؃;1+Cz"טTwڔHd\3dWt.G/xvO|"~>5ʑ\wB>yrc.iB殥x:F6\8,/) %OsRvt@wXuˀ'O?=#;̖ Q'` 9"2v9՞ } @ڼ&?I&sy_|~'3T|?* Ul UK Wc1;`=n3 h}زjٕ%|yNِ /0EP!T+Qo&@_xtZkEv:3Ǜv*N9f\$ \qtZQ IHh?~g{?t+HM?jZ%(Svub\}o8r u_`Sͷ4kPFc ,;iKھ W'ѱŠ" 68jEew@[0kW9 }8i8n"xZnQucCU5%2[u$ W=[ ] ;{c/#a 'iτDĒ D/`azZS;5H Xs%޽>L䍏kjr?aGBsqM*5񾯫A]A Nbf-Wq6{Hv`h&i, G]|SɛR<B%D8?ivL^+G ZWaIo*u 6 Uԡ?ExngKs72zze %H{:@c RpHD }Nr2'2mȡ7"3Ѥظ.ktPG sc*wȡ;g=K%4Sכuu7t`ÕmO-Z\%u!Noa$X-.x\n+H إg Ԉ$B&\Xΐ(≐9g0UiW\b+[{jP#eALn07us׎ubȯmX.rшU̔Ivl1֓`9!AU̔'L^EIk3@,.]C|j ^Cl *jc$ta}|afZrP.hIIN`?u)jF+,8vC0ӌ8gY&'RƬ7|"My,7k7Ǻ[).#SQ112. (?֩G?-Q$^)7qCb$'.&;W_g|{9 πcFO35Z9y[8 -`A_Aa9'0UFUYfn/ ꎏ]wxkH] Rϩ'd1%&Nv '6'.j!u)K[XMcB?7rϥ$1ZSc P5TU12Pyz62q#DYGmq>A-y@E."mͤ-~I4djKk8 ±R *VoYuϒd{r &mWhfc'&݀ 6GMywb#E֣ޅ^P'\E_]{"yвQs@F<0izf7U*+ʫl TQޒgXB\UN./$@YQY_?ٓU6Ix6OL>c*uKH>'ܠx1cJQ 5څr4I74_ Jw{;OZr1)}rK .< rUsoq^mylE͕OVj⿠/gȑ+&ދ_|Lɿ,&h-Dc"imd-)a^ RHp;M ơ/F1ݏ$.T3yݔ}0p? LdSd]C +7W33Ѭ/che*/ѤG_mtln5,B%JqOD5d Yk<^US+뗨#ҫnkT1-pudD40`*D">^FX|RMKKN23Il+ĕ<6ՙ'anb~r5ӬVfReNArmݍm*N$ R#R_tkeal'E i ^dL='3L?D*\tv /=wQs;?T}TfHCWjC 7%5\ $Q2s&7.6#˜%hEC{L*)+&'=ðL z9q0)_נ3Mgd5gTIR{7po9Z}=V,G"םkT<.K+QCb]X4lXۭf@+c$xD|*1`B 8j,R_JkYUĭ \xjns5\l)-VeE vhcւE:*:(~!X 719~&[WzN<$~BQH6ĸF^[­m~}!wϼBD/9~lWPl c1CÔYmp~ͼZ G;jS:Gz}86tbk 37éwOZz-=ݟ&էpKJEG_XlRG+|ncTmiFJie)5z_$:mK'O1ϱB^Ṽt(&ܹ[@W;4q:(kW1D);tطRocaHBeJVL^J/6U4/v>&i4c-\ N1'nЫRiL9TTwhGfKs*i*clΗ[SgV"s͎`*hm^vn. j4C8x"Rj'R˩kF>Vý}֛@0tYi<x˸,AF- ƭ%h0Wy*0zԝ?bwqpuA>rq2~S |)xidkVZ$i>6N)cwkYU_7pšCogEIa{>YtVxv=M6 aU5Z= d>_nu2.\w_Pq}B7#3@"HŒB&> ?1ahg$6 %hop74Y3H!THb ?RpO2;tO rq NjJ2P*ATJ̵ WC{Ce'#C(R4;Rwv)|жN |dIWP<"xXD:M {3pd$=y"K2XK+ +޺ R7-B[[JϪ&~X֙=CElk: A`<͒_¥څzS'W158LƔwpye@=:t/% A6TSo8#+IH俚vݢPR,Hvn/ec3Jn~!zqc }emXʮ]25+:yUÌ!Uv~Zc4~6n@%U!T"c @eDV% EP7Iƣ2HIAo`RU!V{  ؿcřjj[DŽ,|/"t`߭9u(/=[0=bR\1VPuԱNl xe"'ߋS7YX S,A`4&NSԍ 7ZI=k?4Ҽ/74#"2 һ'h[jAѥUf\ y iGbo2ܷ1n[~EFF"3F34nfdXI 'Mr"콮aILX776 D+Ӕ;z} fYQkBuk4T!)bȿ"'-EU3f1}p]E M@t4ZRuδp1v+vT69@ďE\5?^,_<. UG';2:]dȔq\0@!ʙ[h@MIѧhʎ@7a䜀7Q^QϢZVahs|g2l-M$b.#[@+b0?WpdƊEF0ifޤV%.}4$'@3 8ޠyeRSNM Έ\u\5eỳ kI8`W>,uo0?|`1\̜]_^{)Y8LUctE%msaKl6ȹZkYI Gjz]u<-ijr~IdZmEjtWW3G%[Ǚia%0M#UO3'FbkauV{ԓ &wlFi+|QS; dL  yngtS?9ȅmx/rCRY_f;[|f9i5GVg*5pR,N5DMqj~v Sh$[V~F1@7цEjcοĵsw@z` 1Ve,=@YVVgZMCdAbϿڋz>>եJЁER\G6θ;.r2A'M 8\Vd|eJ]8:P ضkg4'bTak]Q&^uS>42Ժ,GhC LcE (=84_]ji/z199vdNgNzUq5Ɲ=.Oo-+JtC·F &ALЕJׯ_b!hUjϾYt}cIJRc7H$q})yb8s䮫lb}Bcǣwlǘs{ߟ'~`SVĔ[ģovԯXv`vdGʬPG:G֜Ǖ372dIfb|$L54EѤ] ;84Q6;K yHTarpZ; ^X)_\쩢z^@ofQB)#]{FN,Ɇț~ 89 .>_.zG"sZR0+V1Q7J?7/* Ͳ*6AtgxdB!p}zmqSQG_[-|U=7T$~ "VĘ'!frRͧ>Hi!oq`~3D69=ni:ҥwOЂ{jHǵ+ʍRLȍNԠj<eML&GxFe~:95j{GJ`"C}7kk㹶j :,zJdIT˶1Rogep(ޢdmC9Foż NOѳYٜ:mprެ ^(Hq8MOSw 1֣91I]C l̬=]5iaS4.PH>mV=HYb;iVB4!4UeumcRW5Iuj-!juዥd{p;+A* .;},݇E{\܉imF- Q+5,1a@ 檔gfͧqr=NwkJgà.Xg#Nm MF,gT:gy6y#eCzIge6ljSa;c'tF[Z d-㼣@Zp<5ouyO`Q]6/gҰp +d=x8N4^k OMBEG㽕L^Av >Y%~cZtsgD KO,aj/| :7="hЕEX|BsF()?C NخeZ8'V,Ub 5QNԔLLʪ"ڦ{z'S pfKB2&35<+離wTLڋg(6ʣtC( 9W_12Mh:pR^Et%9uXbZYxֱL;F圔|S*J4HMlna_E&:[`5j`o>othݛ3yB{֎grf#Sl]gׅ.(ϱ?J!6 P{[Z&4ZAfTr:FY4;V$ͦHd-̥WǵB GKH-nשڸdI杙] c^ȼ)M.:pط,׼GWFڢK}"oj}=^}Ic᡽}kK*0V+|2o_SBnIm|FWg)G0$E υm!D&qX'{t4r)v XrgKq{᪎\TM07hƴ|&|)΂SM>72ھΔ.(Aq x mrӁ~f Oku̬rjXwE%_glACڛ?{%\;n6(o~}Lado?q/ܤGKRP糙-S<3Eٗ4Z˗b d\9>#;z̤謊90ן}G]|@GxأMFK?@q҃tșCjzyO!K 0zD>EZR-PGqÊH0y ڡzMG6m(_t?' ?3ӛ`?La:#]ܡƕ|w1THk0-Z;ߏ;;S4R4/ԩV}[O/`BD[ k @r]?6EPOa;ed?SB0٬A$S0A}СKޚTb,ޯ#/ OGR&^8+4p/7u~A! Krm u-K:&`tezkqe)^>fZ}@bc3"8y .?EfP\B9v?N`hxO1&hP?[n罘;UӶIVnj`",MPG@jl( # wVz[ьn ʊ5:IkbKI HJ%+gP~J/L`h s)z8WՇB,lkjFf)?!_RD,V Q= ](J4Ā A;YI%"(X]h\DzF(* :9W"Peye#8 C4գQaG$,f ou–:cz KVh{᫰QD3 /A={ :]E VH=8[#O [K5ؾڜWɦ@ dIJ֎)wJQ‘^p^yd8Gl.$VgKeN[H;Jyo`rxzF14v#:\2Cb' SUνF}"wLx g3*.+ـ1{E(ӝ$Bo4:|e /-/8/0% 8 @#A1P[&5m]'Fْ33DZ-~ݬ`q&ƥofM}ɂʔQImlz2lm4wܮmc7·aFn y{Rĸ p|FE8DZ->:M;uNIm)B$r|f=#Eei8@AAZ%Ow},a^Vvjuk!wM]z)J0wrYV uüNj!Q%G$O@^ՈLq9Hƶ1Pn3b~޻*Rf7PIoede5p[nlFc^-Ֆ ]zO[1Gt T߉tw&s z;4Vfsn(+YMQY^.ҭ n B]eȴM.$c&DfW':yY?QLU(ʇ0|TѨL܇QMIC@MöNZb1lƚL_:\%2VgsSϧ zbU^an뤚& o9y"=Ls"Q 1't|%@g%^KLcwTio,v)B#X +Fn]ۿp7UEkr,?P=.eG\kg~`K_ߟ%/,'ROXQSŴ׷ztO!a"&vT"Vu 9Z#;A)s=gd@X* {gcGfHHX5!xG-քa!SIod%ǥDԓj"W8EiR9Da"=bZ/mC@^B8]7}UghO!eH3e7.89iYpdt%y壆q&oVzW1=QcOqgfUgBcѤ2!] QwGxm>&DvJ3c`n8Hjt3@7P?4ޫ kUOC5kRg&"=VӳW]LDJcqf7&l=S׀ո}C{JjJGjμ@D NT"~ aX܎ Hø.k), %m%'L-]m$t9yŜkݝw5, H9]Pv/+x)rl'j-c!ݙ(2NG-z8E8WZj:> #ƄRv%6Lo3cBF{fn7C4IKGحj #Y2 sxRO^׊ow 2Yq8˴:VЩEL'2e(J럧6\z/ 7ko~]S|DӭT>;;/m}=xBe !l<lߗxƚ\/*( ^:fk&0}]cP <ŏH&o7K%_5|O#;0, P3VaxHB*y{ ]Lz\ĂaM1yªjl.g{{ r+Wu@Vu b ֤wn\yX׮Oqn:FVs8)4“:lFZ6%# jKнB%+k*@$xP?0@F1x䥲!XUxJJ!YZW.mBpxݕ46J3 q 3xn?huZ׸E\=3j(Q 3Ih *gpkÕx9m~8NG UzGsGhB/ <P=,I|#oC4 =coYf-[Sd)mP@XwluhQjnZB6{IspKKO(x0h'gY 􄉓M'u rҲQجili6e%\CA⏟:`5iQʥS(G(7^Vj}-r. KX~(g{scw^i_6wq$"ӑ'ðSNKR.wM0,kPȟMHj m $??LRZg  āsGFk;gar@-jtvH\,rC` abSPnd^B`@_r$D[=d>iqT VYI8|e8"ϼcE ;ګ#\1x˾Vn"ԅwFxWCVUL-%#J ?cS*ˎSt <^-fO:,A[.,yx?Lz/?%Gr,lkdlw_P8.'C'ϭ!y#ǎ\.NbUҙY?U,l[vfw`XQxEKouL%Сt6(Mwct--#mrvkO':~X']3c5itII m7wƚm*Fe-{6b΋lWSeZ:.r ^BDBoF'i2Rgz+:ɵmu!4h+YozhpyPoӣթoT$g>0Yē-@I"oGyx-O$!`+ߡ`-rwIt" dK{TzH}2kw\ !U.#2'XmKD^֞<J7uɸ Ac 96b$v$M &ϛ!g1,Rp-7 _ EmK0BzoD)tpB9 ܩ׸ ЩdnQTF3= >"VI{3Gk̾v譎./Kc>71c]Z7 7Mhͮ kIoSeӟePH+!)#ڡbQ7 NC+|rK_Lc\Uà F"#d!:A_]0ݹ*, j"`IlNj?;Ka]fIO̻ %dQϵfNDxGprpOݹcU̠'d穡D;o %NڔW|JղNܟtf[xf>h|Ǥ%W!$3po4MA0B-÷īFPw&YE5Y.S11)2N\e]\W՞=tU7@Kr*va! #)p%tE^;e ^;B^iSԺ' ^B`[ƅVE`׹$6; fP6oA)!j*kn}k/J? F@{Ɍir`KH59B"G/@Í@)&XsLN2CzKj:e^;ξB!~r֣!nhƐ!Ika'W\\?u+ֲ64c$=*;7/0@ϲ/^/C FO]YkEu7Q9D 4*R݆T_y+%!K_>| AƶW "j8WFbMGKeCĽ%Uv2g  K"h{y߽iƽ3á|@#{qF-d!h7@PAR 2.0MainQbx۳,<ܞPAR2PKTL@p~9Hq-~xqF-d!h7@PAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2395616 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.vol3+1.par20000644000000000000000000014413414625637207024272 0ustar00runnerstaffPAR2PKT04dƏXKqF-d!h7@PAR 2.0RecvSlic 1hC֯ỳ f>hǘ7Mi>.%͝/Uk؇`c]R%3Nh A )r1nVyHMq0_l\c 81KXB*T.ZJ ?z5 r-0"á2Cw@m+{nsT=h>ka lyd1X^Qxv'{IDw*ͣ@F nڔtņG[J%֘gQD@4nS oUsCBwEܙMiy;N] J\4kˢdF-9 o g[EDeXJ-S?=guky5Bп^s{Dݴ\Mx^ג"D4Gƣc*9|//49fDsݰb\ԁ?T$ ?\1[9W6Вr auv|*)dC= 0\:.Fi}ۑ  N<!}Vo*ihjטM~jG֊AФ (k;$XFB,ר,)JTY1Gul̺Sm+7<0f hu a98/,8ˬrkZ/?5^B{@dZB]p)* .){Q`)")d'Ukƒ.D`[lTa[:H.zS׉MŞSn4wͪBeA<1ӴMJ^CQ)7 gmWh=l9uT7_Br)ז?G__o?xPKRSkk@@<~:iI~keЉ5& e˰$-*!@p\4R[ɋIX* "x{FNJd,K ؿvE'AV*hKS٢u)spN SdR~/{} -Bjz_4oa, h{klXn9D?TMZ#E"=1`|rCB>?[^+ H0|n\pPI] q=_!kKծ5S.7V~Q3- (sM#f1 42,~iqELg7=,yyDo`h =|9ECPTQ:9t ?Ke5?6vR*ql*}Bt2w4R(r3?=gA:I=0 $eE 60 boWagS{9cAK,KP9ak RVl)!!*#Rukبc?OULm 栜Ư v™bS2jCe0f/0B[e[pLx7VTv d \jkD8Fp+^l-2|_/:-M/f$R+q."1 j~Q(4ֆ~4*sdi9O;4?4fD/~c ض Tc<^DĜ:\iwP~ȳ48^r(~(ר%g*8x`P".FsY#"{nXsb+ .OßX?12Z$s,,bZ$'W-~/Qsgm 399(\"^i,SAR7zK=ilmmwE j#/8 LR o̯t蘯س1ׅ6z{p,IW9񉸬?IXǪƾ%ȊaTܳ˽8'`?BJ Uv C,RY$\Q[F<3Ꮬʪ|]ޭw{j0BP|OJIA2r 9pYMPZ\lMocadFg9o<%0ϋ/yT>3>1{KU[墡Z'g86V2K.{K8̞|p<%*Q 3C˥1D>7Eѥ%K)w%%$5SW-?]c7:MhT#ACyI#ɇwUxbŎ%Bp 7>j@ސ߸t8 \9g˅ +xqػpkWVNu&NMm{jc&Ђԟvdf,|/% ~qv5Kc߅[ %dʞ{ 3 ffGtu;|fȩ6S-k$|b{ 7mc^3}Z+0Tpm- !\I}5XVxU!@!0n۶6h@z4c3 ͛-,CT=5Ck$yKT¦T:J1M)mX{~db?)-0ȔAɾ)QOnRV _I•mɈw\긕{:;k@RvTo}VC@ 7+jv'u UlԔ`^.1IP *_6{RN,Nums6mh)xL[MyDLTͪ4h!-k7Oy:"p K,3 3lDe]dxb]A!e`۠װI Ysh Lߓ\Ǐ"_ryշH_? n ~!N~o:Oc>xTl0(gBe-#qJv=͇ĭb<8%"WKenݰ#]]r[w`FH!xY{_uv]?Egc8/hl(wDR"{c:djढ़-;&v`r7Ij_$9"@ͰvZ a온B"k7T3?Qy77CH!>羑L-;QmO_y%?̗DG|"䩑H}®&o$_&Q&<] /q X|Iw!s]V#c#~䜝1i\*]ܡ2k0 `TKm'3s;N sKҤvi3j--p]΁Q #Z#: a]у2S+]=# 3ȧD$YcO*A.N{\i\T?; qBm<Ƀ950E޾Q\gs|u>q-1وQ=MUrD%7cuD4! x}uo3(K2`\HПcg܏!ACq:\d$"qJO)^~RJvqb K#zw( _˜qc5Uxmm!0l7l;gagG_ҍC4}]2,v}BX}އQQYHp1>O0i;2omD/nQ~8u{’Hk_30lw\ZNAM>,LߖMk;F@LO7ߊF$W='=ϧNOvp.*2iיIakR`9zY5Vi=7={Cnއ1v,WL ]VF*v! LKI,)%6E9tZ{qGw\p=sQ%+9|&Tjy^ͯǾjbO)ƨF{$ -,.!6s A#Wjn# ʳboc#f 2}.?>p[)kO<3yۄΑJ=J@ q/i($szTr"q ۓ |*֝gD9֚wEќ\gshDR['z`퍊OA:8ri?ID»g*pw1 s~|~^?c TArp>4_=p3ZN3:P~=¹,uCئg Yjqs~Q+3緺|e{>aŠ(,_ sxWJz\<H-|ZLLXiFuzN5YX`vkChMy *!Χ7}D(&CˎWEA| asKx؝\JA{Z3[BV 9Sז9؎wL?3 nb|A|wQƜJ5uv=Vÿƙֺ"\ZdT-`Fu3:rxԎ`K1}`+W d,aH0u:X'NÅǞcB*t+vҚQUIU5Tr!d` GVsE2AR\A:4$Y'T>Zx=sG=]ʀkk?@hK^oUnSuߨM՛'&?D!] \-2zrBK7N;֕^0z)0l̙~,PQ$D Fs?e"Ĕ ϡz 7Ȕ{@^ (KMc.mܕfgwۧ{.;b\We|.ǣHA6!KuKH>&'^,YE '<\[/hB żv1#U>TWN 1A͒|)>*lMq%It؆:SH<"jݯŤݡlm@eT*ɶDūVLhJyY BEYh2p=hNheDE[(WUaf8΃V*ux#`lcGN`hgxD~hyRAtv-Hx*VTa FrDdwJP$[́hG?m$&ܦz YZL;꘽?T| it\FLn|?W<ކIZu6-^/σ`M椭tڧ~'Ń7Ld,9 L.tXSp—~ӸEN8QLNݣ6S/$ER?5#q; ;ffR$9'Djsc2OΘ j=yd3ci`&s&)zV2'-E&I\,qGs@^b :ӥ2,)=HƓ7NC-=c`缒#x+q?R!pzNtXp{ɤ<"cH\r1DI}ObP| O4핃S vdJTpَ=9VF>!]hs-G;yeNʪEg1ӜGBR|Rυ[ۙaRGKaό]|`ӡd%ASL9ݞkT} >?qP]ᆽI؇#x= {zg(ToNƬL<>6f >SF*`~*c Mc_즳|>ƙd 6{'c J&h6tsTh5R?~UyhN0 g5Bs&OJL]BYTm&w:XxFVru|]o Y0G %u'aE ۙ̍T4>orAhNKЕ30,'HQ_jF1 7J)&IQEras5>ԉ.P3*^HSv&6=q_~z;8d% 7POt a"aC))-f8qB (9-xf* =j">2ڧ$yT;`u BB@;]pI(_RANVXTtKW* 9   Qt(%@I~vVXJo6_:vaHg%bP>LJ-Ε9*/_=by?]f$b ,v_UxN劗>h\ # "R| WG3 0Ow e9.c =WHF~y|QS * g,- վ{s;@ϊM֗G[Die:)GӍ@}F3Mx0(sf%e;Pe]BwˁQ ϔ<^>D|V1_f* 9+)^br/}E6DİV"r=>q$(mұzmp`WG)}c|k(ٴxq*xzrdaۦ@D}vJgC.E t,^S$NJcxgy93U=}%c58;r| R?HɯZ!rhk-`* Mx@G্Vjf} E5@%9$O*Q@v2Vs ۬6%o?"t [ "1&q9E>/V3n>\倰[} {#tU;v+K] 3pY TѼXwYsI݋sn=͸ iRƓK. 3$9 ."%lv|4eOnm<hrL!vinw(IJIMJcK})]8 ŅVƥ0|fLO ,u9M`K4ޮ)־(X  ʆYU->4MϏɅ1D(#{3pf'lTR66= ljB{k58= &YHv۱ U* B \DW1`ΥbnZ鏠&!̒`!s;ݰ]?ɘ nk8[*n JC-ȋ뗾s_ 0A&2(!K­i9m-.G&S; d"J9:F-%}`49;n˵YԤc :3_0c;ʴLEj$y+řt3dx$ǡkh94QNܥ#C)~5Ģty~䳩kWu{W^OmCxB1 b'< 2#U^gKJTvК]q+aT͖LgSlG?Mܜ)$I2A߫3'?o rA g΀fjѥ֍G<5۪hvyjtNuá߶XӇ*YN-mzs^o-C]Jhs4թrmd=FGN`8sJsw7s{ \O"v3wbVr"EE[:ݫN o_S_^T!,L~(>ܼ1cM>2aĀqzA7 4+xџ*GF8qgQWN!7ҭGl c\a-"GGV46]1~mgѩcR.t%Qw\$ ө~/2QkYZAFu[Ï]^%UJijݿqz# )|]Oj9T u-͌=Pm=sJ=6o.&/b'W0 -_YJ?FZ_) 5X2r8f@"y 1R9=o=ao&SdFP{\x>=qXH</,14_-9Z^k宇Oڅ'FIT< R]Y?Df٧'/;J%1hfv??}!='v\ntٍ9=w6f7+JCx@qGkPpGfx`I fʥy3'=Е͜O2V=Xs)v8wzRC22z@ 7p'0f`U#5c%lݷRb ۆ|ԧ谰TSOe3jO3|,܄o$hR܀;AӬAQq.It6C&`P ̖XEjUQ;b8w~׏֫l/naF5uqbu疾ҜgvMC9ϻ31]e ^j^|XIKxM=A4H뻱4ȈO[2Oj t5nQ:H5jU~bX-]j3NNKڪf#iN'0C]!ǤId(gɣn=F}@am*KgvsC"WTgbXԗ|^6'[6E}>W`QӃ yw2*,9h`*gdQ! UPE>Ce}'OU>q 60S=xgD TjL7H҃Z{Œ a^C)>1dw~Ɇ{f>әn _ MA׮W 5xXp.+&$__7Ԛo#tskSE:P^*ɨfQw\"B𣪧͵H21 *_8 A9 ._w;3xGm+ZY3ޚ͗'cd,`iR't,x:dq V>a~S煖LF\F!%@Z`% %NV|tqMk3?0(c[}x;|)YfVpbqH@ k5mTy yX&=0ۜ=b f/6Vrlİ?M3 dc方hF*>[(&v !U`fņɈ8vj bǔ'tS[kWˆ|a1gEõ'J=hK{%)]rG2A*DFGsKIJ̌|^.hKT"+畛\7)t1vBRBH\<-4XY$6ⰉuJ[ИG$//~m>lؗC(X 9I0肟fUe.6fjmءq؟;m Dz}\WKh޸Hlʍ[y"%9j0oϓqCt''ExG>ǰ/z~o80v(4ۙ:[ 0ŔM^ j;d3I9$GN\^犈uf-EY^%Tq զ+H c&ťy/S!dѩe4vX;a|)@cCLL_"K{`5:VppR)?jYo*:k+w>?ZG^WfQw*(Șt7| ⽆d?sv"vD$Tљ̳7f2 n/5QJCP :~1>~y)xP#BYohBc06llsW=K'Q=y_sݯq'-uF)`㌯DzHʆ dEb&_}Å皒<|a@SdZ2̖3VTERϸ:KT~Auu_ye߰]@*C~9AE#esC|#w.'uNٴ3bU52ͩV&P6פӍ8ktQ!peQ;ʼAݲ*>K׻,2d4`RX5/EPN&ihȭ#d5@"qQ状ӞKO~JIۋB$pY _ڱ};c5<::TbUq1}D]sY›[V32b!ԃ 7TdCPHY>WLla,ͧD&x.GLdkOisၓ=s:+{?ڷ!X{93!:#.: [i0ſaӯ߆II;, V]O2yŪ$[S!ϰsH ZͯمrX+.{DW ^cI?e7!Yu)H[e hk7#wƂR5&C AB).b_jDPf|NCdInl%˭“$ñ!{ˀPX-[ŜZp΋wY.LZEML^U_w?|V+Vda˸Ñy6o_έw'쌦PK¯t:leq Ua1=a^#hH6KfdrT67Ꝺ:4+&Ejbdgr_VKhĜ6޷]{]Eh%sJl 9hqrX`cďZ0N;8wU;^'GQ7 (m.\TdP3WBGl_.4w"FQe\# .(#Ϧұˋh% %32%6ih ~Nmʗ?FkD_ _<cD.UN'qkdf"fkr T]R\|>7Q},9Nd#yI0fĎ:6{v2䐺FP#v:VhҧZ]nvqe2EA(!s'yd ܧlu zTvMs[ahކ.`+_#){V}Zc7^? [&T)C)_$ / ul`|EIIsh(`#aT;G<@3:!T]ֶqZ%ClWߨחPR2%Rq>Xf.-&ac~茙֧;7% gʼn)R 9#Ub"'0 I6Y Mg`xRYS'=&^|)\{7)nn~4_dJq֔SdKm(*P|m <$ k>a9.ʎ~߶?MmC} ”<ժa5e0ّPQa1L * !ڿ"H7*N]//amB\_1׳$mG-ReTY~yi0T%01wPmM0D1,z6:[ hCF):%>.ˌX jN)iKi<9Ĝ t 3/'S]3;Wx"I kjJA61B΍>NZ&敒¨g}IYd^VN.`,VcNӝs&;]m,GCkA?\d|GR$(5MSZsH쀊2HbY]:lD=eI^sQ0̪QC߸-+G$ &G'۶b-^ ;Qg읲U~0-3çbys.';k$G\aunx3\ V 8 f<1U8nW#"ʒP3VRFLu&}+GjZâf TXH' gG/z~%%#}!җ0 lk tXt %[ SBa.H$ǒFbDDh*{*YCg)/FX z9ƿW(T$;%W"Jhư3Cq*i:t*`eR@#0_3ϓFq".Ŝ]OwK6TաU3?[ʌ?ыa HF &?wKP}U1 ?1a44qlcbiS k-@|~hEK>-Z뼍4* u EH@p,ZXW A({ZrQ Y-}}2-V6DF^h9̀9#nEBV{1 )2ԟH:\4`˰4gǗ@#kُCDFe4`CxObv`6P5=&ټ=D@!_ Pqc59SZ\hŴ%H܅%DNHF)6ɓ[mUb]`#Sԏr㵤h@;LɧwijS27,f^!K}V_P>Tj,.U{}a812N¸+zG.pWۏh5g^PR8b8>*k~ҔH];?w`Ή$$ z\PU.xr'lFBάC۩MI U;J<%Z~\OShݓ';VE/Ӿ?c(TY N]VlCc5t/iɿ^dZ5uA8H)tˋ<9LgD4o/y$jp96CtH;&f,в6A92FzQPGv"/@B$G]r? z~ϣՓ5&.ҐLHқ)7"OÌV.,~>De\ӝ@gP a8ZvV"ٞk .1D]Oa gÑ"=M: <÷~5tKk]#+7tyyy+,")MB=8#/G I+둠ZGf?-T,6P_Wn^I`,ޫL̴#fVUߧ5uI#Q@٥p)2u AcJ|Zil||U.8뢎x72B#μ\c1 9pq28!E 5Sey6t@E"{R}\(\} !# O0t?#csOexUMCS,KNj<_ү.RȊ`5ւޚV6i%aD nj7KQ퓠4ATMU4pa2:4~e֥_1_Z.t(%A2G껝/ O+ A5ς`Ɗwچ@C"Y;FƩ?t>OAI{w|l~{x'd;7§^Շ'6u@.}G.2 #]2T f/?8n| a-]ӓ?!\i #QW ϩd>YM+9W$G+Z< D'Eלd'ck#7oK+WTD7B),Xȃ BX<׿Ӯ֒*AZ7"~hy~8Zsj~f$=ÓeUJ\yOd Q}KArk15`Hv:E]E[Ry(Г0q2Yꇯm$f1m֥`sBV=A}Pxn4#'>dR6TM1HoZ<+-Q Ux$\ MiDZà\sɋp:꨽:AB"aP~c'cp[m'walfVi@xOT=si(%u?M+{HIr8<1VQˑF+<ţK^Fg#d f7%^lIMsP㋟Eqf tj DVg">u?hS7(IA"֕]NqGu!]fr?َߗA_=U߷tr7@x״wɞ,R8 k ӚĐ?ޓC Gy0>N]Wύ4+]4abZ1y˛<ݔ.cN+>snViuRgH&Өo94K6S'o`O/[y'gD z|9!F#Ԩ[ %NdctF]L\vB DEmrf<#8GBs=+(d29?4qL;Y 65/"Q*QYqH2c|n(jps e]\bᬢOrT|HKNe'ZK1F2٣L BR8R($vPO;4ISs<XS0ײ H=?NJ"c2^&+vEmz>a2Dw~w1u<*10E3|[_#^?Ӫ617Y1LJt4H=J%?tVY˭ʱ5y|r1@dUy$̨5agMSMٮrz؜\d~6]'UW-\DK9c hHnV%&4Wx:4X`z2k%ۈZ*KӜ+\Sh=# lY#iku`"F)D)G]<@ Ѝ$cp?<~]̑6ѷ2;ɪW`pL&.&iJh;*iX[F9@f}V1 .\%QLFxnGE T|͑ uG//j8p䏣k;&-dLa>a4xBQ&`_ uP{SkχĐ"2vw؏Kث9 !&&dFJlqD?_u* !6+4#)ab EdtC-nRHrH΂Sx|lAM^?6au]&T.5 F] = |.ySt_һqNHTgi\N)Y&@fWx,}s-vLr}'* E.a{WRY'5Y {ּIHX7+8 ٩r~ "ΰ$mH},1{crY Ozu4F4ңݎ+1"f eqdʞQTt:Uybç::9XCW+00(_^io&SJHCZx.c1'e g\ K`T@?bV6/XW $n:2lGqr:iZes&LoI}0(pm1u!Δ+&D0:J :3}'oŚÍJI@&0u۵At晫 * [GLۇ2n* CʏHbp9@(^-:"$81V<|hĔD'k\mdpGTKgŪAyC%Olw9T3%x(/>P[s9. RS܅2eVv@S/bX)|+4Jޒ+ĠЅZ7H2+~x6>mYE kć"T/Þ]m%ai MeChHRhGXF^D{ \w+#4WC }6(e6z0L#zsr?]qr~D2UkMJy14Ӊbs5C?ULcTI(\szeYTX٨ xLAx8؆U8㖏4*Xh0wȘt jAA fׯ<6vZ}u *ܰnѪ*VBWڈ6q퓛Rx\N[p}l)FӜ▔;n~cD/<+1. qhg}-'UW*Ibyf7[śyhcH=ګ ٰN$"lef]@8 x YKKe lߩ[D[q,w權D|et Z fA(P]+"S:'])NIP-,+#yM]I:;[u42ux<m&|) E [ua­B7WPy I?=A̹诅R:Yڞ h(D0z;O k"U3[hw5,ۍHz*Jz"ԯr^_zK:.ί-ᴚKLxJTVX7JcRāVx I5B#r sE~n;Mؿ"ԕ<* &nQAUiԒ&oʁ#\_!T8=\ǹO&99ؾE_*RB(dvB@7_ix20벽!GH4dlju`peӛ>nCH}rX0WhɄWK#pwIx!<*T/4n 8hrOQuY "N unuRCc@p=i{:2rgaK\ȦҔXy>h\gVxj}cVjdq,T g>AJ0k/gTt_9b7ܿ^/KV{Κ]I^4܃ {phȖ Pi Gƹ #]#㈈9$?mi_)C/[t;6Sg\6%|H=٧KPC!DL`sIJɘ0{đ(m7>łK }b*O3pl |, ={2G_ЁO,h6>7 db NTGɼRf5[ӱ Beouiqp[7W-& d8qN-HFzBhD^(,n?`n6+oMDsVSR*y`?񕲐~'vXj=m≊w.`6K}Tt=OXTjaçLB}pJs*`Y!9oF }ٛh'% "[n$Z|*\Y^hOs/Xig)Gd^ p0F*TI?%[!Be{n<~[`3K:H_svO p8c2|b"(gpOjdS/U)V'(*Pax"}rBD6: uX/'تͬ3INL6O1{, ikx}/\v ~S}mQcW.xyhX{ .Q'EOQ!KI_Ah91!}xE?sf, mE0?[;?}kc F}"9kԕbp=Z7߀c4y[vrPN\ 6<x0Rch{#)E݅p|@l8o>u*3̒FG^!fh'Eva`pܪ"[TD# #u*bO+l\dz8e!LML_{WՃRNor0Od3]Ɨ2BGy"5d]]a6f+6<ެTK ͇&07hl;h ձ_=*v@ j-3`v轋5~V]<a(I c)V wIĖ!=@,#EaɠypvBLl ){ ^y:1^BXsI gE'PsQF>Pg?~3ԷSs?6LF6sx-1q!2<xRH2*.۷v $)ԈŃAq2]Լ))V_<7 TeiSIE0BvcO1@98D;U$WR5Lm+amz0ѭ+X}s]W5.BA99u9 --rC|.;*n` ݲ+h%o-uݴ udD֞4T'F*5ܯKɦX2K̶Qn6O[V푦ҲnbfN'GBLG 䰭?C$1z1UpoUK2cg#mr0ʕUԕ)AV}ø!#}g1#o2H-`t'eUD~D(< "q$ ` 3Lu-$)/;k`%0/}Sd͗%=NdsX9Y~X1W>PUg3-+Gv*C'~zhCaS`ѬcFgcRi@2$ZTɛ1^\ٞNx2CHQqJD낸UZ&Kܙm;V_sW*5xjIP!ĻᾓGjG,|#Hb7u-r-US pQ7m^4{Z+ XhB3ds*JEϢ sgDceY"8 ұSϕҐnDG?/)^+Ղ/R1i]/G ULu#FQR#:w*5_/.1_cJ{Xv=s^@~2bUSIc2(jCX!_aU3riPY g #$Aߚ\8u`Ԟkۆu :χn;$CC7*~C)]?C~ըtQYw@3i%gCaBV@5Y?^C#eU鴦Ľx7ㆧȮ;8<n(7 BJpI>{JϙJ+c8'2wE[<kz$V~M+ҽLH=X9P8qp,IФNd}Hl%[=PWؼ|SZ= z}.T`ww=5$'HIB)wu ̆%qHLbN#*IC.솲 LsWd3w_r`ǑZNWK;Ya>V˚ŀ x$c㡥q^XZ ĻpSҘY} T G݂ r2вORfYCq $4%'QhOY+wYJK$,adRS ZPM5ku>efA'#]%`RCR:$KDN\0(J?)zN4 VA=e6„Rsp.FĘ@܎Kr_px{NoR5a6˸ru6Y!a~~hА9BCjZY !Pu;+ޜK*{'vIyu]!gmiKwH6Ph;̓Ƴ6$JN-B!nl]כ yYvl&Q9E7eP!2uݍ̊3ɮMA&0]ʈ“~*2W\6`ߛKc10O@Pkװk'{P#0LUQ"Kt:J>D>_ E1xՓH4_lG‚.UK݁U-&\I(Yݤzj;pb1 gGJ֩e#1m'p:Z1;gS[ cP <iH^ S iH6+Y RI7AD<@5 &!pB: ;f6,;Lד=WD/{T~%;܉un)ԾͲ2֖(t3TIS~b8IrMe;Z.cIJQǬ`]rxшp__1Fzg9j>9Ás6:$gΝ+IG0Q$2y dt᜽;&WH=yEv'5J8r\,vZDTeΒJ.< T]P/M͗*ښi]Hg{5 mnÐ5hQ~fi LDHFPc->[ZEEi< E B`0A`~`n.}A/(CԶCtBǣܳR=,To7ӵ񙎴S%ǽ>|kRkuƾ]NbE]"vuZjA&^yw "[ Ê后ղu@30D~E)8'#~c3kŚBhM<!0F>^U"VT_\ ;7h2×mt;A&D&r4|1kjf`;nyȷ% #n9N ZyƄ5Ⱥk3*;AUlœ~Cv+s7KKe`~%6 z+?4.T'N^~cɺngj hŞid"kNU:_R51B}^- n uT\%X}C vRs6ݹdq-󳍄JpBWƅ#gy2"|oh4e,L˫t# ^1&=:?  Ƹ%oM$8'lf(vʼnU~@c z=%"PREkjY΢cA0#&( ;^G8Hh ]#S ih 8zA 8 Z}*7hA|Ŗ]oU,򠎩ݫYdRa[ 8qőrZSX쬚O=:6;&D2ƪ$VBXiۙfcee.CU9(tKNaJF< BdE (q/DI@"h%K$9 QHS[/,k#D }qg(Z/@Ll 3 drG1: oz9Nnķid,m?1Yft'YQZRrq:v(.ts7PI'kISA":ׇnӋ1'%j`uN DkGmWE}Ӕļ2ț.K0Cܙ༡I<ދgR@ n1QWFlNQ+ݪІFy{h5h?9NF8`mA5a\i[$ծtn&<(ɺ̻0 =V6_>MCɳ)"ԍkķMGK=6Xk $ahXݓ*zp"4v ̐>k- KmBo/ uنk~?3mkп+4Eӕ/5<t8h=ggԩh046jZ9.^ / Ycβ&< y8FuuT ?D>}KD8pRN: ??,Z x \Y4keގ[ ZP*f6[59 :[g2v5v/ IьA{ FY 6dAI G$!\qrjʿQ"l2fE_۴L] Mv$5\؟Dbb@8L"ܟ \a6gǁ,c΋si;ڷ mɈ*JO[G<,{ϫ)٥L '! ieٝ杸>v+tZJ@ѝlz, }1L`tu7R:i#ggoU0?hմW3y]71P\籅=NkαU36"V#] cU?7%]Zcum$t pé4v7t^HoC}#P|.g pxWϱӒҨ2*շthKeQwn QxKwH0x {#QzR/LM%V$`sE-i]g~?L.#'^Fr*blGZQ7F>6*z(nԗ3.M3Nό.F+g^;}B?(8yej3r1߾?}> 7ն4>1o9+7UO4E ]UbO,C{oi$\>Dd" L}47]Ր Q PREo}s8ISy[=z@5xT|gx~p"~J %Kjāb3t4k|lpV(h`v&7LJ ݵ-%\7IG aՒⅣ$uWQi ;\p2Ǜ _24`CM4KkRk1' hO ,c20Lޛ@ע]UǞ@[8Lx1&lTlS7Of$iq 5; Q'/g5Mj~R7vFj( be.BNq]km^w$SUE7Jِooi8z/kAl'k [YybσVm lc"L ݬPV"#P񈲜|==~ ^.}#lel RJ)|a駛KcZ4\Pb9YߗHq;#xIF_oЅ(<+HXZp,לS{\#uN6.f(@s|R]Rd\9JB*y@a f"+5,u?u=vjBB*]%%hۄ_t n4$@aڅmCB׮|$Fr4 @gj'pGb,F,Bc^-H.COD}ѵP Ȧ] &;h͸dW>ztTi].Չ8t*IA27齿=kR\j!F16|H̸͆~=7ۣ>13 ozf3/$H85AcN;j=ks?8\|]mI9'Ao[0з T-5P[w" BKA`SQ<'ᶩT&WIVCo FSZV[Ͷi~\ s<Fu*==4Zà)clTa儨qSAɋ,SML7'wuRL'%.AGri];Z3> ߍXNrQ>ujs7L%.Ǚ_x$I21Niu\S ғslܛࢲ-M8sQ(A H`63*UK~-oT>rBeus$OKYX氯 r><$Ve{@&?9C@oKZֵS4;@-#&Ӟ"WWEmFN` jңyoTvr.60Fmqw4%aZ8#w1JdP̈Ըftue8 U^s"Qa~XGB*N[5϶iVXf3N.RM,Zdv AHZTPyq6?DK"&'ed ⤺ntE'wC #&=x\ zh42XG=,p&\3*S98 9I4oUG=ƒxtP!X$@mj20w ;ۘ'wg!Ř(o⽷[>^2rM? a-t +[+?!BzW \e{j[y#&l*p ʾ~~zgץ͕&avF7J:N޼DzT?jhnP1Swf/OUn+u14;-~%3-jS<&Yw08C$N-i,|EJ/-H[b}-{dP %Ll&УptGL#b=Áb)f&/rI˕/\_qS,'Qiq+0ʞ y xߢk,a uUmҮWù]a@IYv טź,Qu++r2G:ڕgNYKAE迶Aofpio}= ?Ѕ _{QKPQk A%a ܀⻫iK0aKF1ҽKŤgt}׋F7- *nL`G sxGT(+ BH<,[})%hqYS/) Gz㣺@%Us,qmd&TUD:T]'[Ҿ'b=* w`Nr tS.r #qƓƳ~GZ*o9pa" 1,J=27WKdzQoT455XaZ7E| hLE,5WruQ)G(Aq=bܹÎݙTDE/(!q%WBxӯ̀e_@GVFI)`B-N}-wG%EB ,bF 6嫻[j* lγI)؃]dh 78 5W :rnO / }D7.bqR8Eu `.H5=8kz^k'ˎOGD@ zz"~I#lXO^d5v k%*mT^Ջx 5Oe柧=}×^sg.niQ&sf _ޥz]O@*/!y yARWȉwʐ)xm}`V*(].7dpδ2#N)F( c]Z^sxO.R?ĝ;+$Yk"> =%eiƗ"۔&32fKƟjU #F{NUA*sJ O:,& ٻ/8>!9]ry?GX -{@O]\W}W7ݎ^:GAʳF- о ]x\6CbJ .7F%.W,tqGv0Y^ɫD^z2p9/&$\uJZ kJn }hH]TP^;eQME6Q-F9;0*6A,ȏA5 CP5N Q>uԣ^1ѫ&$-ɧ<&eQ.;̉2_V';KݡY #5㥉$dMho ZW @Xj g! GLRۛsL8Ah5JPkKWEoI?C :zػ "/q1+tړ^G*+Ė1+-";]CGlɼVeϔz>y"Z$gey J&+'ano?^ 9BL!#+qw~MZ{XE:qn=%3#*Er|VmHEݖm-0b c?Pax9h-RƳ@`} EoU[DZF2muOuF[AȐ z+U ZcyR;CgUr}h,15{-UzNw{:IulO2ɐ똞E*r\W1@;.I^=KЀX|^g9xt7^Y[0#wuNCPh|),|H΢4Si?رmu:r=*^@ + -8,u2p^½!Χ!#l~. _֣*idk]s4 }U0-賵odKUH@ דԮquE kCEa2_+ÞL}NWQ!2'>qpS|f*Lٮ״w.' E G8N=6nFtU?oc|@ $mεТKoSJNvIMl} 6=38ہGmO!UEc|r9bϮIja qBEYZ4 (p.[^U(KlQKߔJ6c@lފOW{Qos}׊~AP&uT{@ Ʈ (g &O~2 u(lsVP=e^?J`?|9e,UL.!ֵˤa+ P݊bm*ZIARD(V89R,``l8;T ɺPKYQ933z 4c=a1:4>IjܸYJpI5AcN|9U[QAiW9[v$X0eYⓆ^U."vEyQ2r}^Nyy-y(J-wx jv 2XuhzvDSFt> vh812Kwϐ7Y'rjצ֑Zrp Rﴧ[DT Sч 0 y!YdFLТ@ɚK߻:iaN"TRJ@S *w XV gTY5rA0چV[f "F0\~0OqXƞ'[ =^0-M{Sp9>rʄU"!Kd. fބ1;+lϡ5I=T@5MlhלA8'ΟP % !xuPhA&X3pX//FՇ r]Y2,'xdVv!LXv=ͪzBϕ)&;N7U8l!ak%SފИp #x(($G{m[ qWP2LB'"lQ,Xg`ezWC;: {x+cA2kzu6)1ƖKc[Bn ZzOޟQOi- VMjΧ_e"9*^EAڱM:?ZR3-$)ܰ x钢AGA՜" I>]ضf8jOcO]id{ǛZNGin;?i2Rȕ0G):bq6L1"WI:10pd> mK_mR(rNq4{_ 8`38rQ_xeuvNȹ] `3~Ζg=rLqI&Iɸ(r}Y)(eWKMRѯ"FU S&lZ˯NɯU ~Ɓ=e|ejE{SlnfKӬzV|=U %`;qn}W~_@>PW[`tMCe(o L<]|~XPDum N@̬r!xJ-dmbm}-C>&\mrJ:ƃ-pMwj*";7o JݐޙZ"K[n|̢-P YFz3DN/bOudXХ WT5l ?cU'P&Бr '[ ϵd8}XE42cJV.>"REhd"Sxvإԋt<pF]zj[SFDP&NDe7{噎Crs4Lf! 1PK8rP xƳn쓲3:vT2.ۯ> I y(1#.uhDU%)12!Ұ3 @+I$s6?ZEiSYթRSڏs;}cz=bs_&nG^=6'ENMr?wO;/6.O^hJtd]V3iP/qB%eoƗ>D63RTE&FF8KZ\LT<̰lVcJ)}<#vtuPݠ (q 9 &sb7_\ra.#+H P,{(~;=*m*Bwzx<;T<$B̭1B)+ǣģ-E +FZ} M*]v{Fbē/߀⡹P[S[?=7cل"#gIݎѫV'3_Et5yѮ{8/..v/1n[&alPg>(qɤ5.]i'1bgE(tꞋ8oV=Wlez,BzhY2>z`D5#6~Tm#睱"@y'=n2i㜌gO?Wƣ,jx/~8#n&(4tm47S y=O#\W._HwpE_5ea 7q„ù0If0t»P9x9/~OA6٧t=ys7YYωE>ˊVAiM#x1)b־pg'Z6!wXuTs5o J Oˆ2D`mwiVPF#,@Aƍ HWn-GC{IFQ^/74%U /t/7h%pb&S3;,M6;L9|V=<0C[U2I^&7|/'%'e*>U1p1)P`0kIOB΢hm;12_#dm j(UKۛDZB #_.mf+;q-do=F &# N]8><>YHՔ+ݽ퇢\j>tbk,|:0Xy  @ggR1KDl)[(͡CxO[4NIVڃ 30h]gsLoP =Zq9Lj%|ý&pR=S-d&e} e(TT"-s x)EYg[Ȗ31HM,ɤ_w|:a]^ cOAjwG":pWuٟop'HUlVB/(jA{NId-4hёA{av52?0՘z`Sb+CڽbEyfRX~mtuL좹8 pcegƇ|}1#0Bkf)*rsĆؔ/yG7,rGpՌ2nJXK9^2Sb/"hkt{m/+bbqԚP.+~=epdYQas?3.4_8!I+lW%GڽVImd.= QM%B< 0&?q!X0}ejjҦXnܼlQ{8 e2gWHt,^h?BnɜXɀp$-KMߔE^1|Dž%ObR"|6܆$B_\fCx;`ϊU6,,à$aJz @ls;y )o?J+JL_:"rCU W ?p6NR=XGXt w"5; ;}d[dC;f{\[ծ 1751R#OiuL?A?\ : =o('uQk%pF;AE<GS|1%/.4#fU6*Ʌ#%*-lhhvKͳ윈jUkX+BnAU(z|anҮkF#ZC*.#;м?D(c7C[t8lKa&k$ ?9ꊔ=p~o.?aվaKh&,M;~“Tűޑ("—~Ѷ|P}\.)1(;ʂ@^A:}Sfϲ|J1-򏨹#;]6HHa8C>a <Vj@[)szwC{ד-Hs=;Wkyg9* fF@6o>w`~ޯ },;@[ x?pz5c27iHpvEok(ӿB'3(RÛtHDy1RQU#T`tbq*U&3ɁB{WfT[0^JLqF@6XIõbtz%}3>~9{;R#*|̄=WNl5u@pNjꑟ~@43дy`#sD̾Kn&i6A]YבO8a.fu^8{*fUhK)_IxemEE󻞗dc}T 4FT7M ՐeWu-PbvhPҝc,,s[A$dXscy! ܰX6rVY^[n>͹.!h^0w"H8L,Qc@ѡ aIҌo`ߙuvF+kx+9,H]]#59+qtif]EU~(枖2JU!G*z*Ԇ$$NgUHviLXC3:~ /xxM-X94 췍>ܲ):w%TS pKµF_6m6zjsZVfZ:cBhsLBD1z9Ê%lE]2K&qîȵc6>k^H 7/j֐Y3*a8@7v_fGb.?($Wo+aJjw *L ӹ- H8zgvEc! :] q$%i@&SiCh6ȪGuicB|YSVL/\ QB JR%,:p;Yn@z)1/E3oj(u1:)L Gh>Hˏ~=ݽߣj iw= %Tcy"eB]emRw]ݡHzV$Ti4ke28?chhߦ}lƜsVm lFj) XeXQgQ5Mլ/R׀VU28pK>ޚFOUv^9'V=w+S<@J:6)OwR }ڍjO<'fg 7TiԯB|wƴr ᭨25\BKp)G59(/W'm9qL_d$MaNAD#bIHY92kcqXټe5yï^b6itՎkyzBRϜY]>Yw5 `Uaȃ>wruR,g?p~UEr ΄0~xJ@ Ioe_/yy~"w)WtæT]L*r 6s |GP^n$  2ƛc$Cs>n?0Y.<8gZ/_zk&0m]φ1NK#gǹ.TER-) vs BKhc'VN/i!%CqN/`S8:.;"^ dV!oDSG4ᚈL̾?=\ts~>Z$aGfpvMGp%|(9;q|K|W<!uN+J܁Ԟ~ŧS|M_YK^mh 0ӄ:*:RZ-jF82 !%Jօ3ڽɵ߈(' TӂdžAGoUIUKoRk}qCR6͘*s$0_"u؊!dbI [\}wȃcRK%$]xUR &d(꣣G$ pڐm RUQ2Zn@:c_zjp;\a( ]?e녆S#xY2aLGf}: &}f(rSpBs!G63tK"Za^h&/  WV65ɍq5㆙)n/.xRx?*͉YQlx̝,C>#4Z}p_V(=~OZ޴>I\Ixٗ4z;Nz19VT_81]ӨQ;D ljPAIcQ=gdϸeBT2t:p cR;VzG\0tA fa0K 71[YtlL<^"aG\']%Exv.LοP"ݍRDӃ^;] H{;ly_>u~NDo_PV'`:1* (kcJ`fZ׫|{0R@51Iǫʹ5y:V&+exlN ƗXD9)-3&~qFΎ֣Ɔ7 |S#>V~ ge~[Pt^},aY{{BhŸ @  ^m_j̊[ 7Ȃ%aXzɹx0v34 Bʶ9g\C{Up6YcKE$" Hҍ+{\zbQ?w oekCPbz;C"_2 q@"Ea&Ѹ | iI?͖(x%ZhRq=2>t3di*ڂP%qrzUS5 =Ԭ4,NXN[)l;D4(ʵݹÌbx7L; 洑nr̕"Hm`qF-d!h7@PAR 2.0MainQbx۳,<ܞPAR2PKTL@p~9Hq-~xqF-d!h7@PAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2397447 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.vol4+1.par20000644000000000000000000014413414625637207024273 0ustar00runnerstaffPAR2PKTZq6}-MҶqF-d!h7@PAR 2.0RecvSlicxXdêM;l-oo3,9i#*19o 0f%9Rj-;<2ae,LHqTi۱P}/s$[^U4HrG }_ߤϲ/r-+ZKvK;.߇s}o(sdn9VU?"Mo_hKʣ#"giH.-RPqF2Rl?P+9V;AĈJ,.GhƦqʓTiH y\ޠL=&<]S\(dʨYP"ez޳ w q;n$Sq(ݶJb_2i T 15YATSvle<0qOxbC/w Q[J͟A88#fU3栨hT 7!0a~ f!DBT3XtK=1bt6nwWj{/8ooH G? wՍ!alp|`*H]rLd9d!y=a@+ꡠ Rrhb؝}248DA J"&@onf%p>w{3[8m rq©pMS}'[o3JW 9͝l`99~"o؉ȻHHkB幕TyC:B6>}0”Tׂ.tv%doW7>ܓe\iHч2<Ylv.t9T#L!c1f;ǮP0uSSd2{ٔ &MG~JOSO~$(;}|̅5^!Zj}Xs^VM_ lDi(7.Awܡa!&RkKeBJ>n/ǹrqrPE;G|zOh.%>GmcgUlRḩDCGV-D_Ft a;_^2$wsOLMaԞtp)}6S=y蒪T5wd\^HW *^϶B&(:˸9Yg7^D /OlngUodD.E)/uŦN(ߢPhMaRO:)=VՍ;Bɼ]{Ӵk.,ԓšt.&l](ye9Y\􆩒ou%C\K%XLż$LUerMoDQ]fψ*R _|L+),vHdutt ZP Ҟ3W9F]s8ɵL;w]ycZ`, ƺɦ:.$!hT 1 }@Wx{S/dJ@\ l1ZfAvمGcSr\W*t^B%fW03 EfyD%~Ʉ5zƪ: C `fK\4ChzQJzQظpMYn9#Ak"sWXN;aeB#l+2SM~aa-2"/vuWʫM$UZZz;ᯭP}խmVjG8l^+iiSȨ$Wƿ3{x&,ߝE<2'iY֗SJ*OVD f@-^/H~cͨ3VJq:iI3ށ|%5ntB*Y:y\ނ]O껦=P"$NkzW,ly$c+H 75&5e ;;lB=L$o>\CL)6"&(oK`Q=. D~$;V퀅ڷ 4  XhDD46OJQy go<ی2#g})=ՍG6%xZ&oU%碻$b%>}$S/(s ̐2F`dSC(f_.yoT/ N9`)D3t>N&wcBJCae\Ζ"ѹZ?-%veO33_: tfk23[\~F@wI^'\ɶi}"vfSځ96h![qP=N>w/%CNO~6[Q K2ڼkyx|K EM7[@'r;pӳveD՜n.ԧgooKȺu=k/d,:E) Mnro gAJt>#՗G5sixW|\Wn~{_z^ez.[@%VJ3NOɾ [t$樽z9~ @׉JfUW !c4^Ż" 0[#*=$^ۭpl>'8'15ĔUUX&>s<1£d%Rj&FM(Dju:B֦4-h<P6 ZEhO hFwY 0JYO4/WS'3?&͖|O cUXC|.!;\fP$LbZc7oLjbC"nD*5?}+-ڮP2Œ"ׂ1i-_F%NBihr=M!:?qYo 6A~W\@s3}U_Ã^Nu(#Z+qu_*~qh\B?U9_fW&m7ak/ޒ-E[:oga.ա# h73BVqo;]Uw\''~U$@c0ȓ>A*njn اQC (_'ɤ 7aCw+_f\y*؟/ܙFOfCŘVQy& 5<űIa҆D6F#宓 8Psi|Iɷ1d[yB i[^Q4O(94u!M.`Bm; J'߯k;^Cq;xޏT ?ؾ롱!%~B:> `q[J\X?n+WՎ*^6N"IhØ^ @^p?.D]ZmN O\I:e3R8dj^SJؖ]pɊ;?Td1+ 7+q|W}B-o &ͩ&neیaK#`,Gߙ$؆"0ukc|xw'{8# (b%* eǘK>p@q\@G;581zeb~ǝޗqv7>7w2n4n΢9D ﳈNy\}hPY=EgTMnIBϯcce]M)@j[&3!T#)f1SD/ i 1J {"KA7Qg`Ŕo@[7"Ka& *wd-bMsɽ@4OR6;Ad81.:@|l7MbYc;<ŅD]s6ԧ{c%nR"Q[yqc~"Ru7NƂ();'Tֲ8KEj'Hӽ]ܛO܎KI,2fd( $8OիPK \?:ߺz34ǼPSTdsk oݮ懇*P*m~Zvg|Uݹx 9._c ˶,v:IcJ7hHERoj)A뾃"2t.Jw= }QNߔ.G|ֿH/UP2'bI!t.h52"ZG^NIg)`x7N^gR7F}],[76e% +iD*gQ#Mʴ,'/;тB~p7kc$/WإWXМ{ Tk2o=_;yrl]Y4C?*m$ PRьMZ19Yuū6=T^<D ћoY7 ԰o{O?X|?ի՟xr Sz096\K=o{;p{k(ugu U2r q|}qp&C&:ކ"6?L'J@`NA_F`#G#DZͭ`?&Z 1k 8*Mi1o>q=O$w[Ϳ_ x>?p(]S}L1h+A]Cٝ,_mPoY (wAbSW/cg`UF]6ėz)hЃ;,͌K~Nb$*rzħE121'=vï z #h7Jⅿ ["qO-WM:8G>v`ZXQ5`+"c閭$Ev-Q™x7]^AhV5֩yL+Jf JGA> uT 9!G VJToL ĞI73;=s =ΤѪ)PʏDZHH-6ةK}bl[CAJ"T$ 8nٯ\aMe1}Jt!D%,}_g 8>rGf4|YU1rhXz Q7 X CLs x8#y=D:fu)kpҁIVk?uQ43jePJ"I'I&2^U]M)msSi|NMD24C R0{Rnm{{1:Χ8.v[-\TTLY۵=?7qJXɾ vi*\⿕C,X?9v\>TЛe!TQK&5OEF*~(fe-|GKoj i Se% )*})&"@(D{?*ƵvtQz_+s2NɚFk"V9|Oa:'P1%BbM_ͬ"G5 #&1W۱?^L@2ٞ_ah Kpj7s&((q b!~6n1N0u7r*PSagܷkY"etӥ9G m̚lYxQE| d(L6c db|d(1i Ҷ#,kcg8p1CDH(:Պ<\U0NS^#Y- -x^j1.1Scd{44.Xz3b2׈P]B/Jb/MY3?c`Q1[cp\!˻|?GlH#i)3,?K84W<?ޯ$Yo\+ !`Ƚjg"PضB^2Wr1=qm&bc!bG#evj] PDZGD] M9]e=(o*_wW7;hppx)b:믴r]w"ZX}Q_c3Y~y^d!r TDJԸ\R~A:ŚEP .wYBK&ف{W՝q47:X$^U +g`n|5ؒC.$oj>\G^uݶչ۝=)x VPe'̿t_"ȘkMePI-7s E ZqIah yt'^BȱG )4JO_u%mDJVyrBXcC݈풪}p6/i N1MiU'=%Oթ,V+PsZ<|ELO>A;^|vmo|H9=`,]_7aöWBP$䡬[WLT.W_f a>8s@ʷnj!Fi* 3@*)}K*hTS]DUwoė zf 6P7ަuTkKwe@7PUO ?ի:VD4Z ~-RǭjP$׼;!c1J2=T#P&a;7Ymxc嵊} )y΂ys_A|Hg5foKˆ5(8ʰj,FgqP|i*D$RXW@jTkp7- S F{ޕO$mO73* _w~E((Ek?MޕĊuݴV̚瘞n* _>8Z0׬ixk0[IhgQ0~xƯh Ya2 oDjJИ`bqSRwOՏo@]`mop 䰥??A(R~ }*SӍk(\a  +vSOn{.Oj w/ (X67h"ʡs͍crM{yHNEF]gl>pdF \I}Th c Fk?Xo7EF{zz*7 HRe cU/yBC&Ckᔱʊ#7"BN;뗝s5=Cnws@}.{ IቒXR!6_B& ߍJ%G Oտ N/tgUF\kk6<4yyD '\0@D=µVjs[i' }YZq[DE˼|DJ%$#;,VlW`Ebl~7y0tJ^r ɟ|gBKAANMDPoӈ5KCӨƭ,N^6N's >aqnG'Zjuz'B!ⁱhSwSmHv (ALHR%c3id浟P蚴ju(KBʹ([AS0*W#:q5.OjY+gCѫ&Ws lGՆrefmI`#֒7Uri*6ﮄc1n 迈Q$xW` _SjnL!(_eZLܽp_ /Of&~W#g_Ar7ٲ^>fkXcؾ'5}׶p"kIO#i tlvΐ Q@27S <;` z}ĨL$4zDV\c3PuThཆO(+4~c/4*qܪsVjY1RcX̂PאN5Q89~"Oě:h($2iBs<Q \q -_uͰMxNT ۷hR&yELP;&![h:}L`hVsq7?׫ç_m;tѧ2@V%!`Q--}L0kX@Ԯ9bXӵ֕%LW噊|jK1l+m뿩1QhZj@qQ~T;Na\o q!xczM։aif\ONxfT[cH=y`65MjccaNn$U/ R3՛[G3  U9'zG楹9q4tNY}.5v[ ^$Rz9ebz1Tm#s^pY=c> wF4_`!.7:9,r3,7C3m׉@ڷd5:!9[j6un*a e5@dXHKD1Vm%} s}@ymOK۲q@ctw8EgރnrbIvN`H.ЙUG;QђX> 2`r*:$:Ԛoqiy#Zo:Hd0D:gQMi&?~ -gK Spp(9sR)`t #morv~0@*@NP~F=&QI:/'ZFƚ*nl*=$c[ GsR"aP 5]qfw(6F7:;MΟqbLI.C.ʏw)ѐB.R&2$/єT (]e͇.9`+>q`;`l3F /z2H%#J i0nTST o9bJ4/S. #\IZaH\>"3TEqU.8X|ciTŐ}+f KES5 -1ƚVNv>h5j㘿|4gC^'MgDǥC<ci,Yv =9xr%DcTm!x^!2g7 GPK3H=rYDA31aFys7.9j:ݯ݂u Sb὾ЎNAV͂Eo@EkR!dPZLAI(I,مӶA gM5!k9bSvQ·P!@sJֲ6LBWAER&eE3tz V3^.0U&V!؋G.ܩAN6Q,PU,>2&o]-?^A/aRy3? |EoCY,5g%TMYOCj{NZ|ǝS.t}>wiG&.7qOa9A+{<'뾋ǃU#OMlJlJ0;6գ0H#U  FPFҰȸ_ .v ;o@m)ny涴1#X rTBR߬9S&}$I%Ŧ^܃/0KtP2w%e H;k:hTa hN#]/u(ZW)ڟVcPGv3IF1kkɆC{!' ]し$檹9rC `T_[ g+X­&eMMJ_H\>0y|CLߊG aqΚ!Ϻ^FJtZcjB ԧ˜;Mj[l;ZUl^}* ԑ!#16HTr&3|Oy\}2WR:g+}yYd$ptm{*0т}[7FfkcWs[V$Jv%a*IC7|@VAOB]V@* #mɋB4n`xZQ &:G.{-&ur)lٚf0^(vK*S\УW~.T܀}/p?fF‚o~-,VSŚ}7׎,\;s =MO\fu-Hֳ'9*Hͣ'FX$t|S-c?j’֙UMNZ+m% l@yw`֖G[#*m@Bۇ;{bs6r'lt#OJ' ]Aov'_5 Z3&FOԿjɼׁ;ͯkER3]3^/C4 8=A9| NM ~sZ꫄vydOt\YMOx6*q#$$F`>T i5/>/[5)Q"x BJ-0.rr[ǾQ?0&.zt;\zDKrRk#JI]փ8IpoH+l[gSA7H5(90 .JNŰoE| Eb1CJ~~ =qK*~Zegv_DžѤIN-E*yDp+ ݺ2]TTO_N0 z]pP[񊫑Rw5Juk\ԫIۯi|8O ! edj N-4lu\$*zǟf6rpp Z򭅌P C!. )QiXc=Κt56?B"|_Y`LѨ݌s0H~ uY 7'C(Ϡ(PcO8dƭ87b;^bUlMRq``r*+}F:d{/M)/nwOg]8ч35-}]߰Qjj;H*Nak= gB!>Ira+6h5A|TZAȻJ*S]bF3GӬ!g:>R>ݓhp!͵g$+d IkY\a{PrghK|XX vfʋEmy]' ]3߈^ ,[Pʪ+Ye ;&iCThTecF4NlyLŴVU~Ci,^v#cIzY#'+^]_.-v/n:֍]ʄd$ g }( S䮩rM"VDdEI6{4'i՜ptV>kE {܉)%a>]GOiթ-*Ц8V΢D x;"3\"u݉YjI@'|Cʉ+SmX|h_>-0= //Z-VTP*x5 Jy?jts+9e)` $G67 O DTL?Zw?,K6#]|9ekAr{.B61APj-lU 0"bD9x~hgR>kskPhXCBKBǟ8b7 T1A x4_p1_o-hl@gb+jtW'nLVZgmx߲uB҂cxby1qG 6.P(߾#q OvD /M̓B5((I6NiHR- jWδ~;<3N50|0On̾0 }yzxQan.* LV#&E[-ͪKՀ*?uc"ƒ>a5W'~p&jxZ߃" -FӇIia?GkMt.^ bwv ufU<8f>-!j݂1#]zOXV;+SVǦ83(F7jN-0(f&Wkc !a:2(G("'@`IU '܈g@giEz.$ܝ~S~%ÑG2xSÎ})r^fS6orZ7rQ\2JVq0P輐0#U{.ߠC8kʞ"nQd(岠TCM3)UxKUIhZǷJ25[a1[4y9bD޶55$jmɧύ2#:s,糄6(ȯZt [Q2"7Չăl<.Q*rB5LGe@RQ-G)4kpgL䇯A@a_r$(ҢF'x(U1WucɂMU)H0/뜠SgBb~*x`;KP$WmbP`4ejdv`Hc3g3/k/Vo`fjǃ8269wGr:FI?=UM&l \]CKb(raDEb~o`DY- t8 w]]Y gNZ :C]0ߗ3 O Vⳡ^C;ժFc 'dO$l)os)r9tc_-``i:Scy^~0VWι0qˍd/$͎/؂7?+au<9*&n~7q H 5.7G"6L *ꄌܼ;qU+rzЂ54ح %N+jslN;bh*>H\x.,Tw;ay$,/oFx5jx@3H Ծ嶐_CB\-\3zGYoDїȥ]Zd(Dg@6;ܶQxSKJ&y,?ƕWLc=8ʻ UB!@n7&XL9 &G0~|r9v213;>p@rƹ&A!dy%&1өC>s&/+K>dѴVJ`nD KSrXB0@har. aV#Ø` 5NV"E=;D1YR?OmwWOmxTfͽss3h{hチL Nj!saQMr5J͗F̭L@pau/ ƾ)C9Tťh5Оzy?4}pIsTv6! :ZnƷU[& LSCqd%N;k 2tkK'B.qi"bye!SLjz }ixlୀ=Y#LlBG{߁R 4謬aTLL]9[|_&5>Nk4Af#&EfRv3zG`aB 'Êص'$`ӕTW TUcU[4^]2um=(QO+LŮ_I4œ4%;KޙcdȾ'Vv V-]x!mi8'qQ]@)PL3- #Ȁ F ͑'a,c1X`߉WU\_ECeakb);*c!:_O@L-=\g;O.G99 j ;l]?ZVv^;v-ΧnTv`UDydfq~u9ۡEhͼwJ}c7?r[i0 b+7Duutj[`̧cuz2Y"@LR)'y!sq#̡0DkkޑX>SaYvn2dsNyZB B8O{*WԣCx s^#'`S#;giFؼU8ZPyh*EF -z7ya>?a$V(D i p4̇r%hZ1C+"Mf܉S}%x O{W{|܍֢6%rh{:Tۃ1;c:,XcG NRBQ:n>q/ w7RUAe7縔܃h҃ ᔇŷ$ݵ۞)v#3ف}Hg&Z"]v CwYqA0fF*T[9ívfCKn Fq,Tr$[PՓ[n 5g]_]OFtSylW~ayTn?&9j9lXѯ-"Rmj[,M~l7d@H%ӥCXwTk]?6bF9FDЗqK*M:m{C;f.a25Bi[|bu*ߥhK.z_l̨pQc |&b|Yǧџ <0ߒ*e:l!sv (I-Udf0KO,Ziwtfa{ 2*Y/F+IJGz0,e,fzP \Y@M;BI*eًQ4Oy՟d y"f.6IWRx'ewbٝkDE>~`޻&ṔkƥSmIh,|gjN(eJC;*RY3;Z^JJGyJo73+"%.7ڥI${iR|jm NudzsOIll7Yi&ԇ?6FޏpfT-#DqozG2^\wzm>斖 KFA^f]Y'r1Kz5(؈r>Deɟ(E;niX#Ṅ"6A\ P>$N4BP:LyaA|-#cFB(},jȘ a\pK~bn_JzQ95`l|LGMtPb.(HcGzYig,V)$W/AmAG-O&97F"V`N,Ƃk%Z+l70}w 2BU*=bR\AXar(SUCfXR*qvql\5__Ol*0S~HiW0OG ]È'6\Zس52[oӯL;XKa`<'ڵ(9bd6:L9ʧ]ճbz鹳x5Z֦dHY955LU>@4Dlt\:P64OX_Zp%rNjCB, l SiTrcܡ,UڋW酔lB>lY5l<٢b3_:/Nd+ZCc&'d \ uϢɔ Q! xiop3X BYY. $DWe\;*GOCPL!s kLusX nBh1$ ;<ًR.Tmd=06;d?|,b L =||\"+iI4kP"4MKU̹TUYP;3Uo? B Hgv7'd,"y&~r: ## ۞ ]6Ȱl-^q>:s{Fm >6L&RaL*>Kl9HȣC#Bܓ`ۜTG`SQm;A#d s%OyIo2gW$ơGXԐWdt X֞ ݾEѶr{DVV  ?Y+;(u,\ L_y'inGPGk)2(P?7=BL؃H6\' XAwpJvZ7fT׮(t_u!0 IXly;.geռpMqQ[f4V4PޓN!>(S##XO e82EsuF\k KA{{_wٟ#6i3INyBB-9~526q =sFʮae=Tk~wXnf[6q֎B_2 ֩Ms8xkכ)I& <͒O,ltΡDx+_w>"G| z i+b>QHi;^{_yYMk:c,A{`Q0y)lev<R-^e}"+#RApH@1vgV\WF.k"$gσ+/LNl+(=L}O'Bxb](O)M\%)Kṟnr I#Tޮl7YQ҃Epcq&¶l-u_9>@IQz6 TtEֲ$lE3_cZΖbPb-gx,6D\9;j485<8kaGl;QBl}|'OwU<=rDEzsȎFALb†z욁)L*EE @^[1NpFQc4t^ZZ]r g$d,ntӍ`J㷡({glu˽Ġ7~B;x&[ސi,5Pqq:bIs] >J+h^Q6,pe,!}gRaj g;E)]/Ya w>&Uܨ2UHk#IZkǂvTlCDW "}D,3,e@w9|e#edmV!:b pZBr^;ʬ?֚!Gy st^ aBFeB,;&{x X=ߡK]_ҏ2 oB˦l feUE;OC 2KP?^t k^)KDXˢSapIM=oPxL)J`e d#^(qOiCD"tew1Tm.m0wy=7>½09u>QѽL;ReIØ`..6ͅ?;CCO\6#2RDߧU텉Y.Ξ50 +]jaس[PX?0{䞆;!%ar7:6&AjXp!I(g إipd|ڻa]6M$EB 4 &ի'2vJ>р\S,!Af[~H^mjKZ8`2WC0o>-!k;p_;=lSYjxt'j52~>QAVNyjvS wTָK!ًg iKƳ 2HTC>Ȳlis:jF;,EHN=d۠Rwu tոTH8IT~$UxoDŝvKlfV'um*s=ݑg2CI'- wx@5[$T<%;\Fʺd0^T*c3N߱OцYpۄ~TsQB'`NRqM.**˶oUD~:A՗ OFuRol)V+tol൞˧B{x`,~^%;e,F.оH>؈AOTR$xgV+h HEls9[?ʎn,=idd])ߝ{20&+an3Z[jᒁdu4qOeR_r6r6#r Õ!ߪ-*h[Tfgl)u<- Ez+ND4P~_U +H+4+O0K%4 0on N3iΖ3 ^FH.'= .eL=]rp.^imTtcHQ 4a/"ӗ>Vu4%o Te,PDPzH$/\_p®|h$67Ocç !hTw:.߹#2 Ȱ.6)x8w^j k~ 0v~h9iLZf! ͨ|DMA@i5K'M5&whYI9=a_%F]0H;3 *lhr{#{j0Z׏#g MW$[YSiG(WyB :/q=U/2=STn\rDbJ&j6/0'J$&ۡ޾._w2xYl íQ=>jŽ$}]FXK, 0>55aoJrڝZn=<|7@@Y8ڍ}HnPţVww+fu+])4vTӉ4fQr9{KGd>(P\u_bݔH:lU-d-Oв~D>F,`H10`AKH* }C"699r yN{n(iTKG *g-Fڔn6Gꞧ%FdYڥyXlmTN1F謁XDMs\:"(B Kjg% `.3+V:!Sej =<OIΏ u9hCK<Г 'SԸa Z%@}]ߒ\Uv]Z=2I)fwYzj]k}\m$Qfw5҉L hmiuFC䖎ܡ@Տ9gt֬ԭ1%]4Bd|lܳ߳Vr|nk#ޞ&m`)і+gTۣhv/pKv]>:*R+七3u pY$H2V.YfRU-NN{6s?`\qbZ((K2jNP`oH A,iLT̟7 P> fIq1M"dGܓdw9: #[ɓ^'-EMijI6W\s-a ^^/MPnv~ w8qNNkLNQzM F1wAIje%];Rw0INlBVzTK5 ;鵋vulfLO. ɯh&6ƓR@v֋} +ط%w;RÂPD&}"Diܡ t)jSX򫧑K=<;}2B i Y84wͬD!C 7lF0'#iq|] ac:mo:#=1|Ŗ,A)9)zq`mLyGMNuc,!(!at1@ l/\QM2Z^whKJ`$ %*_QO6(6C~!%ٌV.)#; '?j5ja~"-Y`Ӳ@X~JGj]CNRrp 6Ay`S]{ht,#f-Sc4!W(}hDfx9#Eت)1qs+ٔɒn6{as6^Mi)l|/924x$*Q9#*!!] `Xk̗XphCiQ=ק`s *rfZ.,9N .J&ѝc򡋟$5ȝf]Kw70n*+>]]8|fMpKZ?DNnGK lݒj)43=cr{Q19W`e&%xʻ<љƆf M:.nol*+Q m!՗E)Z0`jkTϰkʎ|bX ޹pRAD"OQ 8Y7|xKOM@@qUe;A-x!D ]yjAߴ|-tT `-dU3JxVӸU2?YIT qh;2W?]*AݠPY[Vփ$-|q}LLRD%i힇]` T|2Xܮl%,KX-9K> h#)y;ҎBJ"7I h=". Gf}5w(oFIDdv \XG6 #V4.w6^33έag Ɗxs =ձ ɩPd8[X !\̛I_(V5;v- ~Pj5Xh=;C@k~DaJv-7B?6Ev/l9* *eڢn4n̷h>̫IBϱ7w/u'EHǍ OtӐwƀ+31ҫ[3C'ޕics)='"w8,c YrTYۥ]yZП0-foSm*ǥv~@TI-Q,Tg@t MDe`{Qiܷ+5}X]#O,wl-s&v@$ 3G"es)^;<1Iep~cVY˩_%2щˆbKA@+7s(,<!Lʨ]c1נ!#RĕvkRQו_^k*6. xAl&g1Gl;_II u?Ewׅ^MZD_@: RW9l1V@A;):H1^`#C0B15HXcZү>Oo1@\A䖺xZ:B|gOP[ $F 5Ygg.N Q }uG$i'_\;Gx5|#QŴ}T;IVq6D7_@@ v,ƹ g6kZg-߃RT;] ae7 b$$$ =N7ze(Ww+ø/]Hݧ?\DgNe#Ū[zƳZmcT u֥lZy^]hqA&FtKIh nx1j W2>ib3KT1k_Tߑ6ۥ X1C0ψ,;5R5 qB" X2ȊN .P3FTA^2*a[ /#IA)gB3[S+~!E?mUNRgmizf&K #1y}eQ^ҫMe7xw[dUx*տbd]1|-Vb*+ M8 Ƃ#59u+EԎ%NdoOBD=3"n1Cx2)ǘj@ fb"Xox?; t,'v\1Bf)Kv%;Ӂ9Rc,lǂ ]pt,i''^ &G<:UmkϕȒ݂eP0?3NV"g ֐, ej7Fϛ8;qχԇ&ū=b,Xyȫ] _xXD\{SOL_b ޝ h?eՔWH3]-]!1',@OC\酤i뉅q0 O.h( kۛyw=WSR&]b%ȋT@ާB~Nc#u`5B?X[d]48͔fѤ慬W5ޑ=?gM*61SQu2Йm|S^яG݋+m/) 3ȽΊ` kdY2,'x1j݅#H->9u ?ՄH`i)V1j)ԶLB~]g=zY!da9G?PeN/>__Kw#s_^]4}f{@a간wߐXM| Dxg#|3Bk__s~p5P.^w `h-4#YIEVUmgf.f l Uw'Jf 8,§|Qqs𶿅îscҨf5vd$osXe ]F.T_:QO1WC1㷇cZN^^0}W9{TLf2z 1 ;C6)@Q9zEFZ7Sn=—Mo0NyRIAUkG>CrbDKrkJ`yxVw EO~Hvgj=;~<5L,]x)xFM uLA 7Kۮo3@ 7$(n[tP퇋(qNt ꇄoCQbR{?fKX No)3Z H `Buɔ$=_R]ŒV!ykN0NIx~C62jU{E0إ+M^[#[ 7ss/<CZ>͏>wŰX rPIw;-w(PNcgZvW0B L%TD|(ݓ.3K eeeѰҔ\q؟`LޫYwda9r%t;aD'&glFChmjNF!dE<2Uٔ_0ꅗ'=A0ݫN4DzyM6MQܝv寕4AzuA +*T^}棍S7wEy&U˶D(( l )""c T调olͰn࿈SE8tgHK+Jk%͆ۙC@0%nRy J6Co.mSn̿,gFփ0M9ك5R_#+m˜hٰ85WHCW"a;#P8~>I+PT ||  })M_22 D.}AS`ԋ,-!<-a6`αN vNEXlm8Z$EH Ł%8ż;poy:AwϘO$-ti6?+^~#aR B'U-fXg?L-T2#{G{Qq$ҵl ?pWVn_i‡g8!P w_sa\["]~j*9`b.dn5D}:Jc4@$NF1r-5b}MToFx83Hx7{I`(eu)‹3+(Hɉ BTBb*T,^xv+'b *Lit '=Ԕ٫ $R˼pR!\s|}mѼPV8\Yvq-: ?cJ*z籸wa׋1VxA>O qJ`OSm49z4i@!J{W7"ohL>~ycgRTd?[1h,c_ea1n I '7"췩Gf/V K|1$Hp% w1SZ-fwQ{zGU%b}Q7*FoofUA@-/rgT>ŹMN~(3n93WH>"^%WcGD0ué =m&"hαV Vp TfF fc;~݂C- z^!(lb)9"?{WH2clU6Xo:1C2ˤ5Qk}N¸-Ɯ(qw?SpAX?ٲJ?*Q1D"@2scߣ!&3H'7q;pmN`7%;(_eNr3:q'W\^//!u,7k6[-%HSD{~(v#z8(Ы<zd1ҕ+"9}^cw`Q@J1 4qD i{dHDB"6lVM*k;1 ǧNp.*)KiA̴@=\|bBhLTo`vچ64O0E2#E^$E0 ?㿺gqƭ^5v8ⰌZ6©9XGd•bJ) U~yx0ސ%L_Ir3)0u2w׹U}ntt ';ױ?PXA6S\$i45!{'].K)𱬥sGKҝ NZ䡌 H{|fmU({-* -K-.Wˊ/<vBz88(N? osYw)ݜμ~>e6c>|p55x $ob\ ˯<͘}v4ױfKj+yȐ/gobApYi6 չ_wJUlZ|^ L8H!nJf`@VAQ6c4LDI'zQ^ n.qRipUqHgT7\j4J1%Zę0W)nğa~!Z^ʉ tkTKVܞc1w۰ ;5T^77S[4M;8) V.e.ool&X}3ҳRR'8+vߤGcp^Zl[ r z P9%;pG=QUoAEiXkm)(|,mJ*rJXyU"gU)k$B*%I7UK,=9P ո"m`=y-R(]JxaMAL#Rp\6U#ᶣ0ϫ{]C/k#drH/[ "(:8v10"v8@_Ϙ5PZHqүN`t <!xĉ^p[?dk^6'esg ǃj4dz|l6Me Bd+zµ VXH)G>@M;<+ʲJL>FdR^p+8CM4ssE4sٺN51iI@`twٚmxrB^e?˵~aZt>*I!QY= @3×Q.(&|`]z_njHR̺O6W0 v.֒ɶ )E~O[x+Z~/M✉Vj< -pzv8 ?V*j~*OpC\ݺ1ftWIv6/Cz%9_4FvdՊY4dԻ?Ŏf;B>TjJ@9y%_~&aGl:{rַ"i4FǨ_eaM6Wb;/_75>;r:ʝ1=D +.NSTJ6|wCP,}i4n96_ }/8i"-$Q0 7/K5\8 # GM}$~ Al8 ^љУTs'H#a}%r)ctWxVI{S앲n=#ΗeWBϯ09a?@QYC O!`&Nj.(Zd2Y,Qgm62m36DKrt9hC8漎Bg}XJ-pjY/p/-le""T-}D¨ȏ1ʯ\]\4{c,<r{9C`CklIILMTX7 ׳Ľ3KB"DD3h7 c`p iz-=Oj_a-ǐ o@+>n4bQ,8ɆtL)0a:zs:^E9 .c}[8y= ~~/v?~a9}˨b MB!]U3~>Rl )RTWjڃrʔH#yeb񍢬ڇB- cM^ ^?<0 }yXȮ p.MR ^Bg6n\u??Z3dD@%DDp*2,q|KLLB m@ bNMQbl741u?|$^:p6hf&8wI˸XoU/O26*fW$V{ȼP\ ov$I,r ~h,?h ZGC#PSK֔>6#֠63L{|!^6k]8ڑu?dp^kiz޾b0D DW25(*Kx@r<ß C2  }r{kA^%>I3s8Υމ*OX5 Jo_}kiԇuݹi@Oy KM@,hI.zԌ)\R>oQw<%+cT9&<<X53xsG zKHVkݵN͋Ő2Oj4FmӚë^[d^<ֹTS+>)f`xd|HOk{XFJj@YD\!Ҽ$/0񣏤V:ԢbWy`Wlތ#L? 74JBN߬AɑD^s"B@ d1d[ØPT c>=MMP4f|CQI%j ٨vCCwSp}$"ǷO*#ZLuVDpg!G&#g~gg/L52~ 0Fu"K} `[VǦd"Ƥ?_H3뱶>I0Y'&Q雖r2l8Rx.viM`+ lZZoè&Z@Y#lz}AmkC|J) LW$%RcLpGK_AH {V!ZcPɼ~DHZdX|c=h0;m6ʓB:JM1]\QlԿpq6b* "98$Æ m `1^x_[.%2asY,"I-m_ӄ\9eK$졵:%3aHyV? (5wUDN Egiט zxZ/\;B3ZVA0A1!wc,ǻ߂4)/5N4S`4@c\+$/#GgkK|7GI_?KcG>p`<{vg4;n>^9RRS6d}a;j =)O}/ Gr[p!S*9UԲ~Nt)hh Js"ےh,7w5g}4̂-Z[ rH#}4T HP?'xpfcCVE.f6DkGt2K@hE}p=;&Noխ^̆'f+0fl^w{?HPqO„HAV`53 :# B$E% pF+|@a6:>/'ƸD\T?#jc \<-о1C5,^ Mx8| *pբ{:ӥ@U÷UB;U)Wn\?vQM=BG];^f012lAS2wIwH5}p)1UQ%t\Օif>s[Y!r輬;ܑ6YM X;ܞl#ZWhuN8?`(|.|w{%^4g&^t ZwӫlS=O /{Ku–{xtL\|}392(Lt,-B1|Z:_I:VpEI6J+G< ,(!X^ bb}}~y%>f4HH0NDQ]b[2?LV]lI,9 .ro Z)1T(߬oڑ8WVA*)U*xgCe`ӱ0FPqk!.ѯ"1Ǖ{@ &yVme!$&z.Uuvό1l ʯXSs{jJg)nX FMIdIp Tfn~4Yoj̴kRi„y )+Zf$JP17rxfp=VM9"AAq{qXrv1y|DҦ-mA*aczKJD[.s_SZ< T1 5y@]L6H{5 [eWRz6]jM 0mؔscV*rKmu\Պ]W@ŰjB;:{y0׿JƱs_gݤ8|:~H~>+z;D*=n+i|$VR9TjOz 7+jloZ(lq 6*cDphūb@Z.K ࿑A1LR==< ~Q 3]V*?F覰u>f&Zѓrjgx#A{os~@ǩ=@~P4]Ҽ?l#v^ű<3"pgX0wNȵ_5o6Èp+S P8ӪW^tBsi+-g0T6_Ȍ_dОu?pNk<4w!1d gsLCӁ^Sy D$qcz؇Zlxȍ\Rd#p72'ġQF ?U@ŸS'S\=43]6U߱j]6^G  Y9޽伴*jo9gQ'<@uU~RAL !b׭ ӛ\jbsT<:=T{$wp#{&[@8|\zT#6QN)_Qq"-|]d!fT;jB/ړSxx0Q+p.&V[^ `-Kעx {io-~Lݰ1zAӬLG!8lg%e9Waf=?LOQdfn? Li%3*l2h~2GOcy+mO6p Gj)F99RGx}aK5D): ẅ́w {hbtESx JGP8#J\@#е5DJwm)ӻ) 5ޠ.ޜ6E,ۺ}FAk[f#<88ۈ2A?iÐqXZy~uivWCo-,tT|pt?&яfL3% t@DBoFQ" v~ NgI1,lMTು_:(Ƞ=vBcؼ[5*d-?{f."ZS|-ʗ?1$h!L*8k_mdɎ׭ ub761"?F0a "D7=[<< nWk͍,o 6GٱPHN|`qP/BX:ŧ2P{Ga&l8FF3׌h7M8g&(AFt[dld}澖:$oEVXzydIՀBP>>7Ά$^y],Ew-$ipbQ]ij ||AVo:[ .nto?!É |@Y`$tݎ[|,#El>RT׎J ZwɦP`ߘ=vTF&/5mCQ}RGINwy׬V; :̒XW ;xj@"` 7@xڙh#n|JvZjzp*P;.Cx^g= ?u2FpT;x3k䍴^YԪEJ`r!ƭ]VZHb;ll/0+guE=k% 낼ɘƎS Øiv*K'VT8IBb<]X˰EI] Q)1bchj;^lcu{{)B?Pypp2mFPřfOZlH7ˇ-MMnt`%vˈhfg67'^.0 M~9iI"ҥ/-\[K`/%s"-d:ƽM A!;0~hF4uf=Fp#v;)Ja_7,HK-|ٖ0%ޘpAyAd??ڈfش2hblQ*A&T$"4hC;tz,l&VkpNKc[HM 5RGmIx h3NR $8qt=xi@gNF֘gyp$Zбj;IOUW/KT,W&T/QXHӪγw24QlfQ_ӦFC IvmW"jBI*iЫ@ )NҐ4 lBQ^C՜c:w2 .iF_X dLxk+uݖ`yDrv!~9p7=J˶;kj{4}2j"&>zM;I}ss'?*fj2Kڶ vw\=ۑjz#Wo UOdBQdvL׈L- &ӹid>̪ux%Fzcs_} S!p^cWB( O `yzms9>Ƙel,<eb'(1kUjE^pBlpdgђEfkQxmOU<‘= vYTӒ K}s𓇚͹!;~(oWk# )6i'"t|'E߸7f^|mi苒6*IPO' cPkc'(:~ g[" ֐ӔQxr4SiCN*(z:$s! 0yiWYg%)%GLxG4Loԝ&G XԹ2V;;W9t5+S3>eTƱf%nTl{k}IK/?[4 bDSF$kz–юHE}l`VՆ 3JYC>x) d pA}ɝYsudTr k|/<#eHdXp3?%-mqh K_Ss+?Wvb|ڢHFCǃ 65զ7*]Ji)f$|JR[]_v 0g!L Pҁ(YL3.~7=!!>hD?'2fHTj>(EQG"<-Nb<n9C"J[#9SxœJd1jO8;T|nDm]w~P u.SAD\NQ%3#3F,}ha2*wS}U^]2D-*=X+F\m@}|kyڳݝc(YA&RWv٤t)˯ JZXL/WIԕs\%ZF*I[/2"ZLGhAMLbh5x6}%BLzl?ȱyypp|'yZ΀L`GK{xdi^Rf"9a6#b!>nj,ٸ᷼Fh.[*FuQe o#ULS8}_X“}a~@xbޙ#0S{όnn߻s.hZwû:-c$$QTg ~܋qЎTږ^J`MI dbt> oȫkE|;˷ MɄS(|("ĬNV0hBg>\'#=^Ga'/>jbrVeu|{6󀾯Wk[k\_M)64:jGHa"+(-*[%tl (8.Qo>ZbC/7^a9?ÎokI:a.—DTq=hY hW^bok3aiwQ@N]j]U:H8'pUs~@u?TcKȲPg!i7ǣ&84E юҺҽ.EU]J¬JxB´{ЈR8g7wԛALPZ fЦ1z ZIY ">Š4A6`I@**9z%)))1Q:b%>{͍x@g;,t-emS{jl5#_Z8f6 MOu1ELQ}brH8˯ya^>r*KǼ?%٠ llzޱGE$ZrZ\R&+ڜrp^ 5Mۂ^)-8,WgB_kTVQv^t$čB)8k=Pl8<\Aq@&ףy_Ͼ~4~vM Ps x{^էf~mIۜqdH+qiZ w%#Sa4Y5i{\Mf`t#~7Y>*7vL \uCϛC&Lī~*mȞh]@mѭ XԛdrP\5X+R V%d$/GQD,o4DnΣ~wHj ?24 jNEzVYW⥈2.]wn6c+~drE=TuJOR.hٹRYJtc?ʼ}@kWPe5-y>G=FЅjinNRt+cմ9fb`9ktCf$py)LR7Qv+Uoz2!@b.cRg4sipwÿܶh'ed~{6PҞͯ Lplŀ!jK؈(֝ѤձHo,%/euۜgmVi6nр=ߡc1trJDm'c2VF0$ j6eg Zi%kBP[{24}._ԍG$d#ar D6Ohvsn;{@OZ~q3l/gf7!k.!0);@|>y/ ]B ͡@XmZamA=6bRIyS,1ށZzX86\5$# .TUF?*sRtQEz>"l*'k #AJM0 h0 Qm$E2OGlŨ9:jP˯c)3I7ԬwwnNQJ膝3؞ĉHBzh+#x32`RĜ39Ug@grfw x#hh4E$O! ̓('e;qlc(B_az(}#nsGZܐ+ x#_ɣ<=3,^d` [``5C`te}.9`҄˿ a=I+",;3S5(+#Ձo8ArƨjZ{7hS2q7VKſjJGv=| #n`5?#!i3͢q?De+3Xi餎Zh %' cUyM_N^"hRf_B X ƒVdZexÓ+pUu|Kճ'ý\@Yi4<<=HT\Q;R6'Ҁ Ύi0F,B XQ$>hWtf{9OB%S8;¦VCK0'a 6J?֫k1":n٤AmlL5e[;uqb7MU_;n\3ЂOMEUNa<\>w&y \Ʋ'|Gs9guuKpV~+uP8 B7د޵ CF~AGۭ/aZh–I [z#Z-A&b+*LR3 䀦|Yxi)- ۺ$47\ ,9 ݣ+4hY-эn7h$ֈ r*ݪ#ͲXQ _~Euَ1Uia82>32!V & z"F/|*_ z,γ"OD'Խ.ݹvѶ9\O۽vˀ vJ59-Aet;d={_8QZ:pՔwT( Vwm^Ɍ]Nqo MVMA9bˆM8%+UѼ_^Ɍ+4`58CUz~ krV hc0ŀ)O$B~n^A&1-(;yN7A@Ȑ­݄콥bt뀌}Rmq͐Ơԛ=.,,Yb}] c].9hWl{.Wcn! >z-]7.pxlF]!>0GGcF tfE`nܱtɇQ_~u _oz?wG7'=ߗig^'-a^ , :]<rz~ FIm 4d]BEۋ/? 7gv^MiM$t򚞒-O*>tb@ xɿ/pġ)` RH!x>uΆ`톡Q]ump ,\7,PK G9/[*`D<gmᯱ`DFi2@€G/TM5KT ?ifs]i.JOT!]Cn*hF·tZSWuNo!k4>U}]OXXj/S~H` HhVg ={֠>ơ*GT$Z3 썗k 9ȼ9_l</?jTCF!DcQ9k e"f0%P,X׎M:&sZdoHb*to/4qyk/ tVzx;,mG๑rՙ,5d/T>=5h~TUdᨄF[rKP'{tՃ08GԐ /j&?bi2? wï[mx= C0md!zL+?@,}hG7TXm{T" ->&vގʨrDO$`iүH`Y+w1d+f9RpWˢͼDR(io"=Z7>]3ycPf3{j?[0Rdr9_noٲ4gOp:6mⰼ4b-'8P#X3çP8c qEZ(AO1zex)N9ku]W4-MhaLG"Of="`phۿ(TdP2Y#bњZj$2}dh<dNjK:wPfv0VPms͍Av(o .R.`')Z}+ ن(lyJթS7&$c4:W%ixԉ6N]uta^y oҷf|ql?Jg-suG8LI5/A29&k$e NPY^-jRDt"a0{EnlV-PKZJ0vP \7iT)_eJN}efs.BqF-d!h7@PAR 2.0MainQbx۳,<ܞPAR2PKTL@p~9Hq-~xqF-d!h7@PAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2383957 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0070000644000000000000000000014270014625637207022713 0ustar00runnerstaff B7 4&Z6'@Dv@č8!(Ae\@xn$’ ֫.;@? p,ySv]!Ā=WNqi砼[pC/*IjXlL{20l/KõS<)~ՖBu#J0h#~A! R/7t|.I^@8EZZbxc&AI7PR6Ri/@ Ntm[4 0W:\ jڏ e2c"2eXD_ò.'C3S;xl+n^X֔H {rhb=B *п S-. VFv.U=3,D2-fؿ`HUna8╎jE(לk->lf7Zc_Q_;~sGn>+0 pVuz)؆HE>À`d1"N=_):tf>?TFp͛$=[6k|$Ϙ p*~D D_eo q:d*9Xe;7_ezM殥04 476D YCQ ;Ǘՠ6M_UY)*|I/TM-xs6Oe~ڜQLfT:64}( xJ8=pOd W[ ь:6IR_ά1>B0OMhG2=NK[ۀCy[HYXg y >IN (v(Q2lb*bѹfQI'lff6\Bb&JܦO'TU`P-Dkxs[j64yE3}!>"9.+txC[`3k)f`2p> -qavvG6%F@>y~7[&uU7V;fzH܂huiA-im<2`'B;\fݚr /՘w ^m$ތdy1 ="Mj5vP\xte:Alep.f؊Rg -g`C<>ٽaGdGg)oBifͰkJ]z-n=Ng0;n'א-h]kqF{$ǰ(ߊD j]+#Wbk@sE<hv7. 2I[ B,g6W .)`u% V9ߎNT!h.m|f&e4@! {aDKDfHF δIKև>)q|af R1H/oo_ZV 徧̑wG@~},ș@KC#+{þDhR7asXAQ#-rc02|ȩVtEו}WiOCEbb`E R\OK""l /U;KƧlPljn@\+/ܭ=$T-GxH۴cc!S# ?=89 wsY8UV4bW(%Sr.rc~^Ҵߖ OVTeAԴ!u9eYyR||G6 G#[wЏ5f*Yq'\8NF8dJ[SOM?,`@ oSmO:.z5hK{^U3Qռyh1A$EHG#3E[ N|\ cID&n 4 rH"r*hC2FvIU De+M29JՒ@h Z"Ho)vOw0dkvf xi~v^օe`"8=NgEY %3;XKRm!eJs0Hz jh1Vh<fbI#6͵1b"n}3  Y^_ZX&XphHu:kʸ-ڍ "R^H{~FηHuOKUsߪ.utMy ՛c/I10ڬүIN1V?y؏\ֵt1N EXrx59xKnltȁ_K鿎pLMI86(`4fQ[b ^ yq̯ނhiyDMCd%nF*<+*EYz2u,Gkilk#n淈(tTqؑ k)E…ǯú_ǯ lHv }i6XێƦ\i~}-+h򓃣Q2]ZW'iu@Y{A2qv/}nr76R?#"Nג5DKpx;ӛf90IE^/%Cs5rZw^@o_4}aМmYnĨD$[:Fb3{%Z>7+>97>1rWdH6;#FK7O {ųUiTI^,R"w1 '" B$\#ek)5&2"<Ù~CIVrFcF(x1ƿAx]aM!+tJ[d=WJyѭu#*0Xٽ1rVK)sԗB00ROxr(1Waݏ5[:t: ,A~=@޾h62BU seO{y^^6X=2yBuC9|0{. #K$&/sЇ,ViBF趸pq0YDAC7qToŷSD\yr-CZ>sTi\2& d>1'GS݋WتE:dWL5E p 휡(5vD4ΒIJ=MkwF:u;0gi̜_jVg "gHj4jOo QN^`tQVR0w^^͍9%'8^*2؂]yӢ),vqHSkB溔}a=kg+vܼ; ͫJ$4ϐEEs?qTq0cx&哄W^PaW ?\fYf:o~xz 9afF)'b 9Ϩ74W5]sP?6BQHd =C}>~*K|>,i/=gX/y1b+kǕiSa^ȿfm<9 u.Q?ɺUYdP֢r\\#ȖLSǷK"\ yL NFIct猠sʳ}kٿH|z2ݴիӬ~oBg[w|#PG 냸׹fs* |x!]Q}Y=80N~ES~~ ܆ BɌ#I%E/D,S5?}`#hpB=bW{_"2l&H-]fd]Kf43XݿoZIDɜb"] LEi ¿"S WBljI*4{}j 4S>YJ ZIU IQ"zqpLLmg*ɀO\(Oh`O뀥X"<f?ԦLB\7wqu5%5NCA&vN|=Lq?h8`o)gGJ io/5`z @ qgoMI+.wTv! 0O}HI3jS.e=ѵly, N#E@gW|k Tw;5rKQLߔÅBAcH!7;_y _1iL?eA%(O; nyʈ"8o<'P)GEI4LO5RVMVFGQܧl,(^_tbǴc=»g[Xz٠M*` 8Ctg:O!DZ.U%¢ ]YB #k/#XƟ>x6\@ⅻ@EpqW/1%Tȟkf˔s ЌBfbN "a#iEM]ɇCWlv CXs%B9f'4~@'g܋k6 O6jyۨ1)xn[$+ɚ(34^8ؤeʄdt&{} [0.yP,8oꯄwYe-:X#fÃ9PY3/NEKBtmf~S["-EEn<+'/ZWc˲L2kNsDk FD#UMzla`Xj|@b*L?=&"jPIOxy^,P/s)4H^@t&5]y{+ޡ=zeT1T/vߩm[(YB*pl7y 'hD_i3FH0aˋ& mJzh56յdRuoVJ]"`AE]&.!1o:\Wp>BS2!|[y|jл#Ӭ\4-q &\Urˌs4*J9,9@\\r]H3P26aTr c;7Bv+|H<#]4ANRo-x>7R@ga) S tB!x)k$[.5k%dI^hn 0VM%v|(Uz/A|wsf2! m4Ln=>8яGNݮ.Qu%,U%8tKEhLJt| N< H<O;B33lwMSdmH [?-,q<5nvj7O ^hb!uϦ vN5XnZQi0HK忷lB#VH^-ч,W;Ϗrx;OZdTL2t|$0 z𑺕:4,PyvN_ Ԕ#ˇ9!ՙn& 3yNDA@&xd_!vqZG9+=w4r=5,# xLTk/ΰԹU$_2EQ8{n*cd_ lq=@A=iN P%VApC}!V+4u#i2^M"ƝXh,˹&-)<f]rl4T9C}#_-oHgH0Ÿ0zi{bCV!S'NJ}{1H=e_ TiCb/Iws(&P BkC38G4"ŒX1@''GNM7Y{Q;iI#M 'wgW(_ Oi98qt%O|}8cBl[gWapVڍIi\7??gii~!@DK4B\Qmf[dN D=!346[oj * 7 ہ|R n-B`hRlsvq~s7XTU=uyb#gE-meДPLlՉoM;+(i>P:Mʷ1)(on߄0\(PML6+hsH祂g<YT 550RSHn=v7mBi\8M\gGV%墊 hN_=:ҰB (P^*UjOPmvbZ%w/`B##c${OKJ,ߍA d!5j]pޅx)z܈ܭ l$ROBf}?&B>TObZTq\ݖgdNi"2ᄐ +n`a57&"zŸ []y2)rIKY_V we`k0:0n; Jd[ٸKmElg4lY- BqGw $!t;>Y:o<OQ#\8mI:_A}+°f'mDzKVXUL͏erG{s.P#aķ8:wk{QT45+]dYU?SD0tfL79*6 A ҼYX70?n:-qf;!QULx=]#rw!տ遺rųXHtE_I',ɽˑ[7kol˥'-2n QcD Pzݮ-Lʹӿ񵶍axm4;XS5lcM5)[.X]̫2mB6zƽ=ƴ'W˂+WTzKRpkơ, Oҽro;0g->Wv%L[ŸЏ>t/ ?}|h\f\4O&,x-yX,\iv ~ٟ(_nbS_3 dRp~jЭ[pĆm Qݕya_`X F;f[; iH3R,-}LJ~޻ɝe)CI긕 = o9 ԕ0Po(KpUqo>8Yg$3XޔٺS4|-|%t E "G8')61!Ő.HF 7S7Xה}d$ 7#o(E2h֜UHQi%UU"aū,9ٶC[8 И܌0;t[bWaZa~aE09܁XѣhA$ڨ$j`ld_>;?({dxg:'cד-f鮱/B%Y*QqeG?4Xa[Kd C:Mqd.|>i k$[i„_BeEnѸmv<GَDq{eu8^&5v k uȘ;^vV][FK[%l͗JqaOgJsp>R{X9"2J%+2҉ ]+1ŬgAPLһ!Y+: pI1%YjUj14k!݂- sRhDzJ=辝KD yPĊԑ H%km /M2"1?6x)զJ/yd2Ijߺ{ ?!$ݭ}]cgu2쒲]]Xc#'>+P}e6zyWKBƙ4Gu Iت%S`ٸ &H}:="9X=֯,KwOXՈ2yqu_Ͽ8(x58\M5MUt|H&RF&jh+ 1{azw}git4pj*\ "804[nN2#b9&wLz KDv}\,FFhPcmA:z=I>"dbK'V)YѾ㲂}\(YL:{ h?qO͖ xǧ5 emKtNd=𪖺1qd~Ac1Fa*8i= u:˄M' (-Do 8~Z iТ㫞:hmp !` Mv2ϊ.3I#gSS*4J#p\#h SƕunGN6{bFxCh5eAI&tOWL))1wh4 XZ3Oe*~\qՅ/;wVuvdc"JKӪT n3$]q*`5g=cՄ%&™-m:G2 Kb,1;jpMBp8Tv*GY*j֛|tPl k@-:@?oTmtM8 Iyl00\anH}^>ϪN-hىB2Qj>d[.9|xUi?‚ZC'KEJ0#'[c(~‹"eS7>XfUT',măSo ;B4:6.Q.U[P`aԤp[FDLT}XOm7dShF*mjai,! e䕡w◁o-'YNlu@1Tukd}].6>+̀WvkXίkb1.|FL 28XݠlDTȆ<:ȋ2"QgzUQ])#]ךF 8⦧ ܮ'Fퟚ˯ v-Ub ~N*i"Jea1[ΚsMtתTy e Kb46De$T_.JnUe*+^ߧ'uA }ZMk1B~dLUG8~C (Jz3Z IOD(pRk354rcx^=n.;>g+QY=a8NgDU!Dry~ؒ7F*p͉i-SZgT4w=G 6SN@7QJb[۰[8. i-Y.=rh.ݠ[iʞk-.YCΩ)rx"l$Tܐ&7oKiuWQ*5Ac>L1qFY0% !絕`%rľB!-So_Gzi#bw8[ˀ7X%!y &YDbe,ZViݧIot%xGze9B>%^tXrԌ8*%ry~"94`Y'2)vI.Eq:ZmF!.qX~SY~IqtVnmt䣤-jY 8\]-!A}T@ѯ M k5RLpUC~7t@ٶ&E길Ɋ:0)%kLG0,LBCnRcfP3MA/f*5k.pFeXҠ) $iTa?pHrL+'܆uP Vrӵ&<7Zk $VMN6-ԗ$Z{ Aի.O4[ "\F3;-ng0~R22OՓ+7O{xH'Ne=+n"p G)zCYofSaGơ Rq a䤪n)/- 9/~ EP\~+taJL%?@vp=MxHjtgmJEoeIC6CV b-():";Jt.JRwV#@; o ޽@Bx ̂ n@NVbٙ~' 3IJg"ͫۘf2Bξ?lfSp f2\FU^$e0wGj3*0V5ɿ6ߛDvGeQ9 bWbқ25$IY[ <%Y4 Gk8c3$L$K׷3t ̄i­_m-8`h+1P3&!G.2/ VMM0 !pi*3,~zAiݴ69~oC7֓%Սz:֮lrV:%˭f Ԍ0q8i P 9nѹ%e] 'Oz0ˬ7ZgɊ ;fIϮxF"ab(8M#u`7/:m-&޼wm6g1nOAy̪|ܶ0) {јU6೺HxjܬͶ/VW+=}jM ̎w5hulo{`utoCI`vcޚ͌,3zN2 uH[ONd҄fL@c}mWi1jvA}_$w|O;ݪVﱝ~Ԣ9Z7$G{dң;%-s(BJ*)mیrXa;I6͏Pl aԒB7as*e4J*]#k/b 3<c|-F(&}}R١- EyڴirO$R++v́-;lU=898l#:RTTcly7ƓZM0\у#g1fiǶsNF(}N%#Д; ;If9>vtA]dy4u\-1?$&x-4CW=.çS"tRR6RiknumG^[A)8Sгɕwbwl/b0y w`eؒΓ~NQߚ\0nt(S.'5̤(BA~^z:%DW7EPA$|Eke/-@k8Ze1XA&}^%xD`84t/ښDۥ:Q!\(!B)k^aT0 eRSaxNybXxVId*:)ʂZ8Rh!#(U(4"zv|}lP4vӛWNKl%f,,g arԜ6/Ժ(7×\T-X#`zّQ4l>b01|T/ ' ӪL~ؚr}L4kT~yA^b9_D|V-nc$"a[Ębx,b@m9LyP$k]nmNk辗 |Gk0(tѣ>^m =46Hf"hQid%- GW:7*Fp URn>.F:Y( h#`8(Qsޟ*b]gZSUo Y˯)i!Z"88(5K=z( @C {k<"Ekj?J Lؿi"FXF׍Zc+9U)l\h=bBؽu5, v^v!3#<4hhc! C)`J>j'qᔹQB!+YRBҀ(Ze1pCG"UűH"* N D $ιڨօ$VJŒgm qח2W>Yoq!hD =+3owm2?\6|ְyCv pޖڕw ,kmgx^\ VuQ, QtJhߗ~`Bļ2xw?8,,Ev?E V.t 4 ?O3ֆC#"{_p^b'JgJ{fNYSVkcwu{D InԶ6c;LFOnV@ϐ`B1T|gp $*K(,jib{0e7=~9w(YOd?v7LH]oF\P9YU/`4@ؓS!|M{`i Wny?4oG(#VIWhÞFY_ԵE7`0׊eƂio g?PS@(hKuX̓N%qc'6f"]@kjsװz.? )3b 1?8 FRT7_J@}/i>hxԔ 4rugUzԦ%Wu« ݯ~@zcLum#vuC$i5vL :q ?6ãV?5p!m`phJ@]"=S?Nk??O+nmP:R[;#0kc*jhVtfL갯ؔ-d+ETns*:&6 orUu;[[nMvwѭt- 7K"=S3Y媓J }WK:>`yn^=:٨-DV>`wL 0tkP+?wY.jXWX&\@/K‰ec0fW:_XV<1P"OjH h1=#59RIGfOIt VLcj4d5"c[۹ M[%J IkX$a0oQ."F[+"QGJ)b=az9U3!i_7 ?8'cn^4CήϷ ?d%ɋCh6o8[O|l5iOv,IuX-WQ52M$ԧV./=sx)Aiϰ2zoSVI Mr> {: v^?W`tqg0~ p^|a#Ĕ&W`Ȝwcq+hp%j>඼5IJ[O4Ob/]r)gJ-l6XaKz]a0 |n/Ji;(8Yl==y-cPS=5u"ϝ4X(fBKxɛQ) rOGy`CR"%"#b١Cci [۳sxef/]{oPGHĉ0-R=*;@Y:g0%"\ʜ;ǝν5RIrQKz!N= 3|?!+'p0mkaHP$bG9-aLt7s,vr>i[QOIsq%Rt :1V$]Ȣ#̎|T.M do;g!Dtƛ2j FCe+QfR,KxDM%5RՂ)GpwNfaOSo6 FLmD&qq=Wţer'2Eх('P63x u;(,zs_ث5>::Mw?թDc1JX2TאCO!oZQ|Z_ QGc| ,rϛLcj,Z^|A:lNkkW7%!VgMB 䫋f}"Hn= 8c8 JSmi)1~U)dgW*r>* ;1h)S#1ֽ n9qphw7lqp^d>FyHٞ!AYuhfOðTz9ubg-5XeESru6_``7oOӪBc䨂5:S_,b' 0IP=f$OrMhpC8&6 qS3rw]+3; S kx$Yo쪥928_+!9bO`Ϡ36|췾1鉿;ptF#RA`bժlW_|~3~l`1BYA2鞆^kce Mjp{S;: )kˎpِD8L،dqz{ArvCgIYTd~ce&t݉UĘV!̘0 AMTx龧GӤt,|s۞\[P$P,:@χMk2YG{/ N ؤ e?!/Q;%z'$5 Jeawi%\/V(bw

P3qڜ{pjElx J+Cimct11Ui gP(nlfZ~޿ﰘa`|uHcēQNҝ2>L4vȫa g34IOW`dM7{+'xb~ O6AFei0.-/nZK,4<90t/QfJ6]uq)*_zrOπ?'q,dʕbb .t)܎"˯֚9Bd%^­!o([`Zz2޾o%Bס! $f"sѲPئN|gI- B;XZX`mDƧ} F6N۽ sms+f0(E+=eFͷ;kzMQ t&6uC:y&BvнNGFoa;[cYYf& 5[k=aZ(!`v>sRr9nE% Sr*xr?i8n~*~jP"ι/[8 Tr¡7C,ŃA !fF+hw͡yVQ77s?ܰjJkƚ,jaJF0 CgF2/ZqMH4+kRywiЇx܊ 7ăS;+b(5{yѝ>l3`IL;גжF~ u@5y,x"(u۠fҳIC7l*_pW!42(Ε߿E>W{,V=.I2c +K{Sw@i I|]GVHRB3r>Ɍ03^@Ҭ $m疁FGNwSjCc{$`6ZS>ա?V<⻢"{?;&!6\ 8x hcCdqƙabMg *5^"C::7wVa, } 2asSm_u.?uHb-ܫVF@ЛU ^ wk2[uٹzgإF5"9!Tmvqp3T溵1UXx(zR[}3t Qw] y>B*R;!*ra+\6֊u>ny[1#KYWM`o9EнӊH![xM) -kH*3?yfD g-W3NAܞԒ|`\cݤwT)>~x9!|1|/JT*)N⻵P~fn9)V=..;’!4 dP"AK$F$T}z-n]9_ aeeI7{LQC gݳ)Ϫ$F,40l!^\BNEM&̕~1Hc>Ъf#G$v'E;_ ZR>SWQ1zy!ΣxJTB+Tbc0xW#: v'O_hW!^e,YQg4 ф!8CjU&'qwqBLu#Xƈ/xVȇ-[25f86]k6{*R/pjnqRdyV} r1~57^UK)-6J:Cc)qIdSç^=[]B?(&#cZٚ30FB4)&dֽ1Ϭ@Jɳ5@%7g~IY3\w)0.@2|y_s9Yz,H oǕvpn+>xqr9T\dȇJlھ(Hy9~Tp R5B9)Tck`MxZw(dϿfÊ#% K&+Ŗ@zƻYH[~;S~xao+1PdrҖHUF6TZ}yW>[3￟xdhx?˖#c:yMݨӻ"8{jdT=P 2a򻃗y!<d:b ル~ 'gX4[lSQ"?,ФyLdb{q4O,G,5d0Å 17mJXtC+ɽ,],E_>MߛD9yQw+Ds۰Ȣ/ʹ}8DDVr/@o,eu]{U_}x|X^zH_/5RLGУZ7kx1O0rޤ̤> Pg%šx?;z E0-BiXݵ31"#$^y /ښ-4EEŬp9B)"l/Ko1u8" n`>k 7f߾IC^7X'Hb~R\/#tüU%'}ۅm O*h. ?xY 2efiLTV=̰>?ͅ\LZE K?KنD Q'rB>Pi?aST斘F;B'\h *c0$ T6"Qf& A{'-g5AGџV8RJɊ`oЂ];\¿#}H\p L_m.QJ5-mV5?= Q^F#D=jK '$y3 *CqZV뉞M i[QGA:[NaSOhzTqrtd6=qg偰)qxSy] {>6 7xaщ>Kĺ=z\n̕HXժwϪe5f3GXFδQyB{tb<e͌9~݂CfLJ$ߋAQQۺs"ǁasL8qtZ B^"J6|iw \&{ni>iV%¾l) (.)ѮAqhLo}b wW$ٴK8*_@?lYGAwmJƣ9{Dg0FU]L蠫XZԝw%s[}^/0S;9EN*'Y0;Κn$p<]M?i7+# T[sC/d?Cz֯s.څ~e?wXW9|EkF 8^R0K|I/G/\>rh5hdBa%v?J0* ]i]~쑃=8=\Ȁ~wqttsڌ Q}V ߪ[BhitZE:{iD2;))'oX6@mPC.(;ȬA'q_. S>W@9Rlz>Ro[S]NtQh EG޿ Y"xPߦ;4'&8 hwS׼a}b Q{%:U-<Zݬt+XB=c[[(HN(b`ʷ1jbJ*Yxfq=pI"h웛 }cAM:65jƂzG{mnf@>5]{v]!b~_\_@5d,A}gQ5 _k-nhy"̨Ma9=3#LXn*?i}Fؽ_gNSɨg >6dFÑX:纛P`'AIh)/> *dJH%Z 8n*8FEJMoKZ݄> D:D>Ch;a4NxI#?Y+ =)K{wDٚ gƦvOW[bǗQ{@`!Q[7)Ȥ҂!槆Ƿ[Լ9w6JC,S`5!Fg֭xVP W#:ź_8e}`;ã 2%kBo ;m0 de:d.TMw@#of>t;1;݀wtXfB#KvFVW4D26&Ԅg^'5V  8Ӳ)A55aq l5bON?<Ő@I?Sƥ֨{?$[}0/c˅Hq)hZ@ *RJ!cw㩋J|+C1-T#IOK9M2[v=h<7z[}RSZԞ]~ZvVr 4|oi-1.'kT#]T=UG!&9_BQZSk Dn n'F0'] ayQq \+NB/ɁcqPJr !x@A'۽BWΟܞ7n89dl_*Ǯo=)}s40 Vw% dxVfaffQ3|lձWugtt16kV[o5N'3̜bޤbxղP퀈B&jy¨$x$"ץ}~pl\o5d|ofH/"~ :齉 Gmcz[~/ΆCN1L%Ҝ1,fKO&Y{=|ハyͪedAN27ۿ;뚮CyS*L,BKN]Sd`=hR nGX{T@cyk{SSWN 2wMa1IB;߶\cљ;c8_XT1)Ny3!._}5GhZNrz $ c frjY[}X9zG𻟃YMSZ_"O#Z#)M~ᮏ@֏ܧ֔#u_0~ˮB~3+5 Ϯ0#5qq~Y퉄d&lF9(vGnG'Rx^z,r_8 :2쉜o U]Lq|NNoM4#h]A=: ((ѯKP]W¢ؗhs5ЖF.T,2*U2^wa7RFMQ#͖"pw#r``qG#:r>kqHk). Ȭ> L{潤X%!,]VG02x)Lz/2TWwY˪`?ڛD&K~-;>٩mVST^*~iqmǃ{A%Nv:ieWu?=$buO?\V[7>/J `*tJ]Ėwԙ[ZݿEEe X^Bx=@eYh\sp)l>?sdlzGG.]$(XƹrDQ,_@1G,7V0UaӖ-o Jeا`bsWHAq!: O~_}Q4C=i" ÓPwp %k!ml1wM2܏YMJ#WafEEW-JlKm:\.Uт)=1s!ZUi].ӎ=q5yX[Rmi(_=6<"jdcXixKw5a[%|xƠ9TKX s\0(=8T n}69w,ѲB ѹ<`K*6 JW͋Y0):ԥ+(+r1C>3nA[%H)3 ]^28ԑ0 =TuדX;ǸS{B^2N賘z[sxj 2a9[.J4-y1`8ṝ,v*džDP鐲!ZݫZaw֙ (aw JT5%sNޙ;Y+nđ9d`j)j7d),hkg¨OָԼQAU;E+K-1(Ekӧ4e c54¥Ͼ򕅽=;ˊF! nXUX|nK@+LѶ@OEeۜOF|<u >L9 )VHnj#X2,Kns4%vgf5==r`B?Y=Aׁ-|coVtϝzd~l?d(~-Xk= c h;FVg[0(P!Ѫ~L+>Eu6Z',!0Dߵ6 MDFi5ճ-5\28OKrmǒgk OϭN8HgJaRBݐo-RZ>/B{C'CR%J*I\](QmShӖZqE1&KEŕ|TLy|@ìhiybkX[X]9Hn*d%+1/ -at[foQi{5jlɚ@˨M[wy;vse)Q~u|6qH 4-qv!~D fCI1N2$DCO^H«ea5*Qc=;xm,rtʼoO06D~p^$J-/] 'Q7%92'mؙ> v~5sxA\6F6„|V#9ЊUmrA{O>Z?Peh=dh_V"bptV} Zi2O-;KC#(\Ȍ|-UD Y4_J1C5DY/FI; tG$΀/c3:5,71Cdgٖc䦉U"Ϫ~vd2lXg6U5V P@o'־W#pw=~bG`J&804Γx ͣy.x/\3Bǔn ^]-Š6@w 罝K6)Vb;pi']D:v7=m=CxQؤ$#{DZJ먩 fu]zoB"וIhFHQs"[4|Zvv3%\nNaѫZ5J??@_v41RX?8TA0#1lPʶI-\C3Uc0v_tQ2fW:z<:v׹bЎ1czp`iu"UvEo39Lׁ=ч y_h51mu/m$>6y#eRȝrUVvvZR JzYP/(oEP ׎Y18]d |yt]‚izNY&TpFvpcOA/TQ\k1KQ ۢD#6=~w(&Q%`HVXcYւD;?TI&5L#?8|NPol-a*<`_GGK:7cbs‚'fJQx ynXzxmIx/i:l.kV/,pų*l~ 9j;% e}wDkdl5r ]|!ǭCGZo_žr,T9Ux^=s.gj0}֨%3hr͚_8z/?/z:տ9Ѣ,w7,?{xy=7 ԒV&BZ( nXʃYJ(c%\J n$Ui=w5zb]X\Y>7O:1BxR2b>5LZ:y7 8/\VW<،\ߚU9 4b̬h?G"Ng /i֬q 7H IŰI6n{ʁ>4c2f80xci\=_++oU"7kI;! 4ɷ{=?1w  ,2U')!^ȺN|b*stjٷ?'XvtEŲ|DdJI,b/'f05=x%^Cw/YI=i4eHo&nQ1'Q/m/E"?qΨDPxP_/$`Јe.QNcg:6XSV|6AgV0=\\06$O057:a`/h9E`. \Ur~!o.޲*G?Ԣ^KjCPώc԰ \|FκyB]&@r79e]d(k2`5<u]ںDN;.1d>V|[ P8s6@IIEeYc|)T5h}&jA,3aƉݸp?>'r1/YqgG<: xÀ  ]yxw-GBǰBQ)qJ B?U9i0 0p h3Y|#"nf5!!z ş"10ABRK؎ͣ=}+#XE֑kv"5$aPt/$ľ(~r$j7I{Q:r~_O3!{LC}zl2Ep(̧qC]tYD&y n@.z23ߥauGb,\Z.fRV$bطa7@7af9TfNVE:4M/Av@m34n?<yWg5&Ru&Xo>͗:˛Q?͙;"T="?w翰9Pi]tPˣF>d [@Ѹv'_@-垈r+6CnV=3gt(]ݺ{p{#Fr+#JvUP~ F`PagYIOLD q){Y2XE '"~ʚGIRƓGZQPK[x/K[r~^Hؼl޼Q;>A|X6 7՟.`l:zYqDO/%j?qzwKTn5sE@93&aI1-Iށ6gTd8GQ2%%ן208NAhC^ZzN}N;ٮ/p j34p7Ny4*V<Ŗcd&:<.w+>O o7$jx 3n5TI$Q'" jElװƿNݯLxS-)zc5WPg1\pE *O:f(ft8l;*Y ;{t.5UPmk65:H?tʹAu=_:m.┊L?/'L췈iB/J9*Lp~//Hnou4U΅ko=f4]Nkޖ0 zky"nClzuX{Y ԉ{ߣ1uשJ5>"i@9[=7zZ FsTtȖ[*F|EoG5!trXGvbGD`ڡި7k8 o$D~4Ԝ)~VdfSQ#Z]j]觘wghXY3$pX&T U/BM 4;ŗ4+-.qF &a_:+4|anץO}vF poƊ쌎dQ\3_pcR/Թ/Y0l?QH~SmmC< (.7) K )zͪgDkM2yf/@8?%s7|ri;~\A   E W?kP=n;$+;W+FvY#&rt{hpt5U) |m6M;6(V3#Q6y-|{>moBq]iOu]p>B ZH<j +p ;7Nđ'S ])kʹ~݆3 S@Xܪ UA UcBCDkC-"Cz\jo}Sm!xlW?PX*xd=Nn޿7,xXeI-, hJA+7:wCzuZ.nuuVw?*0Tꗇ)?4io[eg͏AdёǠXzs J>)_Hy(-}[Cj,;HtE/Nv]y 8+~@mMebm1)5IuH< .ouw~!g~XVĒ*;w7 lG~SkNw$?qh901.NŒL<CW8Z!;X+݄hk+ *s9]HϤn }b;h^=-Q3w'ڲ;ݮOR'::5w9VP4?Ci((%dlMa4'uK!(odvGj 7XXHbt!2F{Súd"{_έB$/ TWuFEΨ-H6:)M(@ހ@ΆnOI](V8~O+t ] 8  Jr-bvfrK&Lk|aez.*<7R d';}+dsH#A]N2BUdx#[@HqwBdƃ"rbSM:EE;YY3q{Qmh"=%< hj4qdJg__CL0Ww H&ׯd t(`ۜђTYe*D`F:ۈe i'HpI`T+G4R8kϹJfn`~{w=B&߻>&Q>VOEXaZ{&/0;yͻmy%vPuɂ;Nt03x㴼*gK8a#Ęɰ.ލΑ 7DG }652q ffªĂ#Dr:Pă W:O3LdY$J ޣ.8eLniGq@ ݂zy# dlݫYot>D[?u ayr\6ϭQ&~D[9.[ 3[(UOo"M<ƞNK;X8 h_+ (h!Τ)_&ܠު1l=< :P62/MXUpDZ엍n_7gJCdn<}cpcK'AMI=yT!LDW^z,9"N >O>|D}EZ?!lvO7e:_.e^gB+ߧm ,q*G8c> V5eGF*PrCʍkqćU`xAt~O&XG"b6 d PoL{EJ6N*)Ӗ\#*Ur޷%WnRW)Oi$$!t)5L{߇pCLtMZh;\_ZuJ=G_eS.~OHzAh\M6~R؀%ZQPfuW@jhm[reϻ83̰] KRɿce@Gb=`BH$؜ &)j#^1U}Ȫq<́o+&໅30.LwiC!.t@UCc 4ݵM^&cʋWHZ^` ^ J]0Oظص>HzH## ӱU{WGB 6MܶF{vI.zjBsv+P\qp!.^~L/jduYޭ7g૷7^OrT68W&T`$ʈgJ aҖ pE!J )P.@$MdxU98>>`)lnjoC`0,/r?=W;sţ\Iz삦X>faI3"ەRkKDۚ.FRLa]S0s &<\1D~cbBq؂5}uwĶ% gYj݉t;dХ瞷 ְng̔-j/Y#kLd᥉J 5-әzfd[)s%3/XĭoKɳցf#?yxSL뻍ȸ 8=cw"m%n g h4amNL_9(4+7/ܔ <ҤK54*{eW[ Gqnf0) @u05HϢA}x]K2BZq$G(m\)FvJ'P#{5|wh)17//C!H18o|?O4RS lI^rFh ZG{v-L%vDjBԬ-ʙc"W5Ґ亩,rDziڂ"`*eD2CvAjBK?^\2G ?a3 q`3 (`,D^/LfĚ%|1<.xtv=wB)Gr o`Y-#.YlM | ijsZBȦXUլiNP8k HhwGâO[->)Y*& VϞwg+ĸ|(iˬw "w87T WcB!`C/J!Ք.%y0z7TB[`ɤ9W8ɾOU\,iv/y;B[@BQP<'Knu=]\;e$\cmkb͇!O5r!eY`\cBXꡪ왋6Skj\I>g>5P2k ?D_mWE%h$)Ă} `"~0U(3YRrtR-\ 9(YՀ ,>,Bsm +(-ɢGU3ڗo?ݷ{S:[RF%_9&ʀl6čm+VҋDGV^dWW**n::aZNSy ҳ~$ Dt]$'IerpJ=SV+l+c;y( ehb/͘1J($€S~1{7goz=>,z2zcf @6pW9-IV ':[#39+W# ,FƊyAqWyy키x/?u"+i%_\ `2`#Pj6>ݷP}6S>j Tt=^S*9kOYzO1R\" Ë* qfx2PECp-WM:,̬!^ x lh2F f5wp*LAVukJ]7YI2N<6XTE]@6KBO3NQX]%ᕯՋ}'-Վ[뉻JH<׋<*oGF{bl]¸PcB5Y'ڹ"0X[ È@G|3MRmayri~do}[n!@§=!~.Fq3<ıCuEsetx:Hڙ~ƚpatt+¹wvdn?b]<%R q}h|y1Ei5P`͵8r%k{rM vi+pD=bťm=Cmݨ,0y4#RM_ ^YJ 3O_ˣ(L/ddnP5 G`yڻJ? D\$uD^#%3URdT@cNc-5 g3 -OZk*7@,9yk\>Hz2앓G аEЫM 9~ 9-Id $|#QoIK)5&yu\t .#зv1N!`dԬeo\ ։6eq@K31al|0nɱߣ҇qEpoy*Twe,<O\qx5=]=q7 "F`+*UsL#s3XʛV LƳ# L&S^*_X W,Z4ЃdDش$W (lvkĞ՛{4,nj-5 fTj":nr )12%Ñ4q5Z鞌CmQ4I~U%؜ .}}6sհ7eٯ[rII+x=@Hَ(""f. ǞmVd,Ԩ#eb\[~Ayʝ AoR5i ڹz V)2䶀Bҕ x)1D`@%/sσʅbH-'GͲ3>>70ᒅǀ1I2Te`,B8Pp=f.lxXAa8Hо{lAؙ"!X )u*AE#/3WWk?gzWgqMC[9HJ nTppS?e6M׬\Mx{[;1EL,o[=9U_R`]2hBP$31Qs|eqllӝGSGIDKqEuJ~f[8iB +3apң;u=kikeX}-[X3qTַO[wrNC(oCS-bֽmͼuשZY Lhn#_&c=lw]D=U7K>v-oDv}HK?g6B[)^㭦vPAUNkMJ_jZ}=óNV #ti~k|v?7)>tz:qObk O`yS(g/|fHdѣyL Q: օfw̷oCO<bcʜH6FrK^hSPvW#&>Lh?AF[98-%7`;IfVξ"/3Ydw9Y##QVEdB&#={@u;02vsD֯#3ڀ~m%3 G[MmUd>'^^x(b]'#uc:w -卒ɘq1˜Q )XH).ĐpG935s& 5lѢ10d,O+b-x{է(ưtR*aM{QCZ(B3u=s٦˧|۹'ˡֻt4'}ăъ0E5pjSBg~OE jp*du3X9"#AsoVyc LC6[lMI& LЌ5r+bs~-8IZsaNDo w/_ }x !A6~(މY/XMiR_ s6ڔ z+TO 26">@g c-NIk`Ŕ=eO|aבYthe.7syH_GfRC%w"d45ޝk@]'Q&CyB3ӊj ^v$WԖŤh#"/u$ooCjl89 q OP]U8>FA@bx" >n9C@th׼n4@ˌ>vH<T^b+4SԀ楾;J`F`idM@:(),YfaYnh_uqSDӜuY:G6{ SZq:w:/$?]2w_m% /dܫa" vyz_]8[";T峴pRFй)k9M' S 3@Q˒Wzf)gQIZtȻÊc'^=4f7FbT) : }Eȶq4'Wi/f7"ժr6H8JyFOe[ $Z>HWU V3!ndnR mYs_;PfMa=D(*(⹂zD:n@ v˞ޥm';Sf[oQ@5D{Yz@M]첖m' !p`qcġCF!3PJ~q-:"L,zvOKH>.Dڛ_`3;t8̈5㋦T z=e9r|")w{:%[hhY0XҬ2Q='QMMQ5:j\%\dܦ-=Lt}?88ۧry.gQw31{~-9'T`  48,HF3(8Dy1ῄ(eѬe6ܚQwhm+IX^J1T ,dRY(xj-P>f4GY˗6b|~/wFh,~>2=+k-o{\:Xj(2r>7ano Y~K/gZWag}MQBex::(tTGRP6'<>$φW8 V 4tFkˮ=Z70JKeZ(E*#Ȋjcᔑ*PoM`nAYxhLgq81BoC'IG9L3֛8f퀭Ʊ'fFO ҞJ@ BP@PLǢݤ QIl_HZ8q4ŐQ]蠸>6(`Ш/y3BSSUQK KgB (f,#BklʇYS]>{lKuF`*S[[PUMc,?`ȸG>ӆ2"YϏϵ(2RaV}%p Mǰsc0P۳C„08(~Vԫ*iOεrm8y _!KNǛQ6+e]YI#2ŏ'7-s?32Wc`p|6Hġ7_}ᵧ aHNm߁#;[5)xM)p)0 P8OB7ywURIK e|{X0SYm>-ҖP"FbVӌk~%}x"?0ϤbuTCקK_AʹOa(BثFb3\\`ãR:ݦ7l.#O`3۰3tA{`6)kIkǵBu8D+?J: D#jkM,6G:4qW=(?$4K{:0b~ѝ|Ų~׬/Zz{p!wXT+ o#Hv{ˤ{كtB\*/{/P}ZKÇ4RN%Ɣ<cADĐԆҊf0]_ –d>%Aƒݏԣ;ZXL[j%FwXamzAKxh,߹boZX=@Rt6JJ "1+vs\S..cDCKy$q'_VKabwOv'꽬ַ)5UZ&~p&*U_e'eCKw|D{oR6NL2T1=bXjk,~("]t-Nwk cmVO͖ T63T2h 68(}֓`*R^.3g֛$^xX{:‡3`94ck>UN././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2387195 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0090000644000000000000000000014270014625637207022715 0ustar00runnerstaffƓDBOQtl^T}wcДVǍ”q/ op^)&l:N^$Ѷ_|Je^>%8 j+Q ְ"Hi/wMKq;mh!o .FҭiTC -GG˳]Ɇg!z&a3{ l=ڱӛVi#p8yPjHĩ:0!ӛ4ޒdYDij)gnBiT}G?ymRnX3UU{) ( z U4J.ݳ^CtFzMHԶ/z8~ymKHDVV:ށ5MWWtyF?3i1H0}?>>|'}Fۦ~Ja/Гta{\iXϯ6:f1 ʃ=#),bF̏UCY@2g gG&x&B9 ֲLJ?3\` i]䠭 `B-yJ$t-}Qgk|v!I.w=G(MOus OۊAcr(-'4zI3F,&Ƣ8ZĎ"qv-{[Q%3[ NZBYMKhJvD〵Ũw^,щ--p]n _Φ;qRB2_llGXl%وR6ëk#emeC+fx G/ sX0M,5g_ HWMzۨAm%wb"m]8T?uiM?>!6Y+&Fцi7Xٻ$4\ LeHnch/ ;}1f'VVNT'm9@Aۼb;v`IBUi+sBc&Dm[NDK"3[.~ mۧ="za_a3Ct|' YqKU0!z5IF1*R/BÚ |靰ř]~:7> ?H ;˙dn: zCϴj8ڑ T_ uEsV:pnujUė4?= a`h \5~)D N$TM_=Mf呠@h7`FX,6oin`|XvWxDUY^J0 r]UYB}Y'nႴ.,צPʣnT@2TKabM]鳥qjV6Lu{S׋@ ZhYp ttƘmP(jrӡ&}7!Yp_D{$?1AD{_~ )K fI[8݌˩<òVe'$y Dk9tʼ/fP=o+HߤK3򑈕:?vĦ,7}ӫe ւ*H\.;\$]IatBwJ4+f'] Uة_mvF=:)-yρ70"/69N!N7[^Hf%z mݒ&ByNM9ǩ@?}@,uIJB6>+?ab'x.XylrU61tYa?BU[g@ {$v[p}Fu*kܭ!7+BTR:7ߪ0d- eb4ώ5^b3?aI,=Z_X FgXF1UͰOhr=ׄz9tԭD+YKaҾrv/~Zi]'!u[vV*()2k]ԭW'bMd>_Y5c2a(YZRUdM__}FWf; # 5cU)7vpiRߔvGȬfSV\s|C!ą[(Äfm'­ c8gLRf$p)aBue &%*ȏN&8` !}+M՛Feuw. !,)م0@G>y;C4PJ yHm^j_G 32TpQAµ,☨ݍD:1BSW2s"AzD?qftb? ~+FIMrˋH‰PG$JzC{ZiytFp a'b<b9|C; ]eXLXr1-@6Li: +3WfWUɈ+O=3bf{8H'3D|ȳ,zf /\ E \m3aԏmP|?p8SDCgꃠz{Əo޺LT-@ڡZ;;` a/ⱳE$͵> ,b5=<0<%PRI0OVz%_, #H+27Dǧh\Yn,ʤeItml6P{r*փ"TFS˥gsfDtB?ѐ\zKYWo>+d$]_W'W ?ܕj`eʑ!fX./BzvVAZ ]7@EU"9ŵeμw/ѡn,f6O8 읣';LFS7Xͥ-=/ YCJ/DS?&aVULvH-ϋNJ|sg[oOй:qk%k݄p^VaXD8dJhuN@`ORcҾbS_zKdռ:ק~d0LWhر<{O.3 )T][.ejLDFOã"g K&ñ[|YɾC #$%므V ]f\=t=!jing)f{_h7kqm nT♗C\wN_jmiOF !|‹>y~j epYpՑSkޱnIjm%K*3A: <6$Crb:ic0Ul`I㦬(vPOp鄜X7 i%3R st?CiAJ_j FɷbP@} j5BXK+N۞{6 zrN6V+@n$ݞ-Ao T'+UYlQ`$ɋv2e2_X \4y63>+8Bl|j_{DRAeucUoVlyyܶiؙϋZ`2lt2e9אV< ShMW}aՔ K1^ Ekݤ|Uyx '8a?ŕ K:3/bF,}0_\ަ%Wu81P@2`iNK_O :BkDyTC3!/U(ns[&BĦyJZjHM *F)oo mG;HJ>$>z(/*6 !h0E[nu$eM士ry3d0`^\^sU mDٝ,w 0T3 :f}uEƄBvK(Yg# 8r4kA~]!AYzjpG D"֊TEwŠpx/Glj]w2ܾzMx 7ڟS~[žuIśԼNI"HWC?QOW*'=SȂ!\C!Hnۙ{yl%6["DOCO^f>7X;:Շd 0'J)eg˳unY9% );`[fHEpvs"{p-Zu'z eDh~EOr: DhHr" %;$mldLDz'Բ^I'ӊѫɞF*ӭXtb@J/8w9ݩ6YO 0ښaSeB8U&=_8B˳З״U|R!i]t/67k-k[& 2AU 17ZΆ6y;,+تCYTdϲIkd9cCbD8eW'u/wt{nRޛs{Pz9'RinH#Ep{e<4)|%\NOO ZWNTD{t>I8)zm(NyD1h$0XzE<#pɚ=hgˢ<E瞸jm9eQu.L_s{g'ʷ@+t;{VX^Fѥt1:t)(;5Mib~_6qsQ\F$uXѭe =(qD 4hٹu.H4^ucXJOS>@aYrcXJ,9p+ھ.a@x6'}lt -G冎4B(y>-T"Gq t gb!g1}yu_a/;"XWg]Iy3RNҗRl Hhx5\6=ΝŒ{ݽZ1/ ǔ85Zg6f۹ ʟ螱cq`@e== Jc¬<.z$.=>tE4;N, 5fJ.'<6o{̖l h-D]lSS˩4!%+v'uHqzq+fj-i^ %D%C& Yw NjP3kX|X`d$Y_6nh~in\mLKrnv,u b$,n5fk14jk q*E"x:Y7x==4)#ҏR6ޑ]V4n'PE;tؚ.sG -DgRĴ &iᛎ.ᨮ!iK%tLĕ-+8kA$^!#S9 hlF#|UJRR6 >M9g,bq[f'#EQd6M%w1f<$xع'3 U,t{#b"e!8|G#yA{B[;bDLu!,TBUɇ`s4 ǂpi'Kܓ:RŜGF{U6햃QߨZ+WPWHS 3,9NBK-᡿\gTh'owe|(#L/ @Z d%O |D%f =[V4/8;jG@AmI۫_k#gN g<1gE`$~A0O(Of L&R4USK/R P# WHxhrVuD-S_['q)>*JX:g໙vڽc rU^kwsW1>?37֨oУ@w؆zmg(͏Sh$xqsLuHnbNlT$&DT ]gp O8x,X2h׉(9vj#5eZU`4Kb_-7P`JT%K4~ҹ;D{+q$0haQ.*m<3KEQGh Ok ll W4eSA2m&΢#Qi8>ck,~8ƊNë]\.Lh/.\]'TAƅg`cI1O$.Wz}S .mє929Bԇf0k.ïטERrĶ#ӣ)X;6- Dᗋ7A֤_jD?:󓿽X5Kͺ&̪6e0\ҕw)ű)dX S̽i0 `'K7oe` UD`N\VZhGcZǍueOм1<0E pDM _]rD^۲4h*K.JA1:n<\U©[& v+AG_x/DeWL]/Y.Dfݵ^`@qEU71GAJo?Uș}|̮֣At:BHaLˎPfڦJ$/<.w(Yn[X +~]"x> K\ ?@+*C%֪SF ͷ(m+g#(qp$=?.s| c]%6͝YVոe\eTt^vz:. 6StH06 g'5 X_w2Շ@A6Ko>?ruPv)"c0UƋ ?Xu i7`VlPFke 9BA(HtmzcN.fvp qRzy_~Fв/t$ί&Mw;b權WYށ"yTadx4djEKF O` ǙI2tB 8eeLM:77"*5Ď18ߒ?3l)i.smYkxlAs5q(7o'+7RY?[md{\ԿuH di96 $[I*/(o(JBl-c> h[V.p=40eJKJ& ;`zN\QAߐп u90¤ 2ӣyˋ OCϷǕ"8xn+Vko4{ch̩X,ѪV\KI3͍"{F K/:! xgX2 BCVW`6xC[?,r(&ʛ=:zU1T xRO?rrY*:ӗBR?Rt2-~6Z[`ptQ3u|{X5 Y B=B,}mw9lM**&u ݗef7U& qI A-#[Ip\3ga)ٶ4Sג_O紥hAM jĊf ޸ωC_q e^] %\+GBcz8-@<#̪6qҠ`Ws,QGH*P6j^( S5w @y;cC쏱͠Rmk64cor"pCi[Qt 6 n89B5)ś28 7˿ԙ"n69fQ" H|Y 賴5Z\\^@a"8.ű? ޒo9$x0Vhx)ebk\TFV,E6èݧkٟ33S?=.esoBDa 'pE5БLU\wl&tL:?& {k5yd"y}tn@.|alx+qEnw9̖%~=K#jR.Dg}ִ !GWAkZ7׌p=f@Z~L L q!j"25Q3TkV(M 43[!0as܏ř x;7Ao$(L`PE%iY)y*]h+ZY~F<:we2b!~Cc>7CL\jU+'_sd3a7HEBl̼W7ɸm݂-G"sAbu|&Δ ݐ BIB3"EY_z:`5anڗ.)ǛJI*0H"w.'{^KUEyC5XbYUׇ]m3Y1e rĨIc\LqdK̕w=ƒL5!)e_A([鵱u1iv$T(M- &%*#e/^%yYZ Y؜/6X ҂K1+͘[bD䯃;Ѹ_X҉ w0ZI@Ʃ1b@-T#Rw"+G0RF}P\ %6P ˶ ~9Sm7 I+!#GM% `"aP Q`X=D\Uja_Cb 8+4ц*0^,oTfomLʮpNBfQ?)V4O3@|X Oj'6`IJOqGbqYhn '\ɋ Te2ˠǀ "km~Tsq+%Њkr`/9c47ZMPD5In|{# 0 >`nMYt0*cO{j1MՒ STg{`g)MMv\C*&_G:HP9qwfcI>qϤ[@1*8RM< ]1,֡X3s\7,x`;Ct" ZYߔ̸-r@zW^`QX:bPeIJ4 䓗69v/uuyVDgT6]7|07NC]݅'J{AN_e(-5>P@:KUl$>Z#WǫFkrn8Ԁ|ߓݚxkG"7_[78\(Ʈc2&mW1h D*<8* ZPʸkSw7$G%@n>%W Hg3Δg!^&e^YKN6#BDpkڜl:\~h? K)-w𚌷#PBJ > ok`7 ?qhRa! ?lns¯?-Nxv `| oRHWc®[,?DqN;ܣ5u9kc}w5uRmkjvT͚T)/n΁ev-u'=/K ^LM`([(5wK:݅U,;guň4Ίr5.FC :*zY%8۸=fNH_?X6"2m ΙDDMNkMm}ß%">ZYԝ۵3/=tw4BJ3vqrb HmD5sdW .;+?L dS(Y?herno}D&שҏ> uw  zc[Mgp|- ķ~>K=. YBTU2eug'yսrtuxwAn*0hbرWG9I]~u&+LAmWbec- JDf.MԴë@Zb}W7"OȺı-?~xo}1x4SL^z5+7TC#F Qš=<"DHg b3Cy7d#$C B)+}u䮁bP@>*ڽoS}R?d@drmk.ku{W+b;IVYn%5X;V8/ k k=M!;n5=v#x$3UR|ʖu/1O$j3KsgwZ><+)WL|b@ /Y*ծRF pyp2d NXE5}^vW(9b|YFg!8%10vȊN@xaim, X/^@$B:3DA _O!Q%g3UMaVW|O+XQ2(!!k+>8^gN*!hwܕi=ԃoG(>Uf-* 769K2Ԧ"nG$ QE؈9؜+t%y_dhC0v흇im+y$O*1Oudfš`cA޵W '>`@ kJ wo\P+ x22!~V'LTqSR(ws< (88ԍ|Ƴ']4}l9jj3NVк+vӲ1W!.)D&s˜wiW6KWB! Ν.`8a.Eh*}b5JhgrBiO5'j2)Tv'5DNsk x3t0̫±Pu)V [_4 (B%FoFT1x Z.O-rJ۸@:ø9&AX_5z@c EϕwX8E#Q,G%bB)\wg?:ZKCoR2mBЍHWsxxBL EIlW4۾3bSRO·^sA(Oc9Cs le=}B_^r<^!4;sJDxg!ej]}.ݵGsVEޅLz&RDee9(2+}ٕ%Mq>3E _Z ;S~%V;fh~ EV(}5-'m߆mg/ܒPVTOӈsKpx]M2鶈εVp *]vG놢+5a쾷Vl̈X8JJspzfK";垶MI}Y&‡M9bES+N%c|n 6]FOfF@GHq9=fE F.c4P YGpe-K5j sN\2׸P7XO(ұ f(1H16hɳz,Zf7iz8sV>I%›v\BҩY"-=rJߛ3<jl=Vmgg)еYW!>T`AY'4}SN`He6~ru7ܔ{Gm~[})1";9+fVTN:ǣaJ0>d)j3ʐ&zj* њ4A7ghԙŸѓv NVi"O/Bu&):~'@;t :,f3"EZ&Qw%0E̵ LwyAW\!c'NyH|Eٝ7_L1tE=l\Gzqd3ru t34:n(="t~M2@_q., 8 7 Nw6|M}wY7AxŒ +xYɯgzFtHҋJE&VkzQ=]{/cVȩ>؆yoFp{"P>kΑ3LDҚ}PO\V~މ: 5]ϕڪYB[Eab<9ٿϲs_Nr{ėbgϝڠUf+|ĵ18gA4<ۯ4G!,޶$﨟 ܿ%$֙&P)'84Nc}>c v+G ns i@ }iZ/>֕x ͢@H"ޜw3tp)J3c83ai4} +y 8ѡ8FZl Vdx?ŷ DɬMbɚWCD\952 *Tڪd_< 󽐅A.*$ %3c?c^dS(/k?0Z e؟UrTSGҞ`՟z-Yh3W{4M2qd1*3(U\0KII#/q Ř@J.0I[M=-"S޹?CDggQlO;#l)%bΖgAZcSQ;/+w Fr mܵ/~FQ#o2.2C^Y#8MȦtE9,ۍҮ|w]BAsHh:@` 1l{*Y|yUpK:[FsdX!{Ua N"2B/~@^Ǧh-BFKGu@= U/@*R0C3.A /ܬCPV\wn8i 8̟n֐kd6pGH"@TMW]AX4bd$Er6==nmh*dgV$ߗT(`S )u8<H؃$8=6dn.>0AK Hoߚt` ,}~Z1Gx;6|,*zv#68̳.8% Y(h,&""B -\@qn CuPމS6~(L-/d-qwleYdUPcMC#t,(OdRXx 6{ӦGNXHJ:E*xa'YvC/UyɮC@,& 'X٥Gg= bG6~:r&P~97S8)x/qcr,e="J 5N:02J8nnܟQM@ؙcp 2ylc q4(P|.+[q>گYDn\"9Ua >k8$IޜO!rNDžECEAP܊)|X X[a3,$~9-b1 BW:mp-Vx 2 yE$(K|ֱSFEE3,)۲(T)&ZVO#x[˂5{Ω .ֺgs؁rd[j:0b8qFy*^YqGyv^1}GcaX ~LJ 0q΋v<4ܛ/Ǭ\P-RLa,m4!OK,^4VGf,gQ?VRqZMRHͼ NΫB*ݒq1?DIx&ɌDybȟ"s 8WtЛuS 61U8 eM"um өu_ _OlƋ5N $L0y5|fR(+ VtEt{܂湺'BR drj+.z6:SV̩tn",Ò/Ts\G mp;mg/TōR@z2װ[-,t%d(aʩ @.qnno|FÎ4qa?:8; lqTbC>. tI#rpYx]`ןH 4|qYxX.vIR&$)BcM,g^d?PEX9'Μ?<(\iƸ{nk/geS@ 0ݖyqz<'[ + bCC!2jҡ%ёi쌬 C,1C̫J cӫ0q$ffPi$]c"L +1{D%rz'Unx5ۘ[@K;6Nǁ7M`R z8=T^;E~gV4v%"i`7zVYAy8]qSgY'һ۲a*~ARd$ pۋ0̈2~_b&{plJl˧jfəe%dwShJ+ -#Ft~̨@ѤhAX pºS:Y˽zCSȍ/9n"޿QREqG-1SM/aOՋmm_k.#HDW:~ D&"liGn^thXm\.Mof1['Edn[4+Y6RA %ֹ=㚯>[-aF5)6}&LlQAX|M"JR>SR}L >>)+83POa)դH3 @W~2pw(- 7w&!Ny u(.#@¼X\̧t]rBPIf#84aO'F7M:saDgf罡L$3U_=g[L$wsxLގX~wg_vC X ,2' Maϐm.Z Q*@C"OV)x{x\0֎ FwG@lFA2'$K clf&BmG\3+gPD4s 9' 2G=,v5r) VX;5ײqwyMw Sm@yx 8a҂҉դ|od|mU O>_(d,Vٟ'-CDI$SDZ1Y5qoN)wtgil+p{͛$Zmsz>Vc(=e'FouCʮa͒=E{nꑦ»&(ι ~>~i:U *h{IG @jb}gfF] +1_3մE -]{=NL|00̺ GRD/a)ĆMۖ7緇O.XP5Y2y;1ZqܔQlN= /i%< tz (Ac處lddQdk ¬#|N߆ ɳb9_46[> 5t)` Vyߍq!1a,dd뾉Gf?ti -/+$5;obCE˞6BԅuDukQƀSTcYq\f}p#)IBE<-dc Mzx q`1euil*X[OxLq^@*H,]'< 92ƞI(} +D= XBgáWD$l6: mؼ/>}=bAP ׮zr@Mc#c8Y8kg;] qrt] tmSbF(wJn`Hty{=bV5mXkWCbpp~iS9OxӁ@\?LlDЊ]/r1(uF B%eZJ>j便O .xY+V*2 uo-ZJ.)vx}J;B5gL,G)+#h2={Ƒuҷc@Bʍ,K R ИzOalHHz+'_JV}eWR.8!Q:j5Пa±=85qxHCNajh1Z{IAYi(UwX{1/Y?0I [*L%V8G}@<?:`GIKֻp^JE>h0Z,Qek2y*ⴲq{>~r:OY /kt3A2 J[:=-847.'F_&[|A4piqeB۪<>dL5XUS,<Ifo˨v-aw_OO G`/#7Z81H{$ #9:\R/)-.~ޟ>`rgBґԌ]D[W9 <8p%7HI >)_ՈiڊÑu5s1Vzzc}v;"Ol$L}<0I9p]jd~>WRMsG .-627?4CQA#?!!ܲ鿨z4)6U=ek f>|cf|}kh˺4qU15Y)yRϱ$Wcɓڀ -9uX(jX@pS&cqAZWErU愐lrwR)N{0w_!X@4 Dz(k %(hoב CRyp> ġgAeô-UGO#5j^^drKt ֡ya(#4vnޒehjc%&9Auh`E] ΣF3lgr-ܲX_ Y86ЋƠU@DRrZ.OH6 axLExi+-1JWUè}MM׼Y/h+;\$C\G|wF+҆kb˖'|ݮz ˑ;u8ݔfI'l IF?jݔvRKyw9\SH?vޓxnW߁"lvK.4XP.FZάϏ*d8>w"GSsӤŞXk&CV +3Ǻo_D+>3'BOck/kϖ iGPfr@p@Kuy-RVغψV)5OȭxnЫ˄`Bd-WϺ6ٵ6>K V)>gޖ! =g6gvf3T]TiKmuu 4m!t$%mXQ̓7!R*w%dٚeȚb| -{44 }ڨCXP3K:"# O WyLOw@]Չ"]Tc]Q WAs:00_꜇[K&2 {иp"9x%1]tq&F/?;Ik:_[Q.Ügje FVeL&7 @3"Ϝ+i\wq 8G\gh;J}[ wAt*7 %`dozQSؗ{Yϸٝb3ҵ$zS{21Mhz)O \e%Jۼg 2ut xF3+jM3זzGl6)/ IbmI_Oȡ)8dy=4X4V&=r}ZQ Eڨ?=1u[Xj PDNҫxR:R  t\L [Ц%DَXC}N/EMzƋ/3^TYYo T[QN:6Wb) >nEـ@b N oYYsʝFzϙXk9\ i7!~,4B:E)Ź*!/n*<^Z1F^ċΕrփrL'DQQݮ ` [h,-lu|qLt8 GN 8t/9ȀViM3\4C{k~PI0OjO7j ]mi/ R*~{x { gpk8KuS8Th^B& (&{Wn< Kݱh:(6˫~ԂQHyƟv&4ɲ[KHwY65C_\t"Hf",:X\]rkD=186|t<.S׃t|fE LUޠOI-59| +YE~H$*e'GX&`ǦGOiUZ/aE@7 ,.א ێ buP+_c뫶hG-ǙZї\X|vJFd6ԝU(\+"(,=8CtaWbS5" =}W kEDy[19JinOCτƅKn84/,M["%F^Y{ G:eAJ2Q%j)ݎŊ`Sիv# ++x?~c0Q[ YC9,P3jI!ɸb蜠~~?1)*EV4\"ʰ fRB@Αtz,X]|JډekЀL_K P%zB"16R~Y _3ANUiVc6>]W3 p_ ZЉ, q cU#Xrmp9Jnh OڏU8!+aҕAkeU/ =T82bX8^bhs 6(; dJ`ܵ)Wv.z0z0#X8Ŏj;=OV .vY?)v ۷P#`*!ւ7*lce~[af[M_xq v9e^AKKk^H F1XDPR~% f)i6kכR@<=4Zb;(fR$xuw=\,c}-dfN>Hlg3-|TZD5ٳ=ղ|/X~AOSrɺVȆ#,ؘjϟmH;:&+r?އMLnS!Wv྄v(n4E >h6[-$Yնږ]h@fuq<9x & IBRJV0#ʐּ6LC^|l4hұ^J)垅:FPo2$8s_wK2h`K6,fHQvlT bݝѷݥLV޷{ qFm!9 6+ ߜ^66x`jP&F&q˙є< +oNPMy=mUy5Et[5j)a9P2E_7 SKNQ@Ӥ8zniju #[5"T$@̃F=4#0YQ pApEM7qqCSUxS S$'VNKX)m˰j+ ej7(,`m0_iOhÄ3jTD]Ӏa>=\!Wl~x](Ɏ6]Չ:]6x sw|YxQ:s6O/}ĠfRE tMXr)E0w c0j[A(*E2@drBB"`빸p TI^fKD$'땩swtG tE7*U,4j0~lإ&d|᣽D.%)Ze3vQ_o2FY"Q@``(͆BMoS[[vYwx>G89_.f0$[ug!$0AOP]/Eh7#Y=<AnNf.t'T6~>QA$\*ƨogՋww%3 S \*L' }|*@cEXI/V>j@+8WtCbQd yKmYVB)<7;-j&dN-e! >x(!f#~y B>t#h:s '-߾Sc\vZgNKp!Fv:|HlWTP'C9mO*_Pi۝dD$ݦ憧lgYVkZѡ?AB#ՏyWGg4Tϒܑf#{7Na~0rbS 6U1w7U!%7jHB"Dy)l;QCh5: vtbA핅R&$|grTb^uk5'#هАsL ycGotjr3_[f|k #t )%92jrΔAt.x԰_;z0~FV<vuT}tct̗T2&Å;O|UlK+SJU?)DE(P9/LHMD CzjA׏h+_O@_w|ћ}x#9=TM8o\:NWI쁵:9cg 3JfsT;aUH_Z 5f f,['z rpE FZh‘IX$3 ^,6n6KD:٥=QctRi"9asgS, @i8@|m^K.'z4WjzƤ(%PǓϽUO(Sl{RQabܵY}&v~ ,[Xh͵6?3*5YI@ްE4):!r8^Ѓ;ѼirOooQ9 gXUx 0|d?K8ɌAIręLa#1, HWe$@i5~%9`ę~ 9QI2MFLg~o[gubAU1iGN<=f g1jP|wq,Nc¶9!ǚ[x{  D2"!7'ҧ k`wJrVlo0VC{X:kZ}OE-/)v.]L 0`{_Ry[~;qPAe@ي;^HPAW10 jb[*.\L1%:Fq bzߠI7~Mrc41(P%j2 X5V߷ +ER |9xMk7o1t=(G<2O`F㔪F(k90*"IchIf7$7/g^Y#HY}m²g@;&BL}U?wX({qgӡGGQfZ;YN͙{KBFjWiz0MOe1ovhӉ !t9m/g4L>͉7" -Q|L̢Md l]mg(ʱteOVY{/o=;`X/]u!|Qy?ji\d] ՎrэNj8݊8{ :qHj-y[.kF(#&X-y6i;([rb}ye$]K(Y y]z'@Xfl/Is}aG?2_S^>d7hu7^ho#\LLӱ>Ps/P)ٽ{#Z\aLaq̦]+X-Ɣ7)Y8þSMQH@D G߈'{WK'hDUv=7n'ÓD|yTI5~=C\h}H)NroC&g_P429'ҧ2w PÅ'ӎml3F[0( IuVx[d2U3(}>EBk򼩨ElnFo /9tVTxLծo=, 5܃#bE>ւIlk;$FQow`\8]+9ES@ e8M86엯DHJ >NDS6ꮑ.n$:zO'G6y[Y/@M=`䠽m `S"z;^Y4inmZ`sAڪb L/1. kbU|odQp0V 2kؓm]2\7n6O7,V{48NUB\w7c0KS+Id-.K RmV6gX3 Ҁ*a+=B$@Wh*Zᶞ_$a<û>O+~p4 0#K ̙{clTWzѠ0q8[`6Co%|Xٷ4[bArLǴ3s>I՜&@8AwdbIIF0ˊ+_0"@> Vy+Z2ŭ%Hܔ%(M lY؏B,0%_2|PށMH,BQ)K6`ASG).MVy#u+P-~5K텈Ya`1[ yoՙZjauDGuDה/ܹ >>+R;3ngBSāGyv>k nN}xjCcT?3 ӰާCB&v}:d ]Yo<]^vQjGv݃4;^=hkS6#6š>c'02([,oD{m.Q˶?'/{N6Ń@!%wV`Wy7M6WU|%B^Ћ1e[C, =QAń!"vr[_o,S-JltTX~ lO£J[FG IC/Y3fqv\m\v&1k'pν>$](E %j| 7{D`ce!Ӌ(oʹqޗ^6,o sREr*Ζ"AgQ9o@wrZ5=o5$ѝ Q:_j“úwїG"~Y]z/>;6@Av#a/ |X#5淅T~7^'Am`!XhW ѵͨEg\q0c{ GXLkhz fCK>EJ6%'ŕcH|p>A(~-BS: Oib8N*c=j'rUg m)5r 4ƑPy?NaMw| eԥ_53~ES!Y8#4ܗ]ܭ̸$}1F+w8Acٍ^[!mǢa^ޱJ#fsŹ֒refLf̐:+eb0{i@wbSwp)ɂ>% ? *F&reIaR @iD|b D_Aq^Lu4lTCQbeik+DW^n/W$`(?x_k%2 May䠰c)5'!ar~ZJZ> :R5'QV:JP?!\?/;vJuLpZ3V4$ E@_Drۂ%[~I_ZY'/;ZKOPxϚS^2ʥRwɇ68D}hÕ>dգmb[2h焀o@3O3*maȢʓ vNIRQ#soU(|+{r@ B25; qaAh_Hclak-y|rW]sgo5}%G͍XclP^<+I"z0M3 fn"@>;(fEv7vY^RZykuR.@z%] 28vxyCƣzFg#=KadV "J(la V';A"B՟GdjtCG:otTmtno{fud̻zx8—rɃZ}=CeuC@ONGH4=@*7.8^ jMi˃♴T`Z*j&v(2$[DH7 ^lG:Q z 0Sh9{'еdMr &_ oƃ%淼;tzd&wQ|V,W^t<ud*8Ȏ:%aS]rOƕD `R1sx3AuszP dDnj,-odG^M ??srom-ig5Ox_XQ3t*%ѹPSgJFoB;21y$ \bL=fƧ9}L1K),mNV'BfmL?hyg$YjpF!u8ocrڑ' u$mI2|ӳak|ʕ- $Imn\cUEmmI8O)P9FU%&cM 'b :\%%sM!> WǔӁ@2>E8_v>l[QJ]l[9 E*- or(LS4:p[ KË{'F9ogI˻pyHkQk0#WIXW8$U2US뽂1!15J<#CLH57_DBjVu?tߦ)" [R%1{ 3@9[g$ t A hA4uLE.7О\ `O2k#,΢>-OSlJ:CQjQ~cK`'ԍ BVHƩBN#o~9Jи1\ 8i>0MjfG{{HN(7~qaAl_4#UoƴjbV57EUR/ yw|slS|Z0 [}<$O2|u!M.ʺD+Z׿ #txQf:n &O J7rWtefzbNGIHSӌoi39dK.8~bPƪ.n|J8{|O?"C=f^ sI\5^n'rHI/s<vI[RO]dԘBEZ)AT78g:c8JƛcH)\-H'ꕃe]Vdˑ|PN˙0Y;mϷo(uNXaΞm *ׅ,\_v#۟Y]^*|2Clڽ{З!B>@ axbU !H-u]HU_){99pь# UVfj_L鉐IX=mBh®1$LrCERB3+L~lqӋf $Rj3r|wIO#(EvȄjdsY*`E5vAvN6NzD(a56wӺO!b^x=//uj*4r6Kyd7D"\x)\1z6~A>oް9$F/B:PҜ<,J>R'3q3_[ܜ HhMBE]F`IHk_EDݫY8ea4x4)5h0u ܼEy@8n_,9tR Z5W!pG= ݅=P7\jS# %Ըb~ g]HGGMPmv|fO*0 0L"y4 }{|^lY>XNUAfb zCMA5A(d4Py7&KT56Y䊹yJ R"m~(CӺz B ̳Z9%. Շ$I D\ UEX=;$VGVD>įHJsx*VnQ0fgDxxei$UǍ`›P3;Gy7vhڔӢ"( iLB g6AwZM(P* 3,ӊKQݭ<;oYW;511LE0Z 1I2%$ܚVYRn9ux$.z܌ВVT#f, 3׌BekNS| h8U C`~bvf)[m $֭01eә3K\`t.q}ۻ>8TB(HܸE f-WeQ1$hOڨ<9}䎻c%5:Sk!@G04":, UlǑ(ɏ~@l =0l:qcULvjqx $r8I eݐ~04 c4o8|a'`yWj|a`x5P]XR (e@nB1')#OaĹTl嚿k/KhyI[4tT}I*O}`\0X<3[,z-zF*Y7 TK|7ߔ)!@J|_54Jt(+/O AE32,7È^(}<#̿U댄, W)<9_ql@Y-p0߄DT)cB>S*%o\Y#,\:y[@tH|Tp+ |؄VXX%{oN'J (ʎe/r h|i'8K|)Í'<*6T4 '/"\"O_^%7'l4ۯncISف =ȔQjIƏoBc,CPi,crds)4eEE!-l Pw!̪g ȝ/15?d۾VH[th?ƒLimT #ϰqnϵC(ksA_>3V }46;T%lF/|(`?IH !N-VHkCaqez:jzg zVd"U׃ QSMP%M"'i'#&G=@YX,,R˅ It1]jLktɎ "M k-&!dGyd{OT7 eR>jkWWi=Sgs =a"Rbu{7'UNmOIѪ }7RIx8v9Tk1w(Oj,Ṻ/1VկwEŷPq#[<û[wJjT$3iBȝИ1 Mǥ0 );=|h U-h_jl̬Khup~1[A2Z^uЛR%}N6+]ZI1 L;@.p G?=yRrZxPI&֜]οkynh<= 6sy|O\|+[x#"3>,P)6+P^BRF$,4e1RFҭ5.Ջ~ò黦m81Su"c]]*df*Wg:m Ρk\NoikI1` >*^Riav`z|cXM%'?C N徧IHkѼɼiǟQP!FU+q+4|vM=!'8~c [j=Ζ{nƝԫR,3CrOv6hj&YݍzfQ#R3 SYn0Nn:7 o9o]")KvƄh?@OP~_&?*j[, ;%-Hc?Rs-.1ZmTKs~i?/d,uK!Qr}tۻR 1j ٌ2WF]\{ N|~IῶKMdW vډ-Kkċ}K?\N]>o(&e*@L'E4}=)^COMSɺߪE$2qC ʜV3Z)5YO\ t+6i$Ս#kvNO?(ZͮsK1 7XB=ͭP`mx%mWINd?$pރY_kj|m c ॆVé"\yF0KGuΩ&WëaI,Vԭ{''fW;)#8>8@3JtpkEQkE*ߜM@o>t¼a֝;=漨{p6;l:4CV)߱&9'y3,ɴW4[胝k 25m3HS*86?՟p3U1`piȥty 7yfu Q2x.8Ë hy9uI{!gKRdNA:nM@di5W&?Ȳnuv<Ṋ`D3S*A#]k "4;Lt4v#CITB |91lu:gs'H0Aۜټ`}ЂX/ΎSv(ǟ&|YQTا*erh\eoCc_4[H@4YS0fF":#/`r圴E1_AՌ,&`DU5GR/T\/6ډ!;ڢ (/1-k3 `G\30F6#I4,E Unl2 NHVȡ{ZaRhU(ؑ|Qzox% 09])vU7},CS@JHJpѵtYfp7`_g"b3vVAE3&?G5!C۬¤|'=e_'M(-kָv6>8r^aӂc˵s(ģ:oa~@X~EXPk0 Kd![Pu2awVǏdX;ё()$ ظ O,`mͥӢ eygYn0Gz;U3P~r\~)x/=dh<`ym&u9RÆ#m|gVB;fO|TkL9S&D`Q)l"m] FTc?&(c7UqH8?A>U"~K)r`B*~9 z|!87 4|}G0A8C#Fc\w]*,1U爛q&92-5rgr^?;{XsLH4aT;6Z)UCiצ Fɗ;wNZX&;« oq*5c?HM̓d8ca\?A[ՙb3y;UsXh%QɆh!jnsMeNxJoQ?6yMpl_rokHVcY̰L8쯠WS5rV`2#4׵ 7Yvmpn_\܊ Nv<`CoȆU uf=.2nςWHp#m%%-J|h]\w1'c%觬c}ñ82:ҌI(~;[GPrke vbyxlL{7[,Iݭsu^vʟ,`j˛rHgǔ#U34t4)kή`Ӥop&- Jj KJvN{&V^aO%Z!0MS5 ]>8=Ǯ2B qz:RČUw>Ԑ$_%=o')) p1[BDJ=!*X5Dnzj^r/CJ>g>mu+\^r&fSA|E'&2`_,7 FLK9mF#6GWZOG3"ҜD:ԉ1uj.Kwl8U\P'䟏a!(f&ڟv)3:ZȊ' ѫ}EF]ŲƍjlCI:] GFjI_F#snRX\NnQQ$.&͌A , kXU@l5㖥V<L1e ;,jG $C܉GsPi 1(2mx}rZvJ.mlGJ3iǫCJJ^9{Ӄ)^2jmp[A c.sdkn)[)/:wcqڲl7yD|gfR;$#qTٸv^4q}_erzgym\:QZz+rZ3,l.6×r|[u5e@VK(FBL" i>=;>S~1+*DwCFvM>ߠ`s7/Jd8Cq|־@sJ\D:%#=6,qKu/ O%Ff.} zQMXF%KY_Q ϥnX8$g*j-!3cjV XE) ["=r%#r6i+G҄#O&_:|uu Wbҫmن}8@Vy(ϙsyPI)@]O&[pjCmrX\rG@}1]9 t kHwT*Gfg=O[1Nփ<{xL+F-"ߝ'ԵVh"l'Oӛ3X(t-0lu ʖ%7pr ۤur^N?Es*\|7 \:c\,4!n|TQ!]؈Op72ͽ'^3Tk[-+hC}0hơ$yo&^ /#nٚ9.[N£!:[P|LJS b,}"1q yjAeWM 鈓~{J&ES>$2H0zu< <;EN o)-Ye; C%]NX$;I5JWCP6gЋu~ϑn~oi 5H "wl]W%% ߄կ&3Djx|gLSbwQm. b EH Pi&H@J i FOIa*.e8u8Kkܣ* 2.d$?HhJ4j^)YvI|Ɔ?\tޡT8煃" '` \&i^ur9Bu2<%c)C/" 3k (mf,<չ[weWw0OWH&FM"qH@Aj(ic #`>uXiŸVG?Jp[#3aZl~o_@9槊oIbۨHRFNGW sʰ86~K Y=}1QG%E-e_ϪMkL&l >g"GJJT{/M#RŗiK˽{s<ݞ[Z bNB1`jݹ" s/LjMt;\c$h|d% F[0fb#xYD1R=Gt%)3R9ce@`[fy5OF6vM2F.y*wV͒8j48W PяmN;Đ2J.PlDŽ_f8jqWsmh_zkdT94rnĢssX#EIi5'SE^M\IiEO b"O_,I:F1ىq=W~܄X/N%錱GI:^VkN"`[~_ nEꗢqra2l%m6N߶yAMІ|\zU9&lJy<5- - ư6%n=GT];W:GG]Vw,4ul`dx% )vb}fe ¤|59 2||tX?UzN-ċڀnz;ԨX4L'ٲ((%ȷ XQpS䎙B:*tSͅ>a y`8#^ġ^ kFdP}sO R>X٤/ mI4$ Uʚ5P$)K `TWp/cJgo9e2Ha?faxQ;yNWʮm͏g>p׽";% aٔUJd~7HeuA&p *{yfo5^ 81p gI2"w2@>.}&;S<z䲁?1 IObW\*HdI Ѯ+tb эZL hAgXqȱ@·HjDAe3hLOy̚h =kB=i-ƖXEYw(> fU5=Rž &Oe_^Q UexIOwl0s6)ʿXg`ѕ`UedtZQܲzx_@vʗCGt3Xkڄ3=78)b%h-(l-ZM8urr`LStpuVM@D8^qdͤfu~E)" 9cX<9nd 6gT҈ڂ𨪤9E%r U$jB<|=q BֺeRoL /%0ꋍb7Mh+՞d3A[pƄE[v6N'l7K!:Rw}žGxS'fZ9L>Mn"@ϕMlτ=QašH$d$[w V2d%^j?$8o/Bcd7 }^Q"PVb}VOnNyV#nl9FـAoGa=]53Ք}`UTd"XeǤlQ Pۗ1 )(qv

"^pURl{Y3^k<!'3Σ*Uaa]QT& zK>=x+5t )wd=&^I\׏Qc&} pr'':=Qkr WmfbygkaZ7$P?؋KMfX^ :9""H+ryaZDɷ \?ڛ_=@db0"AX)bwKh+4[X\P\⯋’ 8s{Q(jEs Tb78yfn6m89F3H- ɦ*J>k(7.d9 >0dicᐢF=`8Taֶf8bPp&қ?H2Ҩan)|)c5ަž"IfE]1mR# ibl?ƅ)lx f4d_*cXXbol5S-de%Cv~Yi&l?&¨`V^>;毝~ZCh=짞*_P* #V"o$M(Zx{\/`9V3+ʕ)"By V<13>N[f!<|HiJ%H!{9T1ǶyJ57/vLò֪:޷W`"WW4&u:7uh[0K䢡)߬0JL#cRX@$ mUF46UO l>-?mԬ@ y>(dH[WǭSZ,?Q[YH]7I!;K/#> osQbuxG(qid' 㘝iE)OCdñ|IoŀTߢ k!҉/>6+(jZ`njRxɹ f!UTe`y;"t(zc Lz/ {XO =Əp |g )c|././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2391646 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.vol0+1.par20000644000000000000000000014413414625637207024267 0ustar00runnerstaffPAR2PKTHcy+|qF-d!h7@PAR 2.0RecvSlic"̸X#r''㍡rKW2nVm !O vAuq$_块vDɑc2wP:G`,%8 /5Gh9_4!z=lNYAja!2#YБ5M?$9e %x "0]!:T~o&5&f2ZSޙΙ]з 9yfF(ZèIA~7D}2uݕ(EwM9ރr Ih/ i<}D""j[~BdžI%JzX9)h:KX4U_@w~H, ͋7SPd1P &f*a1|G!Ga3/~|0lY2,}R=2/Vc1K6߲ՏX| de7K9uIV^Ruj*d,.1jN})ShꙎy _LϜtl!ߍ*|W],5RhĘ/'7@bQ矍fewz^(I/y"'8RrGGt '62M }O r>kaT ueO0\4.YB@(FEA(R-uSYhxVgBѫBM(ʏ]{7ܧ٢w\l?t8!bɞ$,}e.Ӻ6=̇,K Ѫi #-5l,U V4 #­Q dLCXgc,SRʙ&+kv;n}@FMi 8E{\N$iSc)ojS;;l?4fbL_qPǧ [/H;?еi!P"滼>Bu oѹ!*&*]#sk|55&3O/4,yjnsn7dxoġM޾~NјXčttqUt۩u **1|<~LE,- ͘x/5Vc׽_, ύ-L5(=˻ Y)TOZGY6=?jvj]Z;X|O)mF, Ƭ5KBti9IV޽~ ^]P5u'i+`g6#y Vw$@vk*ɩH/#"z)X|TRC/аVƗYʀxi$^.@)SL?CÃOvD}ĸEG:{Bybt\@JX[{HSiZ=R9U8#ΟD~ G%xMcݡ$#dX>q\BoRA$\qX,BqH٭tz? ˼,4bpF7E u8 Q % 0`-^QQzu6tZ[ŀ{Y7}FsɈ2hQ ?2}^;Vs1=(S;bd?@WW`6IS{/ǧOF 35T}Ќ!a'؃8*y&HviWv]87i,foMF|)ngnINJ+f+2 { [^L9Jr(lPN)D h{sx 7}z4z{bV0wm|Ԟ֩(QJ*S:JgΓb:DdhorLؔGפd'X18oxavq9Y(^<6{Y_$Cgq~-;b5;%DHږF{ޓ,M@MAPYCt_γmq2Et[l |Ս\b&,ȃU Bd4!nj0@ׄaeI!k 6LJU}yS1 a,&`#x[i4m=>JGi"bmޑs7=* |c:N0&9- 7JZ_OrTqbZ5iZ}q`K)UuWV!-XTN|9?}A.:b[4hVLX[K5=;6etv1V 4-K4XTJjSq@-&!NSYE)Q$#?4Rꜰ-Sͅw0>D\#;cMpk'YtL,t| Iܖ"F+Qea⦜|T?JJXapeC1em K>,f/f&J=0^{kFVcFaV&|[r:ۃZƤ Em {Xcey_ T<&KTml4aT`x;EJ>4 #׏t) rsq0a1QƈФ*,Y[@6fE 2ui+_kŠ"ɽD##ca6z+z4rFE3x []$ĩ5?@SGzw\.arDʺNL+&%"- ,v4C| ~k 6Eܵ}J|pPD}8E~z.>s:.3Ujhq7֟}7l\T4O[/4c$3s^Q`g08%e;Gߞ{q>'M:Y'РOyPR|׉A\A$?>:{AՊv~Qimv  T'uܮN{hএ/<=<9O8t#(a=S:ox d_h ^jR<;dXvFx|j_:  9o޼OtMxigr-l׸YjsM3xEpp+2S4TgҸ6= %CCQ@8H/[+\&Ԟ~V:#RY46yD|<1\JحꠅWD;/h*gMqlڎ^zهKtO1n෎Гڧ/ZB/uV6[U7\(-9bOӽ8[/hD[,_cFs%Bk<<\;w}/腽IjLH{ϠwΉ([fLf ?ņN9~uM'e"J'/,`$7&Ǭюրy)sԎ ç~cf hA^){gˊ_`G_#(2=qS!eֶ&1ܺ2O9nHȢuC}_]rB= B:Z2g )!Xuh8.5[=q,H `;T%DXĺaSb_<`!:Ee&4#Gwfc<4C]7 4,ݝn>_J}x˘<_n^6N_H_0q,+=ƒ5R9.h~$jQcKC0W0yEsG0Sdnh8z4> nҥK13ɰ)OIlw rEk|ڟZuuˎ|H: O{WqCX&c;7=Jj(|ږ|/y{`7S~*OѲ ;>;Uf Xq BÒ&m!T5 w[69|I?MS/>7KcGߐbȄ[N@W4&/|Wg|!#l~ %b"wɒ X뎩`Q}rѠϞPQۤAύvH4F̰C<?gZR|ClܻNlbtb<,oB˾©%J[o$Gg뵿[\nm!&cG7D w 綢:S12\5|jpf VEH[ͧ+\S;HI]S+a@s~@|!.Q+]+^_oPXIuiU&H1*Cw=${u-0(M&.Txol;nL>q`hX.:0LO)2wc$>R-ѕPs9 G{P.XZ'U+}^LMK9Xz--7o)YP&5#OL9I4w&¯:R[>MU1" yZ  2,|N#f[Y8P=*s cSNh1lqFoAS8>?ČF$k{Vi0Ue?⺀VpB 54xDÊHpgYG F7 xRu#ŗt#0KYND/"vmjVWJWb =r¤ɏJ>ld7hsL 4ʖ╥?=ϔibR0rSy[S_@x@ ifQpP|JNX!2); Mo)=;Ϋt`mW^ˣ,59DU"I' ]In2/x_eY֎8> ɈAa:0 e4E84tKSvH%Xtg e<&~2FQ}[=UEL1dekH@AVw#U{VTxG[y70Y\"rpN!qfo2P.Lm/#li8F݄&̋ g;#a(qQ{Ecu|PJ(/P5^B[$U )}BZFoϳ4dr)yߕt9<>f ZlJ /rG18媉7]CZb!dB8Q.XmbOӁDAO&"aK򐺅fZwǀ^5ՙ% )gv$PEy8rknbRb2{(SuOx IEG_[֕@҅*"Dgm_8Pj25)e_v@8DynD]r?xmH, W[_*!?Z**h|r flǒu&l&ߨ-D(Wͪ|A,QKk$K1oi(δ+I`GS,@7h5O@!tsOw5:2n!Q .Y:2XRQҳDqǭ8 d~!OTV>RbSeJz,P煺l6Ռ'M(s7`]ig%wI|:T8s;eš@*zJҹ)r;zeR9^r6hrHxp4 :X!1mK3 ^嘓a766Bc} ٛ(F$=yljAI$Z_4U˷ 78ͥp4krjL5tTZŀ*[".߃޳ bgC0Q&:*3PC*!RzA5Y?(Xg GWD{ G@uTLpg}WM \쇩q|z wstH8Vʈza3;$E.IpzAq]:V]lnUR*̾g0tVtVHbo3=u[ Ԟ8fhumnrRlsG}u%@jC$jiA}Ǣ-oHps/sWݍ]!#$5[ ܜݕs'*$zuJ^XA#.@lCn6^Jx[Pg(7:rR8@qVNdy؅.3'! XHJ[?2Xpetl+.d1>. E}XnbC!-6 MS4УC@z$aIG'^Pw Zޑ> MR>Qf6ul,D襼- /䩫"{ޠI1.ҊMPs趛MB@Wr%1L6]g 0Hڬ2A! ![PTY |@AH#f_Fb^;9Jɑiφ Hcf747?!ZzzaܿO6U1I 2D ̩&2EmOwNWaj~:O'N2!{ ZlfUcwc>X-dy]0dL)[K \esZZ Ԏ,%(iEfC4lrr.R3JA@DTz 9e0?qRtTsn`b|KDm3b 5'KD wX8yGi>*ցEvl /zࣁw^eHXPees*ɐ= KNtCWNTx`Y`,dGšy5Ac=~ K?&;/<Axwh˭{ %>0IbP zoW8MT3pu $k @TS@"u܌.VW-1<?TW%3›/ *z$}S >Z4~Kg5AJ؁x)6FiR*"Z[U#o4c+QU#̵gIs'-Fyxe/oq%jn)tbv@ar6|_N/tځu?: GjX.> JTKa[85'@B#%c>kfSx$';9SUAjguFPSkĂnpLX[/TKpR`1خcY7=;J}}ws%D8e͝cSݲkM * '˛,"= d߽>#Ꭵ☾ }slg\S$qJn* \ EL~b'ʜu &$A *M0jv.sʘңsO$SUdoNδtS5~Edt$μP_^# frsFSs<48a#8[Wjr{݋`FOwsԕ֜Y+@jf @Le;9ڒMm\=ܒt}'r%)./osSO6 k~5 Per5G0aŕ^rM%Q6܊>8KF˵MRc0P{K#Y$ap`S]f#hID0o{ZWcr3oު~%u,c _]Ҹ%Xh%ݕf[^BhE φ605 >NnL{[-PK,C0&_u5z`M+WZ4 ˝߰-|i+`@s - cҎv^| fW IH`=¦0 N99~Z3CgoJ.WT{6]:Ry+d4˦ޙ:͒̇q(`R[Pё0j{e5Vlؑz3ln*K,3$u^boZnUF}ȗM-*9O< Y6.b6r61IwwL]OAyw@NټE _nZu3\jS~aij@oDN<_{ u*H=^Ak6Z}&(vW=yFcSY;cL]Nݬ#F9 Y3z#%[۾Qz\Ԃ?9Z g MB[y.OqUyg3Y'Hhk@YIBƬvݑl!Ԍ1Ǐsmn0ֈf3`.?+F,3 ?&\W ׇߙHxݱQPdMA)#*p'EZX .!b:2_ZΟޚߦyZ+jQvNeU+;}Kށ(/+o@MYRZ8_֤8~0UgYL(7{@~eG^T◁{wnf{@gTM[D>"{{bi2n{WG~/ſ~RdXʅw|9Ywƥ5ȗ߫:/TZtSk c_pKW>=CrF\+kk0-U#|E&3fǕ(hVl#.1WQcl\*!m2e(qjڎsJz0f$ጻXGJ# zIn AʅW-f=geouyL{7LF+ΙSܴB tlW93q1^fâ42Ks_jp&LKU(2hY)I\oa bA{lGk5*խ^yWW89`3c]}~b8QLb=C0nD$mIkphԔbF1J}"0Mo9I[e=ХIe!Ѿ[Xܜ'$TPuR?U[̖?*6IF)Z4;YqTyx`)'…t|WF Շ@tAq_(5.v rAΒ~nsĵsj23@`K[Ie0mHɺ7x`»jيx;u  &Vw\QQ߲ҹֱ]W@5BK7P]lŲ6@ze=\C\ȅTTcq!2QV*|Q?܁KTNgM{BYK==/EeeC25 C%]auju3$m΢H[Yړ]Fj4VeՄ;ly"-D:eG fcC}>Kt`BV/^SBF̵Ma5z%󨻨d8PJEN:UZɡjvKWyeż_|X|^ D.ˑ;iK=l2@MiAXJF)-yĐa^&Q*\Z?kɸ||eak?l.wkP6V%Bv~6nD _{SX4jǕ)N±4?'M \%E-5$#{#T.41[znpbOF=9-nAv/38J2}.@zʫnnK&0(`JQ쌽Ė;q9\EBST4R碏q˪w,>=KPC%ٍ[hJcBjse{;l*=tMmFa_" Ev/ju#V M<)ˈTЉ&C\";]=@>Kj6k hLZj3,lBџIKU8o-?ܓ)מO؄j/ ~+h=Dž7\yaeL L%ƄmXL$TN.|BV9AXSGNqJugAUSfOvFNUn1lU .LެRC)9u0uв*ziK˰EG5f3(1O~B@. 1Y=nâe\qr: ~{'pu>wz~'a*CoZhƠ8 E WZF[_?zp^86,XCa-@| M4' ط$M]fjX[3oz*ZV܂kgP\&p} o:?q0-;{xx;O-Jz1GPz3 |wes[ҝKx[+\rοc6cYU͊`=sA~mD%="}tF$3raK'EB0ƋʈQDMyw>CdH~Hhci u#e־$8;7\".\B7VR_5 R,8c*p~_Ӌk8(ޓejq_RؘDv>'`k~'E !-ĥ ȞB,nrm.ح.ܬv@AoEot1(c>DbnU燖RF3Yk`6C^!H:՟, d{g/s-8uPj9-&Tjy2,A)sbu`^9Y5ےhthJa1|yb/HK/I>~T9h5TtYe >Lkn᫧_$,%}8sBX^ ոȚ[_a\?g1sVL¦z##HZOh PF﮾VJ*nHʻ!ٍvwΒZ^vaVI!πub u m!!|_ d&m5Օ-ҖWZ:WDצ0dUoOF"!m t  kjX]פL6rG__߈S"vPIga߾*USJ6ϲdUkw@E~`iE31tذ PcXXCuLZvFIN[fdN0SE;fO(7\ | -M8]6-yE{L 7"v6.DhN5bZ8xCtFwvl%>1P+\QVmmǡ%hv㶭{}D@CQLed?-M׾k  g1}y^cLetN,Jc6P#mhx) ܉ Wh!G7<i>iKea] ;&ͦ`L[Ob(;B,y!oջkxT|Jlwo>mZ:wNjcKр<{zZ^dyb$kl85{ !g{Ӊ5DORdٲRߠqDi( eC|Ė zC*Ϭtpo2~b ,/ǘ m{<(}Jz5HոI(%}e wZ#Jz~ v韯4<|vU˫FFڠ٦51m[NjsfloxLϰțM_ JBoUAcZM'yMJmCxdE7b;>~s9;.t#3s Ǹ<MسI0 7"RFb E1(qxU[oxi'ߡֻb`+]~*4.p Q+?4)rXYYų s'f.kV0M%S \on\i`GpEC$% }[o1UާŁ1흿>|X~:`OSGI*MuAde 0#*0]89mV(|k7n=;usHj!ZNfm_#fcW+ $jgZ{[fV?Z5TZyGR[a10\E~n+X7wN/>ՠcZZݿ[IEykj -aJ&޾wٓ忓8-4p^vT/~Lw39D^?T)a7pV@%{D;_{2J7~ZM*Hv-Gxɢ0d71j_jr%{Fz*(fS$58@^݅^D5>+ KTEx[{V Cȷ5;s>`Qu;PóD`jZ$1 h/3>_5Kߍ*]>s!eqi@An:W?p qk6l.ћqrK;nOs#JCkUÑB1?WVIdW';CɥKjN>5Z -+ޓJ#Z¼Qdn>Q0#+FtXTId{"0N,G9Ggq~pu In7lN3b{X_R3GޢJ%0Է jzԬ \kWhYm<j/e>1o*B[,okqi4$4ӃCQϲֱx"_eFŢ moB\@l%B7aR1xNv_]hdci;ms3׆؍-o OUzgU$HLe[8Ԅ,y6с'[ZϧK.E $Y]V$c  !7^U2H.r[N:<A@ua|N_)'_f w}t7נz{ *!!uh]63 ϱaUAjB5,7Iiؙy\B8B2"rke#%~} p"t )J;1<G]ĄYc]ZF꾊}2~/xZ$gUS_&tޘ`bHM?e k|Χk0,5o2-=7M(&y{ZW`w8jjKkS[%i/23Ca1[ްrPonm߅d='墻 ѷz|Tڗ'£r4גGhpI^n7첉RŘ|c.FĻopSc~FZ;;IvAƩ:*QHxkH]"r'o@ϴ`\'nPgGj*s3J 4bG$bTN'K`qC[9r ,t;I;pwu~=r͘~Ge)-yfLj6< dٰoYaԵ{{C kL*!<J|u$<)2kpsސ!BE,D0m/TƊIWmbvZ? ]huP 7=Z8?_Z[MLm櫙tD_r+ (E G1p̆TLtɱ5[¬kڱ&U hCdse3a5MU=KLǻl 0ry|fә8pUSX )xEczA$9 %"B#`m*CT |_>`5wE0,ʳbB559-̩g,J~|%tL̽6Jw4̮Aοu.8{0)(?[K< /f4044fӉs3JUh;zAΎ 'upz܈č'f_w{L_C/\Cn}S ZÆXtkO5 6^7F>%oee3-pB$S? *ڃaOR>/+lX h n&O``E|JAzЪ#hKϮ+^ا6O۲+:a{zβS.Hpm f~Rܭ -V8Uڑ_֐.牀hx&̙w5gd&)C l!o5j2j9z+clbfb&>D>8=)qU3Z{z[``aJN 2ir$ gꉤ.24+Q6 ډJu S߸,`?, WQ6\g2C|P&}(j%or.$#1jz4Ygmp<}]4Kc__ xQuwxX DU PS_>s)gBTϸL\,3^YYp50AUGV|mFmH-f H1ClalE/r5ý/Uؾ&yMkQx,/VdF9ftV)RzKǠUOq^-V)P:hZX9rtr:q0󶩁")6)Jb6a Fg'CQʞ*(&-h :=剐1{ꐓ\s^Bbr10:ss*c1DtM)mBT (X7-|p݆]⽩֫聙F%Iv$ gɇ1'xQMkF]s^t~ ѥvm<(($7wy\_Y 'BGZcq&F+/詪v)Y?ކw`Ui'p6jmXiE;ZRMO-9H¦#>17za`LEGQTkg_T,mRAqQ[(.Fiﳴwa~C&$gՌ>R)zև!rz;X ¨fwc.fUkݓF)hP0d'd`7xD@h;4>O~-n-UYcUWpBۆHg(,…,-v,Œ@I[qSE 3:B),kR]haYڞ !I6v.^Zr>Գq)9pZ@zy5EFB'A#r8Ҿl(h5 F_ZI!YSKn7cL#g(ب@|9˦P6ǻq^oB]"PFET/fD`VeY红*^>|k8TڠЂ RS7#.\~Xd7\!=*j UX]dU괟:RܯrOmB|z_8դcU}rev$b:> `EEEj͔ݰ|B%.(}*iD8=e af&:N삔 G?_ c"LY?A׮$ܾ\1Lry|AW z")GL.~u}Y|'(GC%qKCVU}SA+#nAg^2ǿ3J;1kBZ6E^0$Ewu2Sm-fFcU݀5j`c`PK<,llQ`kǂ*7b'tFͶIHC[D[C4;Оlu_[wotvsw"x!$.L&^V -΂ڀ*/Lv_aC^?S-c+Q _VGT_x \ɢk :ul ]0CDLҕՂ)c ۈUD l՝U0ceeBt@b^m-2v4'# p*ڈ5If/@ .V TVxU&$]8ܼ2 N@{C(ةCYD$V檃_E% N'm{j.fNCefe3lCSj>ށ"dGbm_jB7O%#WT`JB؇p g;9A\y`מbhGC3#XT(Gc)']2bբ& :3ʒPs J >ƻ%# :w@,m3\ΑSQܜ"ZHW&enS\+od˷qvN|e3ZzLܵZ1ݴ+ ,TRW6\uRi-} ya.Z8LP^('y*&o}I`+}d֍r쉇58vYZ% Oo֎k{ z^ 7 S|0MJkI1O)>1OIKwG9bKv-ݟ B_bZS\\y㙰 (-˯χ޴%Gԗ"u@is1G wbz AŬtV7, h0U!}8y}4FZh]OA3 -9S@nMCI/ Lm)E9Jf+D\]ӎ(h\̣J,\6ԕDZr|~!Ÿ #/d.'Ume9%@D#S*jdqm]8P;t{%6x!/3Sl6ՙl777ZU7:5rm!Ј?D0x|mKi{J>%)jPK?d4Zi-]<yΌHyw"-_n?^'fupaa1A0iY9D6 ^(ԦzVa֌'$VxIGi4wDM);WM p9 YN7'wEAܖpwsz&{l,Wy}iˑj+~9ʋZ3H"18B6O9:ff}AU*!mx4^C >1>cDCP6O ;בbD@c*`?>_RRIpb dz|l~Ki4;5OHUKO[.)A%5e,`WSP{ǿW}{jUob>rN7ȝDڗ6ks b@Q>p;E%,O57١TZ MZgM[U9#RH ̺.+bૂz C]EUWVȇ?˴C :& \Y'E`oN[Ӆ+՟+s(&oWȩa.ʝ-e\ o7T B8n9h._Rx?5b8)gFړL%zݢ27["yqS^xJnu"|#o1GkQzt/ ,rfp]0*NP0DSGd\|.3/8]Wu>d!a^LV]_>@+3UQ!{TmąFׯ / .YqTzerZXpv0)R$Od.C1SOj)|'t&e|8D\#`PB&f `A*9 5Qy<É.$Y}< ]R%s=*>lk:je|fUxie怇Aq(Ir? u&c$3 L1>]| y$?Fnt ^90rtv"&x<95~Z>>Aןf l=J{Z.fNb2αP'U!܆K  L3%b5Y@fcaJxQ9v&VOHt3Zh+ z`; QȬl)]O̗pI@)qC'λfL_\On*g R\ ].0e$gt&]'5Qy&t#=6tREX )@@pB#1?OuP"y' # XhoCrt6E risH9}iyzO? [IĆwzS|%=ZK Z*7Dʋ؎;Xւ/:Dl\l_OH𝹶wԬ SOXЏ^.ڠCdcʫɯ\q|zնZ:W+ܦ (F>r-/)dCXzUdMGTڮc钣,[S ]y*VP 5b|SLhi^Pu`T_-P,;V .J;7vFIz*3V I=]:u 8׍fcB0fԠZ_vzev,DM;$L|΄q(8\AŐxQc2 ZՖc Ƹ*,>LXXRrGH σ8Ǹ4ǥGq@?̙S(۱*GI.AA)գvT .AaGٞ]x 6"[<KDEyxw:RU Le!A-D+cWycɵsefX <k yiJO7#x%cהU(  !LCDyEkTWh}y"=hk0n[X1)z9 7IBlĽ;q6uJs+__M&á+XL-V 2½l*QAolk6R|qy0Z˷ꛡcT -BY</E 4s<-'@a͕䎹<>a#'4h3c-I!zYag~֚U`i\>l6lɩπ0]6QݭSv>gWK ؏,~zZ`_) y S坤P5GQɖt= gFJhŏ|Qe-872@-k~(;\;NKi| DQnf'4{dq?7ূ"|Arm(J6~vޯ qhVle)Sad_ӅZ Q2ךxY58J&o7}K!@6VS X@jR~8kOB$Y/b?o'ˎqAZ e'.Pm>bF9]C^?TQPS OX4|5O`ѥ;̔7[5&L\M(^G!q9RTJFvzES/¤2z</ص = ވ?Di +Qq ;DWc97&d`,PV+? 4G{Bѥ`]o=ޘ"4No(-Qޑ֜qVة @ ٱ1X .\ATIxd&%⁺5wgbBO ԓW[Rjᯮo V1aH~N;aƮI,;O 8@9P2 d3Cc8թq)r_[ h 8U*r j2gT8$(H.l(F/茒%$txG#\醮wrM 9ŝ;5X"(X*B%@hWͫ2vƠz[U(1 |N`b!9~xh y"`&z7o 8bZʫk_jx_#]GBtԴ@ݬmƫ@߾ 6*jkM2ns.ĵVΰ֫ϡꆐB!At!`JPkΆЀ xyKk6NΟS i?Ikk2t/^aΏ,|V _:0q/-" |" Dx y[EHvDzDʑӦ=Oy9`JBdzˬ\~k;bݽCOuX;X&5meHħPR.Bخr蝴 o>,/uǦ L'drELm! J9LY,*xw:q0bU^|LM'W;07A i`95 U3J録s*?x\st!4U\",N/CQ6bfEaDd<% YB 9,&ǝz1Ď@&ڢr{=83`@/JCm]4i\ڙi7JF陁L;=**Cq]Tq?W.4.3)7u{#OW%ڶsho5,Oˆ ck--]vxBe!Ѭof`ۻMI,f9gϲEp< &dyO3o~IFnؙ[U!Ǧ3BIEG<)Zzِ8RXLlMΙCM'K"T6oČ" m=bµa݆|ycgAy?_Y 9"o鴷7Id1zHXk1lZ9#4;Ek10ߤ1QU3L aly_Qӣt=jMQ#܁˙"f`qp! 4.9w.^ǻ a.5ihb7'cr7s% K,6bXvI)L9OBCkSߣu&4^.ocAoUت<= + HC [&uxU:Mցe{>1 2IKk&1/k؀ r۞ x) 5@5)W<.6#2K0ӴO] q8 ݄ĵ:: ̹3Nu1Q-^4Gzuc&sul]K%NAk8+< OR:ʋǷkFOUkE9Tu%P\=<ɋig,]T=fplN+œ_>-'yJg^7BnF=}שĭ$ʆ ?ЭprW%2U5fׁƙV74"K<M;~7]6 Obv!N8NY[ey3cM+# o;](,4)W22(ShN蝝q_mq#; J0Ikn}}~GM*bUMW75?{!Y-dOeا.ABG>Ҳ8<8Jnw7X|Ha@ʣDC\u?Gr׎}?Rxl5CDhwGh%r;L nw9h98!?}Kϫy2}!Yr%]'CֻݝsϸUӏm3No׬́Ikfq3өmQaeNYQa`0#9hIϘ^?@/l=5̶Ƨ\K2o O;%RaSe E{晜nC.m?{7C% As4.GmU#g{>-Ȉ% 1>|Q}Dct&<sHɆj%}_$r78dJ7.-,Z} z;UVvq^3v)hpkd\aBCRdFYK {0(.=8{)9E(r˺mh&Nѧgxv"Vć%>_S=,8&s4 - OЋ 4{ifV79 \Lrc/H;9/'@"r3$lp w(J|Ga[wZ%w|W|Vje\nrn3` AOt%" J޵KB=-(C@JJ3@v?Ð~F+tD NAlleLk3S2({+rɦy0}ڑ^GYO;.J>%eFnvmi[]L*]<;iϡjB^rA/=f5涏5$_W}D~[Vv %W &F)맍p͎- v}  ECR:vC2&ڣ}>5?FҸ|#or9p"t3ve /&wуy9U>Y(evoJt(. [ry2u%voq~I~͕W$ۨՂسְKrq:lCG#_a#|9P6u \;Fo qjbGjhFvOnDƤMwzNjWYGtub`OBC{LsC"!]b>ӟ-{ jriH0+*7@O.hz%U2^-S+G $$n+b{$^4l/k$.zrG᭛uC;pNTk<^Fx.1X4"h\y@̾mt;=}Դ}"v.=jvgn,i ܼj&\ܖgUzT~Vġ9q0pV!^?q6?d`On(!AEgApm줔WvmR!# PòqY#/ ƍCu_5M|#Ƣ;\aY|^*^\+{qv֭= _RKo ` jGwʯ0*}-@%{_<"WtTjAH.jyNLMmv@-t5ϦX$by˥#6UZ Z"(=̙" 㑝DrTxl-{bA!d@#_yy'nNk}T#sY׶糯XL-zNFOLDK7JB p|J <9o|`<|ieEa͏QG7nmW K*DFHa=\$C$`CLksRzxy1i3社j1ډs6%S;D|q2+^]:ٱxrgdfH?4^Qoc(!\Pk{@" * C8~(PW .]R&Oסhծ/^)- u#ӞC~B7oQK\棿)udGwD|vAWmcdrf U]6hUwiʁ Ej=[*ieF% 9!6{ `~O{s.)tDc>o2="3Δ§AD5'KA7iw΅M1"a2P֎dQ̆ "{ s$E}C}wkWڟ:23'׾ +I@s@1c0x3]9q {HwvBw8/ާ^ٜ.2)^1"n$JZ&S+9!Kp9vrvAYS8AI\1P]vK XQ E1[5$寫W! m^ z8i0xGٌY18U2Zu"I^r(p[t}ذ|{vaˠ )9N.,PfU D伵hw3ufB˹PGql CyyGln)ׂ.-0p>B2L#PwaxT?BݮL8)l/,ށXƒd:W$Ѝ:D|GbSx3ʚad\ZF| DCKAakrMU¹^l&rSAtoďB?BwTaF1ljTiǟ_kIkVqBPHM)^ BYa߇gg qkxu| o7B<=3R8^ .Wy KM0:E<C̒mY{I+۱ Af"(*L{Q*SI)ұV#w-4j~ͱזtdmII, $>\1}H{lzKvUNl&r'֦dt[' h1+*^i$MX֏O&.lO4mzĢ v)%=.8J{x26EG>HEgh?v%x,筵og(ld7q8$%maK~!eJn&HR8d?:P 56"L! G< R~Y^t]u jٱ2U6aoJ5%? /Ԥ!tšzbV (>g0ˇ}S;cktٲ[:ztiykRr MIwP}%(f /nF|ёkXhoV3=lFI S)+ng=*״f NN21p5Oԕ4ŏCy;D(F]MAK(>:\韥%j-zMRWdO3PAGg!)afc]J~wl馾"vJX7O{#mi=zWpa_Vc_:-ْdO^?L>LOЇg%pn&|ޠ)5n\ ,i8{F8H/@Wn?Ѹ nQRZ`Ԙ"י:A64|_qd:fVD@;qd+=aJp%޲kyb#%??fcry1[ѹ떅 ޮp7 </6Ñ ^Bf󘠺Xj3\H W_HAxQSԔ];\ :Oˈl'B, Vo0Yȱ{̴IYEi+B (x"5ŧ&6NgKT:5+D60oto Wơ\ܟ1>MHp(@]'ŏٶ@J fm7{CarXL +0HmPKQC7O.9^i 6چls#^x_[dln)Wtoz*qpgrzo59I]>W`A$?kAZib?FA T&qڕu8Q+SQAt`Zӓ476| 2X/Bi''Y5(*֣anrw ;?u!fcɅ߹-RЩ^ A.(ҩ<*͍б6t`Q gp/ݹWܔ}m ÓD%F6Ո`hxoOø] AAx3``g1; ߃ýr];(bnZEqF;0X|]j_ 86Zΰ4'ЌW ,톬K!`"֧ 5SՁK7'1b=x,/"<5J}&: Ӭ)AއFk ns}wc0z|; T׉F;Vx_ړb'&wvkb/LmΘR?#Ž/fU^ۃo63հ3#}|`V&;d=Fِ-ψqso3G*@*^<[=l%cF,+By9DDGR ey;R"HV˛Y@T+cv*] aEt.bRK lփ.<\OЦ.odTcɧJyZLPN |uKlњi0rm^x+iB,$@PNGѦF)ܸYUn9cH82)iB]]"۠ya|7_yJx': ?=g%Di+Z6>j6 gmCB…VCͥk |lQ2l*I,7#E7!CzB+`Л dϤZhv)Hѷ]'Ka+ ~SD3Iq܁āBCͦ~ /!& oPr&oop` E ݮ,{p#8|Ut,j)C35f_gIUR6}~)s1SL"_>FoTuIWc+ODXD# |(~`xDmVut|PWՠ\gM0N-,U=wiJ&3M>?BvƕJq)z"iv7/vP{*E3M(tg}uR_e}'\ MA~U>~ s&YHh"k#pz L?gPc| +7ՖZJ&oO׆l P>}O A򁳩7%VToa jk#o,xn}M ͮ=0f{gG8$ n>gBk[,9tpE0P[;G2V5zUÅde4h1?7^yDI >$fxm|~WiDR)m5~J0E(a7I^w ОqY,]:gˏ q2VpL&*2kos&vI: E<hIKkgrKEyqd1ĞFѠC|@q$[QE q(GBp4xH`!ĀA X?tЬ _;@#jRظ\VFL!?5gFAE9߅W1 I(_KQF3K50_#izˡ}(g9 2:{G-fdwO 6 m_ jHX 0!]fu-BלUFoy̅zz3<4g7"?~FN68_$E>wh`f5ƦM28= 9 )Ldi7N)q5őNOcj+ԓ3t\?V UB *LaWwEb7[/rì'l'S:,0O>u]jyJw@947+߱36i%l`_[\4s,< ~H.nL~.)@@z g, Nia1~FϸZzeK 4׶2BK Xɾ{LmQxBg%x.dvcH13FTBiCY^xFW9\)u*(f/{O'H Wۨ5M$&LK/C KVl"30kbeȋ.$5-Ocxq6LDMUUY7h? M62Ƈe TaD:?_.H7lǕn<]? *e O'#H@gCfx1rF!Ї]AofWȲ{;xnd)k;~0H2YT=k~Os1æoUm۠V$nlIK8gGt6UrB Y3 xB6@OQ"0pZ˖[ɒ04+~*ͼbak$7Cl#Q]dG`荂& ȕ(?=u9 N&i)Iqen)i; Hɛ0g sֺxp`K6eR؂ yY uXe<&U֔ףDEv(Eh3~E{OU& =ʢdB\u/T4希}C*T=+ ͆2-6u-f2rM!*0"3 Y (lyqN\FV\G#]ņ ftWU6GM*>Oz[o}ob[0 Z!bܻ5cN{֢ѫl!=g4kS]Nt>O36_©ب%оb%;@kv).fl&uqOJ`}.oD(qE`_5 qn9O"/$mJ;N Ʊ'ɸ0AmޝQ|[~LسMY?T{*$ ިL9sj8$$U*"<{)l =qUKnsş T[LD3;7-2Z0[tp HMQ4y#b_1'\ZOw)??IO{cx]o;DoH3K(d ُVrYfT۹ y4dWg+7^(He:6ݍׇ I0Voeip|%φ `=&zf=%'\ F젒$F1lqLNש~>|!OaQmizuofMm371y[5a͢ U'&}yЭ6< ~\+duyE3.15k_U4P?{%Af-}&q%f%* S'^D\ 7)n3Jj,i.[D_cďoZRr%eBo L+>vv^rSOo%]XAK,$yՁV7n=q8| +*03z-96IKri~AtMet ݉Q tng+h*!M,<v*PuCuH??m"k[$i۩7vK\k}q1[=̤dYJ_AJY$-(s 1ByMD}L#p(pWCxAީ'L+IjvW>{MYh7Ӧw @r[ ^]h)>VDnk%JQ {PhJJΚpO~>6x1YEt/yj1L5VH=Y?͸-Ѱ+n&, #s~֫#r?b#nhNpa^|;Yn%3ӜJR@,SXvO-ɷ',;aEi; Wk)iL7WsAz)G#O b _gO C[^Ky9_j'-ߡwUR3 ^`IlZrŎɤ;j~n^7(Z ʠDG^Z/~`Ȩ /-ΓKRTvpXb{WF]O"_K@(\6q\J,MH_ M2n䥡=)GEm z,:(gYsDTL 7?5K05lSTR^ʖ;hbAϺʳՋ`'XV 8LN˩Vq(QX'5h( )wJUc<˜[Q Um]w#[bgAnG8MQoh;r|#:Pь̡֤*#OpQmm,vƹq-.st؛ |]1匰2N[-K% Ј6Ze5\DSؑyVc*~c4~ Z^|)iJخ(G@ &H#z.hެOIƴjHHwdx+IS~};f?Y {682+6ԣdMM@ )TƟׄmꟗ^ ̢ i8長ey6PW&z% 5w`Z;ݍ> 3wbUCMMx`h6qb.w؝}{}w @~LBr0vqܺ$1B uw<o@H6No@דԑ?['DZA~z@ꞪW >}iR*suGd ! KUz>6tr/ɑmC*C0z#:-;C;o=M⁺accd]e]ݖxL|7{8d⹻Je8p{QT ᫅=_! bkHǭOt`L3\MF,ԳWJ 2|c3ux&K\$ PFWCA@|Jd񅒟{*ȟ횰V9Zr;Gߵ[7IIe\"oD:ȀHQM)na .kh*ۼߎ`ȻaTL,AYqzkķlx"P5V4F첃-MLRYWYs#uW\y9e8Gu[̳Kx V)˖4[9# ͏*obF6bET"Z3W3ySl$o-!%'W #̝On!] G,8 =p5SH`&u]JI,m 13M!-/:I#E|1a) Jg8Nigw/Da٥%I m7k#-$Ff!ȿNH3a>9oI,ėy(M=#ax#Iqkj+jLY1S:C_$2=;qPeU`^q>#UdoU,Y81t+Y_bȆ3b\VVB&~YT4wRJB}Fm7m/^c_-%h\6/P:irMk{Ā-:ZS.AXJ9]T SrX;xB5a)XWnxIȥʴB(rOeNAs2Tvqi D/n# @wM݉bb\*/6߳uAKN( sΫu"5EPW.`ȯu(cXp;TBH\FX,ᴡ[d" S^'o`/b;xqgalB?2K1J3b;G1USگCÕ ]Y{Pʵ C*X9uiWaBc }1JMMzN\\,/'@lh\g,e4$5tA0xҸCJE @@v!ۤL8Sxt9MT濕^|k]߾`35&3&W!`?% ȃy%Ҋ:B47XwKcfFi4d6Oic_h&+ m9ϐìFt*ns3fAȡxpAn8Ԉ?֮$'Iµgv’ m|y87ؼq?60oz`3L<(av aW("uJ Uxp-ʑ2]\z+ cB#J:&=fdoDHÝ!x (/ # TLf#\;Uy.C|bhT)> m`4 {jtlFWW T_ #Lm,!c/J_֤&j=ElTz ћI+u>ڇR4+֡Ve5K'fKQI-JXLjd\HXF9Onp/;]%4{>Kx W3ۥflB1%oPZCB’;͆|h"shpV>x)R|۟:!2ۢjĜ1~bol#4+x7C fn$;=]{ݮrIc]!ނ0kb*ӁrqSeSl`r Gxddd#T<}XJM_SG:~ pҕ,Qj}C4T[Ebo2;/O ,RQ{{_\ g>"31MM?wiINKy'iӸCOcr1ȷP8@)dm%Ǵ^)U*A+ߺ KGJkxzJTRQNJXSYv?:\)#xO{X';noLURuKCԳQP殆j3 Mub=~&ZgE͚8'ICA@(Hvvr`D}{\) Fxvũw])$0]XU϶ ;+\Ͷ[ki`%Ro\!tjL?Wsi %ص i 'M13SsDV2Dj.!N8`BaBYeJ^l@%뤴׏[H!yMmv HA)L2$ sv0YHb_ːLPNKUÔy[m 7L3ɑ3e>n~J!AejTwWVQPR =%S#'/lvNP:VD ^ElOƐT垩qKerI'WeLHݼoˢAiLbfp򣌎Zx+t‚ճqkGQn/YVɒ1ž*ei*b!*?S:,q/a=/ AKS_/=0iBy7I JQz) .p岀11z`|-x゙/nKƎP>/g\87hĎ6&@0("9g ?0Tkg 6DSORf"!g6=2}~f܎BK Ew ZU~ UЄuR1 ZN(yXu~PYZ-}km8s{\{V,\K;`Y .] N) ]fy!8z5 ko8ŖG>F? ]/i[kV ?~csո%yA e%ތ&c.>5A Lzl0瞹}^FB,5Z)|{<2=^֋- kF)+V{T*EhU5@{&<ӏ/ktXQ=Z>9CS֟aKz!5D0 z\ uR0|Af2W: 8C,"h_"aa>#˾UЄ<һ.rVLjHoStp&i>xn, wv ME :#!5F-$scaw M5P 6DcwEϱ@\REI SD$Mk-7x 6 @`'6DXx M˟V3|Z0 !bx3YLy[&ȰϪW|&/\ֶK:Hzwz=OrUۙ0}|k@J qXEͅ6 BfZ괜M#+DO}GYQC;F%`@# #O*Xi5@8YA9WT]Ly +͟j*cvc!~ \pU_XdBUgAl[И{ݢIE>UOH9{ܵ'AjU9I7veLwT@V­#2.[jE1Y!%nVx夌ȞҥWh;cg_6 p&W27CD'L?j:qNM4~Xm!\ѳZWԅu]xF4T E0,Ju=)=}pQ1~s8m̰ WfYl+NO8(9[q ?fjhA<(;P/b0.]Q^0ugH|[HE9,$ 딶ʯz:o$X /l?Uw%@_Kʹz*YSe#鎯S n4ˁ-{[u#TrEIBZ|Ʊj/~GiƱYr1Uw+Th}N0eAa.N,dvZCmX>D$l8!kQw!OS*)} x|'7K][Fb7A^ٺ p_&%_/($ZROfAE+zTgGK8;}%Xim$09H,[Ow}W:!v =x ;ŋ{HQtjW2cͪ_9X'D".}ˊs  (z/ ;KI Vc< Ir+p Д(']h7Q^Iz>Fܦ`1wDI "'i2Q!,TM,:]^]]Y;L܍T#u>}[u27az3r6eI5AQ}Q1\.t`NlGNBCQ?O wy54P@7 v~ш4]~owsiAf>#z4&ٲ蕠U"qx})fqtׂʓ>u좟Ю2:oKV Dh^^a!{h&BwՂ<?C4B_KQP.БZp*]#wfeAlǞ9jUI=۝eAI돥/IʕȁYǖL("d2Ŭp6W2C˨`RO}Nc sU- 3'Z7ŋ G] :PKBïbsZ\96Zh[^ZK=GXntZqp[(~XfC$5CGιu TüvY.-#_n;Jc9O"n8;/rEũe]5,T?ga=ndo3*"f'ո )M%CHÎ<0xxq*IQItW7EXfuR{1>=%9ɳzLHHl&K#eduo [vUd lagqF-d!h7@PAR 2.0MainQbx۳,<ܞPAR2PKTL@p~9Hq-~xqF-d!h7@PAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1716993671.23851 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0080000644000000000000000000014270014625637207022714 0ustar00runnerstaff5'N + _@j.;LD6؇$Ņ`Er#/Mbh@ ?Β@JIZ.2Dr~$U}[X-t!`>HxaW0 TB G=)xCj=ʊEǃPPsd؍D̑*3S1P=p)Xů$OH+`.0xnW6I`8s~qNzzR1= Yt)toG 8yT/&|&Ax;.8?aIC99ʪ崫<ȀG+0_IQ a(4lt?~3nȈ'R.e6X< /C 1l]DhopLl[[߽(2>/'*bz>L ^ۋ1l4i^[Cmr[N@>XV5Rb'X(. 5=oSGn l %3b{]Ml"cٺlË': *E(I\z枯_Uf,,'L#9pyxLi&hƑ^ҽ_՜1`]zewGad@GׁD-mst)~ II/N5t'K C@,GZ8*E1Pv{x4'y;ꙮœߌJPdϸņ[& Ȳ)ft~,vdJlKUMѮY!@<6jTt)9[bх^QtM@ZRRe5?6oczXaEjp(xCI3qA ۆ:l=3ɼl8㧉!%XLH#(pe&٨9n{ ) ?zI#w1]j`=LTN7eGn80ůe5DD8ǫ#n令4| h ^a[eK-EgՃ1\*ϵ98<;c:)MO[h[{wdTsk[|B#@Y~"B<֘ŧ|٥쵴^deVqd| Ӷ\Q; !3}H^d0fsM "VdyPЫobp.h\M+i0%idߌ\J BS@o @iϊoOVdW30gxP ~Aąg\Y~Ƌi1C6#"k~$3ZίB::BckfT׿攔* Bi'/jVH^j\5Hy25kS)BƿΣ5& IZB-)96i"3c/AI|I@e/c*P(Hae!|kc,ˆ A"LoC$nT8T=d5`wU^+ZPgH|eǧeb0yh;1${j)|'F?_a _-* jšLM%0ɲ~ 浔ctSf+0®n)7X=yvIp-)hriZ, &L=ˤzw*)t:{ ]Eb^{"#`ߪ`͌Ezvn5iQUe`w$wÄX)gnۢj~ bs\'>.bExZg::T_lB^7:`M'rav'tB% WcWoՁAi?*!]}4圤Mٛ̈/>EKFROVZU F0<=s 'qZDBӘU@\]36˓(*U] +&xBy^C5NI{J-dǿ)9|ED8kUZl}v't0W~x)mm1{B*p%4QpE{ވD"1DycM!Rhf9^EHl@i&%ސdJfLv. Nz$,I"2q#A7PvyWXYK[WE#"Wsaϫx'R5]HR*-D* ?Ԯ1u;NrUo8 !S9.WB:iU-ߦX.;UFe0kz""Q`=*ʝF&Z FߍݶS!aoEZFz:֫\v% 5lj 9 zy) goX*9ξH[_Ǧ;Q~#}m *qE9YהEc zl "R95lh^:Tl 1+WanbܡILkK[Exp8bs:0W5a ^~ ]u }q{ɒ֔.EΗ(< ߨ!ɶ9w`8zөdޘLw2!>[BPY]U*'<^GŅL5Bf=xhZMAknQL:wʾ^dxXPa*Y7@>uϒMrY矽TE&+(v7'*J?GR; q<ߒS)XjLfA6Hgn[fffK#4ł3 ly@ 6T,6s*s3L [/ Pp7 ^#Ѭy#kjz.!E=pmM*(0YLԀ2f dVJ%$/Z@:]z|9h}61$8|/Yɳ+T\pLx&NcIw]3ASq:K'|0FbSu",k9P ^yɻsփ!(Lǘ_k6g{V]˲ %EM6&XoV>5 E86en2h)VVڻRy/O"(.+kD v͘.CW"rdnm5O=Ja§K+bZ /ikGe-)Fpi@_6񪮉v)Tf5@B!ȢaO=D$ F>;^aA"p7vupzHS[FFLV~UזX .8 Fkf LܤB"F91Ϋ u )8 |[pe,YMM eZ\=/l}ݐW?{ \qk2M&8awT I˗Я҅khC"Okվ`5@oi]Y;GL(|PϱL~ O0#b3QjTtPfƀn߂ȵAĸ+N,%zZ)eΒ\Z=D[|GR` [\T1 9OPMs;זO#VZyrՉ\3&\w ;oT!/֙Ͽ!#ɞy恻U{&]&J- 9FyiaK30蝠MlYj u 5h\o &;8Du^VBYLֶbhb͗A~KCYVv׺#3xRP(B\5ƥQȖŇ~RnEk 5&Wp-qOmLTtZU;RP]/ʢ™]Ftȯv#cDtx zolQdxx_g()= $ō>qs1p %; *:dhnvU-JҶ/3~p@6 8k>kA5(tGu'SU4K~X<$"KSBu 1+ȼnX'EvADxlJ7Hx~orv̵5 .y<:Dj+ d 0@byh\1®j$h|0>TV{slJ?l1I8:u#7pzɸeLm++X* ) @VM?9]s/.`gKpIehc4oh%CzCO ԧ҃(u]=$fC\1Fv5  &t՜9I\ %_tz:T~Uj~|P:,GKT  .!6e_nf sow4t Zұ`qp8Ҿ$ӅD'Q(Z:~bo%.I'^( WܫQL1J16$yXWb P}GWKn6 {5͆ԐCkY\鱰tc)> nOp#CgXAeAn=cwu,&/v]o% Z)U2p ~'Xg5f4%lע #FFpZ5SvuP c妤1Qj#qfSm!׈@ZcL֛9 rfi}>Qÿ))8._BZ=x4/u]ڼV+3>#Vџ7YZQ LD˲ !Ԙ鰨uLSۭOdxdq@•:^-d Gπ *t~E=`4\7l]8hX#yNS Zkv9,jGd/.+ /nNpv?^ߵ޷'/\.3R+G|G]F_ #%ty~2158dUYI|c[kVxyY.Zqz:sW]8/}wr0Dk]sՏ˥|Jz NC8v/@\ryg$ֲY&*^G}}unM@4F.ZÇ<; 0pi pb+ZJ6ѡ-[ 8l3X"1mw%5o^@@{yQ;r݄ s0ka'чW6UB >*k37jF6Ѓ80y_3-1tohyz=w/e_z(Fc)I!~n ;22P iw8,SZ&wRbi<{kJ<ЇjxuІs/5&V% /mAd=0a.L(p \ſ\T0œ7oӬ1׀Uܣe3 HKZⱮ'At/!˹k! &EBo:CP}F~1_vKRyP^D*R@A-U܊X-{}M :=_*|YEkQ\J @{*=# -/Z'~RꟂVC[#Ce>KOGj 7]Eӛ$4 .'n&GIz!?Y! 4SH}\ME҉1u ߴw dP=5l(>`b,NMZll/.{-̸cʎB_N~Uj#!SHӎ(tpMqKVh]/Tp>E~6㒾e|v:Uq3Pt5_e 󿧭^9ޢIIjd4 `a?/m1L> 56gl~cI[U(Z9Z@Dl=؅Jg+_^G w/{G +}hE2~T}ny);QpHg(k;!LnyA#-z8~bxKC^~a* >G5L&+B=@/ ,,]k,`D@}{8Ae-'R(frZ,K$BF.`+;8`ږ(@x؋?f~PpI\yڣ#A">h{FoA;:'M } c ,+8}hwAޏyʛ썣JǍV )Qkt2^wwNh7{睟!}(1՝%g65gFMGѷB}N"14 k_Ecm $Øv6.WlBOjGl~AiTs86BLέ 韒W ho{B tM$jw+9oͰkRS"h1+X[ ţ*ZH-'Bbqh%DE޶`473۝~L sI~ wv& "2aNh[yyӒ &w]4+^IS$kUD:Kϼ,[vj{0Cq op],2S4fYEs9̏$:ב,S:[@ٓ=[TEskx*AGmwnRU+)B&:mۓ|M#(rk~$0_JyiK CpaԬG@^(~I ]'ѲhS^{ U] M ,$q}^?vh@ZQ^+ԋ'h74{Tޒs'tuS<'Nj9+z,?dH6[*Ƕz ̿skw/ " WE,3iԱn?f0A_cLj0ڽ'YWC pKM֨2ܵ>a>al8yip!ѸQyU S9e|_%VWlfQEKu_SV2QV )\N 6o}:Z%YѢRQ1 Q'F}|a8&Wc1V,5!CdL0: *8'TxluGO`=.R p"TUê ;Է5sWMb` ڻS00)!>S1RJwC٦͇>UBQLj,IEUD^m^X2Q&C;cGwf[|ko(4|BR :?e@6fdiUqE#|80&'6Y{t͹eT;V[x2Y0xd" ME3 ~땸/KJ9E)1y SE#ŀA%*AXHZhHu;{VЊ"m Xq)ۚݐc =;=r!2{a A<\wuo)MOaY"$2,Ad0yhN#ǐoVbT@~sBWxH)χ0& Q7Znv QT+20F1Wp T!@kȤcH8e?g eMXO[?oHj8lO}cT1:t+a30"WI6,뾽ӼUC}SWY3Ш`=W`M!N8u~)kn5q{fXaÀ>=7c߭?*o$ )e!7o=o-xs0Um 9=jxm@14 eqEJL4k(z`E{Wt*j%Hv錞^x 9R&H\Q›c`*f܌K`?s3(˘ 3HN%hiMES J7_|h%{"A O^Tsɸ+M_#Gv5u- ZyEcYWƭt z(C qۉ-C[D@&c9 ^ƐQ"˨w EI/6}a~\.M+JDv{-9f@O\I3'> InђnvZg}lX=S_7nd ^PNӓ+E` D|o,|wQ͐4P3j\M/*@F8Z|:rg_y"RY:f0.O\`uܯs 4Yp{mf^L;9H93PR1!u U_ ys$'W $pjmP .qG %͹y[/4ϭdkI C9Ay,&`ZzP0#k}BɂnŻJ<|ŠKZ$<%űJ -WYiWbCv@ ]|JHa2:g v=j%~HgH㿿 aα)RϸLtzSnBYa;dpu9q0;}z J*g /i:sG1>DsIbeD"N.^W[&iBYy^@e>f%1HsYQOqKTb" bjP<QFf,qۤ HW,`:AIH5kRx 6,\K`J9u26BВ_ǘFc ӈ||mYQtӂtIcpٌ>jq5]AhT\1O5xkv{yE^Of}1Kz 9q:rSHPՈe֋[Qw_jz(p 欨[@LO=7O8&!v%}m%$K% B ^U^2EwYMq 8ɈQBכ5 {>:$Hu5nf~cqXcSm3$c *Mr&xՖ VMߚQJT<҄J1yw)oIh/YhBʁa45ٛP1?3*Xxa&]|0AzǼQkoښڢWRרOrIcqaN\AT0p?x%7-f0{F2cCiGB*:RGZPci Z` ñlΥ[&w^p"Iɸj`[p_ۼh Xw?`sMڞx/ڛ<c)eT,d;2 $3Jݰ3uNN㑕~imފe|?:65PyM 'Zw:O5~q)m#(Z6&?{bI es_?!%~zGi FgULll+c $sjŽ[Hmd4-=RgbZxNm ߍBMA br+M6j햷rY} /o= CeC\jx)\,҉?2*aD8]j}M/G.!!^e*dz>2 qIDZx|"uy< 8,@ꗫN->Xe'ܥ(o!A""GklE,YSX"2XZv'ŘGdkˈ`ƜCUC 9wбSA+ݭyd/$CH!hӛA;:< ,kZ;&_\s_a/̲LQ?%K~&~١^~Ĕv2j]r旄_N0)_Mm\2 MĦkI)F _bH0VUE"3#Ж2qQu?8E3fr N#`T:J|2%Los\@,_dy[Zw_Np;krsקU„v71 $.NoYsFKy$xlF*>{KN;*~Q%z:̑4qhC,.|>@alŝР{/ٰ>7bV1!.kl%v1f=iҟo)<оx!y4-HzMC4!zY ?v8lX9l ZS'{ rhe/R5&nٓdBL:rRI u zDqBð"b'Ywjۃ xC[۳}(8nBcihA4pG)vAX }eT?Mݰp3KMT& dzHD-֯uU,۵K9W%~,: SisU(IHm#W]uE#]y.5X3?;U@[(}[ۨ+%N4Kgd#4w" `xDmSٻw?/>EG&+y.q@?LCx\^wsx曬'S{GUoBc05-9,u%6$xH>?۾钉yO,ۨèiEÍri7A:3Jz%J/+pf|=H$h'IAhG#Ɔgsǫc}-Zp_##p2 [ ˟jB!A8/x`Y,:t+0p#ZBȏ>OT3B?˙ܪj\HyD v26ܞծ9+;OqGMd瞐oD:XYdP,-'(cgŘ'd7cذv]p-,ju'7DNjOS:2G. u8v>k*g ec -aITgh:-# *s=hN/gc:Pah zPʛAr\M1i(InEg(9΢JEjک'FW2!#gbYmv\er٦1;8`R*8| Ρnt8XҬMsn$`5&/GbS|W?'uBdj7ė#bLg S`:BЛ)s3ȕ!#}ob*.WV5(tC8gHix < ,HVI4xDѦۮRp@`Cm7W\qk'h77B='N Jp]#9dOrL޻ &fTgp ?>-ŦJrP3{ϕݟQlpYĜq˷wنF.dg#ߝ ܙ[w<R\~'5b\.rG>w:x14\<8ĿU?zYC5t v,[ gp,cBMz tlXjS̓OQ5C51[n;%^5`"sk >jPeo`ᖱ*` ,_l !){],V*a #zs0$zYԕ[ BޝdnkPplDvp:wrRy=\uAV@H:4HZ~4X8,]Jm9-qύ]e94$+u隯^sD>l&|F0@؍f ʬ5-nKdLZyBpxDbLnE9tE~c+}oV&z4(;=rWUR[B]y?o'X.og3>j*bVA/`T a\/7APӦSMB^eq:%)3&dgdU\OXG p[X|<Ƭ%\*ms<,ƊK b?`0 $ݼER+?.ِ{ubJ%ԫo78L^ГXzwח7ٜZ K >:ƻ䌺hIe<5Sz7F ˖_^v/6džiŒT"o3 '>:&p:x!&LI XG6K"z(g^*ٟIa[ t9)bXUz&h1\vSTf \ndVh Y{d3 B@φH$il\Ixpl.m523clX Ii$U(=kn5q2]>EU$ߞ\ oI+0`MH S |.C]5 s`h[bzf+ޮ.?lgCkZ[̆3vb~Ӷ:ٍ3w4UROʄL/ǎ+0[妫Ō- YBg+5vؤn"v+(({ }W| &zPLQٕ@MCSs\Ϟ6F 6nYߧ,5ѩhe=\AD@Zbh9W]Ί̉;ْƲ!!<GsO%6Q>U;GSbZwh kso,Irw4ȇ݅"`of@U1+ftV?|EKR_Щ$(EM|>x`=}&xS:Bi$LL#򃹴E}FwDiQ\XDvvHpgdfld#u5gҧPlmŷuGe}86C4n3O:7T]cjt ]vU|aXk_U0$bj ?TMm#1cRUs_ob%yɥQHim.J}/?$D+ywdpV%K6gԺ[*|ŨOjk_\rra~UMU9SH;$Ys?7>$dS98Bun=Q_iF2S\;*n7 񪪿."mpB@ c_{JSIʺc:vKqoEB3'eKҗee,# N8v%g,ٳlO|# ^9GezM"ng2? ϋZ]k"t[/(ʲ0oV*[W7ލ悁>G ZrMs%N6qUzՙ oIHLmğҟDZE]<4 h?i,jvL bLA\]~ 1ȕ;OHw$[g= ӎ`T EEjPi=Ct ?7K #ځ4>h݊]IIrᴌjƲGN\O2GP57Z38yʶM ؠ k..rV\]?m;"n}"A@_6}|qYđ.,JsflO?m%ggZD_( R *_:"Vj:]n wߗSq'd6M{d53Dž -,YHsqtWܪ (]ޗ̤> Xbx<-ČҚg߹KqQ6?%EY{6VrT;?Ka:_o)zw7ʔ`\"}t9YD-نuxΡD7Bsn.GI:#֙;a˜A~f|x"{̝&+ 7DǺW(g `!pnB+-sǨiq)0fp=fO1jebzk[o6!5՘@dǒؗ`Z >3JՄ).$OLU(Hz>RL C݈~v6tWA+«Eo^hr7zZ@ }s_'0MB:?S$#[]ݶҴƎE{տqAf( Z<*y͆e4(_T>>s=s`Njvlplh7hZa~ FLo6AW)lcxrB@ܺ:+lS?2?ئeH\bwS F!U0#wJp[۵#γiW^b$z\GH12=PbL" #D(E$Du\6OWK)r-̜L`99#C$5Sb[ʭ 8VsDڇN5|R4{o3l,M-E1 NdzKߓT cw+ J:`WmOj_T<ê`vn{t5qP2b^C%-`\*[v/7Ħ/95p{V5:DhܵE+qb_O_sI1=?w5!ѣ8 :(RW&'gbd6ku%8`=[vGBf(X~MOtHަ8=18ԧi?°]*5D6؆^A$v%3j2zC-u-2vut5Y@4S!jWj܅',. T ecQr(*!TK`Wd-bGQrmY kR&"PPW3IO9\eڳ/)לl !JYF#KLs/W|3fK0 }l$ g_BB{R^VY>̧[zwc ݁>ǼS>{ +&>;=[v6 3L=i+)ɿlq-VAX _tǓ59P[zbBMWm݋54,DR )bxz;E~X<]0QG1;ra-%1l ˑbm8qWGҺ n \ʕ==Q.4rޥlN@[Ic^ӓ]OphlhDi&R^OZEuu0*_:o~ܜ o+^~cRV~wkZπARcZ#kxJ8S/E{.߄{qLXoYgsLĕ:M73;bb_L+誺w~THq!VP`kyՊ$#7&0]k۶͹@0&i/>:&e5&e@cϿ4q;ze\+ Xm:JLc=ZhbJZ5@2Z F{hK?!{%h]"9 zf|BI>I2z݄+S,A*I4&ctT{$SF,?"Xm.@q]!nlu |CM%<'դ߯dx0YU1{$KzJg~8X^CvνRE8+@Gjq i2nxNwnS3{u0k^?{zrߑXc D}0RZa7t+,*,";II ZDLw^U}%0O0sFTI%cp'@θ C|L6 *ߪ 8M Iօxoq[N"ߔt2Ak ŕQj+ 1KgGeDXNBϓG_ %W?jGkSCqB<+؏u'X.魅Tr'LA8Pw9O(1=Yk M[JRAH[5i taa[G =E: ^ 1?ˀAn"vcH=7\A=\r/#+5Ooh) .~œUn;6mr'CW; 笺:H !>jF?4o$aaп㹛 7x8,rj&nd+o6jۿLFFvRf6(9 daCٝo(B(f>}*3\S4 e^ A W5f*W}tjQot7ԇfjQ?UWYCS/WW(i _^>#r`Kr|p-,QȚ,r;#XXQKO+̦t50<=\;:u_"-ݥBy`~\X7wL}>1KUv.G|.yeʈ)Be"N/\H OJӀ Juur v?/-ÞdJ]=nk)QD.E rΓ'mhkpۣ !g-v88}lӓ8yѐ5Ev(5iCt(|L! PARXr\O O$镘. Etӵׁޥ/] m.BO b?OlrnQx]O }67䂁hF}Qm3W='۪_1Vl^}`9AwH| TD0s6׋IoeP[ϘuWm2\m;??m/0Ifڛ4`n?8pse S wo Ojrm􏵝l"X7d# LT- iW oכ@{[Q:]E8 E!wHp(GQ!.͋!؜m[%\95b>r*[0 ~#Ĵk1[+yFTwy* Z,5^VY5G9YN\cj^t|:LE ѹwi<;-Ѯsh!Nl)n '@5z$д\.դڬ x ֚`e{<7,n Z wR o^U?ANG8EߖrCG۱}>8N%Hx`hi쒞vϠ3}`ڠʆl5MPM8$\0u8HnPr;04 Oq2!~ɍUk+w}YO~L!`w3z%0ƹw&[* ݘ仄ay9U0/u1Վ[[S ~~*GGL4Fn*lnz:DdY-bz $E8Jַ1]bC]On~iY&7ow7Lb,N-TWmȽb;4Pn7V9=E]$VoZsɢ=  >˖쿺b/EHS~Ti[ 1Nn|a1h=g5Js]?sxuƮ`5P{ {0GׅYK2bכNU9l6t},8Q JÛ( ''VyCa_gh((=_ui2dwHҰL9HCO1Ta> ?SKJguLQXMCX+%CD]UQR`-5*DSh Lpdux+%X6R:-wVpb? Ij򐄳PTX) \+ #ajܜK^W8 ڢ8Q5 V`gU8:CfK4SasCu OB(e~JMPwa"bيh=U]̣4uFGd=(wUߠOjn%s@d n%Nۋqʫ4br 쮀<ou) N C*1 dhX% bl dY3n-ayH.Z@wCKfAVCbTsI;~Mj$;$Ƽ։)TE,ǠľB Y`s6cf yVAKv `D8z7.8"w@ '9zjY]A:1O:4} $|Zũ8)Z-δXkۿ;+j'~lΫ!Zfn'ͭd ,C.)܍jiuR<p|oށ±R\t8LITEt2 "^!H3A*M!`? aq_$Yg"4xme;4>HY2ﭸb^VĒ!RJ/bLߵ3̤Jgbm^G\l5&ǯu4d!ޡk+x!e\Fx@{vddZ׊ ^6~B" AR =3ry wEa_ 3OK}TyDAϢV CK.'?0O2‘o+r4s"Z 4J dhNwܡ.6(Cs㵑gT.Z-~xޑdgpiKlR1$<ݎJ錅) %Ϙ̄}E>nJ,biȶa'NL iVM|G'ۧ{ 1䞢iԁ `0;\z`HؽQeq8ǵtl2]|9j>?#*cQQKӍq*`<7E4Xv6 (ğWbVADڧMx@ɡaYx*1#=ˊv^ rqR8׹" L%O-*nP'ODQ+7>_]s>־8] p-::Lx'Z-3tb+9 .tT8*C1:LUQ 4V7sތ=E-f%t#aTK@0w{T_]λGXrȔPlrW 5<&V|S>+{F[/گf@6能L )T}ֱ$ 0\ <ŨbUpːKlj<-%&[3 iRXb>w7:QF!#,"Cl$6K4RRwd./g-7BwY`R|R#xWaXp'W|1!NȲU*u/\|ZTyzZAEWMb>RMNةڭy/.Bk"9E")= Zs/]D|\\.K9EHc9'=%VI!ҖT{MdS*b#D>>ciCJ v^ r?N\41z[scSU7~!a5G#<(7Ąu( Iv(%.[%CF^lT*\͵x:U?\\UxxuGu4K~ gXz>[ΫmnFYǑ;`TVC;TVIdHk|!lesT5Pj׺fzfԣ EW ؠ_lk[H( sr2QyɁ)V0`Q.z?Q5STj}ŋrӰ g9_WS^t>ˣopveVHo].2VNd򃺣xFdG"DU{kBXfFq~&EK^wyMt,bC2qaˊGA1YzD)Aph~J]4yP ^O$ yN/k%A a đƒpfo`u uǽt4cCa< W# `Ql3/bl DV|1Jؔ^`1NtW*5vW bYl֣q{Tr=Ej*GO|e(}C'm#/]ݺz@Hp)TXKr1t PSnW[C1WR233)ў"{~}^2~q8k ÄҌa'0x% 6"E9\iۘ=$Z r[bƧf[}[};67$|oT!3*C% i)HɄ2O7΄cОmUVwmO MzXĊ6ABuHK,XV6b$s#r*#O SeH^jx-;P(_|ds/I&M@Y;ҋ*Q l^zZ0XPZ.] ÇqY^6j,Y28/%ROunjOqÖ(=e6Fg'I\M &~9loj m͋ ;0qtCKyPwR9ع$;=m"Q+ArmRx4Գrӱ(K]):rƛTߺ8ȝfWQ9%uVTTzǩ?OˎHGKdH&Iw;N;۫ݯ"yʏ&g ͮ0W5ZmqME`yT |$$+ B,CJ$^«e$$c񐱡!G'KJ)l!ikϖwιw{S̜){f8t 5f_%/c>MP{\~Wr&kի<· &TLthxѐ9'?µmy|쳚贐~ʐ˟e_]g^u䒼Ph, j`}5?B'C{3}P=|B.Qޫg˰ 0R1SļKAb5t96(q'XCq4Y3/`]фKFi~NZ.`yYBľ{nLm7DN$5X֥SXcx-&)*ĪZYxI;U[yO;wS;!p= =x:r\G9mv]|K. % XPa7@^'w,`Μ-ctê@\:25j`I wOe$U bul=bnsS(&$tl]^6#JeGy2!t\D_ ʣ~H:KsbR.ցWD8Vq&ӶVNl*+$eL0jĠ#)" q c>}nӸIP"vq^2gVNZ 2u&%*bxq:n4 Ⱥ~008\32]1%R/5Џ͆  A*.Ѐn zm?5Ua-a[XqʱEANp'0{e@фFFB:Ƅo*=I삻~f}Yk>yۙ^cz.yک.1M7ԷG Jc I@9] CiAZM&#.79_ϸseL@ܿ!ӺG?ЫzO&b;$z7N0ףB S²b"mRA}c*)h39nX䧱0l&w^W0lv%JM宼!Äjk6H'flӎNj9 Py\냇!"Ǝr@5t[N5tx `ݑ6?&N]1cQ;BT> g&6;?\NP,*&L095DMǮ@tKSWN230|CC ۮ&b2!LF%XOaՓHG/C0xr.ipTC&jt(ȗ--]\$q8~yy-&3lrw+v:i;ұfVUL . 83>g˭5VZl*u&m#0ݪǍ[Gw@1{ j'dZR|C;믱+>-qNcL]՟u528W2*.{BgWGwL?L 6l5BPz/ǿ3>T-=5R Kj̠2 C!Bh_)bg7zqmJEsna(CuF4ŴsLEJs]mG^3I*2'3'A|i1+z!2.(bQ Cxg:*XPԥ~H׉]9 ׯ9-iM_2 r)Q; R5Bx1>-UQF+n}` rVj$XAaR YK=@un:iun3q I@qRw1ɾ^/j4۲Rlo{,b}NCZze-e4 i,&WP+>-Ym~dz ?Z2@$?ŀQ HU^RnqSj 3&BMD?rRuIL!FWUuE1%V\cwňoSZa7ӑGVy.5 V3"$glp`-4׹y S4^B#a mRaiWǞcNhҍv7櫪ؑJ)BI_m216v}Y~Hu&e0탎ZsI. WU>r PavVٯ|xeA0)Cs>]NE$"zI!wq!Dq=c=ldzg*&Nc%9(ONpqg^9|Wd`[ƖcϡS`=!'\V w,Sϟ٥};aPh쫏m !s_G$Z }2 Q<h!'(oD_H;]ũH)gYJRsgrm[ еp*r:Gh֓ vW!tV=o^eN㻬\LeyD b,1I.42Ħ]I*OЯܼJZmTd1!5uLFBݔA T7F#:;tij3mUt8 >@)k#`Tmҡ&\suϷ`Ʊm:_, 2Gx`p2.d>mR,?-Е mf(2 LGT_ee9 yR\yMOA(sNLuƭlVZ~GA,Gz#M  S9f$up6㌠2^ "\+ /Zl9W02O6ӫs/H4J@x(}ܘ=m"N!CG{&F/fA?8'^o|V c;G[|Jz~HiU삕ÀT6!DtvWMUȌ_ĔBrH8;GP__bkhϩ0;"B2/31]wxsrf2*T"H:Cjd ?, V~/:z,&3jQ=xS]{;e< 4Zr?7 +taߧFMxRdSEG׽e %g77@ւȴh|(쁔zKX=Pdf"h$z[S}|7;!J^4Mi:^Ps{ȋFD>X'9W,@!Ozec+3 $9 H09Pi^M,<[zIf%n9`*fxq]U2rbwbNo/>o ?#ގ1kA5=.H"h).[%۶oS2kS'b ?@/_"h[ (J8X*ځ%, [W!j'ܭ;xRQ~}7l[gJ`/'!؅1Xmqk-]b.07J)jP$jpxG6QH559' L "[;jGŭo*stɎOk5.)TRT@J)ixR~&^Yym<1`/ ~;F~S]NxANl]6 C mbX07~>tΌ#>tGm`9mtĖF^1p Zc'Nd}{1HWny6!,әXPds KpqU,;4G;dHVáNG5A6)uHC6|L見֣QƎ`1ũNp zckݻC9N0iftdM?&A0m 0CwJgyA{ T 0-F˥B#ԧ:Bt"qݙG,*/'R3b 9+luSvS@}6flbyzT2<K pjr.>9@ 5C`;'[95TL_Ewl"D;v.a`O] G* Ԓ?zLoV0R'MLesrs<o/rA9- ԄVIH[QU:ĕ+/tq$&QȜB@ ޔ 1î:W.ehcV8lvrxSGơ.G"9Ⱦ<<ҧeo D /Ofg ka1!i92x`0`Ѣ'dr9/ugGqYKݛ@vo3x+M@(u7iu޲Tꬥz>e hy_TL&V `HTRK4=einm{;-)BN{` 䫉9-u gGP)ܔCs^~l3}*YR]7 b )dG%GT CIF%l%j~zҠUE:_h&kFX9(|Z0To =3^+M4zG :ugqf$ dl,+`Mhl\L mjOUXjM=F,LE),L67dNt uNUkBxUn:)nZitLR/EQ{/0|qXLO%ğ5 Zv_zQ`py.(N1euͽM/.4{_$hY> ,5%1Ѫv1 C:yX'_QLrߢ7t A`{Z~f>fvYዓp‰d]ɺDpk5+Oד&OsB)~g+lܸpN0pIcW@_2>%qzf/olŠ8qf{(?j)h̅Pj?;` lFjr+GyV`mC `Ruط&]~/^4u@= G/z@?ձ޵Ᾱq귿Vϩ" `. $4۞o#5FjLxt a -KcB$ŷ9B$dˈeF#77]y%}"S5#1#v:0 E2~Ep< Rw\kA,7_@83=LT LHuldq/JߝډiҚu>yx$;HR6# 5!A[H`v$iXvsy: >7Ɨatl=o[IE(N a@j e^IjYIa%/·HO/nDR/\gU緄 Ef¼!BQ&c2V~nh)KQdŧV}ni, EQFw#*frg;hPgXߊcCJ_Ƿu{ ,M24eX۾H#lDz%&`i,[Gw^Ouj<\%6K~,"ĉ R6';л:fC}5A#,@jc/GnyGN`1 g;'\"LVJyjt]&9͓d|Or`ߢ-IOj ߈ƟQ0w碧 {ͭU M.Nͨ4h~RV9iAYga9Rphr@HBB !M.D#?)aWu)hٔ> Q%*S- },䔋_jN0VeCJ,wnCbyFmV'^ ΐ"umK*mò_{(S5ƒjƟ![vbBE&,DܿAB1jhQGADy其+ !r3e@/Rfx9݌0N3VeFt;>'(G"6< Me/j%y,5QR*{++n֙oҕ8^Is½Yi4Q+ W*39;o =kc)5qDlR?i@Z"mLf ~ӘQy^Ark62[aTë=&$Y# Mg>3L|쾚gCD'nҊ SOa%V⏙Pa/C[t[ݛ~δ_]e~v8ʑY~Xa e;#)I MvCYV@ )mB]ҼâL:'. N cU!i=m`1ِ\Z\6_4s֩a('Q&P~2 FWm豅鱇l:E+NHfxy ;-f(50)mj~^z!xEz"80Isچ$&ڐo.R!:k!91z\Wf%c "%dz6Dvq _%?f`].*Ve .\hܾ[d7q臅@=xGMfAI.f_=ȿFN] ʌj0uF!*V qn\w^hݾCq9{Z$Oʑ1jl T^ikAUc\ ;Tl'50}Zow5@K+̆@"yH|ݒGlP ҋ)`=f(;:ɓb/*.4x!7%qh%ڄL[;8(O{&2C1 UzfN Q7nU|#=&y4݁H"ٕ:GcҼ:d"U6Bh땜l!1wW>,d]e¢&00:]p"Ӱ́ؗQ5%ԁH8s,`Q"aXWoTM[XY@nZ΁P67#?֚q9[4h?{g݆g̒ӗrc'w%,,*5jۆ$', 0&c3M,s6N4íX7}uFQߦ+\A&LM5 $mVZE;ۍ.CBt!/K_w]%*xܤ}#W!R6;hL)OKS;xT1Q2س5Ȉ}HHo:?XA\rP8|D넪nns`oIx&uCt0FHDʡړoٟՄot&a?G& Ȉ) 6_xGjЫˤY/C↳J{Ӑ$_M՗weC%:<?Q"p|ztTŞ3t\O`P썄s4P$ixۯG@GI/M0)'EE=kLř}+r'j[HK6P~dE9v/s!Ge$蔒bs?p&x/&U.Wnv(%eA hUTNz2]2Ӟ1ղ8N`7z"QNlyԼg,9CC4NQT+&qIh)q"wbg-MD_0CWd+G(JS2 ֲBCwӍ,;FdW!+4HpeޕBwxR gvTfbkqd=mv[gpjI@"? GjseI0'\>iBS`rG c><9 mV[{LYޏC39bW :qclm3z_ru &Pƒf]FӅ\ȗ"t홛cwIS g 4JJIH‚x)ZeY w+~h )W(hhz|bKFPH,η=V`E,m0P#π_XzU[.)37>rU--= cUUɺ,HK1݀pzt8&NI#{0&r]dUX`Z?噛fN`@̈,TeZ4=Pq +bՔզ| poiW#aDx8EPŬ8+@ش<"tZfYQ7%(h{Gfgv,_kZ,?UnJ1yǠM=%iWZ3 ^Auw:z0FQ3QU[ZeC@+=X"B#Z1.(P[ovj =_wb 9QUǀBa ^ӹX.&x"-@~( ~?]p}]ߜ {WDx8'`>u|'PӰl%_Gq]zC+|#s2& Vzd)ROt d< ]K_O:0(mĪ!pƧ.ZV1eU|+:){SkF0Y5#DOH(᳓#z3.p0 HHK*Q_. %{Bw6~vjϛʱaЅ<&&.z 73ej<V$}3.Zn& tO9kh)?W&*֬ܜR ۡje6?)_,1$Q&p;j6aiL<--O&ǽeOY2WZc$H+NH@_toHs1Y@^Kg]#p$ť =sf13pRBؚ1fœhN|5, '0"DWˀ lbWi#!J#}H):s72vüCf)$SW I(1cs̛,'u>6M|^Ny,ˊr4E9X^wV  rWsJV.F7p W1{#Ng5>X}߀n/X153"gG^)dgp8zm.H, n$ELAU&@Kx.=I`Q1Z8ѺgnҌ>% թbHq6sSa O(?29Lt6şshg aQCE84yVRy#>_ YDGqiq rMD;Z2b ߥ(xQU0JK so hűi3=u&_z8Ʋr -Q5˭^ Jؿo kjjtԍBS=RKVVBE3 dR)mmaOE89˥xwAD:X|ULBP=(R_kA3~'fX{5u~pZ~;yGd>g̑sJ}zLkt++֓56G?@ 4, -[s~wd{ 0+6Q?DKK^lѯY k BX.ͫSY<8D$3hҝ}Av#pPY$k/;\-~+ݱIǏ #z?jgܩ[LL*d*eNv|޺U-xbѠǐ!}<8;]s [GK`H.;.:nZ,Xm #)Fw0RQ_՚{o=(١m!zXwjηR4^VDCO*_Վ7c-Kq G2Dqڱ)vXZ!mF ~pX.߉d],Tm _zˏ#"hrG#EoeOzMl$r {UY8%AY}%ϱDlDErJbAS=5b q7yم&]ԧ :%OX1;p2fS O:T1aBRRڔ| Y>=@mDێ;:3K-=Ӗ2LC0a\^aj10̐l7ɐ2h@<]Ҫ4yfr:'}Vp*s +pаCEnqS^cmlJݘ y0$OTy S X7O> l3Qx-Be 5b&j%r[^Ă'k@ْ11 iМd|`Ǚg)KLREte p?h]a/9өǡ3"S? H v9T>/;٠g#E! FC# bWj;Bi7r^+tA{hsfWr׌1D&`ͥi4bɅ Kh".o_bGUr 6hfJrS★ʾV>P3L$e7(Ij܏9u:@c%%Cݐ0 p]NȒ4hR'tW)ބox) ܼ$jKUd-6xp=[?oɬE1{"DL\WƵA LzG(',f$N ?{l /~&:W/V]45:iv,,olPfin /u >]f#$z~ 2sƲXJ\ %6 DN'xydӍ\!eEyGA{*ƨعMA V/'KB"[u*{+ mF qB+ HYJˎ^lW)xS̻Ek14S\U%ԞQJc@+?qqIPl ?'X"V*좴8S t]jM@O_jE**1r/:,j9nPb}ho^L=wJ;8c OG=d%7᧦1-Yg+dN mq4o4 F$NaҘ؟Z"?->YfVܐlsVc݊r= R`TȎf9,ZG,BZX}Q@Eۢ׷pF8o閏6͑\՝'49 B/Ŭp9q;?ew1= i'[>M 7zCі7=6iȋ|^gvJMcIgpLd׹x2!rϳFΪܝ/IJhnc3dR* D.p)>g6ST)8-x_R~1,~^Z16|awx"ݹ*^l%Ƞ輚qa9Xams*8} 2xB {hz2^[*]5j)ŭ`%4Ăq< ;ߊHۏ s6D+p|Hw yG>r @{=Zy&!6zLMoW3%8y֏7;7Kw]}r`sg ýU4NqOs/QB*io~P{s$ z/Z3v-Y+CVeG/ԟB+߫  &FR?M7l} WFly*p:aje_K[.Pb6L}Szy*ċ2t V7Qn`K`aPddVaaeLw!6:EVq%pr`=9Ƞ2\0'#GX5bQ"d}}֩jyӳF'pWGdNcʺѸt%2{ְ y3$ch'.h"qM4{jLo1cLbGj:D.,_قv%O'. b #T@]Ct8GG(&5K$J݅H-Zז-NfR6x#-%q 횱!I\@»G8zr:+ 8|2)oAtc`܊!ԣ-he6WP:U8znūmљfxhȂ5BTP\["iRX RrJ*Bd/?U]A\kpҐQ\IUD_[2,^%Mm qj ĩ{+&؄h$ >'٠Z$wnor 9h? uuT]6ydLc4oR* ڰ)tDi­S@ c4eBҜ@XS}R)똯bKsi|YmD];5xJlSva B$k2vM4ZxJSB Bu&X{gϪ)+o)-1tw,<ő#^j'Y[yzk4ecƙ@~P3}a\q6tܮXmz_+Apz*-=!F e3YȈDeOF"ݨ!^Ɠg63F~^gFnA,!?Vǯ Rh׎cfnfE`T~/*U"w6ț`Yr(ke )ED~R/{R*Yl=b~}+9|B}}@-sgμ׊2zyh CUJm_IUӒ_y_`X̌cAh‰3yY`@لUWpR* c~-a1— -F!kP ~Kܮ$[ق' ؤ48tk0p{#Mϔ r9;d֬1ʥB&"*fiRW4KZ)8߀^O}H ۗ!䰬>Pv].XIϡS]+y"i}iSНɩ fa`@Y߆pCIl)9`R4F|NW[$BZ$ '^-. iDagCMFyd.i8fU߰*xn/N5?=ʮTw`,Ƃ+d_0LCƾMr!~N~&]}O dj1n_zނ=]w/KÞ IUbҫð+ `B!V!k.ʯdH\xw sI>x0_Jԫ kŞ櫝[wO"Е;Ujes-zV$^AWe~9O]!{'He ]ܶKt&M/a~"ܞ* ࿮`PPW pEPһFp%z̞c^Ս %o]P*nt鵣~D\Tcz"qcbR6sQmL#{~ijrv;m@?kcԓ9eqM3 @MuR&T8IٻtC`ڣ7s_MPpww6ݵjȃf*_7LlimMu[ 1C<)p@ $E]k+t!N ;(o֘: #>=k̛}\//H !G/FJ$)uEܛ%rW&(_SƀڕJ! "jS;eY`VqN9·DZc 9%IXǠ"I*3Ϧ>'0f4@\#=ͽ=(ΟeQ"QZ~hud#1Y!vԽ;ʡ۵JF(!x^opnH/.O\g8ta("3[S94$oYYlI wq_R,-W l'>)מǒlb0pLnHYݵib9Ț(@97u["ZՐe6(I1T?AfT`9Q 86fC xDt|bLIT4NF!]<9rKBjN$PjbC92E`+a8Q%N m7?ޱIwT -Ulsa[蹰ɆY8uJ@0͟A|=?ˀ =5 P5^Yg?R)Y"x iY:8O?kHB8[>*?dImO NܻoWEڀς hvl 8nF?" B)}%$P'SˇӄLU`c%V7slg&-BJ;.pWʢvK1+؟(T!0e"j [# _ҵh OATbx܀Qz]>Xqkjrm-q{ 7@DZbw 9\g~&Ň?U'QUs2ͳ$pwf*iz߾S#ֶӃhyH={]<䡘$(*JjH!+XZ{|vF\v|>~6m@iTnn#˜SiQ0x15Zp|![b9>oGh̟߄iARm*η4Jd5Fy&|sz8Ժٸ1g-B@W4ݒMa0q;n:d2"jkZ̓^ 2,DZmV>, M"l!%\.m_CھKnsj>F=Uu{O?89YAj)v-4}msqM454d "r;I1 X !zؙ.$_QXjnA:^s?֌ Fͧ圵Xmסر;,^x:ղS^HVTKk@cbWݹ+ru,XLgv˻k?4b՚# xvi@J7IWsԁbaXmpe }JY J_[DR\AnO䶙 Nm j<hSZRtU>G^WG< xҿFšqHlIo9vP=sSmBB'0-a:ȷb;TF$YNȡ$xVtv9*nsdbrIdUI*6HRr}4lFg|8/^2E^fH AV},82k N`-T7tj6m=hZ.$_GeLwj)<:h-BkilX/j N_+FIa@gNm Xn: K69ZISrql1b݂F}CR2/(4ɛ*2- 7Cu7Ct[DLȑx6+.xP>͌s,H {RаfyRsuD%=N/ZѭMrswO5= %Dc%!WTbi38㠬Fp|n|J7\Vu1 ΠNw} oC\I5@F*0k]$jb*QjN WEcW[0ቧ pP7cBXX^qd|҇,]%<3t̂.~|*vU&>kIg>)2T7^NS{_EY,tta^+MJ2ɖm5ݱ3tTXO`!C$ۺ? )U././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2382631 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0060000644000000000000000000014270014625637207022712 0ustar00runnerstaffK|O* Gzg|(e(-[В=Q=IL^O75ϛ@ z޻) l MI%;;wL KD6 pI<:$sp0ƞNfR=HQPPh,e猣PIj1}Ʃ3fݛ5ʱ0Ӊ÷hS tc Ƒ,;YpVq Z67۱%!oVֺ̙;8j,3M.Vm-IKZu6Zr T=m!Ѽ  $uFsw.{[3!~a4u$e^^:c8O_1p׭=B>k3%hxvCF-g-kx[Be?ʷv,A5]B`EDbrX|݆HZxy faX`loer)kofVP%_F7Q J6K"ЬPٿK' &1G{CrSkgFj쌿g2J%vD*a:WpfF]cefZ I2Waxc1L8ܝ{+!0"{B[ڃBcUq@i_=F\I?#+b”$V# Kk 3$PP'01<*<]onPFDUp{ N)S"@ɜUu|ֳRzV7=p &GwC0eQSSY$rUٌVqr餸_5 Pє$hTs<(қ6q.ۋS1xY/!SjutKM%W2tHu= W0 ѼJ5S5 iH2mT~U(Ud,_%jĖgm/b|p%&Q@R隗뵠r_h"F?{8ePe9 ]|BO6ZeWi5W_+n!PGv("Yje@Apї$;C$o:#u"kln~"fRvҗZ#I j:\gnT BhM y\]TWƈMנW RqsfآAY:e{I%O]?RC@@ J=QxlӋn0MD9C,ҒZ:~o[&V?N:&hVSEYBm>s@JOng? x^> ~BIvZ0Q٥GdI7e`R%PxK NTd[uEva ;9\6-?-҄Ik1*\_q!W} /cJSY~2b^N\Lȳ)h;ok |]H|F7S67=1#QȲQL$u#\QѺS| $R-1GJ::YӂB?UT]29=|O Do~w|v^t>3;bY[kd%}ѼZ2`7X`H+Xw)4پa)AGbx}}vIѴ`YOt7̕";T!E/#{|.r EHi<Ϭ1oF/Eftc$ՆZ7<'sɻ ~&}Y})NVFUb (UّN 녃.!*:~`?g n*Ms y],&7) 3Zity a@^V: zjEOSم*P9)Iv48i/tQ)%?DChR_ Clo=[;8x% :,{s]  Sv r~^xjy.y1^Jvn(qjT$0u*gU!ZM)[?UǙTY= 1_:9mA=E09=pH[ﰳ!g00$?m#-'1» j8gkDm7!(;J1CM7q֩Y_ޛ}\`>]ZTo1obpXF59# AZ3/UUbX2})13!0iD7Y2c)/1E8bo;gsb M*R/t6O0=b 9T жv(~uB!O Ypqv% dkX> )cG\[v/kL3-:F~:#uw>O ŭ) Hvc(a!}N9dݺmS(!@0^%U9`L$ #@;gwg݋`TZĴOcQ 777sOy)K_Y-6BM- AX֠9fZH= >Y 7+[Mz N芕L.? ٳ.yQJUe~0!.%p+w]hQhS;{=U/{Ɇ\8gzx=DB0Jz͚Os{([ĝ<Q bט)Zc>;.jBDy 1cM9,ENdi>uɧ I_yio2U9n{|@ rqfG/ hy9ߧDd˜Kߛb"$r☞Ɂ=eM$;ږS/vZuaK˺$\cOoDhl_0u|Q5X^(Fg"@L)" Y#3*/[qb{!v(e؜$KAkfWYB$}Vn!p:A.ٌ1{W%iʀ%c+2x3ުܟ?@(/IT#YQrAGv]\.L$PfOmr"׻pCٿfõ(pkӛ%ìJKZvYRE[z^cP)L9?@ϗR 3]J.<<yiήS3,>YuVhnityK4i.a k rBd qb) jʓHn;0t[п& JBa9IB,6Re0fnǰ^h!*ZM*DOaԏ*X1{PI<(" Ygr:]%iIBŸjKq>BF ^[ʙ.nGD9'I&c lϦ໫ar~J HI~)/M^m,X LQF.k(NafUa{d5I^ԩ}A^XQNZ/ț O 0>R!dV\rxC62Op]pd;U&p`X|eV8-2h5+ ;յKrtT xtBgj*QFI%JBbu\#rh@3?hd_hUgۚN<*É~P-U PN |$/1x|Z YGh6?_;u&ڳ<cr9Xn$ ySA0ݏG2Q#`y:+?yTp9-]c7ŹD޼uv>xfmw;8*vNAVI Ztc[֬a;mvuxP PuYZE Vxq$G+\aY33<\`w6 #hؚ0yj|_WHi5D*HNAG PkJ?tRBg`X6|d'qJdzhR" L[^ !RS}AlhH 0I=UW˪!>,<}4-.uAҬFwwL?NVSw4P qAZv uf1*0T(MT&U}%7饮qVTV:@@sD^9d7%lFtR6btM\Ӭ*dzs >-V$_Z?AXeD`( ;*frڪrA jysc'h՞cQo2nY;KNݿP7POKkk x#*)f't/3v+[/һ@@}ݦ>}'@SnLůQ74@ٶf}4#.\iVWFIF<9RPDə6AS`^ 3N2i srLDlF% J6`]797PkPL?B:)Mbo/.Y~3LIMD%4Kϵ+ۈӐj}7ALL`Caw"8|<[:Nt=\-]Ssy"t?O ^:~,BKYAϘUu;p|"  h 4` 8eX&lM<╷y*_mU6bcnI*nax!!o Y,7V)b-X#aM2%c$8&S0Gv<׵Z4&|&Y2dbLxl8gk!i ye  5#]f[{֠*糜 pIאO!A S͛ﲸv˖)a#TI˗Wp;Uweг/aBκm1Kذh^`3S砣^ip9hBA" :q1\~(ZZÇ D$Α[ejGD -(bx9l%od@%{'غN`̿@vN ȶK/CƛnٓQ[Ш^7o݆fL_,Lf˥oA,"^퇓` hpDhݴ=X%g%a $l(XC sX Cөt! hߪkὲh;Lg~6^h |H[TU*C*yԍ6+,; !J4wUi|Ηy<~XNt$d\>>r".19T6j2Йc~؃UzWzwTnBU\?IEhIJxbjcNkBgZVs B*VhG1i~N=NQ#0|1Pڼ sH[lP,7B0!ҹL!&"!5Cq5OS{g%DE1^0=J2zKKAҦ(*J{sr~Ƀa^bʃADTQgD+q s+wP?ḻ=uWQ> ܖ0b.ïJ j+ٍr ]ʄK}˜u;H{O|Wc),u^ AGRbYOJǎ3% ( *5[pޘ._/.9;Ha 3 {jS51R(@q\E:[,hhO =~ȍl3S*UB:ْ@(ŷ85zO㙵rW"v&=dT[y[#mHvb&n Bi`B~{ _TQk` IZń]iIGi(he>u걸%m+/塶\CZpH3Xw*k!M9 dgLHo'?܎ `7&r>7"Jdp$_( (N6^ʚ+̯%7uS)9gm(6M0 κI^~a=e6k=:~[`@5 7C;#r]P3@HDʇIԎɊ4THv\&qaŁϯ#@4]KK;+A,YMq݋`  a,aMMY{3O5G#|zXm`06m~?GW;Y;7]]tZf{ 4a g0ʎ;Y&U% ysnAAɆ Xz~.yrVSv_!r-25V6/=aڂ0Y5B[fh69o #6{gX!ʈ=n[mDsc8W ϥᒒx/hdG}WE;AScJ?-C({XZg;?`#"!ك͡ku|z3mJN[.TKrMጽnvӡZ sn 2^H,C`rXP_+Mi0Dd[xip&_D\X aeHǻten\PVn}BuKCk lͬv&`U,];п @^G9ZG77{U*ɣp};x;MDEN7n +W.8mPo&pGjJ]%².:FZ(Lt!ZIbn e1^Ctn\[~dhJ=,Qc2 6~T2/6$ljÒT;6'En;EVϥ]v O 9@bn1若&1ųXm!s ?muX» ҂Z؜d3li.ej:!˻iH8hrDRu`j ?7Rd؝B'}M@,ʭD#fU$U0"8jqTࡽau?Yد0(y2D^|UJk&q!WH\ ܑw2G4;Sdz-DtdAKɪ T,hOG|FdAhЌok?m4Ce uIl } "zMD2=v׋a^#Vv/ǝ4qea0k}Bgl%6@HCuL" ?K%5)K?ܽ2q¾Lrۥ{x~dGS/`xBjjvR\8Y3Yg>:8ʓaHnu%8pIMy`P^=nUokkB1*n~y+)"]IyKI=D7D/RѢtWjv74<@w3@Ұ3dпy_Y#?%>@!s/Z{cUN6Sΰ A,eH) 6̱vAT\+of5:=XChwg'NVcX #MJp(OuUf#$=^׀3,*Bg\ٻkfS q 6MJ5m„񁶬Xn/>5FW z7.%[82ڦQ=QOB`~W'$,]pe9j.; ;L{䤃'nj0iv6* FL7 -?0"i[F)kI"8/DO#2y׾[<-50`cZτ}WmWmF񐘥'_%E/ۘB4qS,vFiv`BJnK.|#&K8"**mu{+&xRu⭫X^/n4{‰mP+q}0cEđ s/1ęW,jVAVPh@kH2$n\vwJ-hsEj~Do#&Œ=ӪVSy, ?,'99b 2!n$"7*nf V~qAOHF{qQNÅ/L?-$+$YWTF# J7]S1~2rO\l7Һ9$@rRƻ )lCR(>~X+K]RJ#;xi!41GS'PaQd:D[02I|#R,k 5 z5l[=u ˰SAD+FWS LF.cZetF<,m /LIr3~C[`Ls.HW2o{iywڒ!##4>j_77 αFTm[a'/6ɋP*`Nh{R>yRi) }{5J`%d^4Eh"F*[':ꗳ6| w"9xkSxZ2?p%.sz ڬ$czنnK+"f0Glk>l+{I'k⓳t K/D];S GUcƦ0NMz_:G %aihG@B&7z2$ u|u`F_%Mˣu:#-Zcoi46_z=|ltz9lT(1a(k׳HyG#8`U,% <ԪΠP rKiYXa:P /ީu1hׇE癱KU͡c%fQ(THu2Io|O5ܺ@-8[*UM+Y'l>IBc}#TDVjpgŭ: h].( <3DMl@M^E6k#24_?uy~{3XgMX 6 G3ezX+QkK+|JN0 ?)r 0΀9/ve:Z ' y~濳5lE𓫭[9rx-hhVnr@ݘ-7SgP2={~/#1%&> Űt N.]??~Knji=EPE㌳Vp vuR%nGŤ{Fժu"mPdF$tNo}e4]/N'Edc{NT.:'jfkBr&Sk"@d \E'b K!'/xO߼3N?ӼVtK. sng|)x9wV$բ цs9Z>հ:Uy5KYwUr!U΀Ljh'iI .bE&3!gRlV ({KttgZ8iqn,nbmPC(5Tn\~#E]'xKPV_܇BKiBe=^Ɏ'Fzi ss|56CblsP>=Oy(T)j7<eּ*}paVh-ژ+7IVB_! ,87MFrGSU7 CNx'IVIn&nΜMR/o&.9-qiĒu6A M.Vp>6Љm!_8;x#Xqe{ s!K:g#U_Іedb>\s~$Lv람_6稞,+AK0:b%'MuB KLb ͚RB֙;m[$p"ɽh•D]Ë;x5o`@)K67ͷ(pdėJAd>6WJ7]>H+WsQGr~~@=Bs%ES[1@6&gF ګį {dxBd Bj mx-(\/MB#~?XJ+EIzUF?>/ kœ  7zMi~1<6BM?' ^XqItA y IEFd(3\/N`.OIOuB<=Wl8e%r.JB۩| _iUY_q394Y2NH W"!#r{u% X2$웒$TK+ OosʛZ"ë́qLzsAacЮV&g4ݙ? B̔c{@N7lBBMՀsd{}sƼSC ^GA@a_]I`e56}N )W e_/ =-r3oP2ʙ#~Z<ôzbT>wd~C-/*p6T[j$  @T>Gv?V콕ƆX *xvȨ^H++ӹt8!d%챍=])r@4]8):p ~8nZѡFSB?#ft.Fum0U~n'o$2]NJ"q+6tՉݛoz&M' 6#GhrDܰe0xcԓ?~d h3v>]Q7]%iG$gM7R mY:'ͳ^$' WØ jY 0RJ1)%Qԩ;oV#SzlO'p?">We?QD!N-R3&3f,p,&>ɦ&CȑZ*%N"&' Ԕt X > Hrڭwe4 ]&X6_3}#*#PLKa68&.|p=Y` P1h-g)hԂFX?9=pѐDpas=Ѱv?R\-Gc"ߏޕ25 34]AbߏTʃ#l:fCYuU鏗/@*Vee bix҅+A W!殌,@Cq^dꏆ2E `6q %[jZ+g"袪o|61ӑت^@]As`! .\EDcii/jh)*_G݉E=XQo& U&'mxH>Ca KV.>_3q ,~0EK`.PLIqJ*0Sײ3KsU:xMjC.Ԝ!_S]' `*e9/.bI~V.^HumQ=/!{8w/ F*k"ĉ_䶷k#ZWUB+" D%\a"$?kpt<މCm«N4q.R,la/Io6v}f"sgwj7V$*r=|&#ԥnaK_I G 0M-+fL) ylq{,xRΜ$J6v"( Z\ҁ&ٛ,---`@%#Ʀi+hX{Xn˨1_U'1v:2]##Qoss`j0,U&Um7x`,M]Y<{Z\dyL7Udm72GSn PIeLOJ ԢgkIirxlD(X0`%ɦrk'DRѓ#^st`GmX_^=}O[Y+Q(ާew.02p:74Ѧe=͢LoVA"2tD fPH@A* Nͮ6`zl䶩 ^q(BbY1Aaͯީ@ PzР7@'>Jhر`Ѽ)̫MG jڋP_{&QE'kLv` jB4r^zzq`B`uH` N@Mݾӣb"bS 2"NJ #Ԭg3Q: W[uRϲ`ndҤʉ}oAJH˪౱SWY OZf< iIQ^< 7 a)&]ܚB~L{OGY0JlxQYUT-sj8HPssͷDV)<r:wmLPfؼ>tPsO96!d(,&HXu))֍~T["۾{n!,#Ve&VtH~pXIs-K]rY@$"LQLTcET KZ }_>ƀSZL}@&G3;A&M?ԑBHKEW_jiQ]W5=RGn]Qm\ 0%,hOd[P%_vAkrf8ir> F[ҿk*|P*j{R53B2:5 Oe[LՏ 6?_4/EƛS5!%6eu7ƈ@B+6&9̀eG㓈7y6ػ![}}\ hEk]|dtY^I@"3qthaCeF곗/6e'I3~phDE|8|l3H4@t lKg/C#Kr//Y "G:Z\X(F*N^RF9L+N=k%߯a-SԪ}0\-'!b'IŅФK+ԍ-ag-P=d|L}I@Zb^}Zayi/S$.n=JU%b(ƂZbnn(cn5@NaY|´QPѐ8oIoqkFxcJqugps*s\cJ_D;>r,F]6Own<8XJ̢us]*"A|XٓFMEn2̝jKV_Nyw @Xhٰx\ZleN&+WښY(4}+qF[+qUnϐ#NCU矺'_Qm+PejLҖT,qb0;Y5b ~X @㦴qA <*Lȴݎ]ֈQmF,O]W'@6ʻjPn ?zy?U3{6dw>"fWQX vT%oiFV֓VDf{_c{ \qZo(- 8JU밋Y$|H1 $WjƂtMhяtC t 8 322JhuFdL:T1yQ_Hى1rxjWH`P:5aF1;.٥uC?0nUȂ^ ~+e9>Ex]kbw;=#HUOx6,]Tl@? T枹Ƽ {I#BΊ/7[^ܮz]Q^3?I?lE{u7浑 ~gW#&A!Tީ(䉲ċey˥Yz8}.+ oYw [Nbo1D Nƌ3/|"!-E;ώs f '~IV0LVށflLq=4m,At&Ur_?':Db͢k6>/"LeCMm8T$57s_{E7y,F>PVV2huu)ټ~c>)LOG 78%2,\w/?蘶7+-- }vB ;TXM\*3(42ctQJ<9AaCaC*(3ҍlnwyjl_{<>ϖC =Hn .WSC;NP5JBRgsZ,&S"y6ZKc>z' PSɿʨI\ 4IUY:E΄hN_,AT9v)T- >Gif{!Tg!*Ync$2Ai= >Z5n_kM$:o䭗ӑʴ)<*JWki^ba-l,QǨeaV0<g%V|#Aab/1/EMdytq)G`R#XnZG@k|ƷPw y +iES@;K]k&0}ۢmA70=bxQY\#t6kHGGܔb\r"K<6E-ⳑc꘸0A_WK 6: ު"nG 6/^|'Meyg@g aA=e3'4FO G9|׃ 9T[+ A؇p5;;KES nQBa~7͍Q<&v6me()˂pP$홡>}c2K z8q[Mn2xǾd,a'ŮJ#Ӊr]mv飣hRX7 r*yamwrsd\Z1FCQcdUkwiP'+ =0%נ3}f5\>{1oNb>8%WOZNr8è?R_ JaPTQ^)Tj^dQH\*PrA  ZңL͹;m2%.B}052 nR^e,PvEC`{  wl'͆YEW Kױ.Io'|C,G6pMR/f(;S`Gt8\ϝ0A8ao)n3WHҖ]Tubce.xQ#/_@t`/y#ȔDLJPrD[2;}~W6=;#"` 4ib-%&AYp5R4h?xWlfQ&[A.~ Ǝ/^촯ɢ2M5mX%Pxx#~óH@ts 46PѨE >ȕŤX7na)YՄt MVie3Z뀣`/Eջ^cN]l}8PN[C# Fd&JV~cHP+e_6ϚplPPm v[r,~ g aIO_;h?񑤛?C@Q^5|N?r/9o N̩(0\_2N? Q3b'tѧx-#=3pyu3~$D/*@?YuBuIdJmv4ai?:aCcFShӄE:؀ijMDoB7'*sHXP Ƽ$k$Oޱ&!ccKܥU}[A/AP\F$@ eQ ,}ވU਒ے%*':T PMc4कt$#0bk7cxI 9LZHnnN;I"I4,>nF~1UwE6Ad9VG^cxe7󣞅y c#k6knl|Re64TqVt|(Ҡzi.5_f XArsً\EhGa%F"\Jo-Ж͜iQO&tBK1~$/f6҅$,4?m~d|Û*qY@rwyhX7JaVf&%$YQKE/^\EME!9z4ul{\(܌0i*:Eu9!9&`I(Rdx\ޣ?2ZWj2k`Cs\LݠTp,v+=4_r[*o9 ^)}t&dd>t]@qS̵@Ů)>X:QrI ;txび4;,wDG#T @9E[YPLDv689KֱuKArLx*3?/?]lus* K0No%gܒZĪ+2wg\ڙΤ4P apRtN.4v3Dogu W7,\Jq4:xz4~7v 0 ~?ss!˩~+[?H҅ބbA9vc *M}V^eJ ϕ4)*["y*7.`zIv)]ɀa]¯KϘlɵ#D[5ۣ5QhO1)ï_r&APjaJ9)W.̢Q%>d!¯M:[CwH@Ӑ-~o%&JI,|G}N_~ IeRVBw+Ƕw U['J$jhi)\VL(Ń f/) %>;1.tGydts'}rdw%s֟tօp|2w5sˆ{;51\]/!v`z 0iT*'a@"]F˕qTX,K%D<)ЈHNtOq1¼˾EF{nd#uQC#A . K^ 8ޖigey `rMr O[ &;`3Y!_FEdz-#ר 5g?&UxiJE$!Vk+ܢj# 7"?$Y> }ν~k{-a4_C$2?6(eP`#|3JY5rKQdо$9$s|Qyz;{~Su1OўZ쳿ME;%+Yh9RZR8 &e]I/dLI(VN H쌽[Z< "-/&H.ʘ& R^*b;>8Q]rMV;"K@hc` 'uru6(җ_j F@+ ,C|+a[,혶aA(G7|}z$nE_p>$gXn5HX@,y^YXdH3&ZqaH g#[Gν#9p ñIQD|A4CDYJ+O.4T WG|/ zY|{E5$A_nHMQ$΍ϧ)傉(ACY|,pa2 `؆N*k-Uyq*A^H-L+F},'3̐ HRe_~9r1ε2] H[2Qrc('];|_j׶O>MT}^EfܼV@8<޽X!6wOtb33lC5g鼜U?Z uk+a'+1KfD\0>c}Mz"Bb>1(%勥1&^k*jIų+ZxQ(!ztpƦ>suAT+ʣP8{mz;UK/JޗTv/s萯tp@V2 >q u1rѶ~0Ҁ$Ԫ+I҇a CYj_O$C)sc]ǸcIUXPA8׈x 6_n~F V^>G|b.a%[\Fߺytعͣ:H9ND[T0틅a6*vR'uj7wtWJ[J6gY_`ݷ¸{ 6 -?T-Y@lӮV"'NtCruZRYoICxU:Y99ҋqSDBxl)!AğBA ʳJ5C=Pq-L2URJF}+c=l1㠱|@F_"`f8aE}K:]#-^Y]!1{A.5wrIO #L05*' 2DգR3@GJC#Pw;@iNeK =3AqhȚT[8W4o'M 1 let@IO^-S_N]YLDM⳾|\:GxB'XĴ,h+zty\c> p}/i`_[QXYaZDג`]9ơY&UmI5epFG5߰ 2AV%luaW6wB l1 $i$6`Q$7F7#Y,9Ay NGM70sWJHeȕ\ AjNzlDͮ$G1!έ8i R:Yh")xP!.١_HF(%^a- dtUDZ1[P^閳gգ櫵+I6gg5E9n3 bLӤ{aj,5j5['|L*M#֑Y#e/BEvM0yx8iw'CNHxE~ ?9"HO|ߥ ?YbB|"=۩iPF|ũVX=;D$$?ͅ5qrҽd?2JTݍn]sOSF SRSc~f}Ii7PVT=:ɀr9`I~}XA-a ox|b#DjKCO-DcʈGi GF#X`={@I[^݁~r}2Iu ,7;=À\K.F}1檹=8 x n# C7i&_vN"22vO$0)N%d1E10¨Fq) @QtvJ_ LPrF wW v>4f8h4t1ʫ=?΅_hw`hPגw3Jͪ#$ClzEG_Q}l}NȽU 8$O]"9j4?#B+E :nOU;΢aa|p 1[Gۑ8K) 3\1H{H_r_,0?ͱEfooE=.90itIoY8@}=-!U ,q2R_Z 7Ư90s"ǂЉ4@17Wu"1#9 3f1/m-7Ҹ9{{bi[dZfuX3QKT`ʏM5Cm"Qzd2cgu1NJA!(\YSt#n߉aF(^\&hU<.$hWFYdK@B.L,Eڜ g"sAd[e VU|ƐU.=? У>\PfI {t!%RƇgo9=Z/ӨL|=>ʖOA,!6A.ONMb(]"/B_7,|@S[g'3%3Rn>*/QgG3G_I!(xS+g\P ,{,$%"Uװº,W<7?}@B~IEP)AGzȸ>`&}0 zyG! rXyid#D`OCϵ.!/Y!:=G:ymC= 9$Jg-ם 3 RlzEK]ux($e@c<7SZ'N %x\i$yv@%1`v[(q倬f@e*tvPDءQ. MUS0^H"W9N˱؂,v]10ۦK.ZP{S G[] /D'UpfMzV,@+Jzުv-#UjMJXc䷸ zp;ABsFҫƷ͓| h $R\W뾔kґ)_{΃É"AJғu{C 3Ǫv50qXg͸1F묤T)vDIVrv cguVnػE #Ӕ N,0*iLpE#e"Xf͹gnJUSU J)l[Q'lbNlu,#p;$ZoAi M9N_T {qb°C>]8b<^:̂>Lq=<!/Tޤ2MkmHz)0V㵧Kwvr!hG԰AbV|2P prײFL8/q[sbqNik//T`qw9ᤡ 1&^ 4ŎhiEm] kfEW5-rBXbFo:FI륝Uu9<Jcb}Ͷ &2CynR/ ʰP/2\ͅhAq(=yf b] ?WhY]ߌ Z5P=(u9qՁNr5O瀞y1kќ3^\{w?\UX$21cs,n5f}LPH+C2O<ӄ$A#KHF=""~V؛`;<+<-씑ѽGumנeQd:j۹W+_PO?^]q/}ha[?}T|F]R_rWlxӼe^Y^-k 4%:x`2Z )Hl⥵NDg<zF:8vU2y#$RHu#Ѫ$dO+mo˿ܙ,:;ɮ+ٖM鹅p ]-zCxn0p}\-G,wٌjq{XPkmUɦ҂+q^aJ&Pۣ٫2/@+/TGl+f ⩮玽 pqI:rH #(B zmMgfKbƿrpi*@IYFDN}^~$(\ j\􎝐~GLPbeM #@WJ I?SmI'Ɋڍy8rp5aҸϦ |ݴsf _tFV뚘-ؽLbaVC-XY!bήgC_)>m?15ex!ީ<ʀ뱶܎ O}U K,…躚FiR 9NSm^AQWA~3qKh>l`\ Pq|{| DuoAoA e]UG yS?04aSȃrrEr^ށtQ2H&m}U{l&:1S~"$V؋7A,c},=\gD[9_( l`M*ݯ75h]dڡy-q3 utc=ЎLP-Ab!?&7+9[RD2مyv9BU'adٍɭ_I<V$qHN'#u!xAs$&19ɍ%3Tg>Dy*LƤG79˄lء7u:zm]w3D 9du5bٞ 50 0I.F{Da_K/?8@d dp=#8O̓@wBTWZ5"̫+GCb9T3CBtN\,͉k; ŪJB̓ jG?޶w^~^ qnDZz4 y&aCN@ƿuW ./],)nũ:R P`IRu೧ou[Oŧlt. mObuyFX>Ak+O(Evhfik?1UӆvI>ҤL X䈉i̊inz6g" Z(ҥW iY;* ՗srO|Yfjb9p#c!&U bYT.rC{Xc,]d:=t978ٯp@R׎J8B \Xi4Gs$<{v6 xG@P7qT!ջ5W|Z{o:X R-H.jz=V}q: 4V:*w5)o5a>IrU8` bx.Ѡ# %r̵ys"Y=DGۙeId7GKQVAЂsYOؗ՟\)78 o칢oӥ`[1Bn[Sj!0Ϡn9n03pv~}_lSF"ۇ>b R5.V/XpNAM&w(F`H8pnxw%Xd2!-=? \c[:{@P+;[SojF gʝGؿPznӌC:CJ1RmHvvnwxҨcP1M vp21>t85Ў=ժ>`WꋶTdޭb(biSݥÇ`Nӻ`^#9TZig1[(_ǿ`*FC r|q6_4B㼭 v~B}U:aI\_uȂ /,N/  3sqdEMk #7Nfi-e'ψecB왼ƚ^Z7ʎƺN5}͟u*"L>JaQRkE`VX 'Iu.]m;Z!X?h?\eL7#gd_s4Iv9;!*R ?SZVWXo;Dj(';N\b+sQ;)/PEw* ۹‡"O;i|nS/LqMq\8;q%wxlW ;Ib 1̳~M!X/w4#%6 j-21Mc '9a2O]fw. T;xn4v-8[%W꟯C0zp/f;R(=;E/۹ `-n(,%}AWn d?&H􆸼fFi>!h\mQ93`q[0_wC&km+ Lt/z2^1>+mOP"qͽyBvH#dfXBVf)t[:$%X|ޘbneesd>͇#$`ȗ昸 !8gpN1x\E A7!DqT<Qs τ7YIHB3qke#g# ʐ\@۩OcM, Y[_Q3Q`t/>|Bws0/!ŕb5؁ljel@=fbr ,e${>\aGf*ϛ% XA\@ z_",_(y.6ce1>1x "[?Γشcԅ:g݅#ƇDR /5|BABF'1oHȐPl9j Zo#l "TJ6[#MbN̯3P24F>$gXl@F]G}IѷU$cmԻjX ȟ2DK)C U?؅_(}I-Z$"aJcS<;a`~fXzy$kڧ,N)1W,mW%ztz=}Q t)ԙhN#Pvi] z N<U/q_+d]6teEO L0TLuGcupi"_qQv5K>"UxKph Z"`]z}a+A,@b2s7oD5EZb"HU{m8G+tRSJ@<! tY뱋*7)0?}#\9:\wS29&oFK>ߌw&n%Ycѹt 4sKxS]  }83y.бp$Ř2LG$R C=}#kɉ ^O|t w'ftM1K- n6vtƬPϮV;v=W) pӸzWk}l)tNbARlIcUӢ&:$05G';1\]u2<4qwD|4m+C*qE1_͇ ԐorXLkP:!~Ҙ'BLv#l GKU}R '>29(s[gO4EX6a+}`dTzqT/tgBUV;9bĞ/Aif)˅nٗ(sRb \a]`fxcARDǭ.y<gm.u# O)&CeHKO($UN#>_y2m xlz7&pg-^@&MV5 ᣣ'د֤utj=Dڑu[gp|yriL͌/7l2 <j}Jm3/$p3sLQr* B`FI#=& vx;s#&>'~VEy9 K;mYꗻUEtH(F.BʋWV._'LYˆHeƢQ#w-,*^~( `E£b-Ȏ4WnNmᄃd:0N'ae~^D~EOIvSc]uC8T"zq+Q:;KjҥL[:` CAdxo Suwwx7G0I︲~B0qSRtS- 4m|sռJfyLƏOtB w_gl =L1ߗ`k뉊t\\t=_ET64TTB(]Cs:~5)<͔YfentqSEuk9fNv͌EX#&ȩI;EuUv !B[C{Dr$j"cq%Zaݵ. `1$yӂ꼖ý,(ҧN$MW6y=\FѲ_{`4yi@ԖLJGxE0:RGLwGzaJ@s(݋Ш ݇‡'5>Lif◦ Ξ&STQ=_(l_&4YʿOH)[7 fnʾU&E ,4P;y[YfL17De5x ʑz 0\Jd|%&#b62N0:>\.uHaK{&;ms|bP#1$όMaW2HWwhAذMss!4۾Tㇽ4:qQ4rpFPR7֯ z~vF3A!*Ely,Bn<׍Ҧ}teq5$u9+. (7$ 2gd; F~6Q5}'YU9܏K1 Hf04+&a& XN#o@H}AFdgfTB֢-"df[}ٔt>bл|a 1tWz+~b;cVE2H`"BvCS< ]hݶI7R v+iAae;:0^oȵǒ%ր(;k#)۱ U93z&f$lR4}:pؑ$Vйi$^[Nh^Tolg%Һ_ Q;g5ely#ْL"r"&fL/;ޭYvu o(b4~haW9|Aݕl4V pSۗXo>z uo>o)+(M@r~<2VΚ1iN(7xuyI0i.Ȼ1Ҫ/vGWGD\TDf %Њ wٴ8HKPr戴pE@n؍Hps #/Zc%^$&8];ف=Dk++Cc婾nb?Ԡl@0|3UbCT.t?I*RkSZ1JٓRh[i);5)L(tv0bj{P_#,;3\uidl[{+ .&J"hE#mls'5GޡDG;4K tMoI2zK  X"e,_ZOH]dgf_'YZ;)ZWw69b|ne螣/C8\$z{!p](Fh3@Հ}7di-[; "3;QD54S~%4;wkğЏuVJ rJ36SgZF^08K_kD k$wԭ6'JlLRD?+wO=$c7W QCET 9sYi d[gS#\Ğ[B^+*/\6HCL06+<g28f Ψ{hih=@YS<ڡ)Y]dIjԖngG0>ӯYܲ0͉n ĵ +qqH>Lx}G&g/W V+$qB۵Mĝm7F^*0_2KR {Ed~8:|piC!c/HMUJHiy'bRڻ>Fʸiu8=uFf7$Ꞃ=`v7-2:e"I<>>5-Pȿ?}3e-,WuYYC2( l:Ii G:݌vH;|쉿/ 0C׷c辦%Q'3+!]) E8fwi<~׋`xg* 3E y2ȕ=̮{gLCufb:\h~ɽ]CjRJ{Z2AYp냮1&(iǹ茍=y獜?ȴnfVG0Zy$r&YA;ROO2;#H}<]uV:}G(<"|OXn@P5pgww{yswS6T Uh&<:9_9 SO1,MIAS+dOBw3%xV N/>w#2RׇB0b\ WpV&EN84_mY[]#H/}oJp/OKZE5C5Wx' w# 1 8Pډ ׂVc4폥{Y83@C$D9E2>h6(m6ɢMtlz$<Q5Rx7ৠRb @ոVWFZ,]u+?of#1°?^!~i6*;')y8Ru/v[q7g)3e`BM,ubvaEQZV4hV<\٧#g%zo;CjScKE,uT8P›I0jA-`Joi4%MoKWoFV`HvցnF^zgۺ]e [!탴n u7Vz S#ZMQ9J5OIچ4ޱbk.ZI]AiV C}WN/l&b j^'/Hbn(Şrr>_0 =}]mQ94P |Psk$O ^n D 4gGzG;JBb`NC b|*Ae >*Ю1A0;}60lğڻ?х. Uh{SqǓ"~ Vre{51R#DaCuᶊ#MTdw.QPF\>%Au'F,A=i(zm0\8.o oڨ*ɣqH%2;q> jo3eӅ Wbt*9tC3T{A˙5#hAKcP#W\ vODɾޓR ib}Պپ)GE_>3e•Jע3.[bRñcf>OOƧk<,K0ȞOSڡҡ8CSwVYSlW[bqB&˘EFGeE reFMi$Z>E=&ih6J WRY6A/jA2wHƟuZ⺈ϧV1AU4@q\qp cf[af}i1vV߶u}gܗt$:%RbZUW\nCDG_% K8\zy䑙6kJŪ|xlUqNX^Px0w~_ϹNl7:vl7YY0ZRجj:Kj n2-p ng!3SARS؟bDW*o23;%cGX*U>ǁLZ5~uL!(?B8 ц&8('S6Z4yR}OqR*دQVUֽY=ŬORQMW kx*(IeE>~/z-ogJV<ԀyV,X_IB Y ; 6x[52N)10AatO䍕Lۼ}[GMyp4W]'32WLlg@K Xpf <{9_1 Mty.ap87N >QPF㥑U bqـYw~m3KsG `~)u(+oG56@FJ9?,yՎ)GNNP3fm!IDwn-230mSָɕ9 vTHslBW@wJ\Z&10[v{OfuSmϥ/z1t3upH04!ELSm_.3bWĕ}? 6+eL.7WAdP̯i0&߼9Ю,i:QOd+"N LW-cѐ bsr%RRQkUCQ}cfgwIf3!Xq i^i*3?Nv&dy C95WM&Xبdt.뮠t L=s?*KfPԖ Z>Hs)1|ϙ P[Q-יHh 5H4 i1@l xٰV|cIqq"A`֛ވd9LbYΝu:aGcr_ -i=w@iwSP&E4TTɃO#KI w&ʃէ$dO~[d̚p^Zfԃ>(8]Ǣ3l t1S*p tyI?BrRcu(ՆZ-aI\+T흙#L#*C |%f&,v5n@TKV[ ЙsԘ`bMebKձ럲qUQC [a:O%zJU6ReM?^1He$v5mCxBC[ pr&Z+wE79O&B1RN5`H-2xK}4BRm̴1e"HNtLG]D4eS9#q́t&'ϔT!,HmK@R !4@M\f`Etp5fAlSήeHX="(\7V+iCl_%Jx%f:ݶ)s8b YrW !Z'.`*>9ڄR&>,f9e2RoyǢ89Q1>$b'y(>\#/zp7NM8#"~X5뼼׷?p _Ds+3Gal"i+ЋrLJ]*Eڼz>yDV,|d|XY!f s.-avaw>қ/ylU&U˨^)][K6 mGjw3bGpAmm/Qnj̐M=+a=&?'&s{14-(kd>3pn P&}d <43q-^,bN7߰`7l1\l4Jƅ_Vv+{՝m\IO fk6X  s5Hr'6n?tc&!s#cJlzu꾯vC-0M/VQn\#mohB ńwՊiUIlwFJ(A:7xaYmպTa ,@ҕti7[{vF8o'"5#(3 <܆i}|Et7r,0!spUlRXfD,fDp\!`n -j1LC t(;[F|PnP !s;V Ļא1t1aߡޜE3Z knwSC'9eh>STO,s* EƧսDSt!K|9wC7Xtg=jd_t)oFX7xTߵs\h#1Z5dXTB}jW_3ry_ֳ'b&{Rc(7H\ӗg×"H>ZQ;j}LNZ7!~>~v<| jv}S5=Q؍@Ԯ[v,v5MpB9K3*VP2V- 맇O!}~N{<[=ʹ~Jdv IvyqNJIEB9s%P}֛p-8~\l$sˢ7T~ =llmo~ VμvQ.u?Y1sݪȺ>h緇;E=уW2A<'YSDH*J~|.m$Pj~s39҂ p)))=| &LzuQRzύljR"rg~(GV\|kq~`Y6^{Wp "34ýEATOsPe:؀:qJC*eW=QSH|mRYT 4|*rM؈fƒ{y6̢d{b9*sL| )BpFkʗ5;Oh4 *N8#8F\2 Ft/܃+H[×w V2\!Y(Q2#^ok`נk 2EE{[}>1/qϿ`M9%PY|ȥ@>(;:tL|Qoqu.:jnZ7jfLV8$i+frݧ ;=J+\1x53vɊ.) '6)!q b2aBDR}TG3*{F aH%זT7 gQtew=F7߿iثvwH-%)l/[odʼnO> Ÿ;]]!ns %ÚoP[+" {wG8ɹJ{:&p& vlnu'6lvTm/;O@ߞ0snr\eX⪃7jDXѶ}m~=TɃگ  ᣺"pg D,Sp=I$Xy.kB0&g3W@ԔT5[ޘle4}gFM}K 5 wy9]olOqL9phgd5̱UKN',FR:'̀vĘ}MFI("ҭ¾<"⒯%Bc[(%'L]]YՒ'韴ssysŲOY9^P='n32^ݎi%^n*?HqIݯCc0 cYFTbگK>mW`O'! ak—2/GZjޙa@?Z9H8|&lό*i`<+^O͞bMq28ݣm(V O(j 0y3!۞[l x PFbpTgPc`b B{_pgˈ&D"6:8r1sXƖ \Mb`wl#sP$ ~h9M0EXRdS5[@aWMţ Z4 HCK٥*\W[-Ji8/|1c%fܖۻ¾ζYՓrLӨJN2N%g{sJ4 'γ֔rr盰[Mⶊw\=.2ޣ4#69mW#^='ˆiȝ}eXCZts{9]]-/~,\aRX14S:Q)܍O x0c="9asA–DZGX[UPe\itVS[\Wۣ[E º1 Z\NO- ra{2M.L pۨpX~hjrj  r?h hc5Oa4و[ tFRRAJDFc/q. Wzk:*h!EwfÆ?JZs-!TvҲ.Zm}=Y7lX;,"Ҭ;/X8 9jUV:Pi5  ևk}itn W39vE^ԣ,+eYs!50 b|-IEZ͐K=BT'\yGx"0{ZO3’SE" IRP'Nu"y-F~Vt"^9"hxO;VQU'#!cFk3Ķ@9yIa =o|!$)x././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2376459 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.0010000644000000000000000000014270014625637207022705 0ustar00runnerstaff~6[W*=WS856 xg3nSگVɺtwzig*txU[VO˹:?尅L<69+rfS7g!fk:jN6WGċ(_jTbCGԜJ,pUǭ~G.$2F^ԗ9m[uc)􁍠G<<a}+Ky(w)qM_*.A)|[I~һEL[7H`d+Fxv~KND(9c1s;"TzbVؕMT F9d!Ê5CJb9Ni9n\LiA?G5|^Z=ByօKԦwvu TY0I dih{0+ mճ͛N)g8Ҷ-3PQQ4n. g:*;}A(@K^G:W{ҳn[fo%ؾmlkٚqi#]qI 㜮~j`4GGj#1s".2>Q.bMg(5%,Q5cʶ?сA\{{_~P0@1ڋZ vH!"a{U!IEk{(]A$N8WQ>@I f+2^yu4LzN.\~Cy;Jb9v>sޏmMx%bDm41ilGeP?OϘ苒"Yh*^\xڅ)yovH5aV-I %?2)9;JE}9@~Y9P~rwH*Y:Ig3l/h7ȼ" +_ s@wݯ53^c-Z!_bpGZ"lrhh-aa +YK ~Tێ$~5IzEiO-u^:$tC鑍|fzݨjw8ʛ/[&4w}RͷeEb^D:_"  e7{੼:ÁoxSB8ǀzƨ  w@0].x(ǼtR@LܦSМj 8Y5xFx˭G=utȶ;CI%LC_Er@ͺƔMni)a\t_!] " $r #~HQ[q# ޅ{zKzmx}Yyn= X @po`n_;@~6ʟYQxi84rMFce1::T5AtI_XՃ#fF,7J ٲFR# zجqA#31={"QpSx܎%Fyß|(]#ϕΒȊ"ȍWEI2IHczȏ`8X'lmq[ND4ZT;O|Ϋp^[+0󒪘Aj"/Y^%؂ >7Ǎ>Ghxi.hn~H`]@jhF:AhWo>/P5#x#VE2h?yvh7Knzfp ", FBz)S* ͑"uC:>6d*<*5iC /itH.l(IjaQ~fES„}s5i PC3.c:Lt<2yYNᶻk8A͖9IOs@i \xB@H?=80K֢>fkAbYĆ HH)?sУj]Sx3&rcJK z`|%GNlP'FybP;ߍ*5}Q xTH@/_~Pt ]#&K[0n.^rӧGw(PEL$sz6]AK`^~QyYZC蟲v b9ÿsu޴֤F{2&4|׃Qh-eI|wW2/s4+뤪q`.牤@=*Æ4rlP J^_h>MANUPKգE[,e~#Ak:6Gr$q5Ɵagd^V-xjh p#I L']/}^`Ԏ21+"B*!A諓#~S!h/hСFuŴdr%ڮ  ̀뢘|-أIcc0\ɯ@PP{h %wYrCn{HG7y(Hp:nh<>߭0r+?9ڒ0.fP/_ }>Tx(1"_Ң&qUƙGYʼhͧ4Ald`K7 ݑ]q+, .Lc4+pC,j'JC_Rzj% l@%ǜ^w;&iO% FWCyÎYiF ~|3bI" *?O]d PBiL6˘Y2fQѤ5d[!cLSNЃiƞHKSU𣬷 ]K`Yf ϴZ+RW.Ms ?p7}k%~=JW s\f #:2{V\&$ U,Ef@ټZՃ'QnЌeS*WW3QF;^n^9 \zqw2mFTw R:S#ҭR gt32FDj9s^)RJ4 n0!z{EN Kxs0T,5h2uUG&u{PSR+x.. w+^#smcn{7/^\nhnJHȳEQHi;zGZcD`,z4ǤȊRK^~>)<蔅e- %nj7Fk^|sGb29zW؊_EP]"TTo|ܫkj @.\=5#wk@VUN9ݾi=?;%JsGcr~$V$YqaV%"*jkղ48X`"chnȞ#/R}jN>F9ͮV.C+׀^`s6st`3f[#PJv$275?@Fw^ 凔^L-~`lb0sbPR^T z!XGNb񭳗_LfGڊf;DDpJ 1laW@۸ӭW)~@؎oej Pppa#YHX#I#GeCNB6W"e` +,_0GZ|ۦ9ʽr+0$:Lo~C_ӃPqZ] Zva֣{ SutT q^dtJL9DQ1U[\=L6TiqOmC]T{>AV.lwC.ؾ22a}6 bj^:0"@Nrn >7uEn9~gxcEXR5BF}  }z:dodMxY_"N(=iќP¡,Jp%r, $"EzP';^Bh(|ĕapz/ZK胦 \$m\SJ(XI& >Bn c|ɝ-xNXH5 #@U .E!C zeHskF Ұu!b1Sfbdu~Θ- A?.F1G|OJ@R4S $Ed[b:7(ŵV1Y^ٰ;W%4NV@2rηUĎdf9icrh y$ 4ˆva>Gg˛lubdW!Rm,P&lP_" 4;1dRf} X2hΏ(+@%O-٩qqTT%vȞ\3) `@d,ddu7[ mEPBv7b}aؽ$gOagt7E2cK? 0e7SKNA,[rAf٤53ZA(Vg,ܘҤ|ft1Я.ܡj {kɣ^;~6"d=u{QyN͖L&{8IB/9)ѡΜ)cGM:F" =dZL_cb@  _O+saCgGvko}S?tpَ{aiG!"KWhD$Vٷ_G<36ِ_PY:=np;cBs;ґ-+-ugUdwJ7.9 *M6Uo0\WTpVf*o +1p⺠Q,lI/E<:Tc&}0ϊP=Iulx8~eT b_ `v/!KD38|<OË~g_WX 6{б@Uҩ 8HN!n&̷oDtר~м?Ee.fH9H_h`eRM9^xb(8ud8;i|j.}KXeqg& 9~Tӛ ƀ ny_o5@xp{˘szP/^tYixe5aTgG!Rˀ3 %?ޖ 11"-0,w')턻yߵ}Ԏ"89/J>7/ۖVHUj|`xA-+ѻhM". BY,\AAWxw*'Gt4kyz(tdpٕ/Og9N9 q䇄x}!0VyN> o! z9Hb8?}5uH_V+$dK4+rJV(g`Bn2L3W3INp\[J9R7"mhVӸ^M[c.!bSU3ȹ끩*|88:tPF9Vmg6 N1k#Mr0=Ɋa].TLP8yQI- q8G?e. wZ.֬뿻x$PgAeB!Xd.abvYdBt1zD`|(hp#MXY 1K: P\ ƶh+bvsw*Ax[t ĈL^f%}uƕ}#5^7XY @vZqn nSP|y4.?"2gr2?4&]c\F(]Ѧ.FջTxRysfI D (A6c1'>tܫ\zDY?0ĴZ>4XoF%EQSz+).i%9fŜ2:}aE lU 7{# <9G_ڴ/&fjRoq6xC(x n 欞@d pՎKO, U\@lPiEsgENzK![l5 xu!f1:j _RQctʽ]ȰUQ>_C=KKXe7D꬟Ki`e<_jcD"N=FEwk Pƻd;v}K332m5 D_2odPa> QL. _0h*'|uY:|V]G2J6QrȐ^<'lΏfy =}( ۪W?Ml {X d@3W?mm1͝x͕A]6fO -oV%mFl)7pÔ^|ϊՎP_pLX=Dz{6؃O},1n :MPMĨEswޥPHpLiώp+});)Ta!zC 66:s֞ߑI: BFY%8ٖn]Upu+t_ $T'a+4^nc8p8_ -'Q,0Dω ̯B= i8!FB vuVJЁ.]=ɯӀ]oF)k0vQW' ș=_.k* 6HHrϜI->?Ψ[sQ $Lgㅔ+5 ̰+{Ybe/233X.MF"MR39Ͼyɠ_E4[tuB6;t'5zvk•!2h\LC\\PIe0 a׺cF 0 {V\w^?Щ P Kab 򨳛;iy|rcl_; Ae؂ul"Vb_fX[AoR_1FE4 GeDgnSY1)E0'+]3B-v7?}҈-_dzKG:} \]ccbW . "CIf;pp)\=y23kc0>;?-20 !NVC*Uy E ?H-V]RR]$_&ؓƒ ˮ~FDHNЈMz^Q4(!VMϴtޚ ҡ毦c|!m-"ME0,̷nցf>,4F2yKO~bVYv;# xz7APD5:2nj, 楂x3+^=@(}ZnRz̲vpJP z}i 5ع|LAhA| nAT*<۲psra$p*4L@);!{~X&S` =( pCio#NY 3<##PgDBJpĪ _VSCqNlXä`u>V5ޕ83q~\ƞbۇ: M@} QcD Sf/ĔS+ -FNkGhS]g]:2lu iܶFqޘ򫇟1^#I8u]⹝w4e V\yaݾz]n1k3ιyMeiqp5utpRb2/CysuB[8d*kSyOҮ&ITR/~<%ug5ol){l-xkp룟o&fDG<~o$ 1.A{w|Tvݬ YZD^rda6,S.jRL%NJ#X^$=$PH2Vl=pS(si|]X|]i_ NW1u$^IcP׻%kY#k%[?rA4[y0\]5z+>\+4<o8?|${tN^jѤx['A3`sL WD,L왈w W1n)bJWL$á']( 6D;K8~ˊaؖЀ+\5FgzGgitJ>YMW͊8o_Dr3@̔f]eQv1ă%)&@Ɍ-6q @ɝ-p ]t Q IY0G͗$Aa&[k%wNIneakUli]GȰ"NQu=q!D-O# =n)mԄ0-ԏ[!{yzgKqop:h r.l l9iԳH٘}Xx4“}ڡߍᆮ -r|;iXK#ywa &<MQxpP<1Hl#A䭙?/شhVsPJ_U6a{aV̍wIi|bYz_2O}e9@6q\PJq\Ty!lM+avtm%v~783'?sR9W%1&iOİHUĴn $o+\:C{6眹$F~?x9lU*ä-V<- 0`oGQoc@QǷ}cXm|$9EXp6{"{̰?}a S7yO{k[Iz1`&2!iEIJvL(DΏxH֩,WE s?MQa/WyK|WSW %|jTȡ&\\O2yt'&Qi*d7;aj[hO+'ȎD#kgrz0˳__GXoڮ`+PB>Ft}*%0ۧI]5)f]8zN4Wnk{8Gu#SY.%:"G '9o;*pn8vS0~gB~ZR|pԼ1" D܄}g1MX?q$"c9zfbB;=pI# O5oѨ0*kB)gy>sspUN6ruAmE]BBO>Mk_H|}@P29+B^%GN F&#*<wiK;[$VxҌe(ȹJLsMJ p'$2H-?Diڋ~ cʥO%^Gя|s fSוtaIVCn"\VwS4񕝓c"Ue?YTS-,<p؎K]#7$Kktg5̄Xdvz\37 j]OǓH˯$+rT)-=?_6~VgSpU~i #}_S191@R)}'Ph%*)"gf~iG/εB*f>55e s Ɨ"[#Ǟ,޼Y;:}R)cV dc4c0+p2nƅ[k@W3S!/=_^3}!@)5IE2[|V[Żv,Rt.5Gc"Vj*P;8us2<jɈ%huWUUB&)[(0prE QͤJoQ}Ͼ"jNp} 'v *z6K>,-V776߻,ʒ;_\XN_0l`A\Kɉe `C}IU3%7e .ғeړ^ZU}>(,"h@fs(OI6*J|%-=.7P. (XLŌbxw=µ8Z_Oz&Wμd ,tٯqRtS~Ki?m13moh^5֠v' ]!<O 1XVI[o-%:k׼GԜEɝ9{U*S=2!@'6>md! ܔLsUJ[AzY\B~S|a<& g]t`}M֯,7ji,֋4|Y-!?a\[q%uuŝsF^yU*{rCXd`:7wZS}[k" EeG=4@ \aAdjۍev7 n- /ݻjRxv00=nPix*ʛW]JhLfEk7&D;.[} 4=j-D׭GKM& ճaucB,+ X/߃L!~;-}Mm}zcMΏ1C”:u+JĤ7/R %/3?*حck:ioYCka_U2u'Lhx!\w ]E{1 w=Vߥen!dLե[+G qK$zC\^;emTC/Wil,٦`g,tt Hr%)ޑ?ah-_AHƩ!q}o]ߟՅZ0B%jf4-?5u+׵A!`B´uO ab j6hEմn LLAݦAG-Cᵡ8/vګt3hv }!ˡdZ-%`r`N< 3oq!a뎚يWC)3V⺿?i6au6M(D7MLߖv:2*|XR Ȉ$ peO^Q3t(AbM2"'J7w 0iikڡY:4bԲyO#y˜x-BK25 'E/1d?+Si 9^߆0$if =֞~ ?[ M\Rǔ>;!qhN1'BL陲ynG\L8 wa[JF ܭ P=aWX-Z h8scKё>Snv"[Vd463^1(|-+7`Z$~4dRR=+'o֔zα $Du7@7Ɏ/|i:{R _EW?& b$ʞ ~&yme;nt{o %p]o\uH8el1 #9;,Ll32x;JJ+ЧӇYmݸmKW Tc{@ie0xL^k2߂@,a-:2'HT )eXoc@FӉ#7|SlQ 3HV^hD"h12fj蘗U0U*FjxǗPG g>1 '$h?\z}1/ۛ"%)3$Rm6q*wBR+_ ހ4w#LN*?qn7XkfԿ45wfv=\Hx,PFO4&9f/7Q󕛯iVtO{9ٛ¤p:F&کOܗT>vS F)9#}Z$D2=ה;TwQX[ʞ$}%x!Cn`:+p%=Ab0su5-=E8]U^%HZn>]0pClg ݌THϱ]~}ujH{5*lGlr,}ݣL ]gqj!@N~=TJv[Jٞkq\֑~Öa"zǠ-I[zfpbچ%`; Q115m X5GS,~ԖI!B+@ȹKt6"9/mԼQ}ϾZ6q+S&b3F57Y*WC8UK9I0|_=8UqAi1bgPYx['ǮZYaIZ6#'e݃uV%go5JB-%O$_pg[pmc7 ^r-\K/z<+ \x@8#Nr/v@4J`&a>4j9)Vtg.g}Sg-ĕm :,ztF>:uk6-nkmM-w + 9mٳiz@TEDŽ5==ilNQWHbN{hiRMzG+)աVA(QeĹnlbGMDW񜪒Y0UMynQ7=.z@pS,Y*=F I8Yr9֘AnD~*rE_`ۘ"{&EW,j@)9PHW۸f.6θT*0oTپ--Xws?lG첪8[;ty%^m_ɥQvquGH]G!RIWD rN>6c$<^ux=Z)bXdBjhX )áJ8L)xqYov3OSob+$0q@DڙU63ȝIj(߂NXF$T>)ˬGз71f<^N(ulb ΂r8h *EATjtέDPY\WO[V#y+P4cuykYpr<ܵ/n(+fϩ{4t"~/0PZBU2cYqÌ+FJ] -T2~+p4Qg^A/ 2h3Rtn]_°oɌB/yRvȟ& Yk[<3isAo=If|96Z#S%$F} My#hjp8*khZ'd)ߌ.NI=zG@ & PalϷYl YDs$ qxQ#_p5'X>W5jE( utJHN+˅4rIW wԩ0_.b~CJMG4n瘂pm,/0U(cѧdk Sf$x9J@E6-×kpTWlxȵ8O6)akh3nie+rjw{"/-Ѓ9%JRFwk .9+@@?Raː= 8=ܳWj<#dPioO:>ª rCRg!?Z Ғ`âxއ'X2iclj#w~-MZ آ%^zUd k)GB;L%4yt7H9>D''C"$`ÀNՓ$09PoYFgտsVMx(ܕU HG֛Zl'{B6 cUjCbYRuP箲Z+|2zc rp }v@ALz ^Sôӯ@z.jqAܑٮJ6 YeENB̨Fj**d4֩ -hK(Gvn¹ k6U(j<+>oo{AmYy lcxwrQj2Q|T56WPhA,m€g3Phdݓ{ԐòĨ!$k#ֹ[V Tϭw}aղ8>JVEFI\m$2e: tL;WUQSA'wDi.^%17##D/Yu ^-fZjXt1"I/RuJj So2pA`fʴ&P[f45,ZҞUxu67C>_gH16\ۆlqU2}?G4/Oa(/"GGF4SR)M:J槯E-!p/IuBچp8+MӯCE ΐpnD|"D)%u.E5mew)ShW=U4^m}ܗY "~J⏕H7ԓ"i)F{6U0E^Qe'+V6Qo|k{x=ba`"B˒)h]! ׃ y3Q./ _x>V}AœͥGM+r0h,fExԸf2?b;k C;X. 4+ CP5Q $b &p&:Mo|ڝԑtg2/B74Y'sK. )n[bTYb}9c6[D^ĔdmS{ ŀw~ONw3XEm/P)< \آeUp"/0v+؏eHʹI;sZT? n|^D!ծ\ߜ(0hTca!6yn_ aGUB˵X dsWg*0 )ov4듸ݬB&fľ$Jqav7m8ho|z+WcITN'WzMZ|AAspr$LߊqӔq%g. Sz*) VK2wThs JHn:|_Ћ;K ARmљ#8s ktٴ%6儉9AO2~7E ;}w?va1;]05Vf1ac7-Q[* "-aL/~  *{蓮RF];EgĈƢ1ZemΟJKcNZ6!$ebΔ0?x{'dPڵT|wbwT~ܶJ VR@ YLy-Cc16Շ3a\6ȓp߸ IͿsGܖn k5 d֔K-_#bw{C/mo"h6QOM2?"H,nj,"aHHXrKhs}uL[;R<%cޔ~vNMk=^ФEoQI2mAʱ`t؊ț3 uS.XF"eC>'R٬uJN]!/\pTpv@hs3&_Ÿ[1fy}Q{ kp}#Q5 '[dCB5Ћz؄~)@Ac5*7!w// P~0YMBT[N&uCs$zyO gZs/1XĞZӤ$$o+YLPvD! -ѹsΛD Q(!8SzͶ~G ֤еax}9 )#_yQ~ۧ7)d*Gn#!%@m;R'dى;diEjz ӻ7j;0RJh~8vC>{PtJkIY%:yh^Zu:  W帓k$q11Pk S;JK avJ4~Z)NQa6E\ >Isq=fE*(HKPT>"hKI| xf[G%j30#%;sy=f=zR$P\Eko`f0 ~!* ǽ~}YڊfHVצ^ )!4\gS֚$ZBe7MD=R%_wHz(xOy;%Ơοn+{UyY2KAרx=vTRH:f@sYAu[%ߎ[Q}6379V=̄")h@Ysu_$܌8w3؝2gW+wxmtjEҘ!98i=WOʖ e(ALkViB Z:,qV8MAOBծh<K]soKx>eLrQ5"N@g諢Qt`CW x?:2t 8{2P#.ۂ%o"A謁KTDGw?wO3l@k%c2=G3.\*R=oϦ;)͹fk L0L&s_ p}[Z{wn1x} x>j2M\\##vN|CqJ έK Qb~/L^$48h'UO,T%Rf&twrٲZk%{qگor:w0ja6 q\!/ y[H -ƯMAtg^5K :ٜ#W(.FE,@׊1B ?#DF!2jqeQS~ qPNF.37|Ds$nY#-3wHbk<2fCdxX {,0f,diC^o]H$Ab YY=W5bt˱'|wV[~8 ZHݸvr ׷(f_tYꃛ;z_=r)Z%X溸޲^?r MlGMAq˥-Lف|™jPgsiZ6Ѥ8w u#mD[̓dXwߑ4 f<yge&T}>\{|Rxv(s>TXk\t'E^E8FTX;rVzzOGsk(4{ln]-lڥ__:JSx@=b'4E+3gpiu1g134xƉ )`'ו6&VckhȵpG/8qmy;Oy9: S]vIpEGoW sD;FSWе6~sl}J;ޘ)%٫kЏ1daFTBɏ[޷P]l(h\K.~4sWZ SJk{̀F[B޷L9Ya+7zAa Kߝ7ZKrۑ}2GQDbz&YK†"z>}&Cȉj_*Oxll+{Uv\1;o9ѷ|KBFe>|'\a91uHhm>u{-\i'ov/*b(&.k||n8dv#-CQ,K?BZ֡HVW UQC<~25?Ucb"k *K8Z0.Fy,=(p:5NocU&F`&ˎT" /MLgҧPDfqnݗb4Ӕ:y2ym\m"D1K+ n wI.6L$&nآX5IxD?iXB=a15-a (v!~X502uBe/q^p`. ;R:RT(c7*17lШZ Z@ǎ wJ w}8 74_ 8ق5+5j 8(L gv`3_y95xPĨ3BwW9KrLѫaDǸ~h(>e6Uڡ&2ÍYkf3R)t`R!mP.F4]@~IFuLj7u|% jcpĭeh %I!Ŷݿ]2 *p/Re #,)NQnz, MnN":IO IVnԅ7H2xab_As%=S7< +\]4}yC=_@etC $ ͈ s}q #]K:(5w*ӐT<a\8ImP\_! P׳"˞EO>▅oMD4;mn# MߜqS[ q } 93Q،iV&v8`:z)B?yh+ 609?m&ӏn>!Od5H깱kd#}sOzRS7O R []vUcWHez0ogc baۭ9\oՂu |81_4)=_(q8hMl>dY3]B[Hi*An>Q{ WOeճf`Ɓp/O0,R=Igj:p {d)2q#pM!67s ufNFcZ_,isd  20FK{JT::NSy3g~G-+錭:#7ve~JI~G~`$1QovJ!!=ztꂯtfN6Z Am dQ?+zy+iCc#͖^KVB#Y1r hu.K.2JRO@쩴ahWFdzsp=8͢>p/Oh`zdcGWKK0r]w7@OGS'Pyʺ}ןх-qM?w|,,TAL+dJό7p᜿Ha4F[|硝w=ڂ޷wLQ-+O(-N߆;| wv:+Rwmu ղjfmeO4F|13HC?+U~1_w F:5n枫kԎBpÖaLH-n}0M ⨳gf-.8Jj361fv ߩb&Xwq}ٰ >:L$DeWo'V" ]d6.bȠm-TQoqp0F6غz:Q"S>A[s+q@f2 }8qf2Ceub;>˳h,+qwy+¦ yA+ʰuZqI-G;>>|گ#)'+oHRr2ڼ?<֗_",8G* ںVfyOoybn~Gfri+((n/D[mufG`n+kIaSk&*37n]Cn^0hND[(Ԫ_ɗ_a_W,֋O_Ye|PJ3D|WuKooB &4f4FbiTQݣ1%Q^R*ɩvF`v])P4Lߌ`ooF^dNL87=u~zDtE9?YXKQ7Iь;]@[ ;lhO+UjNf!1,d/ۅΗ yy(XcstY¸֫MݛдW}EfFjSd|:4,VoҮEպ͓e]RMƋ\vt#ʲk!0!^<@NfOyIB鶻V}3A TrY`~2~ {!ehL;8#hy^#Y5Q{KfՓa9G)Nh2Kw FUxp+L_z'lciH`"RJnaeRB¤G+$&U%T|%+t$G[ϓu3O+BeHʁDU004؎DnD2Re+x$Gg#؜o- 27m6ohu|5Rg&J̘U'pM" {TK*.ke:И꠼Q%{a fs| y˄aw.&1z@=ZhFb"Q!MvE'QoꎇYVu@.sbEP$1ͫqQmɭZN \U~k7q# /l>fOU9O\`}\۲m"$1QVj&nw0Tʰ,ZjMLyVou6S0#Pf^A?2@ڼ_;cKsT0ll 8r#vJ5t\(<Y?.1x}K=7|7tDG}b2s;>+"']{E^ȀXwE˛D#}Y̊j"!u-Ws.li`bx!&vq]z?k#3Ar#U冰uSOݘ:C *|S.媕@ښF僗ONbc&6TWiwcX>ԦU8ڔ Ɩaըo$WH4:DMle5!s,i =7=\,pH= 9f2v8 O\cbnJAw^:iRSxEՍVa!oUM:p$hLsZvԌ2%6sE~M>[9ڥ:Y'+G3bxܔSK xLQhP[% իCgNeX* Χo4x)k AAV 2)ff @(mGVfs>8aIj?8EOk U$X Y*)lVŶv?K ]VPV *\[rH&qҠr{)<]wȬ?٥-Xbw @ؔh%"|}l'Q)uPuk$PFFt0؉\-dI?h8K9hEp8(OÒ'dJ1늢u(VQ}H[3VUӑGdHƄu٦oG+tOyD烅+@3v[r"&uRC2DU$wNMs(aRGQu^e%R=<ĕn JAjp[ -@6<ǪQK|?J|$僩\ #apT1cG.y` HOL[߻ ,;OH^HX9OZQy8,QD9̸v;ϙXCZSp"5aWdd.3/*+tXjyr. hO0d.MGܖ3kX ұˈ!f Y-|ׇ, v8E|h͓_fk'<'ʃUWFuN;R!~I6`FI0XțHeLlH̪ߵ;CEȜ5 $/-0>8w\!_J& .cdy \ hĈ9|X.5\ыIMhʺ&MBn/3R 4KMGQCpo6;Ay%O3C>ʌxWRоgT-`)e^#zf_1u 3  ZYؽT@ 𳦶|GSQoPgwSsni+Λ햊KJҎ\G4u nNDbS~Ϛ6U }"0H> *K,|fElTw4](fiVہ=[.^lĐ tXUrRt`Ysf:qredIa--wWnjcSU*:졩 Y2bnDm!7E}>c|tp\뾥B_g0~~q^eI 4N)m(/y#\@j7[מ>G #l^KV5 CW7ɽ^<5%o89⎝okZT9.---1msVV¨M]ƙ >pcٞ"h-uA$ < j/#Z7y\o;g™vLfc3;-5CM"QLrXEPjAeFkO2f<1.`C? h,PF20rzȣY< 1lʬ]Xx3|Vkh!΀WA(#/86M Nԇ8>pz4İZit?ͬ;k]4)a`;y/~h"II <1[)F8)ܜa2^9ѩㆽXvj攵+yEv5 tC7ߜ_-k/Nd:?9a!/5G@u7Bm6+@JSuYxӏLuyxMRQ?d%X,77(bcF~ȠTp!L@=Y&*5bЏle Ҿn_՞6#{1=:My)Gvs!8S"ah&wm!:g/"&a rawӆSINirۤС::]+k>bbQë "[R.7FBP|:ݶo:J@5ut=)Ky H᩻50bÓ!{FFsn1-a$3>A~4]Xyk:q,8z0@_yL8C~Y񛊛U.T;q6m2C񜎝 냊֏mM<ٮU =(@!# ?0Z׏2J?5e9 LU (mKS_gMcWn+.j% %P5SдC=COneB*ˤ#if+X$*nMZŚKqmQ+!L[Qs4lw?Qy5H!44Iq8ĪrB^5z1X;.CHTdB9MaH*k9͔m># _=º-!1՝+*? \"POuԪ.R8,?H7\xAԡLuSAƉuDX xUҐ%#YtCCY0V+ϽS_ X1l"7R{rTF[Y.!  DSN5L@Bɪ q)ծaq|4"*2A&0K7Qsz.fYLlyu?=}]E4&Sµ}IL5Z<\q܏oPHj}ZF<|l Gҿ0ZJ6U6Avצh'=L:,?A\gϘ-'!t? d.mwͯoF6;3)E'=,VV*ՊDKz`Lطjkn渌PV]KӃ')?hB| H!񏥧qAB+?;AgJ,T:H<N+N4_1獕DĆW?]ߒI^\JjPL7~ڗW+O]Xv̝W,B,l)+QiGC^&D ' 9bȷm7&%6Ì)rl$M|yGJ<fKpFΝ׮bY\Dz1+,,BNJuȆSQ`t1tn*\!VnX kEu< F"ⶍPDE)OP}D?CZEK!@Q oV< N9noߖkxߔX,IY`le|Q`VYUϩ"l7V'qp(ȍ$tܲC:gҵ>4Խ.f#}mL$R YzajA%'(V  U¸\2+CXgz&N$=MUgò3+Sf8֩bH \VkS0Y~^ XL g̷D WVn_nge!G6=ܞ^~Ilstf6UpP܏шګ[1n/֛vR?wpÁNdT_:嚬9\r;1Z*_' ϻR=ۋs1e//Tu޿.V@SN>+L"I6J;6VG;7|ʖ员̈́ םHE9!쐳/MprV^:FEDwaTAzz ĢbA|iRFwF M/& BlWqFIN1\rg30b 1]AjyHTqdyj ϔF5r<>՛9MT5d[[3dl<[X$*v:p~nSDPY'ôuMG3t"k^VKo3x RLQ]SK* ;A\go, G <&ג Gd7ג"ZZEc!+$ߟ͜ukŸE%+Np]. Z- ZN HQ]{Y| XTaǶW)K1@֫ &o W{Z4w;]&^~ő@?y^ Gcٓ^{V^FrH#*gnXjF$5l9uhXCk [e@acd;V33ĕAc7xika(N.Snh LmᥠqA ~2*-m".#apy;k'%5yeKYS«ŜՏ_S1%5P؅ڞ1}oFB(^նmО=B'9(qWϸk!5m7YVmñ4^`| ^7 '@p90'aa,$XldKϚ%<ߴ۔8$?KFs_?Ynjݿ*#QFM=C:%_Y3OK o:~p7)1#zNOf kQ/&w7H5Y&|h3"VktK1즱^]wp쉤`gT2; ;r&F'UyYl*De c9a]~ |Ž0t Jֹ2->2bjxȕ9ځD^1N95HՂGV1==TC 0D^獙%.jV㖑ſ-S}im{`7Ƈm'ĿMBM7+Lz 4m~ n2)U^I?u)s=gJ<0wҪߧXUfGݹٚ7j2+!-,`D> CLNO#dQlOKKb@ 5 Vp'KBpݳ +fZbp9VKp!ͣ~b/fiUxnE"]PT %lYĮrn1+흏_hI! dȖ!T$I1\0JdZQKs߀_/㉀F6@Y<ܠ?J/<#d@$0P!DG?v ᨉX/k$ա~L{f:}!tY_&L2֛=nͽ]F}#FP%o2'yA/Ȍ ›frJ5C.|wRR4j:<s A@3SNkٯo7!Z'Lc`<x[ڠb6̾6.fP$%}}[A4Fz5 YVcU~kHJ+/&aI*K`JKpuSG=yޔNY.K(jJ#>eE I Q>Y7/64Sv.\ebz=)M}O'~$1jK.xg,.l)\ZbB]hwjjXl΢ GB IIKX Rb)"a7Z\}eW~Č89zӬNmLׅ tH¬9Va 1,g>1,dD90,[.K$<"*5>$RM*:u`ghz?GVb{ uDM(K }#^FE%ɯ=ԀbƬږ"+G߬է<4EZD0N 0& 7%3JbH1EJ.P,Vb,-"񟧊Jȓkn*aJEpx͂ W'`2iUSߒBqX"2 ?7O(815k<FsD'8j7OOuߧt;4鎿&p"Ko.DJ!{cXeVcY8ڤRhn)ЀtSN$$~ |Ct]zy?4}0ݜQc`DDomA 1 %4M0?-e*o8_1ח}pnTO9k{{0f \}1xѢ|5I-G1KRQge昔͌E21P@B`87'r:q}S0YiR5*qu\A<8Vr,Wҥ70MPA TQ%:U,dG_Iq6sMtYszGe4C!o؏of i=oީwr%΄lDr^: fa9^@(,z@αA$(ΘJ'.KFc oK;`p4-{O|- _`_1"uQʿ w tpI `rX 6^Vf y6%Q? x SUYY!h]()ܚ9kYa)!#<~2 pIB~/MrChK 怗V*J`k`E+s2{FBoO⢝vg$Ig + ڢC1*K U0qwP GmR&ITxEs8|4&mܡ'Y Y~A[3Aj/\akՊw.xB|$M >Kv>F7wO>! QBu1PIP8Wtu]k8gʊ/ȡH1^𲔞*&|x' MZ=js3R;U *o\l]#&H/z7Mܝb\'@yp>yvd ? M ^(\z@fc@灴K+OwsJ~CVDSJW]RrƇP_F82wE>O?yF7WX8{ ئ; =g .к_c®y~_Cz`5ڭ (]HIVU嵂 TWK}Ðm>a|#.95G/%:.c\?7cYC_*Uք KM@Ckapng[X0UE=Dwa(y#}ePPEp?4&22E-Wv{ZeK ]NlA, >NvYxH!Fǽ^*z?ŇTWߐe boαfd*Ry ܚ bq0O*@UpQ| /FND,Zg{,AWg6Ƽzp}|26u2tZT6=m>3Uis7 o=%1AZ6σe2528Cik"L[лcilj J3uL0сպ̋~i"ȧ7҉7lQ Ԡ%o1.ql fKcmH[#Z4.{vt~ieyC , ol  ]\ªxVuM7rtjP9}.޼l{wH?λ$i^ޏ1̍U"' I;Kt,3DK1tw]~EwԲ5l|^2jfL~kpj:L×ت?gDs!(مբM !S*{xINXޘZGf]6BP9u'RP Xq5kF*i*4Mh"X fL˷qs>n[' +nX_ck {{j|8KE|HoD CY>1i/ ™29t(>m^X]˜~c2 oۇ=$4s!Xc,S/MuC3^дqv*n{ doX\vm:(K%-} VU4}<eRx w0LMޓ^" Y^%5F-x@<<:ޝ프`[+nرhεpX4mԒ&Tў*71*srȝp=a#PO$88]@}Usxֈ y\x3O:i[|U0H(/<^$h!a\ tQ<0 xݟzi0TkNF,ͯΗ6]k9a3x͚fDZ~,YZ^ħqUN'8zJ\re>GC)KB f}T샘 )$!i<K?ί[і\ Og}? &P|/nlM;og7)caX)vK]«.5J~ngh QX7[y? lZ6(+ +jL-^q?m*m<gի}cf̝\F6r#-Fdjr|D 5TAG#V}(cpEC2KS!I<(6%0~_ ^CS28i]AW i}PoX-FPx)jiܱh9Q+ÚwkVWX_jpS+*zڧw~xx9RQD[cA*Ӈ1g<|ھ*Oc'(\.N[I0*)XdGWqUib_zcm?CzJ4!ڟ [nࠂGbU#kPȊKήvKa@C%uӾq;AMJLMx\7V| Kzk>goUr?(0*ͳ0LR-uN]9vrpWo9;@P9Wovpɚ̉FA 8ʣ`BE?;b?$+>ȡռKFgHRh='ڏ*ڌXS#L/OM*Z47/YU9,~rk8G*:ւHSfEvg.~<'%2e3I s1{?[39dMa7%T!|S_O Od.v£@5ʇ܏;+q ,A]7@,Ňf80ZhVvFh\2uYؽ"7N`эVU b5md[Eޒ϶8`lԉ׵^ʰ`@Ԏ#$=ӈ$cygV4/:}OD ;  8ďl;:]W(*GFHB c{ ړ O` jn#@|lf;r35ܖ@MP3 X٣>4 -&'Nmu:7aiFM9 % .) q4ET4YZP$( nfn dԦ s\ɀ Z/%RǓ̋='g`eϦGLJ+P>4٬)r~`sAKoFt$Glmc] [`|;9ؓ̎Z)NX.TmfNYNpA !}T+ڄqLH'P!*2ܸq>3;i;&ƈP%/q8 B0=%J SL S}&{޷9#jC1A*hEo00PwSWk c&AwS3Q0wEͶ] ]B#/lsxYu^L®/ ?KN"Y<,`i AࢺA5gbdoo%LV|Tn3)"un!6+`/ e.R>Lk34˖>K\tCޣ۱e3}P.t2HJ$cJJwO2#'x;S D}ZJBufdBΆrr%qFp @sqJn#gRalj6p+~ݰ0w*cRߔZz_mLN|VJ_8L``;"I3MY&' G,B*MPBLz^.ġzn3ISάg0nfbNK OQtNkI5WsYxTG➽W}X=8Ӟ+%zJyɬUl%[i'2tJry=Z%9k>2^QZ[٩46x?sJ=978Ho _l6:[q6QcAJ'`BĄ oNIυ F(BW4R*qD/ Ǵ#eFݒ6|Ӓ2Úӆ@\k+>+y[>6s196{CΌ)b/T"ghVIڵ.bʿ'>6p#ΰ} %T6cVL>VI&$Us{FZ;7反F4Xc~"#l"SY&1@a> ĵF5Zhd;_ݵރΈőCC~Aѧ'"L =+%y06_iK/(]G!tvE fLwc] E#w5=A0D? TS7Oܒzܷ܇ b8F(ko1Q}F$L~ .4J(TEFoOuJE"C^!#@b Nu(oO(dc0W^V-lk6VZ^3-Gk%P>:dkÇi]Qa uե ++9bP<,g 1m~s o ,c_t.E!]@PܖbJ^QtB} cSsk+E#QzHQ)K^0>iQ 1p0 f4 (d{۪SaZZ{1=/ݪY07K}6T:촽WoʛG[Hpә%ZH9lo lTX-^Wc 'հЇ̽T"}x v 0% [ l }:CS!nq\ Zeq;LH)(V4G"'Ǿ+0*xo~)Os6 Rdķz]&*pb`Lb&a!̪aJYiP&=0Q)="wۗl)#HL>׷Z +)G =c]Rr |Cg,FF?#E=NN|UŸz8ԋm@H9 .L{mVMG?j Ci瞾['07;=ZaХ3gl[\d$_[p~l>4ߢ7P(R_~D|r*ܠ8CGtEQOupبm9VKC@a`}J Ӵ0eŖʌXzuz6xŔɆ8r6JEFj lr @&OpE |CY~x侐~!p.kl}SB1l6֨FeI$JRS[Nmv;.k" 1.X" iT9u(zo-U,'DEA)Z00R5ʺqb8xڭ` 1NmF&*Aʙ%jTBmnV6XK#ykÄHzj/x պTt'+-ˇTܸ&bQ"ulC!ZzZ>gfiZ*dePK.C.B& ӹЃuug/APz\6u(/pV$lNՈ4 ?*"pOE9=ONH.e7sw>*x|j_0:@V ?3]K>Xs:o9QAՒ2ˀmYEJ*){iu)&JlƘ PoP>=e3xpuS,D ]g;+p0^6鿜ȼR$ƫ ŗ<)#FcCD*%|6 gv@N6'F;?U3A2 Q4!r6v z9cQ|џ0q}=.-=)y(U僺p//o֐RESPE'2'__4F9@IlC'{㔹ĩO~^c,&jL=ȧmgOnSIG%#'ʬefϷ SHhdD fy xH/ |Č~ |' ;đOrfp:NlHO>vf:5,ǮNլt:2>K _ty/-y#4ҩ>1c"U.wa߯4Cg2ܖ<;$l ?{ 9q82ϯ ys}&8.U ).DJ x,._sKsPy` F  ʋ.[̚ }O^eN|7 M&۪ ˽J3K6]ɓG0Me,Cc|\ .p#dKzD^p9hz[G{ $md߫\aqJs=#!SkS././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2394185 SABnzbd-4.3.2/tests/data/par2repair/filejoin/par2test.bin.vol2+1.par20000644000000000000000000014413414625637207024271 0ustar00runnerstaffPAR2PKTܤñमPJa ͶqF-d!h7@PAR 2.0RecvSlic͎M13Cث/e=Ϋϟ稸f7(>Jɞڐ= Dcj-W[ IzF7S]?$)^U`^OK|m < py{$$d2ѯÙ%6;^d N|uCӌ(ɕz8xL'x &;̣݄/}MB-y=&mḳ0_~o|C**&+ ːjk fV}Rn65hC q5 W9 ?Yp e*9cYiK;d0[URx( .J(1^:/83)Hf/rp3(i=4%r0%;S^;LXE!S")ӓOX+~կp #-mHtE%^^iҝZoIY^ OwZ={0Do#>,Nұ1O{6RE$YxLiq@*c9qj|̆uָ\gBa"α:u3Nyj& CX&a;鰁gKXN}2\ $p\vJ&m逑FX\+ځ;LgB&6~ʇޥE:$' )µfv|c1^JcTg+B^Xb.vJ$k`-m7&ؗ_,ovD@!!GMo(;H8#0riu0',xDV{5 /ϡ7ު`pHxKG`{0-Gq #yӬVM OL8eB}(ѻXG(/԰qfxw W׮ [;/[ҭ>AloIt5či?\ds'>PeY} :\c=Hj}qp+gse7O|SvמF84׵oŞwBuK 7FCî?17u 4z.W4pAdSB/) Ay ȹkߣ Ԑ> 6yZ!JKm4BFo^ߔhk~ 6Q軔_'μ'o# gI"^;?}45 G83!{fGtl2ۋĒ/Lώ4ӱ0ML p;:АJqBΔ%G/{aJǺ:)]x pYbr:a*qJû-*iaVE~#7]uVXH}[/WV&tÆjBтژJ䡅ٺbRh'ic:X)SFaq_G, 9``&moL G>h`|vjK9&&xE2. 6dVuKg`&7lGGL[- &ǃz~!XMΉ\VRwmmSJl͌H#$?[M;u}nw̖䮲TFۖ8oo"cj,eȑu;cf }[qZ lN8sH,^팰.)Ndf[*~%hT}&JL,hn? \AN4˪R `>C=zό_?x"OG3ls)u>5g cvU|Om06jXh5:4) 1kQ3^fzD4c#Vxۙ*7K(?c19̔Kj9$Z C~~R'snGQf0UϚ!\$D' 7ȁ)D]eduߊP e@~5x?x@^}@ 4Q :pJ?D@:$3`/7;3$'*D.sho7je^ -Rmmv4?3rItzq{P )%KC >=m@ߜ0\! ϰ˚[#ǸL "PNa_hzH1,k8 Eakfe+W:V TTMw{$DNeGU\]q*`E{!{Gˏa!q3У[اaCIqh[Ztt޹^揽8`M8-PʘH?KV8X+/}_3Js'ѳ zeq ״b58LF$ͨ x LG{a%x?'_ J, i~@8nN./4KJ@օ,¼&7>>c 0{ٿ۾=hsg =0̢vj^U!H:;v5; M訳$@B\D> 7x-L6 H:|/}$\s͎vpXJ@ÉCm֗GJFuF (,w\S/yhgʨsc;]?! !}y3n)`/k;[>dЄ_XHw5 Q-؟uZr2t?/v8,Su \= W:kbACa;c & k<ICӶN勫Dlƫ?_:2OU6$Yl3'*eݲ[r$L⪔?~҃IxZ Oպ"SqsIrW2Cב8)dm}p &HFFf-\XЌ*F$RGH‹5YL1f:x{ףgx*S:yv*3vH= 1CʡTXubՇV[;c<ļU}M?:] `귃LOSdޕ$'Yvb>Sd2T,=9%@J|87IUvƔEL 3J\P&}dpgSL.T@YE|lj;1L@8qW6v ^S=4]0Xv’3K魡 +Hl\vF7p 9IAAYQ~nJLlRM,7̢켜dzcVF_#Q͈,7mB@~Ce1H7W 4= r'q N7`-.aiԄ_q$a!/_#((fT'3l֧DZ- 0J]kü&(bt=(i*2M'Y+R .P,#/qWԟ%I8d=iq 1)4}ۗ0tPY e!MpP Rƃ5#|2*;y}!T;{yzd[?/cBº BtjλK46ke#@݂XCVgr;R ՛WHv4H~Xj" WX3 5mJNG4K\8;QiW8u\z BN4L}b$e\ H)N\A`*d= jwhA%f!wr37JHˉXC9wF1o5,+|ΊY szF Sֵhm Euw df0-,"P M$72 ٴV|}PkMgSJ03%i;dˇ_ID'@(cE" Vb-2(N;Yh+#Ԗ5 ci+LZnk𖅐&c 0O,%5V+9Wu6 !~73|#YM0>8XߡaZ$K Oy Cj6Zsnn4P2?,i;ٜnL;(*h:Q7`ot00Q~\W[8cvW7BBnԥGAҥz|ab"S[އjO¿TR3}Q;6zeÂ7- uՏxޓ!꿞:]E$q~Df4 Pm "~4ur: >!;tNilIeT .$MK 1FNmO5xiתwM:@A_QR:2[A1w xy'R:1kڄ"n5r~pQ .9;f9-d>⩒H~5ЫJkP(fo!&?*ml "c |L<Kk=9e/O: ψ3_EnZ ʮ{:ڌByѾ`]W> C+lp8)㞁@9g_NSa.B%Aj7RAXSpjWj!f.b kxd!etFMg%GU, ,82 iZ@ܸ a0N<ԋ;^$*Mqs*=&߉\ݻКK=MhoOª~51OKUJ$zCF"*3F08uݧpX |5{ϵuWst]hq7#QlE.&|WC!n//T=_g޶…=p[9ruJ$oh)]|=ؕjGཝjeb5W_JQ4]zOjEL^8kVnHpJ9z:h̩c;<2^V5hB( 5E czYUxsв=k M6bc4G3aRcĔ ]a1x[$ކ6(7"FԜVHLo6)yv*0\zmvo~țHTVYv>n?kd, YGFwVz'}L.Tz'ԇ[M 0b nC:$<#Dv&=ЫwћB?0s1ꟷ0ʩE\FԯrS A#!+>Ҿ,J/kcS"#4ITzTO|ImsC{xi.Z،=q HʴRP/dR ;{KLW~Yk`%^mэqu!﯌^:34bEEx,iN 4^ -a^ׅFʡB:*$IXlG/>ZqP MC ~z!RofN. ̡q)ϖ>a 2!nie](t!Qt49\"[vks Ua?@Y#5n2gkC6<~UG!Diۗq"顙2THcy$=DgکQˬ' #U|;dQÛ`A\xqZѥIC퉘]%y Ǫ7}ћc5c w-\ d+]&eN[iZ'X@c+^c`~rr,&\@ 6l7A]ܷY!p/[ nAgXPto}ic9.ww. [7K)~EY/~gq}Ѻlq ]!wCߙYKKԬ}Ykky5ٞ YS=zefB{OxL1J_XUj$Q?Z7fh Jh__0Q?ѭ}Y41," uzPD*f(w꺞R?ij|L&h  ~O4lMVEH9/9|n12"cg2+ nd.`$tA="{I!Y>٫NLlӍC(h{0`lG>XA#7EJ-$G[ Z5)PQ#$5} 9XXE)U"-zg&ƫrrqC P &]B_l XEQݯYAcsuPCHB''q^&')Xk (VDLm{5Kj .«1@TD SR>Exu0(M1$ [|1LFiRM% D0tA WM kS{@g'?6ZNxЄuS!O7*;,'E3LO4z <)8]/m,q=DpRF!Ԗk J1+_DPW;L蚴(b'~,ΖXgx4$V%=Z*ڞyYdPߔz#*6`Mda=-6an+f_`P[VO#n٘h:n 'mz m#3<^z*u&LȎZa=l-%|%CHsR)NEFεAx^nx珆PgF#J]5hΌ\dֈ4rH{XS@D{|>o9^H(x Irg:[sV6"$>/uQHh!1uY)+$[9\g-jU@z]'d}gcD\䊊FލhHW"ޏvz8,lKf&21T!QZO>6*C7p9|1) cvQq.SO=pGˑ+JNN8$K=:nlFu-_PC7L=.qE5TBS(z(lXOGAX%d KI}JqXBi_ m4sP-?RK!gI8v%L(+1^}c{ߦ&Odb ݼ+01'kB-q;7DA{;qc d U4M`"kB2Y*ȽJi(bY. 9rCm3B!D{m>v wݨV[Z,"$y9L'rcb2p`Ogph$LG2hOڹc>=.HccslZھ9D!ީ՝LoH B%K<2/Ø00n]0Gt[_%rP[[?4. SNq>rz#wf7XDyo 1o !ֱBm8'Ƈ5)}nE2~.,d}(.ߣ{Kg7oq?TG91SD,| S-xJ48&QՠnvȦr!b@=nu1l!>氦kFճD GxwjF`x⑖ >W&C3/mdP\n&\@gL ]N/{~QP%6 Aw ;xM峪3!#3SQC#4cFg R&{yV Pc`am~JS;}tP,ӲTuykqOeU' T"vI?b@oXae剋Vdy"c,z)iJpfgLx)N/O&hl5Z aZ~&8:/gӶvVޒSѣU? _\z3R-BJhbѻ.cd'㞹r4l# m7I|= O{YS/x^ !aS hC>C}xA=A2.O2r{li{`T,8>F a%i T u.Ae՟a%<|GFzGdCU 4cME5*RQ@j I%-gyj~|Y@䪌7g܏Og?w8aie6Tk%J|vWHh&Gʁʽ7; DQN:SAeQ֢ ,oE#wޭw9UdD3\U{#R"f 5Ypwgb˿FAdTO_X5G:r9[_Q-ȀUѣINX+r|Z65q.2lW{qy0hke_shS| EX\*_%5Զ ' ͌\hNـ!_֡~,K w+T]MBo{eP:!].`~HszZipCB˺*,'wx{9i ?Չ|8z#fOC(sXA֤晙; DMsf $нgHrgH^zI1yEYyGd\!4M8MاTU >ssww%ӏ]F>M:˲U$#i+C|uہ1qhnX#'_8êSsqg |g&s_8J9dk_sXd ux!u?v,s+g<Ǜt $WG(V8ꬓ6@ mk*ˋW@Q+< ͚L'؊ /UK!Ăєg Bi "wh5ݼ=tU$ձ"xB'>̠ڵ"cq}cZ>{U}FGAiH+ܾX(H$1eT3=#wZv߫y|+E?"4 ] # 4p)\U Ƨj Rn*LBͬ$%R|1@lJ U;q ClpPH`9mO plvz媾y7ra hހ6?5¬}QoKBvȘm ugLz }wJ yvC~vW>xe0zڧ3:#&rƍ@/n 4z=>1dfkf`|{_E 䥲(i)rWczR!xjvA6s#W\WsU50]a}% OLiܱ=wu`+X3z{}}tm5vTt[r7TQŸ ycq{2״VBry}{8tD[EgA /HdU}C e4ylIN Gglg2mlm &*DY)X9?*Ȝvg- K6h6Ci Zr X֐CcqZ%?b*2 > 9 jɶc0suBeǽl`J,tNBuS3mѼ&!Ehyuꣁ~Άh[(: [7Y4Ivu:˥P"aU*1NJ m?eNbyM&;XT-&qsz ~]`:+ޱJiϼhx$niF T_U)][0ŏhSVy'eJ=<~a;uS2rZxP /pƚbsj;}CD8a.X#+bO3RhHc`m^"qEIc^yk~C+ikf6Hj lE)=d$A{˰-Ȣ mFŦぅ$%#"dJ܃2Lj.S5 <~iXڦ ij׍_5b9 hܧVݽE V}4ehxAr|KĔBj'^k$F6v]e3M:7"@C8?ѕDyL:즳0m5XZ0moTq"܂-YaͿksԖ6E8 V w6 %5P4,Uzbێ̏$EI1Z zR`dyϗx,P?O@-~-y0|=(bJ;hfĕN/F9qjoMX5Y[KΉ ZK2]vjڲEat~۽l:.oSܶ鑆^!urZ<,O-a@ :|']VqʍAlhl AI8֣,P\}@i[6^K<0lûcb*s >j}*? eZE+ k2kTb9Uk}u5\*bzh>AHѥћܧUEUB=d>]Bud(0SD~i'_hBZח [YUosTӅ䞸}HYCwd4 񞸔r4b|1ʠnEj(^Q0)QX @!]+U;,Nd]/"ln9?si?<=nuri6GÏSNc2r,a,tPܡ:qPuXZoPX'@ض@蹉k7!e{_('<һIg*=r[EWtR ߑdu/n$x8g5ÑjhׅvWTa^lBՄ3JR:--=yi4Ctt=دŐ/eC6 1lEBN]Rօ5Z[l"RN陾HMI*2A,[ 2U?FX/IK:1Iad72D:k*#\+8j8 .dAM#0OlD:÷AZ :KLӓL?5{>dۋNRfӯEN\jh6V8| -w&9ʾe_n-c2 qqܩ1W MWLu܇-?9&?b[KFb_i;b(Y(+.Vڋc*|Q݃ʕ45}|2fv ?7k+[ (Y*Kz8+Ap7[)Kmm^ͬ!X~NlyE׭8tp1ly()GT/70hׂãF(_a侮lG (JvB5ſ6{?tV_6lAݩNj&gfu$vZlT~I{ B  |hb~pWOg1HP֬dury2?kS >~A[C^׸",'-f)Ȼ(+6OMp) 'Fp1\6r'B6FCu v@Β/7#2oUN*{IGzo詣QMqb gk 2RȜo^{6F|O7E25n5³<{Ȯ{*JҵAʧ&t_;W,4qв652͒}+YC"qr ),!IQ5UN+ /kMA Q\ǒ(1ʔ\Qd:[2լCE_^kVx_+k>iտ{`x!i? ~IJƽU!y%Z"~TF?)g77Fɬ2)vA Pb64.5 Ja/WV OKؔκ†>H@7ȳbиb*ܷLrbٝ8^gFMe[𺿴= ~oxLAQ"ݺ רy# آѢlʹv:(+ʂT$kCYC\VO045*= T j0=}?AH:!Uf½O]+Ƙ1j+!$)^[ xy 1f[e݄Fٶ =GZ0-b`Q_ -o D#ǎ`2 Q˅:J0qo7$|r&frMpP\b]2{+NP6 ;Tb;t >_6+^B0 H7r[ /JQ2Q*cK7s<$62Aiwx8?-ȬĠ[^&jf=uGAs6R^3jE򈣜>NTpk5\=~TŤ}|1Gc#_Ms 1ւ9j`Xia:- S߭vOXBAz) =lw\ z܂؂N4 -Ud/Tb>IS,GGieWDUc@d(sEbMBV&KnAcel<=!# @8>q{*MLPoK_ H µI-C!.dH`\B:z-gǰ嶋fMW|}l'C1M[8L4B/;?p@{%Lݕ5mIq͔ DQĵya"a+;2 h=ͫ]Y?XSc$-%6ѤTj*gi}ƺVu:WM~ݻ'&:Ke2 ;jЂ~lrBl+@^#Y5-P9)d /mi̢2 T M'=`͇C< Ye=N(c?M/(z/NܻK!UK%x4>% ̅?(>REXOuhSDG 7EF: խ}? i Y<-]v^5\ 19=aLKLYk358+F*D9$톔TK6: $L3^p5"!*m]Ay؀/f)ƟHir,ȸvWjO7Ep@l:v鞸{@6gKVD͔vc1^1$mzWwn5 [s(UŃϐ}6P`ku3?~ ?XWF0KZwБWn싔gBEsfH|Ah Kr +dy榠괭 sҢ uy4 nTRLVDfݴ'; k+ 6&긨s F)E벒rD?NJm2{"2D͔%E:G^8@g$8!jXap9(?#'_ 5InGvx8n jojdžI\|rBW@ !)S䘪&ܡ ʓX?TBLg߂G%__Z[#DGdIcm4`./&T9Oϴ+Bs՟ 4+Ófζ\{XPbFvwLVmE/}8{!Ĵ4FП OMK7"oBrbn<MIXX: dgь_XqN̓W0:bz+yݟ S)f~@~8R.egkuYQu8ѢO(H{CBrsv>7+^s7aP U‚\$Jvn3OL|n鬊00ڒΘ-@[l/|/]PEp#)qA':QIlyx?3e) ss(r}γ i p޵w(lx =,i19Ed33~[yjJ37;3\-rw}˶¸2ULG%kta$$}2o:ߣɛXyq΂]/~z.g79Z"\a䰙%4mΙod5pJ ПZm,ϖjs(?\"r ր_EDމf1/`${?e''#6;^.ɅZHImj4_+!`rp-4|qKH71m8x_džnk hlv?s>fnw*b-ʢM6>'SN*1GnA:2j`oE@M+3<}=L+ sj8 )%UaA?.%38hb9]a0+Xxߓmy7'N[$a᜽ :ʢ[,Ux^So^a ^BA*f|˚yhمDhD]<('HbU^f#\t.DT+7z"ŧ?{y_ӯe\Bsh O v՘kL7 &WDZ֢+{ ؓi' ,9D2F 4'F7Ӄ?^@`OC;7-Sx:*:2 5|ƋemQa"i0 \%x2^ty#IN%^v#+@U4+\PCMDIgPY sJܞ>$eЮ xn+Aj_G!rdH"]QaɟFu3W vQ) b h#󳻇tofY7_={ '{+?yieBH`Vl:mn D) ޹_"rR8A7.KCGMc =WnWYAWg=^+NgrSoD^Gs(T* V"vYcO;2RA3㗂9۷|'h=3K3zSAw'b Zh6odZXڽ/ vOgt" <CiNן+f(!v) >ylf ^;e>1% ʽ$ͲypX@zub]/*HT^e̾-EpۍnvRGϕgI\si/mw"ZMZ+\pKN&Ӷը00.\ aNǒAibYx*YYY,[Jd)+,Kh~!^!5 碩E2K܊g?]n>޴tqs@N1C gVrż e0}udAAuɷrygD;2zΊ`9|ߖͼB6E<Y|Qί8aq{'_'"7Oan=+-!vhB<"rMgdd%!\x4xO%M@ lk1{MU^%+IRs̬@[Q}h1FVڵ'⬞_I= u78U&iL(9@}bg`bU!z8*lopU x֝(vݯfYXv"f=gΒdKP_%Ѓ5wY^ʪgMcu,Y٠BEֿbX9P6R&R `PQ/30ű^б EuىzG]IDn&12Ҟ$Dfr#4ZFaY.…,zDuWwt!/H*S_uc^$#ʆe.uuZW!)RjaZ=BMntw+̀/~FݧN#Ndʋ|y@p F%{3RLG8?'I0f.R/ݐk9MggE5˔0rk;iH$u/f(8jd:Im:q4𾾍"Q֖]"5=bZ\@ b611<ҥvf>e4GF5ʨUp(pt+J3{j/)/~[}AՀ 63A|"IN%U^"޹p|^1GWM?^h m`zrb_lо&iv+3)`+~Cwd(ʽo=a44ÊF-QCH>yc27*3V}INN).Ŝ><=79=GXL@ *wPtne3P?`݁GX-d'^r%DS4D[[+Vu2|:sͰ<3 8?C_h!^ k5"$Tj*I.djn(@\mwN(zd-(j:"P$$ + H~:0al1l[v^<(X7o2y-崹bOY`[_xe)_pT-']/ITy~/YRn`,=:#;YJq2]04Z/{+.`V^06oA^i$l=uN\H!-;so`wSoPfbδbgXpYMv',I.^%(U{WL䴊@~?1|!cͪ:LIwz+C84?Q.fn+6]=NVy}i܃y's4r " OIM ViI +X$[?<",MP* M`bZ*F6gx mlb!ڊFWHE_F Џ²eS,b2`ȥ.DVYj֡AC8g xpU0ʕzor r*D:08{VՔ]$ۢOj=V}jN:1zS %$J%&~$6e F1}~6 Rd3M-~PyB,rm;3dN;뫧s$OyLM`ddU0Gea( DvYtmLkQ P}0skT̓qI.()3\8sV@ V]^ukO^YBp]bw AН:2E?8X]JX<Ӻ]U㽂;"qpuqj|>ނ*tMkLBM $1>"<ӉW&3f'p9iR|2|]A_=?ݲUpZ[p?i~{U5m zBQCZJlra:~h7B `mÐHIG8# "g&M:Ld>ANph~f1[sh'P;բ7^X] ڶ+yvѪҥ&U:BbbLo.s?4|(a.k `!N7`Zv##ZzsFoql 5뾧֨PLg5dMVo.;,3 !>P J:-Ė`))n\ M#V:$:QJJZ-ʖC cuƪ(s^ hTl5~@gI){Fj7@2he!&pH۷5I%2D'JǧHeZtȖĀϜzjAU Oͩ昊٧X[SiN;>2Oê#6I(=6~ _7zdbK?>>ZNtJ nx,BCdNLWk-p늟ǃ4J^3!\|i(i~~Mߥ[2>UvKkH'@h ol1q,m|6]O ݿ}+3K]^ #_ jPd<p2dV~-'!]hyb4MVF;\if?ҽ87n. :_ c\|S:v|39,EGmRMV%1C׻)Q5!|nr+V쟍Ds0d['Oؤ~ P],<~;[Hfw[ʱظsՔFM (2ǕC wwjgl?P! EjUxo;MJ~ [0~> `2ؗ~V8o"F߂{y['lxk^;KcDv%t$oI.ؿAuF=f0Xk7ZDpLA٧]fѩ!/j`Vg~: m` AA}wL&e,΂Ű}h}i)dwHZea&dpbI%;\O*E./eu>^EZ^:; 'iB'<+O3b%S'8ha e4H$+3`cKr-2EK4RKetrBeʚ[v$Ѣ!$Ϟw~ X37+J+PI1'[4&z;EZxm ;4S|~ZujBDt=ָcЭ촶\"*]a2N T^ӲM<H uN΍ƫHKfV-н* qP.@y&Q}֘DťUl=9IWߣ/j8Cha=1(-OS e$hÜ'|Iو.ʯ 5(D5'4Pbv75qCc`$K&ASM&%980 خ94iH R=~)1ǯԇKwj>:i B7lhTd`fS̊~ߩy&My7ۑ5EYPb sGn5-, S]YϜ;Q1b "Xh2R%TpZ!݁g KjK̺m3Ro>#N.iߜ8 ,\0^yPOu$No44`LqT2jVs MX)>6QO-͘AmE,tVb]cʝ]{X!1En봒u'`^!RaαϼFAg˚k6zOM-;Zp‹A צ?~ٱ )]}g 1 %y!ztRI;`7OAT^ 줋zBfn&DJL.HH9| ^n*T}_g #+g WnI#4[[W##P(bhiu$Ɩfv!A.) @_x3J=ƽl&2V Wt+¾SeP1UpQIKd]&l~ش2n./D#˸ Ը8C6|c~:i^[Q mfC}5?BD$lHQMY#O4T`-(TC_HPCQRx@ <%WOhQjqWI t+D("=lx>n0ž(){׆3t"*@씵W}1I C9C5u_HJ0._>k]3Iǯ*!Z^Eh+;^&m}^QC\BVlQ- 853MOTl9o&9;.3*]&7/R 9Z\A\mWnu}Tw`7ˋen2AX-t_Kb I#x Nͱ:d?yZ1 .xۗ)w@Dw9\0\ 8Zp@5q;qT޵J󝖎nLBӤ`Zܟ.k 3g1ҏY k2ϊ4nj,s؁MxZαZ»5z LNF\.d bw8ߕE66]Bp]CgKBXNƶ,a)e^jԢBS'eIpZu 9㹌/6xPZU!R+?c!.Svz[3L8POw-v va wXVJ5gΜOp;%j'NeŊ;ݠtJN]V1+zleP-Z%{!0ޜ|B;Jz&-v]@1dmO}UeIb ;w p9Jc}ؕ/ UU^DmT/q![5JYMZUT@S2ߖu5o]r `^\|͌B^^x߬2UEǵ\Q]+J)لjPm3{T \*\e7OdjV!f|\bU lA$z̍&eYš -EDgkP[ajsɻޛ %̽_ eb"HF"ak?l]#_?3k0ڝ_2t.^U}G 3#@&hW;]>Lr)+hW$&P5 fϻ^شR)sNdLyQ`_(omn^:t>Z'C "*PFqȿ#i,QSѴw>PvM!){ZE[p' aх?o2h>BI汥&7wR k:%M]zj[rS"G|l۲,͜m_VR35*sO/Y4c-,\f5 ũNpVI9H~'*Xe~H-t)ǟzN:?8n4UI*v1- ;0*˓eU{ͺO$Q"yjP&;v!%l$uGVLY;y/o@`h8#!|TP bR#^ͫA0M,5Yű~NW]-gkA_p (ýOvuyTlN{]ufYlw |,:&:*ʼnS V3|T=53k8kEf<Y1.kgHtj]"$PgњHpQu2iQ* gަzp}-+CWEs*$^f)_1̍̾N1I{%C]>Lv*?bnhoc ibm-S׼# K/&x7 e?1z[Y*\//ҽIMCb~=GыO T\~ >‚'ފ )VT'%X±tVvff6Z Z~>WNu5iªzXr0Hvt4<",^k?U*C.$, , 7w ihKĒ[G3 _]ƓBU;T[6'-Ӯ=e";rMKc\IP$W.JKZ+#o1՜_/ o\[:m]]ǝXaD(I>#-6 qSD] 9Q:sK 7b]M] rZ?KFu.Gsqad\(\]6X W|:N]q$UX\O9 ŭyp.&{luF(!kYG~h+dnPCi\ .Q8y$̦ D/?.xnВJgbt.oH:EyJ"oZ9;Gp~W"ZrGe_ }#+&ڸMueEǞ@Gl xtIed%3d%}x<*-3$Uc`>o|! k0m ;[<9|q(4m[DBʵ |YFv֨BGZg ؤώ!r>ȥP5֚Ђkh)k|>UR];P J0":`Tuݤٮ q%ZPZkkqӛgo kŴJ5[ۅ8ne:ם8KEx-F:G!ٗ銬(u% eG7$9e]ۮ-EZ'J&JQrX]Q{u,HqEz Ig*tD'n⃰Dn'SZ6)+oc'TpHm0BH$ׄZ?#|Vux5wSC-Fa>j?be-d ^[z6F8tԫ&k̫$Zn_Ul«GX'H[fҤrΞ c x3=$ &+U8p/rMǹE[}0  1hȸenMe3[hw 1SB;p ;%` ^ԫV[XN!~ hMQZOexF΢p˸(8`-w AWyP`S&ݔqLؼm=&AVFTI47 CTzhrB㺨y  Y?)fC :Sac {d'!dM![+p,> ̩FwccER&C-p{&KcR曩1'1HWUiD !\L4@Q$n~_ZX_´*J ,^stg[=Iq%^3/A_>_P.8LL: egON/q!֭ynrE|9yޅf吵zMc {qAAa77-!$ ,@ {G5lgc5aBВfskHU{oKYRR`>t7 q=EOo.swD:6B3{k8$%Qab&WkCN./q3S}W$LR1uW.}={l 7;vxAtHG0r-?|~i/uֻ:p-t") :W"LĨ\hBHXgPVd΂ gF|o7K|,e<$;z3+H$76[ QdF^Adgk7Ћ${dg)}&g챎aLr@@rzlBӅxgSѬɑΪl)̉6spU@:cqw~XSV<5zёZNOwv'鞰w?rEtE ۑQ'FXT&/fmY*jIE$z6 }{ \{nHMb `Qwvx8x6֙?YL}lep~rbdƏH_l{vgyB@c:N_/28?C<&OSx&Xҁ[-1 2*0 鏴W%U}*Qȴ25fY̛?xY׭6O^QAJ1*1/F%;Fa|H`m~/(ֵB8J繸!055'UP7ŃZ|/6hML8@_g0ojB&{*^Y"E~}iH߷ó`ū݂w)#0߁uALuqk~̬?ړ}*APC.3ߗe"W '/mJ,C Zq3(ɿᛒc}@_\ro\eǘ#O#K-T!ѕWq@.)LȂh6VL7.#ιOaP/ 'JKHSpĔ: sܚ !7H8v> ! YCuJ,3X+@̈́Պk5~δ-_Pەy1Qz'Zf$%c70p}<ܹkKEh.Mjo¼zLJY k$hƳu!z; k<I:>e;ܢamҤ>VemߢhEz֬TEk v" y(힄$ JNw]P!wCht*¹  x2rG+)Ĕ[Yfh`S;7]7Hc0wKq:>JF`:^5nwx#oJș͈Y{sZUuAT*KO%3Ϯ~]=߈".'Y_Y{7",!D} + ;jկ 於7FLh]!pSh \࣮ZLS"& 1'z?K$4> 0N0M0W7G,6Mm2*~0sْrM ?Zz!|]XӾjT򥃺x\-0lOZ$=q$W(p +I> $buqňUAtwhLR\+q^&~}bƌk] jG z 0(D"Z7\Tf׻LPU8֖;L1S0dzȝ 8܏ Cʕ򽹴aū¢$9,_G8ÉG-MYd:_9C*| Z (Pɋ uVFȖ! o1)`gʚPjqGCç͕HIv^NR3B#+A2bk! ƓgAzD M'V]pU^^ǫEkqpp ʢd~S36 hLa6[r ؉ uin?(cMo"s]}+-?Nݜ.3qdc\(z'`ްn:C|Xa!5Cf [,F=:뺠2qŎǶ[}XYÿVP=f>"He>J&5A @Pք#܇r8+M_Sủ찪Ry^‘RSkG F.(}J|ܿ= :һz/S;@8±qZ>'.p̙)%z4J 7)zh d0s6v]!'h30 &Oр!3"Q[xDFa֥MΧ^K$PlH?{VxđM[Ӡ 6*sxF4 lzۯ繁5<͝-Hޫ.r$PRue$Ę{!eb b^S2]7#i5޵!D CnFO!1iZ~%mYik`{w\\gO?+rS9NtKPЪ=6P F rAN`gbn0rxs79(ִl= |w5|C}bZjmhEKʷKL`v| wD{ǖ>l)l6-DׄWvOWH03UL ZJZ劑b!\.,INI_lyɥM~5VtfZ^Ԗ֊sp[p(^$)3 5)ّpDոv / xx{7_+=Ew.G~ vI"Vж~哣#z k6 3ky޶_LpɁ4EtudCFcEǎ0"S,šu-2^oN@ﴈ"*(*gߖ{i *%1=$b-Dt NNœι@_YNNSj;:yGf a*jEEo Xn$+r\u+r27I(WGuMKߌXkC8"`` tKM" .6ZݸAD}! wh0b-,(TL 8[jla,_]TwOVѸ`Jw7Pygj$'max!ꛊC 9*(+ (w%ʵ'l"OJ&2S7Ġ$i;ܔ.s<諴(enVP;]LL~2\x *( j3~ݴl._ske僂sd\2v{oTI[y=4.lwT]);{ֻ؀ Xlx~WG#ˆ9?+mcWL)tZm"cJx@ޡ:%\>Kn@ԹzJ`~qÈOV52DEB r L0m2fLXʼn,1^M+1};$+L~B ]`g:i4sψFy /=noC)]NH1˼ %̨N!Br1.1cdpˁtՏ"oե:J9]AT 3, B$$c 6z_ 2 c˭Vrd<d1[o)Av~],ȂrXf h(jҚ ~4,܅̗&DD}=6?/֗$EHO c\\JoÒ2"v4p#'wlj9Q!ctx]<^i,3M%bMPfGoiX[o-Dec+.8zKkzkD IUs[ۙVs X78V#B2$r.o'ʅ_8}`x pt\LD-osi%Aޢ)]+4s]]ښEv;Q* $,2'`JxypN\>8Er1HPc޾6z ENE@bqC#fDZ^Th9õ&X9ĊD ңX24&;X#a/ry3.zt%L4qxOeZGc ώ_@d1XvT pp§E=^$CN7!6_s BaK0tPTEcFwJySu)"A&V1lnye91\Z8|כ%NN"bZ} .IH~ H|6~1iZxL",O< Ę,?5bwij1G/7@)\nwR7cB75%iy9/9ab,4_Ga~x֝6=NևԯJZbB[q++_j KCEO3^ܹ<38gw= 4x'v֖sxPlм9KSlcPOQ p:U $j,$Gϙ:lNMD9T/p@ O+I F,#l3B/7gH20"ZE:RׅXoq͏=&滖| ?(|e0̛-ƽ{GP%KC%zC?j]r|14p[Vk}tO}<$끼,Uҧ2R,r "9pîd-*ɜRrڽBBO9ggNRaYlb 5FS~os~g-4r nfuNp%rgEGJqWtz|dp:f폱oe|*T{6TdPj{{8Jz |^|Hx@Kb@J'F^UM;S >/2qPcVa!6WD(`6~ZX\ *g= tZ3iέ8Y]䃯hGIhen$6 '0L ۆ ꗘ0D: 0!O@{re1V`).W8IeH4JNr诠MW>xadz"C۳I"0#X.%Ǟ;N*yaxj7BO2A,B QNl!D7HnPϷwl3N@\*ej硣ÀN2J锽IH7ʚbq%㴕dtXw3`c'ٟfNm%-zMw˜eg\9;v/聓?.P+(c>y^r058<ϑhwISt^?`w|I-]5Mq'!+#LzEf#Z 遵gQkQ5 AK@"I|65'[N;ni?} R1MAG@Xx9Qr~!ZҴE.8`V&de1UE!LTPuyNzjx {?´BV~omKvkª>",c-a) ,4yX@DM(G"bCTOxo'fpc++eEl*vk{y*r]xb# ߐT]# bKMD"(]L2qIpt44Sf{`-iE $oKA a yY.+k0?_L՗ "q.kܶIZfz32t "Kθd٠‘ZKxnyhRz1K8K|+46KqFȡz[<Ф'J7;kwpOĦ9x$T+0A5'qw/pPF۾8\S m6<^"/*K^^^;CTxEzY$@ œ[|UL p|FY@VPͩTfC٠!_9ӢPpv}?Tp Q쇤ܣKV೤K2"MԿ6l""~|p>` aхv_<.x CW6The= ~wPoy0 [r6B+Qһ‘)#O?UwspXQŃ: x| 4K1M3$9'ƼrW8=0`YlK9 -1ӎ{=nݲuŊ6ꤊ4nz,M>RISt]ǹ>zJ%Ы X\S|5#Yb8%'݄&tKn}Q}!5!M+6~oLBX[N3ε}ㄲ1[ZQ^N9=eQ|D硃 @ײycL3#?*NW:-S?0Qe0y3ę(:A5Q4?Қ`G}:BI7 (J 54hdp%AjcRSL˟LLzkd њ1˴* >ej2 RHsv Pʰn1 ePbi W0!Ɗy*|+,Hk2| RfXhyV7TBZ`x:N}ur۵M&IwrKhe ܬBHCa}TyHS?IDYL]y]KA5YzVxz(+' @! U1@at+b{ٿݭ,^hiш^8/㳎ݲ$3d~^S3~\fhL=bn3G K dk n$+=t3"{HT\fEc1@|Be&qr"V gd/y8`!@vI/@OjʐsMuݒYo9Z=P`jv`kM%KpJƥKDT#kt F BTg U>)}O.?OFs ]7O®fJp0538@ev/r;֞G2HG7 K41TÁkoE1*qQLWC^'MG]pR]VN%Q4Ar"t3 U2H|~3 u<›_;zXuo,nO1 ROVG`z8aT`7:$D16t o@zmUa@n*#}iTFA7z`AX@'9rhz~iٚ]I5)n?0![œ1TZrŊq>HZfǢC%ۏ7ޅɾ?TmBӏ}\*aaٗvA|>EאuRӶ!/+. Λ Q-TRfg}/V>$ҏq ~ -1X\pUHY Ut7҂gkQYkީwtZ2 b}A,T89݂pJ݉k=YŎKz B35- sWaΡfӬ=Mt7{|X3V9yh{ϢV44@ʱ%D8aMǝ0(F[zi\[ <#fGEuS@Ų;ѕ"JDbDhb=nrtZc4_^!BV3wѾBMPğĬp.X| tx^ {\It PgMC+gR⌹~'C7\YխpG0nwD[CXC3b{ :?L/L#:pbZc/E~(iwd8V'!.VNǰ+37Sg-+:66Th:zs@7ΰuIuhN{y+7n\ 薩R}4,+tTV[na5nɕY٩Ji˖d΂q-ԩP,B.-Tt&5bL%iy:p$3frO>xFY$2Vnl>lTe ?Ao}:2;nbo40R[xw|j)cRy$* /̳}W`k S@U,Z \6Ҡj%BW!6[h+h.{[P7GJ^37PK8.[>#?x$Cd K$ Jy6؟^??6JMvu,)h洢Gʈs:bC.P8¤ iYGVܛoȪ3NjP)FSa wc_b/FGV#|kM^4~Su; P$Ǭ2o501YQYHKQbx&:Je`Gg#*EUE.yOt_ a3[F֣~N*<r$uk 0%C(8, Ȼk}w?V<SW-s79K6n"ԍjtso;cҙ{7eKz7oՄU}[{MĊbFŌa FP[[<֡z7I9#p'QQ¤+8JzDMKm+NJ75J]mfZt8հ0 Ge@fxKגĽ23 1%X6.t8b"4pT ;kEe69Mţal˖ʾ̥vǮH=}x[P$g%?f9|(k~nՁ:[W`jI2UWk-z ]$`tfF9.$dBh/?1+voodf: 7Z;a&P@Po (CxMLYԷ*dc0e~NX)D8<`qƞkPatr/}텾smF ~߱5pz҄^SGI>9YϿ z4WkgxeE𵖧TLxfYosNF;>B1\ w,~CM <AԩecTg(\x⊬QKpW}-;-t 2аP|h2K1Dy)MTCs㵼Yt1X {g-LtSpPc}҄Y02:BaX˅[rV`;TmQxQ/f(~qlp ]c--Դ QC 2TDuK_O+WB=sVGR{KVT.>VlMg l(7{$/{ٹ ct)BL41"P||D<’& 4 ܺu VE/{ϳA |aF i[!ą*f tQ>͐t7j@/7J:Ϛo ;)UbSA]i/ uA-e^pTXEL-IIVS(+Ԑz6NF11Ff63V,0av̤UjEER5Bp?=!w=kHvIÜNʤ{ ~u>-rۿ8cy" -'"MU}ȉ` 3~i^OD|xdx^ld`h(9(718r d)Fyl[,$_J\` q9δ k/ 6nv,:f\`qF-d!h7@PAR 2.0MainQbx۳,<ܞPAR2PKTL@p~9Hq-~xqF-d!h7@PAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2359614 SABnzbd-4.3.2/tests/data/par2repair/basic/par2test.part5.rar0000644000000000000000000000001014625637207022721 0ustar00runnerstaffFakeNews././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2361124 SABnzbd-4.3.2/tests/data/par2repair/basic/par2test.vol0+1.par20000644000000000000000000030674014625637207023005 0ustar00runnerstaffPAR2PKTup6{5єD~sPAR 2.0RecvSlic54hUŒvRR䂊StI IezQ:IظA#|@ 7Js-(d-u ܲbxUwMFP ?vq`6E ' ٻG#SH+RVj:WW~.qW'@6S#p֋bbpj F}输`Ő5l0lbz'$SԖ•dr˓-0iⶳcIDhX{Q0A>.,M'KnՁ(%4̉N2ɖ^7JQx,%d\Q4,ߧ|(؄a) \ђґ%:x9X9R7(&]h#rlVj 8wB5Rf vUĨa#Asie.2ay8}1z/ $.*Q?k]1&ʙ[ xZKQ>sց)p@nUxJH'sTlе6@i1KʋGΙ{pQr0ɿ!xЧ $KfXhmXhS te 91j1HV# 6os)^(ş:d]^tx }(LJIJ*q%nPǀ7s8t0. i'loT+f㨴?mX6!zjYPG<.7['O #ZdhGXf{cfH lul",<ʉg/TQm lO 3L2 VW&&3QUrWx+sf˼ZM[1 RlS<:ڰHUX.!W{"ςN*&# ܕHC''1<{dw>i!L?"zcC,i)Ƿ'T`THJָ"1'̓ڔpnzcu "qqF>DAx^g/n 5reVK#pxN`l '!ܣk+oorv<fbϴ#^ѱ#KKܾ4=l-k}W<_:bY77qN 0b:;WnzI$*i{CoK 3b :薞`GBבQr!$jz{->NzOq{AȁckI,]%vmiV -O9lǠsnB.om?Sv `vuwsRȪWܸq}pq'r&oʠd[l@"GY CQhTDwr QoSNnb}6n}qNYv3[S̬Y z7o:756\Pd-:_q9פ@_U I%LF/QSkdE8gF+B:##oԭ c9-&DIrrfI` @5+ ?Snb C?w?zZJsȢ2^|ɺONZ3&֢}CyB9ܲK\z3OWnB۩wi;ftήDS&٣@Jcc'iΏyZ[D6Si]\Md ;C[aS^ _TYE#_@uj|IB̚" 9Gp27f  f6cvl -RƓ^E%G_xZ&8+Vy7,`ϵ(<4x0,9T#'S,5$[?,L۽(#Ai?NW_rXTN q5iF1r};5oاxf_PqAsfDn[$/Mv|R}:~M7m0]\x-\I-k.&fl@5As]\a"q0 R>@.՚V`Сi-tyʶ *3>H<W!dZ>C*\1yӕEs3TXh}R NӺ*ťc)o<X" ["% +·*b)9#pzALJ0c+i86Qk6~|_Kęʘْ qHIYH[A~Q2eM&rȗVuhpOk,%R(xRi"E3[@ IJo"k [aZ̾~7|8k7>wz1v 7Ćq]A30(K܌v"wWR,b7vKz=ߕ9GLJ|`]#&& 2Q;gfV Jd{pN6eI&bS+pt( VCVU6ِ,q } 1*[L71;,ᒛʔu!Vd ~k#6W~ m`3X;&Prl6qp~]XBTNe:sf"9Z#tYXIrbwy9Ln"5&e,SB6| ^1,(:QY2ֻh11 's~\TsfcZ \`[z!utF&\bLk~CEL:ڮZQe>wz(K5E ުuf7m-ZTӫ½ cc\1\0R#6EP1q hxѹ;b[4g2Gc7uqf0e$Q6A|A +` ܳHTP-'ZrecYMRI|/-ϰ6k-P}c{QPTĺ%h(U9!w͝P<Ļ\_*w$3`UwaΙ嬉|NΥfK92-sEd3~9U%YSʥu-}Dcʿo8 z_lTz2sJMWb. 3I xY6p*Y@eX& g2}@;֔H"t9òH5&mEn޷&2yζd/|jYjzR hH0D.k:7N܆N{UB~Bs h(@,m'іr|bMqNGxt/&"Jߜ ʧ8Qlo'f[ҕ(1lP:?@IIsWUem\=lA{.vXωLaS-C]x?RVXu C9^b `O.߇Q _|e'k ?.$%(1-CXQ`ЉjI68ڝ8S48Y&!lk-H4"~ T'  حAk/~ 8bcS&TԥdOҽy,'&13tIW%NĜ`xK_d @]oN ,IAɿj+ϫܺbj`w8_òi(g&spZx?v-_ 3) >ÂP"(0~f0h`$'4w_ 8'ojU\=?xcDfGXji7I8!^*[" LBVCAqdz؆q3N,'6,#g]MwF7lKztY]_!laFO]j:s?A*UӽaGNXF$h+>W_Z]<gyvE#aSnS Ħw`n̐hkXER=:%~ Jrqui{&@I/Fed[@9LNɨɇqvpcz_H?oqzbgUchc1vZRB %q.)6}Ox:y0bch}Xz gΗH뼚O{u]T "VIbȭq n+%w|3 /y1ӛ&(}}RiH,iaVy?Q=-YIB_xH*;z8pp"D[3w 5=d!8$rBu?҅:`VKBk'CؽiAV*_ʒ#f3'}[Yѩha4~hߎ߸5CE!O䵄޽w\EtٳBA?$e緀ki4|_};=Pw(@Hoѷ8!)WnR`˜hܘØG$-t ]h;zk4:qoBEvTjwyjo@V$hr IJ92ހ^_ :|؉ ڦcs_Eo(i7.-cW[*Re 6&'5vpRD<χo@RQ~+"S= BF5x(cK6}̍nJsl.eڋ;ݸ/.latp(+y<,,2@]ǭ*]Ϯ;2(g!&^JZ&9^X܀\en<,6cskby%rU@2b{?j^R3eZyI$^ FYd"kf&Bi5/'J%5?wᄄч4rv+j#'e&M$XveHa𞠦+\>ؾ-g*UD/?P Q^ SAδ5E (D/0x/;RR2rXnv31o[߆3䎕}YBnYkWK^7Iw,W y5z Wo:dCoSĻc_ѹ[HN;ao|/a 2QLT4ַ#rBz[& ),v깄Q%ŌmH8O5y"m6žĖ_Z.50!Ldc쨬!VAK稥gi@sj=Ē!OE}/MZ~=h<]%,r@ eb?l"ܹ2mlaʎKegpi /Րr@{8F틱JڗtVTAr)'95(kDxGCW?j>`?&5}‡I2|:0x7s>#gbd[kf1jv)CuH_lS{BY?\U'Ib诒c؆iQ;喫[O/?1D`<TK{z LIv!1k40 X̳#=; ˕бjWYfu|i ux^{*Dd5^T>%d!_rP!\/[kUIJ12 PCH:c|?u5] IgTEdmnrJ]@~V|&?ccD xb&I(wꤻ,2N5- {W7bA`mz>rnŨFc^%¹yDؐue{W{w|n7) L.%&P1(?.by&j"w/6d4@+㍁ $N&UşݓgB8l| ZPt,2ctoΞm@꿤KixSgxv;pw0 ˦gKa WѶ?ʺl&Ή*bQ`)H=}Ec(D*L6x|{d63 IC F`mlpDdtJEw-T_fA+ (5X8޸2H,$M XK*"EN=!K*LWdILJ|! sɥʰS ]IWݎΘr9f_I$;V Le렢dhFy\DHJ>xq/Lw~vn9b@1h~X5Pzi NJi&L:@S6}$M=[!%֔d9 ­5j7#q#.6Jql)ǵ)Ng{;%J1FAef!GcrIOd`cy;ɡ&XVNF $3.]0i,)eڻ;xשYB$QԿ0D;e\]mBSOHf ?vYBa㴨o>,ffBss/4nz݉fsO;sio'Md ;0whD)], ^JrnB FM/{&RbTMx0aR*y'imcDǾ~AsvN;UnS k8: Q¶iO<)S|oބJfNt׭M#'Aiz.p0BWuCkBҔlFMT0ik*Y=vTt1Z9ju aUobrp30bA:8E sJ10Tyf[7Ki6s'Ov9Z]M-Ɲv!< )g8N(։x柢VsFDf FBNBª9[(ܣTR"$FM@NU&tBJo^SAkrHŖ =sX2<}ְѠZ E]n A 5ZSNQU4}]V pB*dq+eR i2h%kC.PO8sP(]]x"Wm<P؏O7&FNjnvfuCĤAT?ZNt羷v]XpD'ؒǕ;qV&q{!01m0̫i?^c)2aT &0MQ,gr4Y=LR].AFF(*+-';"[BVhM?Ff|ɜ)p0\b +`lgl ѣڅ]a}7(H.O̒nHOj|, Fj, 塱k>ݻ+'+Ι0;aR+PU'T wvkFBh 0@˶{$._>. ,{rϒA{omOt l'o ~ mB#]AXB>vx _b:\O:|Tz:: ik'I{xwȜ!Ehcv7VZzr^{ ,b&nI muTm~Ƽ VUMdޏ`)QZӱցFψc"A?gh# h@+b>-nb+Kݺ7炒z(HBwM紤"yLꤋhEViY8*FڑUr瞓Rd="QYk-h?8ˆ=X?kX %E `.D JOIUTm R"7ʓ̃lJYd-b1-ҧft;̑ etZP8hRMUPRp}j44Xs_B\yg]Hx0H$tAj A$n6t1ݏ^W~wszZW4g#fCI1`OS7YRcƿyqiœ%fp8g}-Qq5qqJWst<3moY "sljdu b'g3➗R2/;Rcֵ[ ,EK &K?I C*cڱiEpnw.xap,VO3hPȕ&m'mf|r\݊f T Qj{O?V ?[X,oC۸oy7LI#v%8BY.7.F1;[qQN^wdђA+wxtML&T"oy-΀l۫spuFj)rU(czuo {'$LF9Xo/^u]L5V/OujLpҏӴS7 Q4Li2(C.e FLF j<md_H2Њω5Tȝֺt~w詔M!dNiļܧ5^{3j'ijK* >Չ_ֶHJ8xIzv\CG<Nu(vd KiZYV!- 0>>T%=CO'8vA^uQbNs,^$j\X<654s{gURƴۢˋB X1HCl|G?F@)/AȜ?ms ]BtNuYp~Kp3gޥB~y<']4倳 ~!yIo#bZnҼ4cA}>JV<|rj=KFu.CVZL@2͜b#Iuvp|$ْ술x~PCI Nͦ56evL3ppR{':p/<%)F+}:spz 3!sG9_,G]Lu2"ah( 2nAX_JT|Oy*pL<:!M ~B5)4ൢY1.E5(gʃAꆎ#awz4t)Xe/(+*rօ+gV˾.^Q'a鉖ݛz>bE-RfGCh{b,'5N4\6TΫ-U(vE7&>oX41զ38[@Fh8yb@I1Th |\'I׏9QۍCXA*%3#O)ǿ*Y߃K x?a M3bǃ0++ԃ3{'0P\b oX;n"z|4qƆYrv^Bѣ̭* ihB$2#j [0Rg3dR6)mA87nTf[NݵgaSۑ>Ճ'I#A~EKXXsl$DWxd` +7P6I*yvoM;kӮ(zhG6Y )%hm5~\=j f\:62%*[g<^Q~rgrqqHRv8p7 C=`0>I6MJI}%jhIG \xX= &;zekwNzG:QFnw͸_3lw}AZbŭ;V K}t2$]tUPh%|U|(oS^'A;ZOEW &C/!Am.~iy<@BXLkgYsH.+\(*b4w]v5-@,7Gnc>-(_jQ"Xw@ym}g<k~U٪؎֋{~`xF&(A-*q4_EJJ#dqM 6u$SIV*딯g.o jjɭ˾Ĕ؝R* [U|J@Obh-S}r@NPv7DI`v&pN5Ym)& )Z4fB ~J)`Y8͚BӲ9Ѱ=e)~f%5q|v4C'u\!O{R)EĜpyVs8Z+CLo̴!e@;wok;z1)ydê [%iG^;W 6ynտHn(&!兴 ^ڣ*.Sᨫ|Y%QBGָZNe&7抢l:NiY,5C3fISPy6=܀}G1sSO2  dQb+> ǩ5;@WOfpTwUT7ePQRcY?L "<5ޒ;h\m4,t+tĦstrXX WX/Ыg]s%3兌h\|Nwv؜\!@#PckX;)4.r9ą7E{׌; cҩ|D*hCvA Y=1tO2{6@/cyIP;VFрKYA͵׿?DCM 4oOuA1*ClppG@7i3)W9dl4JE2Pɱ%@Yىly=NyRXᛷs*)_BXϕȽOh$4eWv;bԁs\r.85<Eaʴf܂\ *  u1ix]u: XAYK0Vkk]XxEfτ91$X: }xaf M8_ 2HK{tx[\MT,kiGCm2X)l#[){3u%1U+*r^7pC[NXDXFk3ȤO~,dZC5Go׉i<+'(:y=#.vV/R:ŏm4e}͛.Y5~b6Wgk>[oނ\A"C aHަֆ!.$eq갛˂(H;Y(J 1( DP |4$XN@nʷSt\t<ÔU,HH ;зͱs5FaX⭄ 'X%w6Я,| II"k>dM/RmQ"%X3/$u!6X8\݈ٽn-w+' 0')kS?S Gi!q`r@f/%{yz2`!RUW֝=J'=MR]F.vtjwU[EcQ*vLN:ݘiའA9٥B/0aoRZzy}R/w]Z/wGUhڟ3N|MW$x~K= F.p~B&Qfs(M ";z܊k/ĥC89R~) :Xc@II $gNjSq;VDJ+K*$ǐ@e9ѵ2#'w=Ġ=] ,l䷻EŕaMF᳛֩K~45.MQp|C֙P8Q ?d:XHW T W@O YK^Ӻ`5$d%î[e+XֱZx]Er5k*)OW2*fAwA? Qiߥ?dk?I˄uL` :R$Y&vC"تQC]gRN8ް=C"ح#q\>^kJ \ttIٞXkZNT7advHb͟p~zi*ȓHhȤ<ȈFISd ^ALYD&)6+TZâa9~;Eo-WM; H^d}Ii*3E9%ٹ; H <(F.G3@"h<ՅI1t鸳S;zP*; 1R:`'bGVy.ReY`pZ&)˟[`tJd >5HStJu%Kn&^^ʮݵtH9DEӿ?i: LUXL$o{6 De@Lh'B٥$u4nяhwh*G34?\=x[vv`!j ҳ'^>`uI|e4GZоrmsX T FW8N1kEp"qu~QDb8hsԻ oa,4xG+QpKj4.1&,C K=sgqdDu*Ͳ@ 2y/:?6~«ʵkC UvLcnwKŃ^h4``I\F:3%)7hya9Xe2:P\@o5 Uݹ.9ƫ?gSeU`Q6_@t~ --F"wiV)&<ިpy̠zIW/IJgg`@.Ky\-YU?gXî㼞2Wbx-߫oDwadZE`X0ḫ$U|9Moa$-u3!B%%lD> ;|6; xâ[ R'n=Z¹EyEj@Talyw.P^V5 bnfS!\Q}$Xʛ{Ov=N t8];yp*5Tq n(5m+J5YqW]ifZ0Z7o&'y_r&Y D晴Q(kƢG 8N- #MNVs"`[ &}Ͳ4ND?k*H;Sf1ܔK(m.FgFϱ2z;3|Hf(V4%/(ZAow:|͜w/#إrE0%O î ox,P0~bQDI,^^ACHJq%- IgJߵ8R_;g,@U A{ J;N/ˤ/Q?W/v+5:F.쓂93fd :VJ}on:V 8c#dz&1, Mw N;ubzI{$'̮NƗꖳIa4t)k{!G3pE beH@OOF"R` }ꨅɱNku 7Q%~* o^ssi#.XG)[":k!P6{AUݣ _ІxH!IZp+̉%fLu7VdcMdQ1<`/\g9QvO:41fxsTK?&"]e^JLߋ %9PY@c&kO9f^_mugp*™>Vkt)Q9[;Q,QY!VG6,ɼUWxvB`дJtIT#Oy-džS6G'^ 8ڧ Yk喟?['lR1:m4j[#d,: CD) ?.֬]sZ RJv "z/d%j˪Ͻb mRqڻfU*6;Jy|(3`N\a~8";(zZ'^゗ ?7-Stouw&]z.*nj c[Å9ëEhY@Vȝ wq0zM%>9Elg{f4PV8]ũ7=72v%Obim3ALA*<@=_gc[< U eS~WDt) Ab<daݼ;:eEgk£4$(Q"#i+[ JQU5H{|0 5$"OO?3M#񣶪dDn9ob:l_@7$EEg'#6-mw~Q.'*M ]&c`u5%ʔstnK62"& "ݻE@Td4stP,> qg~^Kpo3lI $gū͒a5NwrRwiwUOUXVk䐗'(VrqTnuuY\29^48;y4c:LQ*im_~-Dw]6*Ȗ4:%v7,3\+*lDl-xBlxZ[8ͥ1M_q_x 枥 ,4lq rw;h'6-G,2[]x'x! 33ᣒ[@ݬQؚt4$ È7Si 2EO^f5G‹,ϜfSV(P3֕4ZI+P fR;`osR9v43:u-ew!b&7 u@O\ˮFX, څA,.%S== wJ*zcg~:JȪ)w=xRyyOKk cps E]{,7gf`17䌜$,t\^8*eUO`R@s2oGTgY٨X' yJ0C;%sJ& +o)9ZD<0I{gXFTƋe|j#oW( ae[lMC^qIQVIWLg4@jOLO'i?p NeHZzx鷷M(3odX9\P@&f3=0vzޓ-  k@1& 2: mk&n^ O:.s~-A_ht5TY ;ǫe6-N]*dfJfD8y}mAr!UvӇ{ȸWs0jx*XV!J-},g}*A%3!sJXg%wv|| (JeX3(YE I's~jc/a̫@NBwJ7܅r 徙?6bS.[EVARlGJ+|5l;lYwj|ʜJ.`rA tJ|9XSfX {%rYgGʚhK JL7} Wc9XG!`QEBm~wRiMiR(m#!zu qmR Ijּ݊?L?Քv8~Ol'!82RBZQnѵΆa=~YXN~Bn];r᳽=Q$PP0n){:q>* 7%t,HF5MWg2%^۶]4mr6sur?V;T 2d .i  [;w!QԪB,hyxtyd)08 ֠D"~&>*r5[NO.*YUEجM@A+vU >0i'!WBk m_5e=M."-'o̷uF{Zgu na0sOHOH CœDfzvX5|qIYF" ܩc~uW7@0+IQ,a@A֮Sؗyj<<-i`XûظivEhB;{['NszrnS 2#Ȼ9p'P ib[+ϲ Co 6kMo_+{aVt! 1[fFJ*pZ7V&SXkkr( H7bĄ ڡ30mm NiL[xI[OnO15ɂOhD7M{gEoSָ*h;МY#Le~[92(/J$ u^WqWYiepS͕9eb 0 ^ݚX<øyt'? eݠ.ʸ,%}.0O}a] *[2WE (0~fq|FSv4:šŇwq8 b>@ΠD;2bL;v$&.GL~6a egMih=%~௠4RE4ĺ\3Aγ}B<2g!lKAj6O%VSIZփ?1A7' vZQx ܷziVHwzAQ4UiN [:hǃz,4S *[mKM*žlAQoMg>!;hM7(c^h# C;!/r*R:l2e.]}kO!rXYlPtBTP廹CoE' 69 wc&\mqJ,%p!7tKJFOXtws~H3#v@h^~ \+#a+5|qpzɏzW/fo?6XAx?3$1(rth:Hf` =Q'ow6.IL~~!"|4_'K5G@",gWc*s2^za8| ˸ԭ{xL$V8͐?gE6#LCqy2z GY--Sq'8jPۮ I{0ϭ>,f+<+]g2b?^*QQFV|L9Sq}+T (EVu!#T+<2 :NC1{dε1ZvX.oʻ:O6SLվ/)#}B Bijd QV2GVwX=Iyl@R5:5Syk;(ƞZNF`(Ԫ+G /cp5'kۭBѐOЈ3| -RP8gCR}˻nD_bu'HTy˚D@|KnzDe*xp</=u]P#kS?9S戜 ԚͥD7B =ә`^C {RudT0,<&~Pn a2%m}$anp(CbM^p~axAZݻnGr()E[nǐSplLz}Am\, !PSO)4/Ln>lsA鉯\5Ȼ"aiden$ՔoQHӖgmL@I%,8J7}7u5PzAZ/|Yh':/6?KxI_xzRv~h7( dUhU+Hf)C» 7@-e]mP{uxxYe,~]m#VނFTD?_ɸy)'< nS" /%?43(? czQ!@YL >aV>TY);.|*ʒ05Q UG7{:L>lj7jæ( ZbG[/+5}E"%C1t7spF*=jݟXݼk#Ο~r:||)P"ߕObHlJ? B/֋ƹ*&VR]zc㈪4*F?ū+ i䎧0/A_0|;bw4$9a{c,TM+- /s[vP%ʢ58 ˚ e-.7Rz9.sԭ}[SaP@J"s,,14a?D@6uVJoڰQ˒I=},ɬun4tU e=RЂDk{&^33_j 풕L53PU!¢>*T2[Iy"klZ˗q>[EV$*B @J~)Cȁ(ߑN2x]dZߺ@`BD(L.%0%^d0bC-"vms;?_rH,QPF)fP8j`7;^7?Y- hΪҫxҔ~Ee7;6jAtDRA/3,]SԽ`7>szSz{8MsH 9pdַJ@LcQo^՜PځBy9۩  eԵ{ѿ0=K@a<{Vǻ-yknOǺ_ V`Ϋ r} Aj*=ʮV*^b䖫VR.ac3tJE\a*C.dۢ>dnTb ޥI@v~ojll'}*(= "+gFG:Ҡ3uUbXo AAڙli!2pq0$c24f?>CkUJ"Mq ><ʹ@^d,"I=)m-i܂Whza2Fc3s'UrQblkߋ?(jODhS{A7qDB^_b~]1i}kUqS@| ĕb6SNxn[uVgnGGnϼS ^ߣnӶ^KYO΀M `w>zʹ+;+W|e.B >?|mfYl04uxZ886]z;+V?angSjw"GO؄Yz%m .N$1iWXq w,o+Ul_ grR({Ff}y6729^mJe! u-jIC/7)r8 夰tC ![y.<~K^oUZK'x RQO](IrA\zF@ j˝Ԥt_K-Sἦ8C: )6](#B *h+sՎ\5B&y\6T }$XI(%˛`DV C!,_mY #wes"yc"mT|zNv@@"5# ?ml߅ Dr szQo?2יN2o[IHy՛Mƽ AT(0Pvx038E hW(@Ũ;4.RKm.v2|7'pIa"51 }u-N)-h&l\6z Epo$zf`31]J(Zȉ{F|L㫌*96>w;Fz$y魐gn,Q ֗ɻNxc5&<0cqc:"r,]edVQ\KzwYo}`r?Xߜ(ǡzvs]B O%}jzP;t)cf9D̫ ? /, crh7{P?E{u&WP7m#dž֊j􃳹SG%T|Ή:&HqVB׭kȽ_0v`m/f Š~Evs|b ߁]8 ̩:4zY*6`s~Z}cDK/ZWnӰOV7lTVz(oօ7k wŶW-ql>_W%e#9 MKqWY ~x$Lz-QdW]s*!5c|{FzF⼻W /pw.@Q.ԡ AbƝSgǗ nIG{m@ˀ/pƶsc&6WX'N<!>8n V89F'd=XDCf.{8K}@\R2|jЁWuak ,v jB$t~W8R} [=(v-. nJU*CY'^,Uv*nk`6Ljp_Jr-I%P4UQ| /8ޫo$xPO ".(lgh)ѢV_:`,WiK021O؎4=&:DJbZ"h^MiO<x|0%u4JcgА|׊70] lE9{9A5s"l˼ ;YoiA.TX+Q~qM 荃Og֘4n'pWd h1 l}UenKthk$nLاt )>zKS&wW_W m=Fzϖ]D$z=t(s4NIlMѶpj#Ui޸qֹ[{-Ԥ".o`D?LR5PMRujn7YkìIV%a vs͛!OWoH:{pLVVt_bW |H%nĒ"PU\$WENh@M֝%pBF=YZ[DI={y r6dX#?dV$Hn#K撗j"r<\^p)A% ioU [ h. 1,F4}*`6 ;dϔq] 'fF6ExkE:xӤw ӡoxI%XL[y-_QqN'4% 3%YY'?%%-1=M"kmt UD[hUk`eS 1lҾ57 fT7f|/t^)SKjW`/&~t,3] hSy o990]mE1wĐO1Lۉ!o5[R@OfbY;1؍ff>)ɵ9b 5vb_ V@aUhq;%U'➌ [TTZS#?l& OaV*4֕B>kv^Y G7@YIoק2.=>!Im GzV6'Sfn_.X\wc3 r gYǼ&\//NS'N~~1s ^v*s8Kb\EMP`y(n<&ͬ G(iz bᅰ$c 0B[s>zai"uMp6l"<_q #d^IOCO013x~J,AO6&tҗ<]4xGؿnki^LލP'Ur|n}+5&2 7S;i{k8s;w |U&y:NE!̺%"ANrNz 1cY5S-1I'3][MTd9GӬXScր{kU |؊MFV0"1ALK׸bzh7OychԦ-Q#8A`xu!v]yrpKFc"ޣC|`jo?CS }A7fAH!ٕfJY \: uICn9Sfw ftY'nL,AeP(\}S'Qώq=N*S4ҽri"Oi"Iiqt]PI-}ȋUl &o7I>a᫶,^i|.~rGV5x:cm>kry&pFLP*(Ίf} xˣ> ]azNa{lFۆE$'ⴔaX9wvJjskK!a0s3CI3C~ װ/l ;Utۮ\dGkS;c;5ލUf- $.9GtHشs΍}T"%Ӂ%RAʴc'nTW/*ӯu_"WzMI):^ riD_E~Ip_3&gSs SSX*hF%-ز_7ѿ&R`gr=%Ʀr }SHhEyx52J.i%B -5DA`XzH2PskAK{\RI&f{ 2kt˪M:5fve̥: pAݫC4ECVh*T=xyTERrAR/+<ټJXLM^}4wLy%Rܮ; o67O`t1:4&l:YV Sójq!#$ ,#뇔gi>ȵ<7h+ k\jx<㮚8.pPh zx :]~ʏX5PMyW6tWFWL8GM=ؓ'KSOB C^/zڰgNٖ9eqS \h C8sP\UklNjZa%'a-[vYŃ |i߿Og$gs;a̶n rkb}(B7 SL'b㩼SI?RVpVwߖ ہ:"fU r2vy ;|9'!9jMv2_$)VTyJ +z ԹL^U!HF!U9G+n#l{}}NoYebvV;;o')_l.aA`%M%UZ#N/k|ˌ> qrok5꒤h&(ix Ohv_Sr-V|J< YP>C%hgAH*o"ޱ}ܠ`U|uDJ*~CUi)[3|]1&5mKEmhPM$tv҈>R^8Vmuy99̂ [݄؎CxXPH -6zk~6}=pfW> }-fXW_+3'^SߧƭeVFGmu"e.(pj; D%1=|ÊR!Loo†ini0n} ca%ϕ1+ hCN'^=5Y"%L׬n6 w #gJ<16^^p̋]Kekkl_ݚZM7F2xFG13;39dQcz^z'Ҏ@ l ;?ᘥ;?5Ob׼7n&ʽD0E0jMz{E!ƌ4BOl3c=0u|D\1Pm ̐UA>R_i]}7wDpѽ +q5Zc]z`zAOG'H,)vw)IYu*Ч}2 td)Abe3;_F EƯ\3S jN=TLbFyGuĤcta{!EH\ @e0_HP -[؈2śZm"=y'W$P2{/z}-$l ĩdbhˬȕ~M]Yy  7f܍oƳAC}N=6lWf =P r\\bBտC ]#,\AުOCǬ`rʕdAF(N^poCc9n d#t7`tkz Puo9c}2 {ƊZ} v ;7^d0,ҽ kcRaߢ _Ϫ %`bivMe$ Ya`y؊/;1'HRPMye ljbiƯa;T 4ddDƴY>=3:\G$=¯[U hiՅ=;{AAdtβHp \pz+i=i F4Sh\MeJfΤ[%pU޸ܡy qrG#UQKjP`zFImXk5ݳ߷W=M^K]{؂6燠%%0G`5ItJb7GWBڒX=*Or#I%=<<-ڤcgmP.gkj P' XIګ_"625Xu8[o~:"5&7.E= iʪ .HFbNJ~b8#Sy: N\MtM*a=eB 3/+^ĸq9w哞R*a.&zQpj^ÉLy=Rp^)++K876N6Z蓤 M 9Yd~xCgVCbdԠh7O*;V:aa7?r$xPWR:S隆\?H6p2ۊLQ@ 9L:]v¦T!f=t%AeFYX rJ/!tN?0ElKw!icgFᙓ5#<~>\.wfzR ӱ( sѶ L왴/Q=rƗ-&}񯷜"a2YUWs2sTv,OD+#&j0AN Mbp[w^s \!|'G{ʽ` tiNl(^w w@p4c0WQyoeŠh9QzLH wb)BlF:0m jАq;n_A5>׮ls |x48'ɨ4Zd8 *a!N߁t.#ZTOp1usG{t {?jƹEaCaؓAѳa0,!y>bbyH?[6;{G9[Ik246s2gz^Ô#A`Qj̀1HI2O3)ϖvxn<ze'c! 3Om eEi3umnl=V)[8`;OZȓgXC15@? 2oMg >eL窎Gy&r5塒q\PaI*+*#mٴC5͡vK IޣԆƒp~嬲Dkoի?żU_:V/b_}qpB;q{g!(u"w{>-w}N `Q'2qF|٩M탙XL / 4/P!gUleه.W)h$z`պ Z0Ƥ~#![|CFzfjC lG_;`e؞9۠aW(m7T!;%OA8r ˃"9brDZFwtԓlq01=dBn2&V0w#襓#p2L`5@TeP»j5.[CΑ]nNis< I<Ѿ O9x! #_^8 9M+bDf-Vbr1qh MZڙh ƶBAț ?V(PGbEQ̐bK{Mw`@tEOY7,߽2 a7dxڔFЪ`GaLb DRt_׸oM֢mu,k{;'ު+%TmuT*!)pFu j3#2 8nGib OsXNǬ (4\^I_]j}!]<|ĚaY2P+M*z:Gl #`Ph9+KO '7 7&>%9G!q)3.N^tLfrN#BqMiNcd!1N&LCTzn@D1[4E0Y8o8;{H.36kaw%ZYlİЩjM. HmŘ2ԍ $'2w,=ū,YVmB^Hӷ?2ФfIc+, PAB|~Co;ǿ@HS=⏵xDʅˠ?IRG]~y=+&@sÆȊ<>vDb`sp4gEE~xovZI8ņN)֊s-gkRd +Ny[*)QwoMK*ܴ YU"stUߡǝ?$QR|e~Z_ P}_Oގwq/Jk"h ƯwVzWy$': ?$k/ݙVK M:] 9P>W׹?b xM4>≎M<:T[ r:Lz)/^| fJ RCf,wImkГA,R3? Cەby}Y+bʷc:jEȻ%(4 > C']}_`&'[!ucwlZE٪FOPqncEGwdMro{W}P5Qt/WԩުoiE-$HHGǚH{C?HX<Si:PJTzΐ¯[)EKOiOV%Z>N[w:,c:bwM/k,Q"^WR43tˉ4\yh`é͂? a O:r]oX@0P+3'Zes6"eFS}kʤrr# Q3Q0?HюSIjX@?*_9p9Q~A5g%fȘm..EW%[,JÙk[`Ď&WW˵_Eח.)!Yio]0=˛7w#*%IOh\+I.i V9

<)&\6ӎ9WۄǓy %AQXunV9CB05 A% /c-fn4qGjq,Y36)H݅^=ZɪsϿߧun ā|e:zskJwysBD*r(caZUߪU6V.ӊO n%mVk:)`ڨ[=; ;ŻԆggϿ1Dc84[+/Q*(;<:{1l"f[8%P + 4]6h\Ki;KQۙe"ND͍M!: bz:p]S:k.d.Rj\ #3X7CU;}Dž˟Gk9U6M?˭f}#aUiwS.[1:3fix0`Y$:DZJ:P;I]`*!5 Dt,fTfYj1NEt;I$x(`$ke+5blBW#@hVNr#Yv!;bP#'= ?f+qh`cީf [BO1-GW2Q'OLO\HxMX2Pi) bsp9z[E>ii?߄cVS\XOqfj\cuLZ9Wzd[)FeiUEd=Qϭ_`A+ՐLYf %.$2\0n. ^͙VAdN+ N OPWYeYG΃S-~A+Wh?Z~_]S3EA(9b`HKڠ.q,aICM&Gs y kIGNOce9 _ȭ.Azr m %#do=Ξ5a"9z2`mͭHK;/X֊?iS']ZC)T'r 54B(8/]z/ZMm*|0\_'dip[HY Wnׇo.Ie* tX.]aRcW|e)avx\cL$B*Ģ1{>1Z943]{2~wzI+&ܢZ5 IE*6Yâ.WEGt}>QVJI91} `q;bea &@KP-\{r1 >,j<ͧO*/~GF3`Y>i%v# uytEȀVsz L}t2 , 0qb%UDDkP+ZWa#^L/CF0s UlsiR,O #hڂD^t;v}秶Z)y!.'(:)=Jֈ)عj0ab{YNF 9sڏB8|6_ YOc~)o(IS7aruD6 Y݌2eDdgnøH<b@I [ La"Yh|P$FҺ@i&8 q%CZɠ#/EyFzNy !~09ܭ/ _<%k70O  iL=c#LQ6VJ0,J655E!~X2CJ29n?}o -+AbE^8bFxiOwDJJEl((IP^iQ "_=#8E}纭c\t܉UTxRwmfb7WrdmWQ)$= { ? `Y>"LuF!pR-ղZ;8+ZǒwC`y R%g'Νd o.ĝ/+Dq!E_-Z:c1@p?̮O vb$94H#Z[ilL-8A^]bm}jkwQNYq@gx)/pvm_2~{#}Bƴ#L+,ق`GqEKmN0M#gv*ͅ9NUI>qMѤu`X ‘)kkyz;߶V<\e$t>P3|aF(MӞKx(t1vz=uK3=WW̽WLs9@d7lc|x?KC;!`u%oCĞ+QRY5JܟlEh-+PެqM@X"AbD_\ uTDxvM.Ǝ [9x3]ASs\(AXu[p Ru3]J/O¯3JU5ܼE]6kNZf+O`xH1_`h -Va.Kf zV 1y{bFm`̿"ktf&_J"m!2q b|bGLL'eޏ[=a֌ ,Ԗ]aUSf -;ފ@H&Zы#K8yhrC΍+6)$><$/!3VJ VS7'*iUjcK^|L )YDGaX思!BBrhbC8RvS%OQN ΞVFju#L ?2 ThfٗYt~&2QFw0ּm_ԨrGXMNlw r{/_|ı1ib? [N[fI$h?ba@)lydjoۀnE|/}u~%@o٬iw~ʒhĬf$eVe9P#{EǤf!CKjX%BųzdBm'5{W$ >G>J<^8ٰޟ`XݍH]6YBu -ܛ!,+Ԩ`a}i!=J":OֈT ~1_m @:DԡFXٸ wL|hzo(qH![-{N68t(x"VNﻩ\ԑ~H=D{Fʧs ڢ] ΪZa%>Վ~K% ;/*0S{) ‰B+fQ mp,Ɂ _qn( q4NhzZ]O,gJԹr!LCvkhF%-WϊOI5/3Allg`n-ZA$.,jEn`X]G:VrMKĀ:I)#g^ xZP2%r'+F`ekFMۗM:k%Q'1@,"}U 4-EN*^Oݣm N{Xp]"k6Yn\8pj7TGY0yy,V ( f0QA;\CJMzS7л(lt 8)BHP$t+#߱ ^Q+5B-'Y[DdK6 ttH͙ uR NF% @KVNe'?Y2Q]KfŝDr-g 5'JCjލ]POY@yclK'uwh1mȧ 1.d v&߂I_\ xď@&ZٝzIFJk|+ +8:x2~);Ӧ#.CE4C#3&L.puhHDNV] 2zz8XmIT%(?xpݞ17.lC>XPjE_Pb"E,&T] :x{~M@Adz lg[N".`_P 8DMƪn؈AIFgt7㊆!1 ϲW\PѴJ/S=LJ.2<;tRN*&DF0Zn=ic Sϔpֺ؊j7=LC!L! ѧvis [E-:IZѶ|TZc)Q1r][R톦3S<ȺL8,v\߽D}OFsõaX9Tz&GЫFh]d$>u/8*;>=XɶSQ7TM-Iw;nj1{9ojSB5ҶmJ~O / 4|\s;:I88W'ۀ+HxgktxL) )`AS %Q·V+BT5l/fG]/˜ZZ~zTp`q8\bݹN'sdř^l$dDE\(,=yH ًVdDhLM1gץߑ4@ϲZVݫag<ؙD`ry n۳^ SFCY43K@?.#=)kj0V , K+cV{̭!-KF&A>G*.)tU! +#1@^Y st!I3|KTcr jP 3s 北n]$Y٘=I;SnDWkySO{3^ʂh:iM1 fwF"囓>h-c긑k(vs|3 QS{ pYx/ @s\2 \N#b]0/z9aXj#_6%ra>+_7tASCU29;&!-xb #v^GÂ5֗ '!1!a >o9c̦\ }l olPh{ -jl(T&]uxɦp+q1*WXu<2CJՒ0U> ]sUMOF&ՒMB!]IG{Ot*Ρ XCOxl\n~&^iZIo8I&*G#o3Up.#0!o 4Tq™KXJ gjY9=uTH;R-3HtbraG^a7Tz ̂Q\N%eq!LhCpGiMtH @r[G5C1;0h!rV`tW \Ӗ Rv[~-qfEA5 ~oiSw\~`O>m1{3Bg;4R)aa^]:сcM\0ebaE`WDiY`VjfckXS1.~K}:S{ctȉf}˓S;YOKkfɞvù:UY @C,wyo[,EBp {V}BRvE6*{{bסqA e*~*W]eoԟyn6o򛶼!5x_FF}:*&pTD"/~L]ñS;CA ?}%Qm?ArC1`&uV%pDtYhqlC.&Kg?97' iFMkJf0B$Fk_݊az`;Օ` g{[[㺎5zCMW2&W0BҸ$pӑ1'(taQш+nV0t2 {6 i˽LRĞ](DC( w:ku),ڊvj5_E g߇xY<—wjS~Vl2צYaޥ,MHL.ٓJxU>1messA3~^ Ķ$IV?>a'YG ^ L~@-IriC jb6V[VF/Tݸ8^Qr"QZnHv)rh8z!f@LxW۫k`~_M.@nK"_Z>3b TL̲:>F*UL"UiD_H5`b# p>)7\|B"wU+0,zB  X# w0C8QZm 8t@~P\]ԝKLQVs Zn %T=35 + )oOn 52VPQp+nGY <:'BMQ^eEljt I77z2#hԡ$ V!ګťz!W?3C?t4 Nyb*И$(Yp7C/@ %'x J[- 8#9%Qȿk.&0}+P6]H 9H|tO(1_R|`4F}2$V uKajsĬ@60xxڌ,( 20@gsl?^$Q?9#N"?*7CFݑk D AH8 _Aj1n̰\W3&5-jƏYcŗmwz.sI ]%N8!:Ƶ\.V{b$Ϫ70%r(v=dqJjjCr P^G1M /l}Tw~T6ҮuTcg:[־pL30YlUeLN3 ~.+pg-{_y՟NCPfZfņ7Q]r(C \bida>!H[_4_ BYQ;TAA)Ri_.ڭ)oʴЦJF͓({7҆u 3o)D%]Zn/{":ტb$[k[}jP!9ivĨ/rKâxke<%#(-E?ڍT CKΒa}%Վ_?a. b^Z ~-'C6װ\1?cjWf8B|]ũݒ:GGߜ'/']cz)f8-j[3wLA0ImjPo4!o$1g⊵L^~:^™UФS0NXhG!s]񹩘V÷ wjL023);v^+GMM7 TJdrESu;&.[q%{d7h9ZmqLU0 Վ2ùA#h }1 7&~p)]e+u E툋_Y=48yp>&kJ  |l@t?ɇ _3F+Qm#8(yGW: =d *Կ _M׶mj)0+kflͼy#fAU˥jh(aJ4[D?~כH|l L(1Z_Q٘Cs`ہnc+}# !zY3J,$bړ&*ҟ3_x&2Нeﷂpz|B5]WM|FnoFXFRň~O2d7yrP{ )[-Dfhm\TX4?6>TFf8d?R5 Ӯ(Zh%>U)jy8 VQbpFyݕ$(f Ni"Ԋ@Uct0{pLgZj@@~N.TxVx bG8VŸ5a/|\i1[7amݒʋ\[^!e\PZ췟@Y.IyTy*4!Bػ ¸0rH '^-yLs_Д"D9_ kaD|<7b1}w5ude|eEݡJA~&2}U)hm\F՞J$YKGg}{Ѽ6K,R?jS_1 bo =t] SҦM11ϔrn4rqm(\toƗ@aB cөޗyz%"88J rzb\$YDGlSP,doUckTdJD=aY"˞$6$X _⩖-G+CXE/C,=JͯQ!8 qQ:q#?{0Q^P6j4IˀY*=Eq#ݔYwKR28 !?M` D{g@yԸxB 0W$/A!Z]dםsn'Vh1P.Epo1giJ2 Fդv!/&]큺cƫGvy0ZF(&&HpK`-F ,h"wg裤RR ›LgĶ(As5Ҵ'8Sƛ~MJ.(<v@hUxM&Ǹ~'_ ?jAY?!qŨESB4. GwxE@r̟ /VA~"+8)g'״mz"ԓ% B%[]O)&ȝ!ѹZXf=MAͯ<ѺN]='^<'|n ᢶ6ϓkV:X6`}θd|6~pL1hTlCc#$D,K_mWiR=|\Q,'BW&Oٴv75G#R"Xn m7Նdt=߁K!. nVxDy$Aex:{")U!Q%ZByi _oц^ZȈAЄ̊h(ř&-f]J }{ /`^_+|$өlpV8ܵD ),MD qtO_JcA xc&]Z%tā TJkwv\K~??N +/@CT:>jJaԚmWlGYZ߼wB,좾]Lj^UC:+X[S{\ m- (\62[^2IOQeeJki&idzo+o(]V-ʅm4&4 D{<%6Nx`AB.}D"[oXٚJOW>7X /om 3VLL] L*`5hJхt &NMθNjA3QU T˘,[>)rEqԨ\/hxt3T7q&fSPMmn)q;^h%qxьQg 1 =T#$* ^eė[x浉AOYfxvK;WdD+'7g*C3x:PM*x^ªeZ$!#͝:DVtKs<̺;59_#̩[>h9#m J 1{|^zVqviExp/z&Ïʔ" 5<ע r?\1lfJǤbf*I y|~T\'"j :淸/0PchT ^0e1sv|8&`*T꽤FzM Eb˿*e+d!{k@kzBvC>JE%XQ}r? ZZ4.#ʦB ^^G|eKjwxӺ%| jϺF59mN*iT{ r-1xoOH3or;˼&H&y'L! XQl'/1R$$E3-0,ucOW#+{Fq0pŽ-_Y5z23Nw Vv@vc`V AئΦhMCȯ_M4 HO$X\`4泎JMwvhkwa.{t>e3̫1r\gGgő=L L38`QVbPu3GzӃSAr n&O˽,צ^d~I(W>܉zx9 M#k^u0 `sbHcCeJK"pYԹ˅@؃Y"-=B#`Rt,g+:5J|ZO2Yniu.9 F/wԟBYP ԄB 20]z-Cd@˳h l05*%~)6YA":k"{IOQܩ;[tU/qwhMn!1$!BTn:@xV趋d %uRt _+ΉeO= 0ܹ?>, m td)NE`븕WoM14H:A{[K' W*ܲm^HUn*iQ{۫S,<*o4d\\*t`ka6s >밮 ѬH@m1bMScG>>Zv@ MgoLh!^ }i]/ ;4=c#yQsFCtWާ--g3'?b'<+LD"8"Q#t/x 62 V~-S⊕֦ʐ⪸GSD8.qDrq9I:JJ^Q9:h]mxXh.SBV :JtL%*/Υʿژ;AK^'vCsxi@ [hM8] >19QK,6Tl9^t1!"m"]~E6s)fRIU>䚸Yn~‘ibŰR6Ҳ^ kȢ=i5`3\VE|TzCEfUgjB\wgb3M7i7k{cPֳ|Sȃ wK}"+ILӽ}NvN榕qCdij6.J%a`Ը:@Kn"*IcΖP`cءHxc"W qv#:܌b prQ^z"[nm6MB6?qjfJ-%,Q'hCN ;{|r՟oekxmΣQ`r52U8>I{ϗމ2̰&Or(]ʁSI[evK3z}]f/^fbP,;3s%썃3چs34+H/w32e(۹1yiu_5<;x{Z<{6سjAtp6ɍ8"gI2 i+IgoU[   ~˂C;(|*&e<=AjNe;RyOranb`aZmwvwz%v6-EC- >$Tk $ J(}RTB^#:rftz=!uQRӳsjHkkA%8у&Guv)T\S?#Mk',| 8C7k`KR9[O`^rh:ds PҰ/V'ku42GwLD}K Ȼ\2x< jAW^"qw?2o'7'*FR*y%!,>9 qǀ3!Hkcal{piC![gb&RH8M+,\$dJ¿ɏgvLl7V6H&0BEC=H~gTCq|4AN,x9 ']VJv:'ޱ괼UcJmw-LtیW$Zr5;QANaE\0INe78"i1~ӊXSisR;Vc8Vz}DηxZĻwGł} w&T>058oS0SrO|rSW#$r9(4G %2t]Byb9|v _o>K7|5!._p?`ZF37P4UohRaT_i: ^ ߋƩgvFFII^O0(b+/07ZhTSG%>8]ρZ\dTL#b١@d-?Xu<F@ f41PГAlMfpL}'ͰfiC,s` (G3Z T5u}qq덉ٰ]e㓵tqLi?JBufɦ#=7zƗQg[#Wk8"mEIQ W} Wmx`@ Esnm;#BxP=9t:Fт\-Ԋh/,+:?12fKYGR!q`j]֖z^iǂS1l`Wl~̍ij/縺GG %$má~;N4Bc}-Z/\|bfe7:?>T!Gf7WM*:8Y.UHoM]+^a_w Fqph:$ W3ZdZ_4v ODIYhLeW|»bT`V +ng֪@EtQPhYMó#)cSAȡݗqU=봝86p-X6#wtK c%x2{U,]c |wꜢڒD0hq: _k<_c^6`%i%rNqev8 J^ŀiu U0ncZt#4Xo57ܩ25ebZ(F7e7TeE*Úc|U.r+\#&H";Ǐu;F jʞ֨;cj[vIp:n3JlqA1Xw2>)փ+R;vxI_vO M^͍`+A.{ac=|s S#ۂY@m5ga$1V}bhQ$C4P9"}F:9CGWH/<0I'LWGzJƖ١ؗgpuh-r@Gnڢpx=nZ{&pq5fQ7[:zbƕǶq5ەh> ,v׸ĸNR8bEнQJU!kn3 '\#Cދi+xQOBu7_d._e)WY`_>aeOJXb8]}ٚjEZ퇘nAżnv {r+ĉ^ Uo֕F2K;噏,ZI/' 9a3oV'!z9L,hpe$X| el Qoi}hL¿խNrxf^AQ >m*ԑk3{YQ[$鄣Xbn1<D' Ҁ GzU&`BtAJ 6kRTW $iO6z>Yca܌4IC%fXD*v%BNAWpY$њxƓ.NQ0MӄrJE~p=_.Đ >J11vIHۭ 'xV_"誊 l89 1B2МTbmy31A]Y\KgW4F|Li$ J5lXB h:QAW-tpR*U[˴PU08TĒUkgm% ԶZ.i ܢG~_9Y]&/n/3+߯R- b %_1bYHdNhkDP6LUe?VgK vsfcfjـa퀢J ށ6$,h4;k$UuN1j4)A #_a]~؛O]( lߏa1#( Fx@kp{>/{)8̫4 {BQջq{Qdʥ^cҁD*]_z: 0kg4A8yHJ7 OX{>;q7W@9Mf 6ޒ"M: ?0\G$pϭ!AĿKcv}}$HA𭙜W\?&}Sr{d|? k%1&NOXl.{=@ֈ ؈`DfN?>L:ex \9"o,?yM6ϏtӘ֒]]P֟KplSʤ5@@{tjUYdsr;/Y1?W]4:trs*JL# ŅlYP0V>'Km[oG/rܒHե1 ߏb$kN {.fͯ,XI5\GgR0q&SJ۾q3Ӱ¥j0Mvenwz 4)s}ijO |.bK{LziP8똉t߉JPe>%JA98li"Fk%ycw0\W_g"UP k6gD\S|PLr#QR~nM@vQmؖ<p{X|'lm,Cқul?CͩFD \5WjMt0mU!(^(mat05H4 4X̸ۘO'f((~jNr-c`u P=7o#dJ Du.|E8e4q}gr)DZ6DCg]T"^z*1f/(j{dA57{BC>IUV Lz+/L ZFQ>Í;OGrd+ɳ6 LPȒΕt%'9\p#Z}RyB-.tC6Y-.wֺ;$D/M,# AҤ_(_m=މDԚJ+؆2e:dW8]HwJ:IڲhX{_!`uYJTt)n"dysF t ^mbݳpǪd4s&lVc|SWc"+ Z9*R9ٹl rPg7~c/gj[EζC;Ly:n?]N)7_EAŭ>E+L`w$ r9arh0;j,NET3Xg2߶5%9[ ʹ8UmI`U:Ye'G~+(B}+>M+U"ǘ/x\ 5O3~z:,p1յ>?>q, $u֧r^=J(e]a;D~PA2kwō}q;oɠk _Tyj$ɥAGҞ`e5:Z9<M<+&Q#5ޱQ >9z , Q f/#/DZGޢ !¸v0*4kJ*Ogu~ՆcT}tY'[zP~d~;ѝS]Ğ#^6t0] |kk9gʁ]),4}J'\8/R> =` 6X*k{.@M[Mm [^s*hC {qםNVX9XsI_~0]'qCF.Ka(l^/OTd"̤ԢY NkRIrY@L8=ee,;SיuG  bm7(DЇ=S'+{W6Ck =F:?Bmce%$87_'2_L_йE~߸%D)Ƀxf+J3X|¾ݳdI7mI n ʀ1=ltc~oo5a PL7|(.! xT:Y>zCQN^v56P*6!3 g`]E^8Y=BV/9`#s+|Ć+`"tEJ!$АZsQO K^ NJ~jxŪ%rz4[1\ ѼQ ƁO">ƅՊng46 4D ey|Cߔ rHqBf@oUN&k-)> ?ѯ0]hiƸ. X9yZ.¨qH㟘Eg OJnR@sdꝵ_W/Gh)Ⱇ[2 GUXkg-oq+BI1/vm"z6v0vF08w 7ɗ$?ɶ|ŏkku~W(K#и|yQK|BbbZ-+N.ŠZ0QlIHtO=aD$ ~#y/](,1Wm1[A]X9.yC 㼃6c){ 9?˾/ c=ݒ.i"ke2ސPNxmU -uvEe٪^sJ4qyo ^Z+%U5s:"ՠcn|ZY chaH-}D|w:ο||e3a ~!zuU1<-af{`Μ^Am 3VEpS܈m@pfz7Mf_H0׹n:n=Eȃ!kN #.zjaH PeG25wB}ĝȀ>@t(e7I2Heh?n|!r-6?-hOoIvGۏJKBMf>O`NַO%H=-t,R=j%ΞͶ%LK"LQ{ ( AdcWAگ[Z:|ٶIAI9?(LB&ljTG0 Wv$ N"l=r$ owD> /9ŌZc)YXeҨߛ.i_9.מ n'p6r\/o}@et}h!F&m*p`һolߣZڻ^\nRUr S5״-Xv7yׂLnS @kݔ{Ϣ$PR2 X!+1q゗$*cB*HN`(za[rg1&7aH0O8 ZW`Lk2d0>񎟡4!㍔[vђ_EboQAP+POY֬s9# ?uҾc%F(. -.m]B>a /C)Ѣey)eգQE")+_ƈdHW@CE|J:uu E$+5[ZK4G-Zm֮uWdY9zM@/ZDq*La?hU*2 xaԙh@F` U?9DeՅݽyMu[ZxZeVY0zݖg<2+ muwIxܱ|))m /.M(*~V#[zOR k2K@%ٮ?;o}9fT9|[\65p7Uݎr7$%'Q@&ɁgtBGu$|ҳ^PqJ9$,ӽR +7߆k7<18%1!٬.S\6XA;T4S p \jvІ15r *vXys 9we@as`!i$B{Ef[N8Ħ 6p|i4!0r4$#4gޠ IHJ$j@#B֔0Ҹ{̰Kc&oʂ1,W 䰾U*a_s}!uߘ>+꿤Ѭ>s;|5/&gLjX{4R~Y彦ҥ햘d5YRG/cW ] ;0vWѷ_ڋ9\8` qnudjvDy.u| XB҂v @O4MPQ)~#w81S899 cy_t{1YA7V|.fe_\f No`9,!0F5DlGa:ymvql<|eL??dw`ƺG}e*^:<ŽLtAMPK\G`胼?d8G{P]#Vrn92jЎe'=rLo[{`@B7u'p`+4TaІ/A\sNVaRȪ6ןqPS&TE2<X[({7fpPzrzWxE_}ϓI?Fi ]J@m ‹Bו y{g[MGoқ-ad:#TslxxeRۺ&5+}qֿh6f$ͼj_`ҊĮbVX׫XMYtzvCt p a:ݦTRu3sXFo=6Nӝ\b9[-s!FVSJ*c5N( d_bDŽKnZ"ɗu >q-y/boTeVOwJϦAXREXb$(noaD)gw+G >UvM ad“n;SO?K)E6g^ \ 9w2ck:e(n `4#cXsyBVb.Gm' g+@P!{3sJ%p6GEr+mJlYOWɘ61~ xM\ݮ<53 o {P6U8AxG;\[@ҺS #`'LL>#Ź۞H+W&!rsg=hL?ʞDy:1ɮ&C0(T]z*$fD̀. Օ~rgXj(o]?[sSm,PD kfے@CQbrLGh/$Gyo2R[_gRОgh1nmv6Nd?yD͡8Ng*goZ)Q69+,䘢u֜אwlQ|T|7cr%6z:`]1$sg7x-FrlU6-K,L]r}Ϣ;ixzI17(}7PNr֮/ۡoe[kd( ʙe kgAu ޻sJ ̤e? ML> F tP 2Q<.cF oHw%f8#fhzr*@Ѿ)wLIg覉EӝT3^iR^ *#@] ʀno_zMF?J3ӫf|~RyݵCy>n>$L%_Pv[DRuAo&W^#gD(mnYpB\`ee_& r(#8!ȋ 1 f[]\~o7hxp/ŷ;^T^%//utƣ7tdQlF5mQ> ӻQH+سEk7zH zh3gdš].c|=R?cfHx [/doJp? JV1gB-D,`άs1Q+}Ff2 le SHo/ѫytcfP&@+gQU J2xCI&-//܄DP"PIuH|'YÂA$ES: !/*4I1o" `p#Ԭ;‰hO뜕ϮV:'dMS]Y Bzq_@i Ƶ|{)1˗]I{d8Ӟ4QFWiHWkczA5Wfta1pw06Q(Zdfbpdz|q6vlP3{׸ (QVv~ PvQ긾 5{#6`Z]FP?V)C*O1A!NE[l7\O2(-%7#8a C5&r4re.-S&lu`< o/GCI/xCtz$~;mWy 5ZiDC(c:@(YwHSEs,5#~YԮ@9dDY)Yګ`}k΍A'b7*~rTJAtOPReo鸔n~d: +ޗQ墖~ Jcphǃj_#똅G3#=:s$Е&E+E!ƍYmHkQ'?ĆuE耣~ePrzEDI+d&}Ga@[w('F {GFPr'Ew ,,obW=Bk9a 25c].S7p~p^jNbx7"Pja=W)=vSKӕ("1yBC,R!j_c[R;rZdh#U /zA03g'EF_A F -JD/ݯ h.O([ =fyQ/"bm h'QJïVjFڎ0!/֝A _~kAՐ aٝUcC?ۑɻV K\_Qmz*;ޕۿ8hO[׏L+cѓ);Ȝg(g64`՟s_iwEcB3o&"<|g{/ob#-6ͭ1WAlF!}#YFMT~W?%N/( WwP0 U9}H*"ezbc:G*j5+,Qr#QN,@NkPxs0HK Ë HUZ^'&/~:dS 2 ,RCǔ%T >Wm3>7YH&N`G`Eg^B sFη4;x 8BQyCo39+G8%Ézuw}]E#htv3ʻi!wI^DM?dn hH ɸR(HBP@,[/jb6PudO+Mc!U([tՈ_ PZS$С­Da Vd<~-J?ntW$P}֗#Rx>S6iW?e1Bn#ɻEKˆknjJn"\d y8 ٳ &c];;AU]q9f=v8Ezn|=9U1~. 4hA]r}g=xooI}Џq>v^?7Vn*֖MUc"GR `f08o7#n*BNz-Em28?Wa`q/F3!08םy\@\:[!r/?~X6y77sV78EUFJuϲ iJ.s"h]&zh[NW'[0@jY^Bz QTURO?:g r6pC'Zh:v'WKEȪ|:ݒG\0A95}|3 ʋq!1f =A&'Tm\B?+um,ЋTEߒq"LqQФɿ 9qX0BswEKgp3~ìjZ̪ٛqBqഈ8hh˽ KXs ӭ;yb˲":ƈ!maqL*\pd9\e:=Αy_fYI8-( :Fa]{D|YfaUuJ\,ef_`|o Ԕ+;|RabJ/xx:E5'@ iLKq_? ?)>&/Pb9؅>xE!!͇ zG\hгDmB'-kwSoъ`.m__=׍onWɁB)l8L^@e!bD @AEQƥNH֌Uhhj=[%bJ4%a' g]qo DW?ph9Z.QDww\WRG{ܧ7h:Fχoڋu4CqT3f4梸LJSZ͓?;ufXo֯A˗ds:Z-b\8ʄgB|QO ^;Qt^۫x|=.3#mUԺ-c#_ݫqJ SK>xQָbTܱhsoX ),^'τdƴ;bU(xNȱŰVɞ,.p[x1;@u( rvAAY%TccT|֢LjD)\akꄵLG"~@`jWK@^렽 -)`m 7ZWz%@X,'i\B3n'YH$pӠ>$,W088P.e6HɒP8zf6x $ Wq=^Y+f@>-'Qze>a՚$%s[mi3.g,v.u\HdPKgDri֕^#F r5ra&B,? }~dN;;jFtEُ,a G pH6.b[İ $2).L_R=/MկbpbTq~SKc^ wBwM'NZr|?5e!a3$Bim4lr 6$4}2+C툛n{T!gUc}|M̡/ueJ&r'LдL+eޯGC!cC Q->F}RoВH9-ןjPzY k8-@ B|[u|wLYHle6G0bgu*u=, }|? ;")HGFSm_хڹ}#a>ncC`z D!4ѫxr>ݛC.ie?33nP[32r61' :1qnBӹ!b,`@dzjۨ/ߺ_fz_ۣ@KKj#=`^ya&o ,EnMI1}u޴u&ߒi0W..' ΆƓfE~(:@Jqp"XS/l?cТv2R-^=n%<OpEs\~7ȞZl?x)Jgq,㴩0Hp0uUłCǯ'9dwykb/=3k,z7"@rT:tbh%OQ]OO3=ci)$NRdɕ6$o3tq@6tVI?bii$. jPJ)Z]ɛEqާ,y2N 2b{XL)-E#9/]ȱx|N k\OņXKaTla]F\俊i]}Os'NgU6}Umt!PG&FSDpvE\ .,tH-0@#UWرpgf `,q)X\$HCY0[ڡܜFLBц]rAe="wZc?ExtA(\z*2W-J>+ab}2oifzgjcPl ueVDabȆ_那@Gr ᖀ4؋"!P`5J9Xj,G&E5?cL]3`SʶYBӋ4JJ5` *e9uEEXqy?F::vz6tLJH|-D4,$O L<vD;'0&*Ѕ:gtSUؐ,8w1zl_)h{O""0 yBi1򌨎$Vh˷58#7:ِJ agaim y붿QB8CJ͆F- q"aK@lBCTLkI7y@2V]ddߩ[6o͌_W.DìjT˛_l-lp] k\[>0;LK-?kD> 6BCSTFYuc6L0IYDPRK^Iޏ]5cVf aywc+i}anE/2ʐӀWdkuhJ׼QGmR ˷Kb=[$ aYSuMڨn&puwD'occ`?lG8~g/[ꓱ\-!zpnaMaږ-exFoz@0 q=p+7|K? 7WbWLu"/qk,q>Zj֚Kg=~y@lKk;9r>ONߡˮ_LxH ׯRʃQ :[)X("oN9kAj9 gg[fD3VwpNe)WXA+4h"/zra:b}317f?"L\+3@8Wk?I+rH5 &v2K1k6?DYcx{pSXnV) d"Ղ2`$#DW*8ĸWwʝr;!n*O&M)z i8ujr6'N@K- |+M 5LC2ۻ[y(B`NPYHh;䯋 ulE! ]I ڇl0%g7ݭa >"Hx="-u{~t^9*qt.ÚM֥?1X32Ff%pplNHVPugd:c2MU(qM28br\=`tW?xgX,5µ;ԷpbѬfGսC X>\(WSa }cUbWZ4rͼ0@ayl[ 1YI*1ۓ2"^ v+XA҃H*ԟ{M[67 =;c۬^E(ji^퓭tis S,^q Su}_V́2=G" !Z: H$/?`jl%9d+soq|MBfwKcGeӻd$$rUOԠ4>J-9RGQFd|ޤ0"WB`@"W@ZƱiV}+z#[=\)DSɧN_Z|y%TbSmDJE{Ǔ? <d$wsNAlϪ~FBpI|onD'\.fsڮ4rpR3^:@B@~?mj+/]vc9B{|e9PؒHh/Ԣ+ Q9DĽ_ qP-wimx\*x:qT  DE1}x ̴((^J-1R/IB,R#Qe:-Ңsiީj r=٣hвJwBt "!`a24WnSԔZ$[JhKV,\p[l.iL1T^;Rkӆt^S8@͂ ?{W9ޞ9I?mvzwJN=,+R!0/Iy['r9[!0ܤ6T[J! Aq^ {aS9AVi o"^^,%F]ve]z:n2,J Eb |) #?5I4 Ft_4ڮ~pXCF[KU&m)TsH4 s Ofz??éffE%crx^^q07dP\BU+[:]HIkt/Q|Ҽr F[ؔ\: do XX\1ґ_BlBw }3ͅÛ81Nt@nyrLWDAMnE-1Y;̟j] ~nR;Lcry5g"6m^O$ mL./EXtS΅3TԌ|ͺxovh>_O4 c[FȽ.d~gX1Qc#]F⽦saCw`&KZKӎ?5Vy&`3 ce{cNW{Nը;̪"G+[H03~b{x>\>Np\ ̰tcoR-e '.(D Ku[38svE*{1qR4?0DO,-é#d#Ew%UBʋ쟑\ZD |z*z+R%{ʠKA8v7ؑ_[TӫW9im't\oZKJ4x/GƲu;/xMwR]Ț!=͇&`&h`Lax 豊Z ']O1|#JLlΥ߄iΠjJ@uDEW9lZbtLV2(4a12MbLs{3L} d+"Mp)#9b">v#gdzՅ^@1qF],w3lZ=J+f2~S(Ѵ.ֲ34[J_vW$_q10f`t)vΪHA*loehq(/e"Qn&M;"{ {#m-MSq:~S@A:)+_a6)͆fe!(LS߲j%qSn])D˄) +QeALՍk*LOL/1/{fdE;mlɒuɇq vTW %qݠ%A c ut :,>{1::i\b1MA"m;2dK}x>_)`yvO o00IYF[ڑyO.Ϯ;1???'NJYk((-2ލ>{l`G@}(O끬P i~nkjU.g؂oMJH% v5ZS`m:&[/ԥ%iS7t~vu.Ma+À il43VH*r{Ae{,DZ`m;G=1@i@wOAO )qUb$gz%"`un?wz/'dcjυa;J?XlGњ4y ȮuT}=dﴭRf mx]:˿kd[U29!ڊ^\RCgjq+-De=X3 _Zѧ)YExƹXSB;C/^|Rv#9-RaZPn ;;zLjI+lOvbL>]c!PMT)0^%8[DT ׷qxYxwj&ر|ak;W{Q~f f!r2fxwr~\6Z Ȟ‹\Mˇ,AINˇlE,/04-crk*ʳ8 -cȧSRc%U XpE;YسFx~ТD|q_z餆S,N?\s9"]!D1S 78:>uX# K F)5 KGv;tTli3Ps`/_є[xF{$ Ck ŭgWf%9؝ߜv*+qĀ&t<<ǡ0RJCnwiFjwEHS1])t|Ro29 cL<&E# P^?g4E̞pyHѨЙn__H;!@e)"țI5bzg6ʛX;Dg?0C]❃ݹmSqؼS Kd< & }·^f"NJ%Δ*u;O%Y2А=m/ <VDw^mᰛu%2K @ 1ௗ/ OAWsI` QH-S &pL+GVJrb'x"Twp %gn#9fz64}'Ĺ}&Wvp;:҉o=ٮI\}#se_ҖB|nml%_O%-gw}I]Wha%9pkP7Q_5zԤ*K5ǑEl-,4+|㱳'HOEθXAxRv-iQmU CGBT5:qCM9qiVSu/6o8h9B2K؎]L42_6t|ː!zNکȂ(BYJق:#m h^+1+fDJ+lHzk$fu.Q";qb!lAcMl& H%4}ڝ./I:@j驣MuWr~Z+M91Zjh4e[uǸM+o0m=u]x⻍|7E 4rmrڄ :A@A,"b p,&(yGj:o6(B*R4:6^~S)!7sq_uDgM^oe[>9Ay@IZ{˰ 7mpݛ"rLa)xN|LΜZK,|a$n4T̸(Mqƣ:--tnvuHON*'Gb VUR-Ѳ-I<\&ˑs.J@cTF]EnVVXw3nO#@"k= Pgp0}C- (U?H \>lE]zx2p@]2pl+G`xT ZC VAʃ\|ώ/{L! @/,ȽAAޘ~fΙt>Y %~?Jix`:8mmKy\ -Yb*mB[)(o%)V%8zR̋X:,FT-^^*l27[;ψEuF5c)j'H9kSQ[a.i,tƏ9Z!sMo22$*klpō'|03u^]k*J6% ݥS W+`ڂ݂9X|`6',mqkܱ96<<Ӑ>JKZfTz ת痐 WM^ƴ*PɪF gxIEHeμ7YWfe_S9(A ;Rޱj1vV8ȷX`Ʃ)'YC>УTĵBLOm=hw2Vp8tX""釭V:V9??fesi3vw.m"pCك17k^ V&M.n?j]6AJϷc ܥ.8Jɫ0qT)ca-GL𾒀QHOgvN;x>^.L}Ϋȱs# =c2r.uLg\R5ÌӁ;6n%'6)E 9t"Xwb~d|[ x&R#MۑuPͮ 8K%*u;K6@qU\!Kyeux[_y|je}gP!# lcohyD *q\!\zb&t |!Щ?YKv!4[- 9)+\&,+Ƈ/  Nq6UyLiWtgօZySQӁ)-BE8f|[d9J\Ua lW赃e,Ug>Z3RT 7c{eS@< FO0p%aUg6"^> "x.ju%)Co(8xlpKD N3iV!憐f0:_kBV(~q1K\((_ek]"HW%"6*P%,=2:q\%Qh+[ryLzh`'ab}Hc`l6t GR֪# K^.572~iB$JUC[Ͼ0>^Q=3"̀/u5_վ">엜+AW*  2,D(ֽt/xo*&>CyBF 6 }vgEژ[j"gQRS}Y_>؊tP:Fݱ] w7s/ #+m q&qPlGsstψL0+ѭ8G BdƵ( SJXAt^ oy' N/q^Pft kS*d54;fK.!tCCG"&Y7M=`|v/ľ@}p=g=X_>p*!*R s~I"xuC*!liۏJ)NfHrjokiD%.pMDd ~R $VN{SGt9I_!sS+mK spW>.KXf#%7|tz6[uP3"X'&YzR=t s0[), |UEW!*;. v` W$° Hr2) pV+K#WB$P븹zXʕс)HnlpuXӅk<:o]<ؼm`ܿe5&TdĨ]Ցڹ0ٱ{DiiOqv]nB9>)H sI=(P? uwQ0.4[S%6`ˍ3؂%ʀjȁ@}>x1,,M@۰RLʱcR5?$ ;}PǍzΩyir{phu7fPmE.RN՗(p6lR^Rkl4.OAiJsm̨9߯f|.gΗfJϱٵҭIk3F$!a^G[kp.CAI(!_E̝tZ/o.Xp74~jKid$yc ~*F嚹(竏$x AHѮ(CCy2KBDS_66ZzŠ-&M0( s)6mY:\mj6`s=ˣNW]'݇^i}qcdsRFT#ZzK 6Tjw5s7]]GLh!N٠J#7P.0V<YϕY0 .ۃi-WM yR{` {ET( ú`_[nۮH^0fL 5)&a;1.R6OKCϫla9jYC:R6ks;+cZ׌וAբ#?IQ9O2i⾵ኝ-_pU|Pom4ރq?,'ɃGyD R&UҒk9\$BElMmI2'ѳ2LH9r>>vb\Kٮ <V5r6s|ʌ[ MDP+he9ɚ,&'7g ? d (jt&d EFT6j@Z|LBJB! b X YXM&].tP<&<_eAϦªrxf6]x*-wxӤ;Ǝ ]D%bwSuugXoq3#&@Ҟc" ^C.%04j&lf&Ǽ풎Q5@hV;@^!0>2Ws+d ę9NE̷Qu0|bm9b4 %'6$vM\$ة„=P4 %v$kM4)/8Ӎ -f._ ,iHZ jF<#zkTE 籋ܵ}f;\Q$f}e> | >'0Gx@~xPmauTLaNl:ߥ^\q|L8PQO^K5 fEliԢ;jm[('w<"o{^aLUrwRi7d~FD=#T3Xܻ4e]Yh$[YG bzJşK$:,ޤ2V ;Dp^ PLuYjP{g^Tm$8#āY#-Z?&YuMܗtѺSpqp8?O?$"cCk@cj 7u/F}{ohrZ.gvIlѡƋQFj8J];7yj_?\jd/ X6:5ȓHRˏNNe^4/ܤ*Zt>qkllB%­4b"2Pꁁr< m3{QVP~Qucf:Л RR7 60i` o-l1a,8IRG0RŇȦ3)Dr1X2Pہ7?WDI69`E _L}5^.2rJQѠ' L Ì _A"kauE@nVlZ$&CA ̍ɡ((5{*`~ HPDDnsl3;9m;3tRZ0趗Xw\<`QMlNt%.琰 #+ntse˖ |cdkoOI ' Y=5V EBU ýrۣE ל, W~ ߔ _F婚˕'ECI8>JB. P/1P3_ɟgf 9u~0 @GbO =YQCB͡x[%S>֫P+Fdt<0[x}Uޮ}jϊ9PpCCiN+W+Gd{c=E;j 9o*$ntZ.x,8U: jwk܆0X,,gPe)Psj1zΚځ :M9wtיNEҤ.}\)NEDz`E=y.U:}ҹ<;Dܸ{D*mp*>D$3ԩPB=9,1"[mV:=Ж;ʥPJ0>uz,_wŬrTwYi3`_qp;"knpip 1 8Sج-4iX:sX)I0HؐKv&:Bu#c,}~=B4.iĩ"לbTgUl91ӎ ɕ'@l5I8A(8Ir& -.opb9"ê5 L13dӆU^~]s%SMVpT>ZVʍɁ]_1B_t Gq @܀{0v}jSaA?}Yl:!˦7 3+#)~g0|Oc֡/XrMtZf<sz]V!JF`s&tE[&tr8rhd|#VerC5永_2isA9|ݸVB08B⣹Z2FגG ᓞ=N|h9RCzX_'3!*fTۧ$]j~dy?vȡO\L,㰤JT$\:*xIQoG$1+:TNGruL0&]7z[K3^x;y?`YFwWҌ 1YV.תOsd7}:7܅Y}FYY-z7JJG\6!Wt x@U@лG,. r6_:J?7;=B$%&PIWG8$ ?J)%h& '),^@a]~p>) m] q^A0l94R6~K;fh/X&XyF?Mby#Wď-C芲1OSzG[1akdOFrbu$" (DHLCˡ,Pɰk2O&Odo >]20K}\'YHŸkL>M"#Tq?CW==h ;ǰ.*T 8"JMgWΝhYDilFՎpy$x+AdU@#APPC!Nȍ@5Yz:ryv:"$5R^cf1&8*bw?/fK;d4#ڠC_"IB41O}Y șIub=h YCL Mw躷 ߱!00LwwrR~zt'sl`8M%R!羊6:XͰj?{Zx5DR#t<#AՎ66ʹLB"uFMX*B"Yxa e̱gsK•$KGAQbQHe>(7dK`^E%STTV<`l9wAYPmP6dC=R9˔34>7&#)H%߾@Ҿ/4CChV kڃ񲶚Ҽ#rr8K'`w΍d3'sؙ9=y/ df/Z2ežUn|٣5s5~D<ӷ KHxY~~-}ɰ3Jޘ5&(^s=Y:z̜,c^CަWLE4821{壶zvQ1%6X{vzo)}10=Fdp=su,HJ ՠRG]>_VYfIiM5;]O=S.rp\ȼGwV؍aG}Ell{5YxnUNSSu|78n0SV>oj{^}WS;pAE8[ј`HKoYR0/i=lcMw STPDi~iSKY=>?eMCj @j?{^;jDE2:A+G~W8ҔR9`y VPA=SlmԫU#f8<08_svgUzp[!&Z#mK߼0%I;aOȹDr9񊗘2#l gLsD_ !ped3Qs;iżsYE%sUkȸ3ą1I`(l4qVTV(S e/ܑ\^Nv H!X$f&\ Q}yhD?V;sH]L%^+KTZr3J_@Rb`K; E6uU2s(k]!F$4MHa{>!߆a W:^GՈG ,yQUaSv|)%+X@*/tKcra!-U/xO*jr+ֿl&#b J+󑧇ޛ.8z; FxV )lGVOR)tFB 0J9*w!Gj۪w?9cYB!>-C?UK_j4?^݊Y(HH^̧ɴщz`o N>!m x DS<߽bJWt>3xx5O $ـdص10 4|cՁ/%@C2ӆʨ0Kkδ88^Ѩ"o0 Pma]>=Йte y`&4 ư m{}3Պw5̔p j!FZuU5v-cF6F> Oh pIhPMJX0$30_lkWB%S Ȅ8:.HCkL,Y>HzDYGID9`@uBynSD2o$CqvMZ,/ٰk6 OJNZtn9[`Jcn)d O XDjVymb:8"1Ʌ-Q*\X 4g u),IM2(| *WXhR:#>BR: ׈@rkB /*P٦\%Č^,1'd |E V)߼NR86:=q*pRC,e:ٯ5-pf$9H,(=mq|c[i7B|ۈJO8illS1o$~aT<#K|zCZJ< QT`˛.1D^ mA('= $e97-vޮIhaJRV8> Tg&BԊ|^GuY`k hRrޜвg{Y$su2Cn Ӆ7,&byS}l9<2eB?5/YF{(4*bo-vOxgk.UłYu G=##AZyXp}$OM@3CKp>X xq7,(06H?=l taC x(]/jfg^X8ۦl AG> :DK!uҘf]Ŷ ]w5HX) %Y.cA\~WXœsEUEI#},f"'B{f cbu@'i+ >H}hjZ=썅Q=|bY2A cw$^8y(G bb23E(dlHȽYݱ꙱F+mؚ&G1JGm=ǼbqP vɇ-ѡBI+Ig};MBp!us+":f鴱j5Ý"8m q :c^Pižw[mijlOsA+gbHYVEKXfbleL[ze|`ԇ3emZYrضz6}k0K w ~Gޕ%Qq2]ww%N*zHTޛO< %oRWR ?@tF>Q:<0 ,e!x}8r^cp/7<6W{hJvF[ް omzO6\+]no]A&KAj`Pt*d vxP~P>= f]}ۘJrֱ(w3 ̺m::lYkTFUwȋa9\xu_#p5ЇJ1\5n \gC*L OW~?I[$TISNg9W~z=RaKguR@1h'jVjή6֊ i6?v 16",&?4ÞTOd T3@EzRh@]*Vv+BS\ʯ#8E1 yyך2&H[ BB`DFֲZiLdyV?㊟ ͪ }?5FBKkZwU|(A- [y\.mhCN1<@B H_ qw~Y?蹉L E>!ƁAePYUߓ:5?Zd 'W3 C-g;N@7½j͐eͣ~ь;=m~~[T d,sJ~I]m>± dhԋ#du*qU:d^ǢӿC8^7$Ρ; &c"x!e\NsũssV/ʟla;c中v2+֟J]-(_GtpL~kNgjd,Ѕv-E`e}R)YLD1D5˙9+Ѷ8͓qqhc{3~ S%2ck,H]fK־MzA2M}/u)~xBwW JJ7yEE xe4"G eT!sح0 4/n%BE/l+(ũ Vh1S`xٵ?A~|`r64>&8{nxKOFQ  ӚXdtԝzގ{ݗΊ=T\' : ;w&YnpT|Q{dОP&K*]7*}wpb+ZǺ;y1a(tL `9;f|n d``Ewq)fiˌ$ N=#b඀E DX68HHNC͆c'fـT4Kr#XIr {-z 膂.fOLz ɰs6j5ʊ,`Q~q"]|}4{$P=Jf %r`Ns6̙Q"N;~NIR[.E(nfvyc!P:)!_N-{'lOݻѧHg9VcFGW3ۼE h 2lOpQgwgn=Rg&Jqr@B Y5Q‚ 1w"ߠE9piVym9Th4,3&RtdZ^AP!< ;l 6Ɣw,WXwf[U H/>|w_lZgFPqp8&ٛr2_z~% ȅRgyiLԅ€[u$ 6np\mn/Kz]ɗO,$jXя G!rEI^)/@܇4ƗyX&K=Ge:)Lx3?T,oV m _k^lgY 3IT6a2vO$!읺}ZiU*Oh-^3?'3]ruD "La½L`Y6~b<=%%>[I&EHl_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT  ]xNz9 +qpd} f<š)-q&beإFj0Ǵ R9X S24*#d׳J1(Z=oRKJW:tJq?*.<ƣ*d5M)t!KIspp\jb4Tì Twnz~^%3ˡHɛKWc/V=G5ij QnizUHW Vh_{  P c[ zzpR1D:棘3EcQLD-]|#kq5^ō BG+Ou1(* UzݴI+^JlÄ)2jXU:"/Y/Tz_GͶ zV[ȪO~oXffC5;^$ )$U&e[Cer(xI=S"8GX~F/K -q~WMMZƼ2ެqrD+*] -s_M-wz8OsOv, g6g9dvVW0PXrk5ޮq/C~fly@SgFҊɵ!!XJAgVď']D+)0N~fv (TBu|ōbF>gl\HA#y.P/|DhY:?l(r j~?Hk8(D}Ҁ\.H7qyP1eiR蹲R4z˧*#+}ZOS0<SzP #k,@l ]^aRv'GևL@LvFۆ WA Os;f=.S b:[y!Îݙj .7G6KrnR~oD-30 3,$gD5G;((O~L-Rљφ/ז.SR ]\,M:gG-E3v `~ T߭@θnbt=ﯢk\JTq6t +}Y`2Rg 4Sz˜Ҷ7 9Pl?xRr/(0ӹi0%m!2]Vi9<ͮ5dBkE$D _Y0LB̐ny?{]]pˏ9.A(|_am1`g Yr^ 1_,jf9gP8[U2YprH'fٙւxjB'RRQ}5<1Cծ͝i)A|7جhiG:2R&ä,{Nf:4&J9f*d\^ٌ?.OxKG8 x w1 8?Ƌ6Aw"SI 1' ͌HoklV[W[ |j*Zx8Éц<0ako(dvR{ '4Y Oo.)p|{t8,Q Te ͵@y,2Hn hbdcv0-vs_D. xSkrpFK5WH#|1 &.4Aʒ^@ozʦ7Z! i tj3W8FnO4T=<!TŌ{d`[Z"Qcn0-8+!Rrԫnd7<∳!|`C܊hUjN8l`Q)w1^B_+ezaOK~TC@4 KbOrz;G  j4 OҲ!-=hdT3;J(\HNd1Od{ ,3"R2bckzخwm`m![p`!U[H%UPy="0v[y,bpp;7-#ϋl,_u*u'J~{ܯ[ _ZJ?*-q3`emJgJ\*UםsA/S]d~+2Rd)e_]Uk+ [Ƥ`y϶1 t IqԐ׃߫TWX~2?c—U-Ս%1 0}-Ij~LFr\V3#2x 0-9:rtZmHdnŧbK—3J6uy)t@w._Nc[i3Vt|M"?s]I'5$' -Y\}J, = px3eضK5XHhQM쏧h颯[) ],~HB;, /AϿ)| f"4 )vyUFD~1Gq9ٰpI|shhV;‰#% zGRC $Q{8"DZԱΒ$`îpN_)zҰ6}ES bM=rd #u9"*YHVp̽_u%E8_sc{ T:(H!֙nG^3~ شv:(e !ڲ,Ms/~n!զxyh p%|GJ =?'AuRKC$ x}Ka^FS KuSyc=\"~6$q܀s0%D?P^Fʊ`:ރ BFj[4:~Q+fy^e:H2{{6*KL߿951o޳o)A2]ڪYw]&TTء2ĎMU7"P%Qݨr\ٞM-bxF&5":-/.Ikk8u0!bNRF9ZFOԁ1bʊ`1 N?u? %m *MԄO73ک4VKcw%WZ)j$ e}V3\!%&} М`ŚJ>W׭}lr@ʌ3H\ Q=U<ɻ-Vq2$r*mpJAoV՜3 ;$_}!hV|}i[ֹ׮ο[ pVG|8la"2gZJnNVDa3y,:ND3${N]2[t~Tԅ;u P곫݇8%|2aJ ¼5Q}njjfӕ'hFg}K6-aag&~Up6ICZ0 OdwZ f+8"-*ǀW1fi!>PNWib2#>tvv(@6A.Gq&>M:eҀ~H W /tEKj) c@>?Rg l#ϯ' gh4{Į) y^ao)7DtN :>{Z:0lN(Zyil / bS{ok粰*{?ʮC0L "1t719r)A3wJ2Ivf4@@3NA7cwlޕ7W_r 9/Pl=[lMr}Axv^5]!1"֫Wk_ShπPg$^Z4;nU]^~;I)4Wf0Ԟ?Egah}uo#< i6ի  |0V>.ӡCVjuqahiZ֩q??W0De *-hhfIB1"ph-3/6k #gJFGLbzeyJ[1 vl\c~m,aa^+ ~֬@"6P֎r UYU9u#*R@6#tU0pGo J;e(E2)( x{U4I%׀XLgϷ9tTJV(6ּƣf`U4m%F(6NX=\Lҭ䍻9/Z6W% ?3ؓ?3M˴_1|g߶lfR>Б*.CIWs*3Il+(3k&ܭQ* <%. qTHL^znZ91$~RVOCS9Ȗ}tvͲ7kTo'j!w+t ,V/DX^"^,\Ϋ*ϘtywɌ]H뽌L#g~y!9D%|Gw 07嘺kmxf[Wѩ'DO8OTMK߯giI0g 1ćb+gT2,|dFymh6@a\ + ͉h6vrN& O{b&?d-ӖF9{.c/zjPTQgi#Ra/jYai)ʚMWog_J9%i;C[b8x|ؽ-|SCKJi}H'ӋZ|B^w8 xDrf4,̴'`=vDZ ]^YUp*B\6 "BoHk\ ~gM"Hotv@~~Yi$B }_M.1?v9`?ٻ. o[bWB_r2Aw}UǷ /ATH1[DZKΕl[b+]`ҕGlq9s@Vg>|_vΠbmU>~ y`r"ƨDW|hwH Mߛە"'_ݽSL);e*<|hE̢gTWGtZ$Po$ #7ݹWc( gV+w!١hVo FvdZL,&[:Q]Χ O[DV LfnJ}uߠNw6u (STp--miY5w$Vɯ. 7XԴsg|v)!GO(eN<& 9zusW65_YOmuI`k49Dm®7'+TxLlJbs21@]N*N1ӂ.Q.) ‚XE;|zrUH%scb5$5."2dz"00` t쎉,#-^0lF]p('N{>I3FM&THÔqlWk ̭WqϬ&\)q7w3}؞c[Ӏ2_WiOXMᯥEE|-޳7[\"`\(lK,^\6A}_ `YnТ(Spݎ=i0_'Ӯ~7- ªcc ܵ8q\ U`9 Cr%m=:lQT "Y/#bɥB7,(SȺa:.#x^y"/t#q뼷v$iwM_w~HMaZmr+Y{Li\U+ 7 Sl OHy;sw ݄\|5Tnq$t5|N7,( Kuun>s/|ZC]M՟CcoSSzq:VI15ذ$,tBӹk=GҞe"j.m:1 j~PFVN.%K-g{8Zn4rDa¡fjya/+bnRK}GlD b^C _Lt]W SQ Vz^$oTrBOՈW),oSzy8Cx{/5r69"Tle!﯄oDUWe!f똚|,Ǧx~^ٺkU"+YhuȝTi3 ݵg&f`P,SsCuݩӒWOF6mtKQANz{.`>0 ~qB"zRȨ]1K[hl;(AC^zZpRoyؐ <ʹ8Y[n~HNFE :h}e^Ǭ7xh"&|рG ^B8Eu7aZ Nx +CKݭźjFɑyZOy¨k1 f?4` U#Iz7Oqz\J;;\l𨾃ͦQmURaـm<(-Qau:}EJX_FrB#%5d`±Һ2UiQP'@f+ T;95s q5BݛYUU#Q7Eq: QR`3C nJ $cD9nG ewGQTl.oS %$c$_>"5wET=J&_ !/ qryc_ȟ'.TB}X;{܈%Gw ꍹZw4Jh :?@#IGg$+,(~|ϩE{(70`ꦼ)bKfM+i/_b"@4T?BMsJ1J K./w9nvZqp0ݣ`5"9OX{_Mfe mz NL=|# P`9AcLh40Rwek'!ѾKx:Oꛟ+bKV18;&Fy+m@{{pN_Ǝ>Y@>L͹Lpԅc;'.<;?~H#2Vj9JjuWWѰTfdN@W ;U>&Ee"Nj7q"8@Մ~ڛ }P:8Ǽgƶ\T~=\jR8r RSt 5ITW#2aҬp*J#gșP8.zʧ=˿%[I_ N#_ b_"؀F@{~ )bX@5}i3Κ{" }Kϖ@Ci;:ģz "" TxtɀH3 bYC!/ONPjH> 4P~YI-#>M17PdW4֎lpk'oP'w/;[;1kSHX©L +,n`! nԜƤ ; y 6pA 9a+_)5[{6I?ߘ29 6} -~V}0]w;nǗ8^On: *nYCTq9Ԏ*o"wA~qR=ҹr?Uj4.xPq ݏIC38'Vfx: sVTFJZs^؜f^ɫxwSNڣ}ْ}8 QqS{q13/lA;3v*\ZH`!qMhdY`Nci-%ǻlC Qz6 .+RO0}/h|~BY3$tqS%?*]H {r Y",\n\:6H݌V}kn7|֤vgji![/MφKC8 t)/TjhpHLz'^{M/rJ~]b$ }T/LG%+ⅨX 'qŢ֪xH;_x4k-̊flZL }'Y'ўc愈 $ڲDԗt({_+x;4Nr;"L2 e :[txf.PmϺ?wE'I 5wy*a CO3F4e+Ծ:y00`t#ukJ1Q_O?ZFd7};FG4"+^1t%uņپ "wj3h66ŁT9809Ǵ~#i㖉dӹ(Aj?Khm0B7dZËpf_.Lh#1qTuVhE9wnZu&HT LjPc}7(;(\(*΍4Uwy a+Qm/Tթ1oܠ|nķcz ( H1NR5 ,IH ')vLȸי%׳[\=0XEƪmw 8riuHR]BܧZ!9fҌ|Ry`W񛆯>|5Ba$*c3_w67J fd, g`Xd.N|֭|RӝkzAZ?*85DJ3ϻ Ey)|@W̮^ !K| \W޼ pIcCjQ!6r^Y]GIJtlfE.T&Kmq toIvq?i~#WEtLґGP%0g˥KP/hO?J};ľ#bsލJyG0}T D;g$UV= ԏ{6/TkV1/ j'hGSH& ) ǒ!Iern%L;ݍ)댞(pcr1ʮ%NOvXrRso{^O k+MV};17uW"'yK3]Б ԤfeT?9(Ey6wD]+n'*#sno|:MRAtN!8 M u>؝r,z/O!LaѴEJ׹ジ,w<8Kg,M y180u!bawC-Fe7DBL;>B=(K_oy%ݚ!&C\K>Um/EC}"jPXnYtt9S#4ݏ V D y}|T4)cVJO\4`1\ q* ;w"|;?ȷ,0Ke:°p9'JrBGӵ*n8vB z5sD@m><ѷC`eaHT-2[N뤖V0cMbgnD97 UvPn3~|wGhV+\h$/v$K5̈|NJehC(KC;_,031tGC; Mআ}rKp'_gjNQ_Cy˫nGJk3hpJvTv?]ᨏ֩sx)ĖMG'7.|qpE閝.b%oN4!xʉ'fzTs)4|bXup->RYx+qA@GvI[?f>v(IRki )n:?X+R-o↘CBD%F+b #bu&c'b>L@@uǼG_]:!WC -ͬYݻA]W90&]x=3xWA u^/0=I.r,l!]E#0]U-ػ,];.3E=6`}%5V6D8hq );Ll7r޻,,^ ??l '(T& R'wIp?8^''L5FY;Z31zyzlefE:x:rsѐ1fAQ'BGa-_ySߛUrNGFP@P p9bHy>y Ӈqb̤ߒ7?}$hN]%(v0?k:yg=xp ).l_E7bLiQ]kV3]csKyHx#vB\ʗK~͙W?̽bI\Ѹ,YgOh=[$Pk'ġ4i:4~I֝AO4I $l6{䨋)3zk _^X"=oza VlrIlzEMX'c=&tޜGn+!ws 1^o8pzeȲJaZf@J f):ɐđ֟[pTZjKNéשkzZc]JyQG7/cg&0Uk9Բ+\bڥȦ~#[C5vmd)77߉fT|M3blDҏz B[_$3>iBQ~S%0&Bl"P4. j۲8ҬnQtv}Gd%~ꡕdmƸaE$:RSl.X |x4ݴ61s0bí94U@ \qߋ,1S=;GĈ3/6XT!Ycq%v8^zX?T:i}?at? uASj$-J-1׋Gڶ` /Lh/ԘmAtu_8U %u=`'ChV l}qSN~sV:u0ARp4en> RrU dķe hn#YR"]L`c VA%X ^Un20;4r AP0tAk?aq ߦ E - UKv`&\2t=bW"\VfL ՚E/n!"/=4l6E4թ8}͆ħ;+XoϽ;JDAWGq 9ơ$ T*oyE+n9~I͂edD*|nRདHLY:+?a)4#z齕~=Έ4 rW7c/OsA+F3Qy⪩8n*bZCANAy7+UMȾp:aaL{v 8J5^p/;j͞n{F l:o_䵙k(Pb28HtuIu9b9б$-IMN>λv|R7fruG.4#8 iQVxjJ#PAv5su!j&OqPQ0[U$G째%Չ$#a_mn!?KI5]9{@l'2:CB}W߆VxTy91}t[$$xt_Xm&σ bz׻獰wIh+~W!r #]B?Ios1I5>|MbgL"Zعb0ֻx |o"KD8G0Oj+2}]1L'<@qO 9S5]WjrbN%N<"7\偊8lqK4l ];+kHUꧩ%cK:Ű>rm΂ٝMr0J_ᦞun,ne 9V NѳR>Auf-ﭞ1'D,᫈;XC!CjZXz7|w뗗G$z &\SFpzlspZO? @Ne=q3׭~k8d{|y N& p3 +)Ucs#+|bw:FY|#7[H A Kd|OnMD yEFl$zk D'Yyki=0i mB&"ܚjZOEW= NAYԲK$-7,&uA#Z~Fz!^{-XЫ@ـjOXbU{nLzaFggo8ڱvfMQ ԁl9D:5N[}J,i45֍ºM3xWeCz>q,(=cɲ N3v<\q6ն2YZR Y6G%ͤIZӊN#>HYSw'=flU*!@+=|Bl=xoϴlUhޣct%z\Be! 9 VyuIUR``}՞Ӷde lΊ;ƖDG>Q 0Y]f)MAhKȣ{3ڟ,z:w>q)!$HCCq/žcUx|9at+t25[A&)x"JAkzNݥZuk!彀2?@W%#3.ǻҼvG&-2_p_/6s p\Y *~8D%/%<%} 2㹋;,UCo=s}vbu_u4 ;ULRslBE}t/mms C>7է]]$0`qU, IKAt߆Zf4`2D"DoT1L gHl^TKt#"נ|L YCo .TZ*wly\]@Wp[ 3\9jwaL#9w&֪"%Vɐ"0Ӡ_r tTl[s ij[ЮV6yjKB^*r3-z^`:S=)8d.;'ݪ?rVv N0u#Ywڙsk;`TOb䷁Yx%nCλgB03g rbUXGܵI!vSM/:ٓزyr`1&iَ]慮7F̮DF -A#T&͢2Dt4ߪ=Z&X܆Ccdq*%_j!.Ԓ?}in }LƍIMsP;x[d|/ԽX#74-z%= Q8B_ .Mׅ&VEiO2('}J`$-xN>vM?a-e;tzS2CU7bx*X[} ejq5tz1q>,w peq!TO@V1KAE;0#r"9pjyokV(iINygol;GdO"5qCy yCEB_46NPQ6t~c:R$}υ7 'rFQv>(<n & %|߶|onjk O"x ޸X )Fc=/v1p慔a,N vw*aOfa@.Ή5x: $߸W,z GC nY1_ͩ" 0A>> zUa'D+ͬ#*td QȪve,W(]|V-NPC"$ɆG<̫e#MCuޠœNׅ r ڍJyaqU3<'ă7s|=O~m$zC=*ʹQ3}iEh'WOȎȒn^xC>jq.(lKfgRA)8>sd&\>/hv<[?ZѼZ~6B\TuY:'СsLQ(C쵨|L1oڑ5#"?NHtyi'YYRTxb΁!|cCC! tIfcDsh&+6 F?9ٝXGtsS{IeŸOY/O~~P(Έ;R!p13BqY9_lEonI901E~|8-VӨ."ɽ}>_*z6rOePmIȧ^ȗ.pk10Q}k錍%V>EWxpOErɷ2SKЃx&ǻ)0d[Z*_v~_-1ހÔ1|e:oY'h#r>(U nKۧSnlO&NF샆Tjw֬Be K7KFSG1"7-]L~(H1,:z-`ɖJݭ 4IJ^x}j@1q|]쇍*0)WFPv(f̴'+&)BL\BhAeY&~~=؝o(9dp &zb! גZU؈ҨAG2ĆhoO@eu*`yy:!HA|oJ.J;+ƭuv^O3ƚه{sBT.Ehi"[qojW^c 4[||HaZ֖f/¶P{c7NIMf<,zjJXgbu^hfKkg >(/Lzdy&CB+lmȆ&:Mrtn^)$)Ub9ŵ^ j)TQku ݴC!H- 8y9bc^e|A)SisӚ')3EnmM">TL|05HHCvd,?ĪZoxM%$ݝ ɑ1coҟHy0`$(#Wv+$Grq{P[)%h;:/YP|z! 5hؚ3DzpK΂UefO~(찘3 3H۔ wkDHq˵OMQSx@ybnEcƙˊ-8U6+tO$,{ꡈC;*xPVATxǶEeTTD d#ϑ'vQX,5tGd\=ΌÊ=Ѩ𢁻(+^D3D? 䗬q.@=,E7tH8(F\&&&#pMܧ$ u]vcz>H " 76Sh'⑽':CZ^9UH4ӽ݇UF921ܰxV~nszc+fR``K7AT(3Dhj.t ^?A"Q"0BAۢATqEXEE:l7+_TpjE B3}&QU$ފQK $C "VVyV=}'$(z F)uS gfՓQ*_?sŐjPCOL}z `T9kapѬa,4\XD竐pD\n̢lm#F`lL$y4n\]^уŐ}rjboTG8$Şַ-p}Cħb|zICaeT'a e-o(w'e" $>Cbx<j(SH*L)Gs`HKv\OfqjPz}t"(ǔZ1F=Օ7W637{' Dg;aJd^_uCUn%Ap'tQg6EA\Fx7ɅDFaKz B~|>Zyj k[fcꘐK>5h* ՓS 'Uu~{%s a:Kvk=7yEnZZHX(NEn1 9pGB#(R.\n|9:~m!Vr3i9 i!?a[_l @G̮ ? T`ӛslɄCx(;;SMI A9Bh!TZ] WU'MGE*1¿軠C[a4jp`8P@Dg3Gb[{ [_Fh'U,_)*IrYK53F@.FaXwh?'C]yQ7$A;Azf>OD>,!,Nf F&DFz48z;Gȡ%TVňG{[݁ښ_'GI19I|J}=.!3^ M}Zlt3{`=rv]ҮpA# Zs0VEzzFvdcl gfԠ^2I~0ԻcL*>~ 6VV},-{N0[ŢoGGDž=?5΢0+w^>`㋽[*S\ (E_sɛ X,W=yP ,d ~h0W>kyKƔHh:- ˽ܢqGfRSgd(?M%bV\a['˕ i Fҹ-:q7vs~"tBwf Z8ԗZ L5jt]q1rFuT`k(5rB\7 ~MF?UCov ۺ Z붾V{3YV@s ola_߽F!7 K|=U$46*_R:.ݕ쨛Sg|[?;p(ha>g,b^8G,tUxLE?DN*}y&Au%/V0 |*B;+#$@`X%73AwuR`P>+>#dɜU: M@{"w@a+\z ESP3_˷ճ8л= 99& _|)- }u7 B_Rwx/B;9ukw,e.2X?|8M{HLŷ\Oyӟ-h2ַKk9mA}{{LU[ ,AI:z!x `Ff]k;[Z̔>vٲ_ &#FAgַ!M_谰=T kB`?4:!4@$)\ MɷnԺ}=˕z_y|Dt M^@詒oVI`Jsw%Q Zvտa#`SL۞4Wz؍Qp4?U^ź v6c,h]]b+p\ŔMc&ב3j0c{!ngf~NTٚ@c7\2Sǭv5Jps{ۥBMh^(ng,w?7?\*ʂl.F\_ ?R2f(,6C@А 0pxR'sܹt>" DY}[}S}t*xX]cb".E^jnY:>1m U*&ִN!ﱦzZiN=ŧЇ]*GL}S:6&NG.m_Qɥ0"rS&9^ }¢M3̠!-AX8.A3ܫ6PӗI An7`=:z?0\1Q?*jkn.k[̎N$,NMXM|ڎ)Ig@ ] (溇GW>>e-;7EV SE]x8N $ϔ[Pӫ_%_oe}Qt.TЖ C2ɘU3p:yv/`$~N2V, V^Ζ^i6nC 8VoW@+`Zhƽ#xyGeBz$xoX4d0L*kf\hQ̂3/#}GCQ|/0yuǕ M*5<Y޳KACQ0`oo㫊ToL՞_nׯHSGO5Oc_tn렾-U5wAanYEpN}1#J޽ܬMA9`▬`rNߧk~pէ} cu=k<+n,VsʭH D/,]O*%v=h!de%Re_ v:IQ='r*ڭxM]=Hw u 8V$,%?sUL(Xy,>Ub}eujVe$K*/i0 rxe')[⪏%7׮aYC;b9gzifړz56]٩k>X Zh?ɊiZTQMk135{M( E~ </B+Pj1Ecp3ӽm!i$b8*^K>4R iZDfgRh,}l@6Ė*.0 ,|.<zbc'}yeS4˘m W8Xe~&ðNc`< tè !pϹ6|AȺ"t>?#/'n] 5)$&N+7?ʳC_#m,-Qb@UDqjKnx2Qq.Fvg}BO*H1D3j_x?~DDvD'|P$~Fk -Hu+>te_oLdKe>µVnm[<@i }`dCY'zp6RɻӶ_NwFYV2~Aw ;ك΋ӨR9:cp7mw*9~|m1~c\)R %6hVL*ʏGT7eLx??e'2;rct8(MV!2#xoև= R 2? K: i1$!R^<-oTh5\Ĵwj bc_!LXePTwwuw[C@=zmbvP{m+huj_he)EmQ

76X;k`QP^ϢUhc˟ /eSK"V g#j._, !kul9zq&/?>[M -o3+/Y&@4X:*h\ ϖpN&9A0s?R ^`*.8@ ΚÕeԜ4T'"7 wڀX [ C;lp hV2B bQ,d *2vOeGW Xk5nP_ `2 7A-e_ ƈhiAE_Ǜo3CK$[ +-Рukл/-lm]Ch$L;,qjIbr# S}s0NBspW`{n-E~}2r=$"afh_$*ӫ$lhTk[(/\[ rj[b'h<嶘K +/Rv3݆p*źqIv8B &6dgơtK;|Kq$ g=aDSnd] V;sfhrVop uFöVU}3|uJISN AҳêMGpCzEM:Sv 3._|h>+c%۸U@ bj:[3&x_qh-]ђwQ V;VcdL6[%" Aj'Z=N~8Mp  ctVeB0(v-Tt:F%44\B!,a?H^q̍Iڏr/lԿM[uRӜg[;w!M4й&s{0M8wr~ELGdj EmR-c/䣝 ̼}f11r GdD d=XK;a9x1Wǽ\W.u/(R9 CRgr5jta ,gO-/v7&~J_kXS$ދJ6z)bwfؽiCy^ `G/l')4v^QsTps ʨ/0}&\86,Z8.esikWq]RQ 04GK+o{YHA6 k5Eok0s:&fjBHW_F=*Cٹ%*].pQxNn7o_5pkյTaAk1J344C$U(_,䔿Oqm)W\*z*2.I%ϵ@u/XG/>꽔sTw`1AwUWbM?Șvk{֤dAp=Va2!"h(EqB|Es*-<6qK>hO{Krz{`8CK"[sף=x`ho=BW\.5|ɂ3I\(bϥ6&Q3o~Ʃaj-yLHBTB]-Ua_.F%~BUr5{́ܓ`ʠUo<ۀϕGk6UKZU3ݵVr(h%!a! @SD3(NISYIRe϶1H xj uf} n9jJ=.4uGJjT? )L@^ڠ"ߏ#^;3jISCŏQ>4r9"Zȭ$d +B-g.oMI']5_D*X F4< |:I^>0!b#4ī,h-F%ܻ8SoG/iRpla J()8٥?AtS8p>zڝ|a" icilˊi1 7" %@:#Ȥ!Mk8#Zd*+5]I9{ZwA;~*#[@푗m8.{7^ f€ܢ 3D;A|-Iza1f'! OҁU \R3-_[CffC}it#9O$4<&{7$ [&2~,z1; CTj14tb| Cƛ@RR)-uda*pO2?$ثV [rf= %s76l\!Ux)h\Xtl l[Ѯ|q"F54+Th@Ai" tVPs <,@:k7v&J`AxJe$HI74pTZg|4dz_/ۢ-w|f+}9?gb{u"@K ܍FiJ!n@3*ߴhGTR{Q5(A-1cjAzYz%KUU>*ʵ^p525|87v"_K@d0Z`u}ǚxW~F+)LA I0Бq5ˋjDQp73ĿYBwm5`Dp H₼iV%W5Ӌ)kcK&qYbJBTϿFR\qK01}YJ8ںYo+oo0vFY'21&bfxMA.g8.;a.^ag|(kZEk6T,߮3Ucgczxmΰydt]28 XSm5WE#S.rS-iS1j!%3/p,)ȊRtr{pG]@<"#:1uA_b[H,Ok5ܤN/7AWݶS@wKs0IY@ė%MR,wVbdx.A?ώ, =, sLyX`Y.5踻j[J>mYDb4$C/=T0pOOW+鉯 @#YTJm6,I9TQ[^VFƞS#xԶoBp}W)o$?LI-7b4t98JyMe'#;G&y-M4._ĠaMDK+lLhZ IV-LAuNZ be]*XaZҹM4Tu}F\ND c0>,_ŀ;#!Yh:k"n4kӉCƚV$O 8$ .q꽦d=F\z#kő[ /{cL 4+B-_~-粚~X3#V7Kě̇p ómyS7g4R.mlxNy +{69'`]D"a(0 wQpgҒu;0hNYUٖ7Chr});,O1{?АT4^_ t-|:Gk!DTAu:͌UVSז^Qjx_\'[ GJJoع n4=f> !e.tM4HÃgDDWKz+֠*l蝮/8FĄ}N]F~ocNB# ck31{@hK͗O$<׊L,ﯗöZtEȋi4/Wf9Z\.4S;~hO DJ,X1Y#R=K+)5ZGL_/!|Lktqt3p[M̭nc`ѐ&>0uz3 FVBj$3w֨`P!7_3OާnВґIZ*-g&&x}1zcnqéD ȨQzBD0kL37#'xC$&2N)x,*:IxlIc#[~J\qFk:vI+8'থx ͫkFtHI~Vm;B]I [mYF_|"9'W\bT-#{{ާc}V:'[#6!clQo0NJ훶"]QlUjY8'>x㉐W^kjFܺ&ODSX#}v3iOg Xeja__0Oh{XrɇX4M(ikA\"uy 4%yQ _Yt1bc #_&؉DͲV>=YrӟLq/KtiOg)y|3{uaoG*Raf|3ۍhH߾(d賞ofM6j_9sXDB#JƤ:6 C) - Ўۤb4/0C^]~N(FF[D#K?nDH}Klʉ8][b"i{=^пTC!.lXj!\ӒjQ}?(*kڨͨ^ _Vs<#I\6`vG4)ab4iZP̫Mo/POw v8ŒOk~Lj7|5\Nd&Sn%ʤiV&`@gƒX/8Vjr\F9> /low9NژH]Qah}q !`Ђ;(<$Nl8֠4;;[ &Dkk^ttUld?]6."iXٳg^h 5~Xijh]XnA2bG`xWqg(nk_Qm#8MMiXkzd =2`Q F҅ : A$u{o Y|wsRI_K5 3ؚԾx5B%TB>F#n+z;o5TÈlp!s矃*N91IJJv861&6#i azc๭"ͰƦs;e'~q &Mv Q ]}ct'rZ:2f?* -QJPtͤ"o&Uk? M;g*7Ի(ɨ(&$ j ߣA~?zˬ1-H %)j;vzM:ArYݪ xHEw0C[ςDBSOg.BȸU7x^ƨx܌P$2r`=>zki<u3"> Gx˒A{I[b3W2f*Z_}I{5 .~:0F1a#hNsdmп@*1]qcUߣB_2͸@~n1_gԀr~gw}ʊkUan:ϵj@C~DE!wuFU5kW }[൯|BN$Zs+o }dp84>Z 6k jfD``xySԯ9T mX-A'Vl.c9"/̆$A^!!$k ]YvWdcBbG *^ZpڳPi F*Q>)E>D8?)10Ь4#'Y3Zn{.)"*@rQf y*F< >PmB rդ. Ťlɭ7{fTmuD4Hخ|[3rW4eHrhs+R⠪WqŵP3Ya}'_o7`$5xmǁUs=զ%ٕP޺3\K}npny#cMr\lMqx{* ?{$5v6vHީLi]6j! L^.GP!I*pzz697n鲅'@|)lێynP+@H߹NYp/V9Ŭ .ȍ[SoWf `.v5!τFmMFGtGf~8q$3;G &q4u7Fi}ٳCu ÃkXK1)N Pphi[d˽NNiooOilIm[6Oܙ_ ⨙l'#@[]D=GKg`i@)tH0g{<I?C7D 'c<s3w9ʹIT;/7\B/8YJ4QnB wq#&J^ޠd+-tذiQ=:FB6޶~iZ>74= v.kbG1K]XٺX  <+\]yji3\W&+3>tԇB7#޻mI8u"^Wr=u3M)ݘQ *\$L|(eǡAN#E**Yv2odIYh9-BA*6w(6 {QS)ihsnF{yr .?;V ^HwV5X 8{D|Q2HG_vWeUҜ+Pw-ֱ^HY7簇לh-{0˫T?zv!"-&GCFMaGj3m$bX)̾`Uz!N;lWX;\F(& @{OaŝݬD"~p.=.ifA\'Z%3/= yﬕV3\qsUCAD=ޭab4X_"G9~cIK]H|MzeJٗaYE\ ⊂Z;Eo7ɶXGǚ +< ڄ!6d_n'((?m65&,^|*I[g}Q~,W^`VnOçDD<{WP{]$FB%Dd6XE:nq);S/-U#i(č[껅3EOp]S9|6q8[뛨k$.FV22z0^Wm֙6x}%Q1aj DioZm&ֿPE(p+24⚦ϒ>5 7y_)ם΃EQzp:±T/@c7l0-_٢WT34$TYGQmk3x~L.텊;4emRJRLrӯD5$Lw@V2SZawvgx;WHp3?.>KX5sTn>Eoe Z-T 7E=z+ 4]Ϭ&b+;-Ajf}óة85ϘBw[xRtoV_@>_e4e1WPR4^=ZD&e(J%urvs[|x1,9L#D'sYG:A/*"1)z! -Y+{F@D;M;D&mMR~џ>3#ŬJ%J,v&hwuʴU* tU Ej|OIʬ J3c`Zogi FjK+ =w{c{֞:uۋ)`]!iP =̯ZhA7Q5=vW b$s=oG!sֲsf_iF[OYk*ŨJ_吹/^Q*;D$6f:ba4'(uDe7x/)/it\/-6˴.ZNzDa021Gc3 N'|9>0~ԍ`OvmĞGܭI-+bpJcQN-H-줊wyfy!Qg-p+ Kxg+MP@m\KqY]]q BGv0<}ެ0rPv{@SCuPv pGg,\?I0שʘy.*"48I\tu<Mɻa8ڡ~3v\ >󺲗hsۺ Wai@z!bg&VeEQJx|ZAQz!'j$|inKoscb_T1}XTZ*4D;4dFktTE=Q245Mhy*eIH,':2m g3v"uƄ/ òb5ʽϾA:Siëq#{0onܒ*/jW2# u>ڗdӓ#yҨzKf|tf/a)XK"D*z_y:+%nO֥)u 0tGA+{?V<ܥDL3 VPoecۨ7n#nD6 rrE6lWx!J=}\0}$fIWFq8q3,sɺnPM@Z{z] 0G]Qq&!$! ra3-wqB,tr 9@(l{$Y]G[8m3iHs>|*IG=y1H9NĈG(Kiy~i `ST$r^QK.f os""P…[+T+kzDxUo%X4b;hb'?hO+rI\4yX2Y\vYoWӊ󵜋>ݏㆅa{>nNٽ#shAtcavvVm2 IHr+*F7^0ļ߻gIlQ >b 5[RVellR,;ꉷG +f5IСa``w^Xĕ,7*ɀAIX(Gzk~u8\RgClzg)J'UfܴzCz$5[Gһ̠~-fԹȡ唥/͝k{ZZ w:f0ym~q&r tlD*?avJxyi9M_0 C2 rٟUzhH3i)5; !m\I8 k|"Qfi^yRFQܽ rG% Ȇ 5Wh3+#RJS@pnF0?᦮9sP7wM]Hh9(چƶzRױqi)- :syȍ=B[4#25U,'ů@h7%mTN}]/ÅUKɥ2ѭ.ZUn8hnW,āfxqa񓿝4@j'nZhDH\s;sڜ nCŻauTUitܴ^akˁIlA3"trW,eQ[w00VƯ!T}sKŗr1 $0zű}R/ݚ,n7/aH1uD˻vbRwȂ]$\LVWSWÆFW0# YbnV>+'oфR}nKw&Qq_5$]E9ߎ:9scdv c塌/c!u Y~5@9'z~5 S#)UV%$x{S_c3 P*ɨP IpƣhK{5j 4OK`VC/F7f~&̪X(k;'VqV'qsANv*-=]TVe)_ugUy;y&1 }/05}o7"wsuyӥeQҎ3%HgA3}]8F=l> W J:^C\ӖS2.5e1HtpzPJ" \=w0R'Xc]cC#{^K8Svugo7Og;u4N.  :1(7QE^N.|hN]lc^"Y=K9H-3斊lJj@_~yƕB1i/)pюɣͳ3OR~4ъMzc햒-eem13 ~|0o3:eˠEcK3?L)h nc&W:^x+Is ~&xS IС\f?T ciTBXOΉ5/e < ;b4~ Ղ+3>!~ձP ٗfheb۵ҟ>7,I)ݝjxΜdANh,8J|SL1/F_`PW;S,.L@de,&`$ky˹8YigCbۡ6`dN<hv /֭g6, @_, jk_7`S-Pwaї#엒@ )*V }<ݕMB&z [W9i&PYh ơмQJ)ex:if`~)bf_K>QS؆Ȃ u+/S؞z.:!$>`^|ς<)_Av'sqPḱlxBZd' ?0CiYqq)luZl;cc*Jk#ۛP`v/41w(+3'64YR9Kq\ @B7J0Nd6~>NNf zKD-,鷬 !EBrd9B{ 跊H!G}UwUpZ3&f q9{vqi>d>^rTa)Ay~k8FfQ1I cR' HaOYr!3E*ݐ Ǥ=ʥ>-r4E2@L/B[I[``5O./"1q6s6^? "<AIR묖x6ϐ"uV;HqAʛ*rlOH΢ms7)jڠ'S~jη-iTj?@_Aj1PmQ'Zz "?o׶ Gu8*0+hQګC~xS [@ǜq 3%}Й4&Fy׌z%5mv:&)#DAǤ1r,ٱM-7W(+H;sÀ%@+2c?kОVqd!@U<@rHTLt6EMgxT7?۷+D| {'O{iea+z˸ڜ\W&-P0+&/?)ǖuh?O\uoq,ِMCn))oYv LOUzaDf,^W&WR{RR0nl?5St'!9i憐q"_V#`$ *Ms.Ue^G(ԱCqcG70I~~bft~;,66b[M]?x.x#鸗G\FYGӤ}ȿuysin"(@rnͤ՛EI Cu\69H~ ;tC\[T}vC[uνH⛞OSR !|BGlM.K9lC[ڔOrtU$Jľl6+"яª^#._&LYG3|:'@ E*-tYDI^~889A_4v[$QtKB狛 ˆLTU *~6\T鹢\jVP`>|7qOqxdejm6GWNW+Fnv FKfqO:!AjV^zO{#JkMQ qViyWW; y9[P刦WX$̏lͿvDvGuAzQS Sk[?cxt\?!MF[SĆ=.$5a>M15xB[4L&'flWR+>bJWKgZDZ~'dPr*ZKb4R^ە* $AdA1hEy&NJFǶIX۵|q.qHВPC9T !: w #+ݖ0hum{02%U8 4:j/d2VϠ?XFyLW_A1Ƀgڷ)5٤AR%>-I?}CCCg'a,U0: %,uPxu{[%1+.PpL4I c'Rn#&tV)JFMP|k^nkk1= hՙ˯`ZTӫg;u+<B#$#F1?"Q.huLϮV4ua3nCކhreX!򝼅7-oةFPr6r[_AMڮQO&-֯ ýAXU(fɄ~NOT*HidwP w~m0@TAH{jHF\*eL;nK Bf\X k4q]ˈ.)!:)- =)TUѬaNKlvX\P/r,VhINFtb(佃F{ZU^Ǔ)ĕ, I{ydo9lϪ3t=Vu븬t $,Zۓ]cUbR L68ꔞjǴFHs2ckޣl2VʠwD;hμB 4 0Eר|\^Z?`t%i춣\6)|Rŀ𺬃l~b!yPiq"C|}+ >s1KuJ}Cq&8ԙb?;m,&‚C:#~U.а#%nn\Gܫp0e^EaR݁;M%}}?MSU[hvh*fi24dE7t\_Askd\[^J"zjm3zl,?2NA8z'68e2[#Oy a9ǧEthn}p~4heRra}iYIwq%nB1X T$>ElF8nG F힇 [HpF:qA=MHA Eh U%~yo-ٟUӰ;؞ѼP=0Ԕ o `JT0~?d_U0jU䅏lߙA#^ԧcY'jAV%kaͬiDhQ=lHt}"Er7@jE5Y.(Tr(&ˀAk@Z%f BHץo>ڟhZ0TSs`0IfaAm_[UGwMpN4{.W[ zxFk^ 5HW):ƥ(:{]-`>uf^;:i⭫y |QB y5r>Z͔N 1V,k:IP[|=c`M:ֹ=b =:Mi%߮TfA5/8{m8pʐ%j](K(=1A,A8/ E: pubֱS;.OF*=,6+84ĺڮ-!eA xR *yPSJ);(p KwxY7sf&5Q;oGMeblA5hMn5M$d\`MZ.| iޱs_n?X gy~ l3qKTl#M'o{Jܕ1Sd1 +Q3n{kg߰Q/3f1:WHB_كp%i:пݴLG7)V;E>zA`a*綞Ծ%/ Y ި@D D-IeHJQBtQ&OE9- $5JxuĴE){|L af-6_z갾ˁDF[?>"LvϢys!q9϶+Nmqoɗ'~΍ JRoq@{ ;%E"ؙ [%cf۟fj B~k[ea 珀;m0g[E}_ TB/T1 GS"+1:i3-:JQMDXky8QoLt縒;SBT(pO|%Dۛ!OYkAxI9+ƫ%?˃&ypEgNUgM8VD3 Kzq=.Pqk{!*$7K܆ 4YjŶ;>fJޝӟ/ cMQDZDor,0n M9}U_ONr+13XÀS]9+L=T|H6>s >NfM?OAyU>呇ᯮZ~!ZewRP@\nf\<+k!ua~r8vc-8q O"G[A?.o3C)jw=GnGS5[Ō3V;"A:K:Q ,!@-@̀c5?vK` DnJiIb\uxXt {Wԟ,K/rW m ?WOUՋ<) Mʌ2Ε#-UeGYVـs1GvsOo9J#glr%2ZISHEHtE8 "=|,{nGD1O0gr4(ם'a{uGB -^hUa kAj.^Qy>'|Zz* B;hĶ=tf.N;"5ZOiy_cZm$7V2uYTɵqBꝬh[y۳}[6;j"-b(Yb L Ke.,ɩ*̕##K@0Qxs89QyF0V{)efgL jGl5+>BiL譕%tNHTH62 2>7֥kTNO[@R"-ˉm8%7xut@}ne Ƥ1fvW6o _gPqݺ/f@a@dA*W *25L]6lQjgUqy\[qͫa^<`͘{c'Z`0Ǿ6ИEewoo *sN}~ !w[s5(.-#gLVݏdDMmѴZZ4e`5 ƃ! кa5BIhAa !C*pE/ *]9L"Q1rflGyRh nW@ V!Swk=96i䳰>/.`/oU`^M轾&$ubk񠎍ZM\U˓@-aϞcm|#vc+`GMtb%~t#Ws/7Q!M^ ;>^A{t̢Y]G/oHcKsAҘ{ ܟr}NJf ~$& qVI9>~HXϽ0VD Lt:1fz( R[!YI3 XuqP2-<Y;n(^Ts{E\Jl5GB+C_ kP]Hw-G$Ի?F˶a*T[śЯ.TP .Pzd#rDB);e3)CcWx[jlY~5WjĝglyC 3G;M6㭠K꼝g<$~E;]>t>[Z?3S_'c7S;re"q=ϭjwaQ4+RоtV!Fa— n{)HKӞNozh8b!LK. $ /vQZ,3^"A/2io=$ U(9h9(K 7D37A,W=٦鬠q:8L's}"U`ԊjWV`b61)/;hȷ LĊз^kX8*1# K!F\9mQKm~SpG+ Q=j^ghhbh+JTt/,vx?(0Y/Tx ]߉ չt^crV~CH7 ,j.9U4>㝱hLJNY\Df^{]9tX/4lUлx<+{J33mQ]Wl̀[elFtnܕ&N[٤v zNRo}-r~ UwZ1i|( 0U CQܸ@FZf Nk8n2eݴlj)|o 5!1/cTFfm\]kF@T9DŜ½-l*l0i)-PGI>mlw'MLO g/v{ } 08mbsllNМYS,~ԌY{8vH8J:qYF2ZyykQ 6vv$M}LsP%@ixznchj 7vc b7P{nJNU&?BW}tcBjQ^<1RϭƮP@2 V9.@lJd&"|u,zu2P܄5cS'%ucn!oB|D5A3s komx=@Lh-Bg~G[Rъl mgf峚V괉MKω''oǓE cEћ흟)1H]Su'NxF76UzOg[Nz7BӜo( BZ^݅dQKp_ 3LA\O[[![X[Tp`=&(QF #m_o];udCa1٦ Au?^ox);&ĶbيE8Fb yvfRWQMnZ1~ɤZ5 \Hl7tQx=A~!8\УT? -QT>roUPgpzh* xS;'h΁Tî] )KVBdž_aj9Gǭj/h Aڿ\p|e"+W ,~Đ$=derNªfEt{%]vV9f5J .օ ^њ\_Yo0*oDNM2emav]jQ~gײ \7_r[obKzpW %^OmKf۹- ,S~JCYw桬%a]DDe$gR~= -N0)C;05Hdh9jw124Q%+ZhPY{4͝ZN`r鋧$h-GwtdۤTRtn:m ꛔn-{=x^frƄޥEk3 `@}&^eV!q *8Z)g^Z}ZkO^S|9\lOIkq+$ fB}ȉr5uxۿmMp_@hwLa{I1slzfH\ W:7Tymbb`[ua\8X$<q$ȥq8Ȯ|zp `R^SKDvN6ҥ6([ߗ4:'͂/&VEkzxX4u樦tF4@bԵsSh  Q])~(Aز)?}ĩ\WSy͑#җYe[|2JTJK$j׏ke+{4gP) ~U/?V\pE9):|^!l ]:'M,vy:\ok覧sgt\Uw> Jj+3fBh\5.ã$)P e[؛*bTmV)2ԧעh"K*uNș熅Fot/~nY/Ph]9Tʖ6@ :2F?ᖠS}:|T@1ƶTve*Wɑo^g'7%GpѥmtmlmU[j$\vBو3vE+"Ϸ"I|~?ѧa'h9zP+@d7(إ.U~AyT Ķ` O˝X*Ԃ5P\E_Οy;c=; .̕2 QkxvQ+eq}-gOâX5U8V2&pH9n&,%XR{MWDS <E{QXdn($ CEYRJELvl`]3_xIOұȩJSr^Ώl~ hA$c# eTPt&`澨ûtvuL~QojhN;͚_z3d!mTs.fB{W/>5jŘJ's(`QMr$U,HW{`X[AзbL@Jm t;$f|W$`v r_nd avR1FSP,|KOi;7VP P,筍f*E2kbSTh&"c]^mˎgH 鞐'AUK=TX\u.Ge֔@UYUmUgx8ۅJoiync+;tلox>6DL#ބ7q0WeKh8p=M gd%.rIx4IoJO,9#}G-Ha)- .+[4|ೈ?_ jor+K*J)P  3co Sq3 y nz!17Fo_tR,ڤJD*1Gq 1 e& T;}Cy`Uv`;Dl!l͆# ~Z.IM#^ӪJd06S㋴l܎OOo+HWpUL+nmA Fܭ_u$a^Yɔ޳f`G X+wOH7@ H Dg15xl9a}v+*EL aܩ4%A͆M-ԬONK6|~UM6E{~"LlRN!dTTð{VUxA"l3fYk9!a 0PR ̚:kc;Dɰ))s% ԠEA'1mO=eQe 1DYSsO{Č3m{ޓ$xR5tg nX4sPf; ed<>؆q5-o咡_3A{ \ޟKX\3FhE,5ӓ;ϧOG\CJI^4MTUlh$d9~'>5-:UǭmWejn&Jj$((=Z+A6xC:LY$' <}-,n~ 1r8R)>kϧ2PS# FAL0wE?3Ekv-og.gPVRŽ4\[9io1ofPoSo>(sӇ\CR.ZưIz\GD<[ٺZc$ml/Vdž(Yl&2(8 J)2;BH?L o{L+`]&)c>C:͖Oy |(S/a}Yv/F\yzghg}"ilfx{v5k"Na1YyLQR bgXm +B>I}S`̝9ِy\h˻RbS\/=.)BU&_FGDG.\IZTl%Ek}65l6TxU Dy]H}_oem1 7.d$PEj;R[t | 舖ݿR{SMCjlgJ;@QlexNUzC7J=aR 0>m%o، *Ӕ ~ B"#NzϢh*ꠗKe'-4GnBERMp0'!/]\zZ j?#~ YOETXf'2.:(z(G9sv F؝SʃR^P>i:$ 7uT4 5X> ^x*b"/翺UAKh??󒳝Hj0\RU=˺ퟀ\VN0G.L/q1pn uOU>rb%)xBw b='u&̅pgp܇BV2ʲ3 t'4PBl9qޥspҷV(C=׼&-}"wH4+0/j8 db I$ڣX'T5%GkͧJ6l+ykM{zKx] l=ŕEcZCC~Xcҧh+m$Xۙf((/:m5ux'yZE3ȓErԠߪ>븁dfCc"ZǑ;ױEF6]$J@ 5Ya@t[D{лEF];bO٠jY̓=<sρ|ȎBIIIf3' 2LȤITjB;o2'Y5dMrDz;T1RLg}||hw4jBȼv{M7pz(. 7 ݦ :('| \e@6wTgnD 9*i?tIVW0J^0y٦Mh_L%[ ~q +g;NwE#n}y&r4 Sɂ BgqGAp1J7캡-ɈAmxH #(!x&аoۊ3cߌ1w:M \{TlmlJxkVѫ&0]  #<0DJٲƇS ]z?032R]ׂMM`dI>XerG{%+HKR̭:Q R)kՐh=T$wי>!lصΏG3Ɔ_bU-ks62 ek \ŧʾ6byp39ce{BY]gfUc"p0=ƄIU^nO IQG'lю!la;nz`6ɇlܠփyn)9h4K&'+s{ocn-ܫ!km,-jJHޭۿf^n'3l1f\U~FKԂ (-.Z*PZ6zKx[X[be87Υ5v(SJz8j7F?ImM2@}TAu/7TDgŸdKF8S@gsErA@;kYDt>`z[bgE8>װ^oJ9޲ЁZGS>HUH3{ô >"b.[u݊t{]T?a0+1ˤ[/Du 103;%\kɛ)8:E4[z$si&oJ܋!'p#(}G"nCH$P<: !q@O"[u=1_P>DF=mHz" 'Ǝ[E D#eM~Uڛ=i/oE枱$TO͜Q(BbKTf'P}K& N9~3+Dmխ;z`m$M6e8w @դ3٪3;㦐|WG6 2x1-cj}:IrP!DVyޱ')u#K, -Z,Α*T62LX D˱ s$#ʟAy1@#?yyJ\sg r$AL#P:=d%ôӭvubڐj"E-~@0b:=s4^J(,zdEȷŠYdZDFLzXk 5LuSvT ,l& k$ 1_:8[.Ƒ+z?ԇD901M*\MHu%pVb$#N\ϲTSfɭF6_//^-ܒ EOD)_*G\YLj @k[e9:S㡌䴩|DERckg^co:-(Y~]z|cmZ209Sv:+"JZxٌ8IDMy ShodPH:!Rˑhe=`$šQ7C;'5'q{{ GN(lgzʧ{(/-aK8jz=ɤZ u\T5wvfY܁H+S$/}- ^UW^<[[ u(};kEdmKE ]՜\yěcYǓp}q\܆B9WR>s qU~#%i6Nڬ%+ːLx.CzeN+R 7Rr qۺsoeELb6M>rSV1g,4+8ߙ-f94x /SuXI m!޶*/ϑJ3!?^,Z:ZD51[T52֑a&

"J1O]`n`P Cn~X~"]){x ЯZGl$`7 z h2<Ѧp7yx,߈ An0(z*fDˏX '&_ʠ#Y ,H**m^h5 Փ4KH뚷 DkCAhYnǮ cAoMtc?X< uMɰx "!dQ]>ɚ[4yg8YLSJ*Aa'|u0"HVBXLѤrP r"z?Cέiף)1a稚# Ҫa̯ ecEhMFND}*BYoYcPTV$w3 <()8= vO ȭ"BS o{1i js[Zao]9bh₈!:fvtN~$3&_hoDhɜ3(3 9BcVPa!͂hNW3PF|Fk {%Udž$tA^xhhl5%XG$=*qC> d8Qq6 fc웗{4:O5dRp{!pإo ޏq|*4A b0R1v_E杏N\ ʁRz:&j'飯F桿KdP/%d-68SPmS1qHt\[,{PZ3|;3IJlaؿ97D* Xn$jiqqCVim8_!s\d-$ikem .S8@Eh&ֲ]Tu(?Lʀi9kϫ-⍹+i df7(z]GcG>č :ЇYk0MyGYʴqdwXZTg2"%-fhfi`w zW,!؅!P +X^nlԿ8"WSn?rC7 ]:G@&N+[$*߱Y Սwwi[LhvXt)0ߋ{kZR.oH0rr~gg/--H1o |-TR3\li/%nq=5MntrVl8Ԟ؉tFN$3MqUJ҉"$BL# ;ˈ'- oZ (%`I"k6HLF$Xv{r$G%YyaL-"~>L^˄d{ڠ&9"SeZF_Z /=23+[#@R8ŧ\\#6$y*۱ck?T9; P~|<.Wy֥ϓ+a4LT}ǒi%O0{e%DZ&ﰼhN!:cŮ34NzqSm@£>uKlխvKBmaDi oqt(ReuM?M ܻie頯pUKgm&SvP.N$pY'~eM Jɚ`qyWu g &ӛ_z6 4&CW]52d}k'E@|gZ6td +QN94bVyd@ki(M:7qQpF,|E:lkq.4 4kj (51ɕU[ൈTEVB/?/w]zY>_(ZS'3WW^>Ӥ`]V%:RDKbMG.V/r2:ܧIB{qN"$?N" RwU%p_BŞ53rUf!r 3 p%G} (.(#*ƹXt-lD0IFc Fps$g3_1dF82=^A]#[/!K%!?$K\P rxGE8n)I!>\"@ S+(،q.Yq?l%q*%o㩊xw%6#jv@R3YO#T%kBzL$$4 6my.ϷgeIR훥LJO@]-AHDvx)m^;F/m؃-3 H꓃BS{6e4jQ\liu7U_O.;a~/ pej\k*OK߳1yTPF?,*vugPv@ْZ:xwȇ浤j^f0j8x)t bv5+AD-ǜtI}/T9IߚDmj;NiF-e&$%v1%VUPj/ AS8hPUߔqRQstO\nT(c _CcS$l7MrD2'ɶӼ$o[ y':]D":@Og\:ːԪN`Έt2z%1i3 oxY%s;RlF&zNr=gdi$Y&!AGPc+0xRPRb #-Q60ovwaٓw~nkEU9z^ 0ӒEŌWtj)?M+35 dFq- lq -~Ʋݘt+0IAږHA!k2n:;6k91,|aƒ,.W/DV;vn7gi[˳mԛ^9(ekc[9Zk_/Y-xs0pǥzSWw1wk:@􎄤m[H+}*RB>l2>.!<lHIvEpU3*Y9ՔqH/] ʉ$de( )d_4 $bniENQۻa\4TݖAWR:Mis,koQUB 7e/:DlyyKOt+*&@\/4^^SY\PR(K)ee,) fv!< ʰƕZ5saK_tPPSe$1r󺯈LJs/nIo6{ 잕IWECXem$k5>6{n848*T2)|2r׋änK;@Sea+=J{B.`1EBZ;@\$rjlu>ek**kF1`#5MLNEwߙ\k5vn*Bk+L#hOް]q(+ƏLGqʤɂOsH)MM< /HƔ|yt3 fcMd/7;W|I3ww/u?sXbW{pe`Ie);h6_l7gǞ˥ hi@s*LXVD|͖K qѲ`=%_חjXORȸuAuF|pf6g@b%PziK ,7 Y,|WI$"E5V?FZFRd,ܬ;n*9WFHkG]8UQ4䀋-xz`n"_W_rcŵ< H 7 *5}AYX I<4Y[0;2[8z]~$Y3i/ (b]rIj`_@3) 7b( a!t_;~y'3-Vt 2g"bt~vЅcG^BH\VfXB6wM:\DWIsc7GJ`qYhRvMQ-d/UA+Ip QkJ!l_yQ_\RFmCu r2s1{yBZ-5\*ak0جgC~] G Qa yRb1nL (]D}nIvf}XX HhXj`)`TE2f"6tVǴ\ZQa'_#sKnϚF2;K~ៈWpn924m)<:c"jP>R푟洢 `?¼Ln/؄qu -%f># \5;d缪haxH8YalsWfEc&*h`8P .IsҎa2˨N J@z]Ps4Z+.+rC>4ߕՏVY?-hE)B@{%~ g3ήЄT WF— DCk+ iP4+nz~F)]'7'︝j-=D؃~;х] (V`e QGz-F42&?K1'1^\G_ =.buOI L{Ws Vl.yLSB]D*WM9o>J" B]* Z g>Iz{}-H-j"NtHEn3ڜKV,e` o{e!3#ʁ ]hQwTRޱ\HB׀ŸqCA]=2*C{1e$&Mi}p+]4'O*~XR#aHD&m2jمQ#itj|I͠5P'jVwO;Qy ykhW|ywiDY?nD)")6&;%T?嶓vgƥЏn txCQ`ENvRC\o̗xk0 z0AIN_ibB{ܖ:3bc,1 8.#yԵ'`ʚq͇(D>fh옻 cu3~ JtFy"xZ֦U>0@ӗ_0TQ"-lLV & -/9fY? [!f$!%XJ3Z P k\4kGB'0MkI\b;+қLXY)fnc\g܀&Jq@OAHpZ~ǀ$lkuRqι;GmTM] D8ɼ4I߉o_䤂[)-FjE@tzG1, eG\78bI6kP M{:g/ñwǸ\~ALH6,6wMiЧC[24xri` ~~%|lO?b(n Vb;eBF= V"s"笣2C!@oǏ&?B+l@@>h=ʞDqV]^g%5Z |WGAaJ>`#ґ?CgH̕.7(32NOۗX'ܨO9̓R5F~ϦXڟ4-yp@O#v)VWQ {bՇ]gZЏhLml,ԣ`G fN _ƨ[5@0kB6pNLXI} /웖9i,50*;6bA~TA>K2tkc>v,bj> Kj@ʕiY\__?/=nbM8Ԁp)б]kIEo2&ɼ/9 !Z% .fOK(m: γgr'X>w!D#Z 1VAhᑠEBVChIxs7InOe'sVsff&M$(w#02e$r 5(ix!5"ʥ9I>>%ekx%p4È^'zMKԋdqC\Z؏kZ52p/\ \vSꇷx_DUo9=ލ"UuPVI312 V5Ex;_ /;k$vBD@ {[qՀ9?0kk#)མ$Tl2.]&)и|auԈf@B ݯ􋏬'ϙ(6v:Ot ~<m õ\%~H Tu0qϬLO-&ݯ=Up~e16ф .Vi7|eՔB;f\7}DOEz80`৯!I(G/ io% ]^' (Š-[p>A5Ҕ[E^2hUF,GKY#_uAz4q4, p"CfChܬi{f'ؕLu{l } j# 2 ShZom飅!`DŽCHMͨer39n/M^W`pq^)Ve0=z"[(R9OTL@Nէ~1ѷ+Il ut6TYoTv[JIʔoЭ/[2E SUI ɫCi"ZOaKA]fFLjXuqKiqJ2r'}\#fJRf7'6 U=8!ԣn?螩afpu Oݗ8KʽVS0ȱ>ֲ͜D7L#-L )v6%PRB½U"JQG,hDFᜤb}fSLĒP<ΑUkr 1B첫 XܣF4J#SL~lf(1I=LMEPd>rR.i˙JOдWrݫ&_{z [4*T[KN: :LW4ҀC#;b~6p&m UbD)(8OaPB \Γ k`LKz|.E M4 2gN*DT.aݘ(B{vGm0'6<,~gBeW0{GĈ>u\eߦ3D38_a~="JAp`E PvD6>j9aH`uP>ɶ6ܞ>`$sN/Vr՘Ŏ'YQzv0DИya8 O4A6ƁzLjEKepYyqb}#+o.`f]@CWcbK*QZOirf4zBLQ)j4Ę>>:,"Hb f+&G!dG;Á_m갇D# XHDlIm@tGEZ ~Šٰ!rb`l |B_Txqh6Y,F:u}Evj_}q>ZlҦ򊅏E-^/Щf6fsGC(H72ց#6SBdgvkX[i?O"i1UAJgiX@4_]ۯU~r͖<54#W;z>ո /`D8{8`|9Ir)`kB@=,11`ndT*+II+.` +1xm7=Ih"d)oͰv/ա55譡eyd )6@!T1h!&Y5)n(#{OR|?w; - nC7b؃F1h%%GvkԢU:|؝ ,4SНQT3=Dˤ_UDXTX \fA [6MZBbzt:K|`' dKC0Әr3_$"7'v/#olջQf}q;r SV fŸMaCx.1~0 .?ǃڛS"H_H (e6" 4U;I吽@yī\9gVmǷИx:VUGZzok=szo)AX͆ ~)8¡ I1A`9 %v&cX'EY# 5҉%1ws_Ie U1nՀ薲*J9 wqzљ-e-?J '`n+T 뛾i]]IDR!tГQixxA&rJkԐab|Q=zaygM\&2O4?eǟL)u$T~їpЋ}Uzn;Q7uaf+Աv4ă?m=u5(ߝ\d眤JME`2YEUl5}(TeDÒ.4nPNђ?vvrK c~?~oxVI`"9F\0_Oi4tAd]ic Y$忷 M ΃AJvb=jԘz1$4`H{&{~5RHreX'Vz{1c/U y &Q _ĕr> CցѮ4&UcHiK((9c~i~N[To:Sb_wU U71`%"f񭮁;c9|xo &/"fY05Eux=L*a)7fGmko柩+1FFqnF8 q!Fӡc9(ѿz`x`=6m@ dFp>l?q#8f_8K8C+fv08IFOHOڽ .OThf8ëO .Iu Owr |v+3n]=*,)Jrj.~} 3V4{Wj#\&f^ܲF kZ# 5\ OԵo%~gᗬWt&A2ro m,B6Vy^#гZC?WoSwbs))QGEodU7LQlhMS#^-xw1xg1ke?GY#.:H-9ׯWȪS["':s/`  ?Qv4辑٨rkM' +Gtw-K@ 2Mד:gc}ҙheqSG>/WvxРekjY,. đ$2Asl|DWqDDm7g}wOG՗vW 4B(djp)B^Ƶf2c\D/X5pnpRݢpUAgP-ޒބ2nCoO5dxlS3X`F۲ sq 4_ ÓKNb0L;>`Ke(ػѼH)TkqE ]髯DmmNj(P*Tјʮ+.ce2ű5{x)DnE!T 6_18r$݉d~9hvv>`,CnbvNs, RJuƙk[~G=2$O@.ZWMޱa?!E O;l}\T¥zA2?İ|ρKۥgwy!C8d7W ħcP%"IΧ(X&sY눽`?>D@5r޲ 鳑 %R@ i;aJ$&KAJJ}WBhl/taRN'<\|ձX(c"ӿ1l^A~Lmpy&Fٺ=͙%DeQ[&<" ]uFl")xAsBQDMvyR+lwB[c?mYPJ#Wj{1hN^fum^_JDMxhϻsa/m~?Vؖ!6SɳV_P$,PJS]\y^fn!4 ƻ>wϿ{Pa0cHK۝>V⊸rӇ$K Q2׺5U~?VdImCFTo(?L( qrgB(Y7֧3ʱXbg:?V љm~Z=5JҸa忦u0F/iKabo8rG wT!;*U0 s{:FjaQfLㆭXWlM;5-[¬׵9U(߷2;,.x196ǺYImCY)[jѥ$}ͫ0*y6Bڙ{J r?3j,-#[O#]U9+†N+|6>f ߩBj|zśkӼp{qnnK7j$@ 4MdHV(8"<} 74F7y2}y He\>d#1+dEPv)fV%A!$ Ҳ^Zj4&* a=CQFpL'KDl6~ IU7[>D4x9"^H!)LNjO!; Q#SǍuWʰ Aȋ->S*l̒H5%Yu635aEͨ%%p.oRDq\&SǣXX(q?#4*vm$M!/h:s/xRVrK(&cJD0'DeBqxL?yx%~M}Ǜʡ) (ICһ[\_ SQx흒x4@͵`UIN(p^~n2{wlVK[^tYc hy540 {ҕeOq z=qs#S&oȾ(J&^ba*O@[?~ wK?M1y Pvب( K]EzM)X{@ϵUH¯ǟZlD$Lt=)&C [βּ \װ&"xr9(tYr&vK]NAV88hkY@z;*5zVMu>L\9}sih䗟":Ax5.:Nq@bSg}ULd}WNͿHTFeTjDC!fըˆ$nݷdK(|Vj/` ;jR^ogQM~|VCo3ST0taJ{$T&1y !lu3\ 64Q`&8q*_j=ELlYq4FkDtSK;%W֟Ti^Ǧ')_9ow ᘒ?ۧ N |M-7a5_*n76N^E.0[h0Qe/dNV\\{ {v$ŧ xXFIsk|eYԑ)^2Sw"+DI)u|dR ]5)bL1-b|Xw$pW4Y@'s/>8&Q$YZSX֑6  ~9uU*1eK+w҉X N.gS {bp Ѣ>JV?"ŀkD 8b8]{l\K/ހo ,kHf{=ϺFT4K˔B+zx $ۿHɈ]1r)MW7[8jg_?ġ?pQaܓAYLmuv,pR]EL>qD/$*lL3{!LW%XO*p#2:<imee3@Seh"(K/cc.逜8h~ "4uM7+x,ݩFLI0@)&׵0l٫"_%G%Ib0lr_ra㔄ADWmD`_ Ɵ3uz+'+Ёzy\$paK1- pjIM..t&bТ4+扔=2M8F5$@ s Q>K3#ϳ}~Љ0KZAgAC՗ޡ8R""5\7-p yRǼ_Vs*[n'ob̮E ȇM?8߾H,i rd,-GPf)󚖓U68i֊C]<`o鿓6O dB7@_RA4[.AtTZnpe?g/JaU$foeZwj~N&lЋiԣD&JiVrd!"kP@URq6[ }*p3z^J[6[Jvntw z\tqATPz p.,Lܚ' ?O D%OGPΰ FA eIM?'5_}IT@snb%DPQu6#Y מj-\6Nt}]eq?voʑWwq?u⽘v]L%TD7=tf %(zJY WIfm_DDyK|tY?S^j42mT^B!l\}"Ftp7m 6Elu/RyJ,O$SsqV4>cODk6{*S)'u|lV~R=J*kJ;E]G8 4BNC ,'M{7*4mڇi$#q/JOeU9M*8xjZRU-&%vBfC;f>]^d=<$&)}X9in@սK_ TF\R1Bv?`% #c%U0Y+Pꪒ\ZcIIxo]vDmF-'(Pݱ2٢FYʽ|ǓkF-'Ĩɮ$X% u)Y˼U&k~Z[ ~_iq`ɥ.?3)cse(Ij;n5+a쩰㌅ւd\mʡ\gtӈZZ^gxΫ>KL& ΘJW!mXLC.l;h֪ve>Q5V/Vf c|I|.OSo ~ V/n8^[^OHx85:/P]Yj^psd{6 P nLx=8̹{uYH([cXZ b~UeZhx˒;ae82-3;Vҁ!S@e{J;2xSm4_r/5j,O0Xow"6uBU~yӇsa紜yYTWдVnҁ:(0roG'h%j54diY 07)UE5#4A"[!), 0LpEH;V9!TTyGɞS46 5h"?E# uEo4-o.55J2W1٠H .0=G<0 Wltʓ؀<كIJKv//?G1 GaݵNLx 5Ofa] JݧjנK=_xey}q,hXdA.$R>:=K]0 ݈T/aK0ۛ4zUtBT&3{eU3~TM/ȍYIfҴ瞑ER b́`tQ=*kS K|v7®rp$U*nr-lEVo!TJg~ څÁYu$*׿bmfB^bR*+HxVch`wlX9>nnB`doBb.Klh'žܷ -݇W  I8~].CscY =EfrCvWsL%hت[?rl&J>BT F͓ВV57w!SEUfj0!K(0_QB8Gʺ+SQQxcv[1+/:̓TC4,L!fܷ@嶩txhG@RoJj[jPyv$7qkF 46NE+ؕU9_Sz7"ӐLYQbɺ|Z^} =_\sL67 nqP ]HYA*BНX` D@ 8(X4܂Z=kNMު1i݅>:Q"՗gzyl$*cjG>fc=t*KܥM[ga*V꟧ߍlD +!"Z t.v$yF}ڦo;i{Tݩa]{ _& 2~ߓll\LBqd!iF 8BAG#|[S+ {YVgzL*6s*dKD֚ݙ@&]U;x"Y*pUܸ+l3Μ$ N%2Pḭ5ˈ:;Gw9l3.Ur8F6 ?Ԅ\:3L6e! & G/iq*;A  p''JtPt=xA&:MjDVq?xToF]hHF`K~+ה)Vg-a8l~\OO@DV@kP¬&JL,dF ܟ,TGBvYX:OU KU=JcG$ 1W2OA6l̲rvT}3eczNkMs0"`#w“? }V6R9S2sλoۄ4θy9" 0Φ(g 5p9LaZzFZEQdBxpp2&,6_; mC*VCxK yꦢ̱w8ϦcqޗX\`,a2Cy*771|.FL͐b F`xVGp> 8OH\::r6ԓϪҿGBl<':]l윂lzU]!8@^p@t7*](Pzx|_掏Y{}_mbTt3 ~¡ 8@P3T&чž$ y9QLv̈́@_5ƗDC+5u4C63ZDcɞ{~^ƃvn N ߟw+'Q&G p((uS:ߖO\KL_#ܘGcEB3}u+C?D@ kG?ʩ`O@Hvnk.Wmޜ י7U? $%k (|}2c:\G) n{05aIo=W?A2Z 0 w Vn34.H| {6x%S_KxCfQo/*[B/8#h|' qzW W,슣JZR2[l;geH.P'n(p˖D*'0[M7U_pj`v؞ =xPO#eS -dL:xY䍊WO쉃MBi(2F,`)Xձ7&dP@E@XI$:΄XTHGw/քvͯF{н5m=7j5I->o7]ceuTFTrʭnTAyE7dt4#iqъf{AN3*[E#3G&CZnqZ/Ȫq|׌P3?ABb6+WƝykET#\0O.l8Hǽf[jS:V704jET:.Ma4]0+OѷWX 3ѢGsǞJnV0m,xҳj!҇u>?  (bPEƐWn"EaF [0K/[G25VL[q=t8[]b5ETJ c~2`NR>^` oIh<,]orVG:V/L9z.jlmjP Uq6m;Y%Kۘ@(O+5oK$D ]"t70#I],&a@OL:zP /'7=$P =IZM[wty;Ϸe'#:2JAC]C!`pg2f@t'6fփ vb6vr".YXd5DkOO0tM[٤]eY_CLF!JhuP^]+61c4!Li9,J@9rR8eq9_pԡE2*=[~FcvwS0W!𚭂*GO I=%*}A^V"DZ;лʀ4=^^c^\oLInU!6u*X&#U'w7GC8/XB*RB' !%4LD?Ifrsڒ7 WyH "tA`í'&)z{E vӅZU‘C̜6}Um ޵Q'¦:Ӌ':*Tb9)14)g91{ :$Չgb-Oc-$dXNA?V;3oql׳,}ynw.Y9gYˍiCi+0 ,0Z(D<2om'=;ǦN]}ۍcEQ1kRZy}_ Q5_)li?eTlɁޛ߿C̜OfRQٳDtx m?,TzN8f%Wkp釡garjJg;Q/&Oë.~Z 7Gj m d$ƹP%88_xq. x(S4\w \pe<7A'mp eH^]}C_M p]E9TT M0xK¯6H-0F-Ǫ5*PѹqVJ_7)|N=xD]q"(74sEAHtq7>dUm~/{$@%Y)RG)4KikC,ȧ.y E ZSu;#ȵuL?"v5yJLh*ĊH XcexFwuJU*;wzH/pdv$lAȩ:v-q t'l)ZzԀծo\aӜm_C #U>ESσ~t ג b3(5=ɊcdL%u Eh6u*vGVSW~ 9 NiB6|I屦U 19%|.@e6*~jzju-uhM_$pqƈʌ"3Q~=Qঔ7\5 G ji "ML ^58Lc \ p;PrءlJ&]|OHk%|Ƃ0m>ez>37frZo]9l!qPKQ5fYtiy$ DB߱{ U~'_M754-GmdÂB-޿6s յzX51>ճNJ2.m˺ѭ[ѳH R!!_>^lμYl)ŗaE9`jtϸZ'=,e-eւ ':&|n,쟜ȁʮ?Zi<+.g|ʃAbٻzx!ڞI`4먦TcחA4.P:)A{eoXe8a>1bm2:2j\(#8-:B~+WܫK1\Fzw9Q|(569&U ܃@.7s_y`8|f\.;#8jAe&/D4C!e,9'Zk뇼yЈ1P{&c2d c-9~*A]QCw疚/!v!ϭe|˃,>C6ӠC/M6hZ輩L oP&׷Dv#gڦ5BӭE၈%qK%[+#Z@~қ)!ǵÁeRL`$zBtNo_EYS-Pml̆YPUnmѷ!.4EڂϩvurMw+0`HMrvioF܃'"~#2$~n4SXF+z2BįYƞ lwn,A=J8OO/>G? w"҆ԋ'.} Gf;(Xg L'p!XOzNbaZ q&{ po -_w-lwf)&[ȇ.ϫ,؁2R-5ćaTV*#[; ULiacՕ} U}e&16 :0Lzru.{KbݑtlK{Agi4]K~.0Nv%z/}ӊc?W<{)_*𹐪-Nji_JLSdcψvimihs]W!|-5$}1EL# 5zl3.Vj1'=lu$M-Y\ N=4 ҍҁU5kB?y@t9Dǵ0 ~I^bDo?e_0%.-XéqOѝ`>h\9<.qT? !,f+ 6lwAѠ# .2c' H̽e[Z)TӲ4hmshoՊCQ ,Gf Mci~H9!xwc3cv֌2/fi#sHߓKޥ"BPe8e/[|0[{7J䊴n7ΐpZGuL`"*-"f7[%^FDyVQ7"Q®}Jfcl%G:%33=Y5^LjPcf&iKL83'Cv=+ug,+?0aaţAwzM"W* Eĺq}FXn͑GVx9򞱒0 565 Eқ zv K3sg'F2i$mU#{ZhYfF;Iye ܂Z1东֧z~U:LI}!(v7n j(azSZhW DH]2yFK~..BÐگa+P-D1ݦ-\jj ^-bIc>Gt] U'oFc*v.IxwSչ~4Z0ڳ$ͤҧJwd@ =@]m;ϗ2[ ED4)j}o}a0rdžPOy'ey2rĵ u;R ~8aE&/Bг?cgN./s l`[!#s,c5ڎ!a:gk:ahڥtڴ`cT7/Dd!)[a-֒be߃ 숖{g$+':q[p ؠ{;_[uz3'hAz^˲̃K yx"BJ;J -%<Oܐm;ɵdRC./u:BS/PP/6 {X- kV b |0X I!w-m5 LF)WFm+z`DE6-#i3(7_y3/'*GP8(J ҩ`ύ`w7DN)UG] w| cK$ReV_;/`٤07Ά)`C'dMyc=bф_"L<:I%OL-NHz~5zg\ۑfA|qI9dԋRY-y Շ/sFϠ[`p6wvzU}qjr8G7u~pRֻF=nc*Ƅ;( Gg,Ū$5vM%;0, 3vRJ:$t=Hќ4p @^ 8ɗH.WH!S/`XaʻąDUm=]z +mIM}<`&;)bm&HLt3΀mDbF@!2>i^"ܣ$D]a/NlA{q4TO \S2#BT &5; Tr7M]hɜE8S9Ն 94C<GLBVF7[f\ZidH&Auc+.q!AO=^g׵>qԦ[T )4z嗓%^cўs?ߚ9SYbzx.ߧpߛ8i_rn~|؄gQI;`;ŽpuOM #i]$7z^1jt81doyc8/ %GԶ_1&"ҏ <\]'a<#14IH\hr~zC^\HTs-~$zOjuG:c7DXO\ ryPa`2y+!d&_ľCȗ0"ā*jn(:T"aTbɉ[O0e-.Ze,"ʹ ~q/^| @u!*E?]kC W+rZJ䪜 [XO VV`b6}3 UxRƜːG&-k./f؟^d3>؝ RߢHe:} \b0FUmPA=_8|޴KK'AL7 _b #y tBTSL!J8Q5c9>4*4Qp 2BOW ?% U [m Vt60Pz^ém N&iL c o X~b9` x@@Hݝg8recS45C> 3X(p ;Mz楙._)gE'25~>?12-_-d*X?C }@h iJT[:̮|%`jq ^ \-c̞N /&G0!Dd* ly=^ yjldZz{%^& (LX}aK|vmteڃUXOS?3PlD8tSíNeUɝ= &{q|jkH-1hDш en^B㥱WކmC@^B[-v*[-V_ =hҹg8Vهu)XxmgERᇋi,ꏯVd| =\"7 <90}٬XWUU_x-Y<煌Y.Fq:Рw/;J45xs6}3[?&z抛47yrGl-')B!PAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT !f ~zѧRU~@Oil _xlɝ"b T~|+P'B %iP2KUwƹALA-f8(9]̂1 `'ňEE>ou=2JRjSʿD~?,I]nU5(+6y6W hw #_H0勿;bͯ?1'r);6h-%`ArH1wSZӱ4RA%]rBCsz{@~MVے.QT}sSMsm)Aeh]G5\䇣W؜88)Ɋ|L`] yƏ*Q%+nklAk)ǩYh8" u; Mx_&,}Yzqc_9@ O."qkn]/3\fRO̵Qt]ҬHi^&o|/'Q0yUn"?ƙ݋ *p’/GeE_ Ȼ dWy31&@BG_ō :c贴83\evh\6^n^"hl|~h[ba|f W6|(i۰̓.<U,(3\oyH#DxQCuCRy yF-:M—ze+}^=>͊HpDcЎ5~ ]g;p7j- w8Ժd4pB=ͱ䟧+1\}~J(.J @d9 L' 3,& e4!wAj:~x:{W)I*,t杓Gz0Э 4.àP@p72#b F0D1#ov/Wk2k:P`kpcLT4?;pePCUv`k[a Lm)*aڀIN]G͕ \|˛ n-\+2r4"rZ@[vBMwdvC%gs IogUeDHS pTݏ.gDLi f(Lܟ;|N=V pҊ Bb6X|"6j?  #ՐKrS8<&.γB;8lMh5Ch]b :v uCr,;|a QHv 12TTY&rMZj4>2w^]0M 5E!χUurHuP/#aQ]!$6njئ+J0;e5H.T+ i" uKebKo$D܄1 xՕ&œp?t>qʳTT݇(a.Um]LtmV4[~ `~"Ѥ: tܛʀ+6W3[Je-zo^v>5}pZje m`ux2vyɒJ"gfrLZɤǓ+U⡱} -b} L;T!)KTm}Y:P;ol@Avsyr3~r5[ ͧ3ٍ+rJ n 8pK6ZM>IIF+'MDXF'`DбHOU7:ۦYPGs_fhМI i h4ec/47./)0qb'k5@KHM)?_=(3\faFc!cOw` t"jև3=Jhz8N㞩EWL拨5WQ[E_ VK-}?Oeo}~TlL*hd3.ϸQ"!dq=DWE dzlv DM=,+hͼ!5jON:!TPѱ]kh%_t,itDOp#2ʬB^s!-w$9mn,Yb$x6G {)_o7.Iw߿, ygAMȏdtoTK_ 8,)9򋪯2p#K:g'R)~c>]H| . su*w[eI/Rv[J*jq RW|Sɣ3cZe{/WpmmkL[u]O-{^Cdi6ʳ\рCD` o-&À t8.kĕ&@No[/ƫ-4.7w9YtF6="n4Ms'w/Pr<-Mπ \t6vLiq_ZQ QbW6 Vbvs&3DOͥj B ^9# e@OZU[ϦuQTyKH73I7J |HDV<"'!D"W.Dn[3Z#Z5`=K#&E U&va.c;cV#7R]IlY˴/е/]-y0ώؙ+CXDYݞϸǑW3Ozm<9ABvk2кZLC.f8x ,g*פA[9RR͙:GKȏ$tz;}v+LqԵQ]#2~!󅋺-#6ú(M껈ƣ]mGF)Yx`fn$<ј],95J~%,PɡJM?pȚ3k|޻n4U/au]dz,e'пOnjwzL$tzA|Р2iu$<2Rֹҏnuh#IWvӒW!aLJY,}J" y9O6O;1CVک VADnvិ?\{(%҉E'9p1q~ZwpqR N"Wo 﨟TDJ$d/(̟x'8]-E.Qz;;+}`]ۋdpoЋha)#P42-Wg Ζ}Rgj aa'pM͔*FE vG":2cisabQN&訥x0" FGy&񩞧}y.%d ]LCyI/Wz{>V! _{dv4VY(xۋk"H GYF =F@UyC | VQR6/l>Cw:X;;ÚN/.[*yMjD?/0&ƄTAD| v?j%B%Lr%+VD2DGOo[VP3_bmM}=`w)}ȽD)s ?r[D>צ’J#IC%NEPتBE2A51mR;}8PH3vH`P υXjg+XX4kٱKPJOAw.K%ٻ h`pf=l9!+P9X'FX=46㫣!}S}N,R/:v}5Jfv"LOFl$CHR۳>ܪ|m^+b[x#pB (P5uHe*hf4 9ܴC9mJf]I "ZCPֳ^QSODM(LXl])Qx;0Ωd%4R0dx r"{n^vG"z+ …yT[a'6|*p߄nt)1zT 9 ; a3_sh" W9#5.!yP clʆY ~Cv⪳P4綂 hC0$~̰RX7FVgP+XES&bi":z č/L|쪞3 z('9$w7$yP1Kt㨽"oDl$Kּ]ͭ+"qo[r:A96! eocR }ͳ%R^rÒG^NJOsjc&[/Κ["7U"6e" XyLguHCyzEVyE/OmuZۅnrkGT7Qj#Mvk%r2hLRh[b wC`8]JL : j~Iՠ*IPՠ.{)&6 qH.bӡ{U6w>+c ui.^JK-<_ k|A IfV,b8SP(rg뒈8.y_Mu%SjJʁVԴ2XLc˕Yai2Y8C{] zd S8'i^q0%% δ.ښw2­S {UpOfG-b oMwp^WGZiiMe(z6Gw?/'u4 \|VK]hfX`l.Xc d^t'@G2uU5˂50L1u`gJ޼E>k:H91Vao ympɰG&r+exgܶAZ |=>r8)sS ^XF㨤ȗ[˄yAAYiaDJǘTSr 3Z ]ke\\{ (܄>ҿË$ŃC\E1o\gr8Hť9">o_d[W%ښT_~7y tc(/er]kSӟ6b_j'-HQkP P1Y& 9q91sRFĂ?^!r:rI]jI yJ =hh>z4 hp1]w2T϶7{ܤqiWԺJ׳n w/$7YK:ⴱf,߇Al[`xRl- xvrAxΠ~ ]bUtӹ2=ƤVɕ 94PMu$$\G/Ds'72ɗd;(M5q(r )Қi,8cրfBYGoeWOJptj"]¤u<ߧ^DŽ|Y4ܹYJ\.t?4Ξ:){^%JxjPQ@+ I1OԳSCW$xLyc%qF+x4aE4J/DžWU/AFU7pCfSbڑC ;8$cobĚQY@99IC?Y[oaa "ڄfeM52/H=diWӊÝ~Ebp:J+ V&I\e Nl l pj\9q稃nth ޼2VRu*%㟜# P&mrNdžR ⯍aBw29^/CV4Cb !.!PI5f&( "j_}=n3Lرh85ɒ[iItKW@RX= 9 "&-YJTcO.ܲR z\,^Z.h])2oރ*VGLfEK7 ?M2}/aBRj!Dr&}aӼA}Thpg@HXۚu'd? 'GO"CѸ `Z"0wl#4tҕI0N:#=Vy|*yZn.fN9wl<aDn#2$X NC+e%R[Qz._o6CN::+ )8Ogj<&uQ] `;*?t2 βC5_Zi[>(GE`̍ =vͣwʉG {-X4_!O] ̧ab6:6h$%4gf7ڠq>*} h \:|(502jG yY.%fˀA):I^VC54}QEE.|?Fo hc͇f]n@Z` 1C|Q>N&xWؑ 1WJՄc:u|խ;V8]1ςL{u㳀)T:S{Oc2{, NI!ؠa.iѷHR@-<|GLi=cVڅ7wgen}S͈ XʲH|(//wA0s+fcvLR){ڋ* 2,G`] F?#mF,2# (!Kp\+HK=kϡ72\JbA* 8i6,JD6`Ab,ٍ1C6D&lqOg^FgyZXvXm죯񒝧(P-:G\ 2DDg;>)0?R+RE0!C֧ fÂdQFP.(oUc.8GPZta²r(^# {|%J.v$5 Bi(KD3s?Mə=#4 6F|3X1FՔgh*7N0-Izf__5 ŭ8%]}Wha'¡.Zg<JktK˸9j^O! c N;6\xN FeZFq 8|e= vEY1)N>9+)T&WoO`Dr:^EsYԴr=>4P1!!?-NvA嬑LY&eXbPOzGS'}YQ=Fv{P'f=:KLSeWx,[Hg*CKU,j]pL#K6FqJHIQDd|Fm(]Zd2[a8يbK/ui6D#5Ϡ,w@'zu b[ږ|_PM F,? 0HO-&sagG/Hިk2 j xw! n&War~2DIy騑qW"~;$qa Zxuτ%;?z#x;?;V@"J}U1H-X318/,JGުA$eȲ)UHoBGZ^=T|ʼE`GB *no,16̈1GfQALЊjy/n+Y0JaY5RC Z wS'EJf:Mgݰpa4X.K=ڮGv)@X*50Mf~[=>TASgm̓,]Q!iԒyw mJWjxBOL72(++aЇYeٟR0{DF}ddS 8eאׂ8:ś()sScGN/tzSM 5uϨ~4؋g0NWh`pZCsaWF@E.&SXdj\YV pl~ 'FT`g}ٺ-ywT>}"oЋĹjVOMp kL~l 1BeӒEƃ?(.- d# x=ҲKcR(f_k+ŁArz%#zwMsfQNLBro'ڊ֘Ϫ<ԖԻ(3CޛYiB\0~_$cE><C(KLݟ{䂲yʿ2~gT7=k&驱 W( xOF5oyJSJޱu<Ev؛W>魱e 76:׈{q#,[7Hd/vmJRh^OqO:x(^ Y^8;7lbg =v ajwO70C.-Jt 쎃'(,\};qUeN vljfY&R`ʟyt$m|!r6@IĽ3;qZĘZ }WrǦd劍$w =v6т>hzU8v٬n,)qthX)fGp){?l!cϣt{kJ3qjmRiqsv}Q~j8|.3RzHs11'zcieuFHH'܎qi Cmi:sHt|b/sl ~aGOWRۖ;7#jGScE/gLRGvCybϠHz3?<jϐqK+nc*d7VAUti7HS@:99;"ҰA󤅬nt\:(6+!kOr5'6+[[\r`/O Pc\F%9EIh}$'mfDB'`DK Egʐ8x㍢"2w*=xzTHL#1k%|eTg=RMfC$7 jDB 쁍ɭ839#8M\k}J-|ͺůԈ _CyE&U!j!O5%~,j5'f<"'|f5i7 @l$,Wvs}^ E.b6>ݭ6L sX6JOEg z1a[͔ry&i H0/[L?oFbzOUH[y;AF!08ZbHfp|]"12P g -١)FnDnuTzw&&h|DT%`FUekt[rO'޷UbI0SŲ@h}prUh?fRNsxgln-R { dh"V'ʭQ$prQ~1uXW?*%!{/J &Z8oS@,@F ڮ䴋Q1d݌=DݲNR'}+@\܉#j-y97_UH?1 iz+wq .K}dQMxYccJIrWg-OrXز۵BkVY;_{/HKHE-⿈W~D A}.:F:5,єk>ևt$K¶ͳd`6Fe5EpqFmilifUK4Չʖ "S(^D# j4G\_1yێ1l PMi_IM[~ tΥ*4S 3GqF}e[[Kh)J>8 1bW?._\6eRp%$vo>X&;_]*JFӗfSν|vZ'"b\) WꅙpY-=E&㴭!)_h7ʲwʬ~z{F+E+v9ޠuǷO.5wBlZc^׃nޓNj YISZn6aaJ\&La}#K6}KLS&'a_Sy,2t 7*#!K03;ާ𚘀ώy(f\o?Wɨٔdj.Yv5T1ӿP򗞽? ,g Ur%pr݊i_0.V3f5bm2í#H͵ Ȯ3߄ytE\ŭ2R[{_OA ȕkg0-YuDK f0<C3`g F78ؙV+m6`՘*#q;0Buq T-5y;D``c&E43DSnc~! YOlq0$nEJl<{; o\;OK׿6,&P "QM׮gK.uaM`({4ycEn٢\հF贰`=ô=9y͙VпLy?p 'Qp@H/FPjY7}mG̈`6 q(לi p"|ΠoM|u\$J{/IXE@y*WH+|E)ihת3 tT\Zt̉'޷ żs8 lA44I?*>ƢhМ72S@_I//NP0$Zvd _b,OW/SU_Z#` 'l ӟynv <|X7?oO̾曅{B?C/v7~$zb,G \j\KmPyԝ $w)z,om[s 6%Z^Y8 ;Ps0A0JMˁ%-ۙ{jk3퐽uR9DwE)T&3hx" bwc<Ge7{ #moaU*ɽ,vy ?ǀ-=YXM/x?пfkbgtq`tt.hN0Opɹ\Af%fc WPkFˡEr|>T7L!moP?7g2YtuXTq gE#; Rwptt!J 1 "{AիxoI'Mbʵ,"Hd^k@6!4_)@,w,,?b Cg+ ycrGko9Gaw2=z ϊ*uTR#^ z:-!eeo:@Z6`/vUٶ`#5"}},8"8 '4/9a ; }p]+/&R$=A!=(."Bkg١<Fxtc oU8W8߾+K.\1ʾc%ꙵ'<΁!*o_4E{5n+@Y ~Qw![5<)v7ޣi>V ܓ9wdꅝPۄ`8J2J_xoz3Nk._)?97XG:%5H?(j `H'U !JO&5i+ryX΂WȹdW)i+h.$HL߭ovQ6V~I8OY ʳS3|b<:O#i$C ܏dӎC~cbѡv [ xVݗ XR6B{lQOܭi$Qvkٓ5)c莪&rBd進a^qA2spSnC+sJ~sMQvG@2xZ*@+7 lZRs+UemjJK `jѷGiͧ9Gj_s!D %@T0:Cg v`&`|XT.Ioaz ^@4{AAGZDԓJ+cT뇙@Ϡc0.&^quU(P: c7ha52$&Ӫ1rӲN!TJvo~?Ms\ 3*!t4>8=zSHY7Iv.Ƥ͙rH׭pM/ P+;gDS|\?eyq`>v-A`~RydH?.R1X߆q ̄Lc0Wm3(XMcZN3'Lmc-{ 2vȢ6P9]_azO}@M[W T[#_.l'cBk"]_θs5^ny۽!;qHF5=eo{] } >n:'u=0񖡿1Qe\J @he.~-;_ _ %b%83%}*9qW,`PuBe5Lmj{A+a'tᢻ>9h`V8XOn…瀥+4SUS<7)Vc -pOI#-33vbbOQɚYN@Q9SfRvg. fo[$C؟ӣ%#TИ D( VL75(b[4I,j-e&"u5X,(;NUkG5kHD Ut&r IN\4Ixr]_!|Àfǝ?eVHZISҐ^+yQ^sFesݹl6[%_:[|}VG]&3qSu=QX+jYh<( \T4'J761UK]V#pJѰ:)ýQ~e6f  TF2G+Aee|"4}KL:ZdOq4{Xj fsʜ!ؽ~XD3T| \hL>U*tP1>TON/I?cd#>CC-G?|7LxkmO֜?W0Q(W8nmۡW=DJŎ0n$TBqW<hKyuӺ^zDZg_턚W跸1tp`3.)>#{Q@rD?8n뵡*P}b.R]9ZZ-aB}}i83K ,5 vpƧ:%q $!珐A6+X#Z U"#cM6*\ᔗ7qKn@<LN- ٭l>Eu紑ڟ!ΙY:/b#k{NNa21(Z۱K8 Yxc~m3fbO[97ٳh黾V3UZ bՙՇEGQY$<k[-2o}l]\'qwz0FY'][y؆m*5Kg[@pFX,j3PBE X~˳U0IV_V q0pȉZNj:ubdYox9o-IKBWSAתuߗevѯ 1Y U ,3r\,W*"䆴-%R[*X>_I?>%8}VCGaL_W !.61ښqq'#pSl"ɳCphv)b%sC6>᩵.a'A_r[ .onLeX+ u]WR8֭32;Op)cH$Lp+ j:6 ;qbmt$\!j>¯1ȩ_+i4Y,Z:KIx)B{aY,v˼٘ix(pKYQp vj+}{ONkοRI-}M!N{BGAk22K (.k*KIiW1dlkʈpJg7g/'pkM"+0ԙ介fsZiՎc3 FI눽VDpb#Rvc: rw?NfzF.8l-N\˟~j![cj6{a eiBHPBI٤[HS':p֖RS7v WSzp "t{`#V3/]!.YM+RN!{e\X||M^KKO'5ZJ, L¼g_)τxE+ YrB3WHndϜ X`l9J mE_U8bX'杣<}1ir3ٽQج쐏fM<NB`X.ê .&Nz-yx~~uGCyc͑~k6Qi7li01Ǡ|uv({H13'd/p'qHlYP>M ; v# G `M^^z7V}ڤ?CB{jsw| \MKVޖ=_[UqYLߥ$+bߪ|@Mra&ag>^}N C#F OM6N +﵊v zh?m.džf0dő`X:ekc\%RŷGPű:|cWdB'fsfD孵U9ASf/,i4;$n&y>[fo_Nb [Z3+OB`A4آbH7R!O$؈m$~%@?X>TV.oD[*'`:{>`" u6W׹gMQVbRX)9U:^fNYQںfcq˭Z>vǜ ! Hj2pkM$Lhj^P3 u-Z̋u됪a5Tkhk,%șfdR1^K-GL f_^L SQjqՐZ<^MRO?RNݢ9P[XzH;tՉUsld tֈnĽpñirHfu_]J (?52 D,p&_>%4B}[NQeAkԼ`,CWDfaÄP0{<Ťu)wכ-˞Fj5d˵iJA?,y.5< B0V{Πk\xN!#ke`-[fs B]$Qtl;"$dJom⏢I vm|)RGTǰGj5K̰Nq%F[p46V8h[?qICu\Ir |?r@,~=rlJ!Pˑս҆+Q=HF36^#=#C=j( gW-A]$j"־LeD\8|}GA,x|aDZ寺M"g/m="Z d{JHBD3+Br[ 4S8\G[܇-{o4CaW5Jݏ[ԙZ+ngi7El, C.$rqҷ[YW@dF+> $+D½F]4miJ~?? ?G#nM+9fol"/U׀UYhK!Vve= /ǐ%\fo$rkr=O>@/zGx` ß xHwmdIٯڜ#N^WެMhy}͜p:=kNJms-]A5Q k&DƵ~\MsC*ǘ ‼QlN<1(y{(5 $i:~{&fnx+ijT+{{%7tYwRcK#0 6uü;f|N` k|䀨Z \ִ30 )Zл""ZGK|-'Ћp\s#Ƽ/; Q~ 'rs$ܠ I@HzVFm}wUFn/"^mZ%Ys[^fPDVQii#WBg(Ig4(jl%SU,^cYw.GA\?spNa g~`\:- (w)O>(6֙ʈT]I.<+1h提|љJbY@fyJx.fj z1E>~8G!ӒBMO*x_)Q激%k>_&b"kj_ی9H4O8%1G U|~^׭IU7[Xi$)\mJ hOo@,2>BOp \Xed6d OI Yޒ@y3aw=166'7lj@u/p>QŒBvC-fqPDxFs:lo!-K^/Vgܹ#F1eKۡ} W X v׏iO`pr3ގEޒ$]ziomv3a7-l[.re RG*5)Uk)\K1E(CnA ),sn|050PEDׂTiJ-^{~ F2Sw&C3}OL)Wg?Ai;|PiwH7vtT`+(FUUj"'yRm7b R1ppJzJƗCdhp ,ATNKY[7?KnY]4˜̍hPA l<4eu'2ٟ4zlLL JF6&,5<[Q6z& MAq}#۷=}&>!@Pb̪x2C hJګOο3\#p-J~bP_cX*N钗.@ZSu*a1L@6 x/ZF׹" za 4ؿ+u U(--R`;oO?6 *OʹS 41?Aޮ뽗s}h^&K]jj$ā%Vk;}-5+m QAJ?eծyuVI|W?> rkB=*0@t8e`ROhc\qImx>=&@?S*2r'TpR3epP@,Z;ׁ`Փ:doVZd *vol19A pڶ8SKS+4?h6`\.(KK6UNc^9R١ML!jՐ&{MFUvl?ޑAM:L8 "ξmM{f0P#Ka8_!B<4N ̣ZoPgJ7@nP''xȌYl xI?,GW7C26sФP4|vKs Ӡ Ws@zSv<)~"NtN7w՝DMBԴ&!5hg2燕c[4*AS,ѬPx[yCF_E6@]ڣv\ɕGf~xyYv߾(Me5o'5@=8|ҎYvxe0sޑ և}wA=U 8ׄk+$]IKPT)q3Vkrlg@Yz]F*o  ~. ,^8[sG8@{Aj8LNi|HHwp;c/2ull|.dLtRHs/9vYe ˇyrьAo:t RH|B7#ۤg^L(a7rQ:վ$Y@ؕL*.jsBbD8] +r7ZF0k6nd71T96#>;etmR~_RFu,qى 0 =~}1|,nɖ6$:"_q}Cyt5[>pB`[U*D^ma1jr`SF!;Ep鍻qp!N/ٳ4Op@üAqI)q )OC>"(7I.+UUbHyXǻ+^yƫ G@]aMW-ꬮ)9ԌjY"%g7y<*|*ac<"d@eazXYP? P5E<94.P1_Cxx@}1#ͼɱHqL {B1oghOiC.az坂 7\kVZǐi'Q`e"_GR&Cr\>(:l"ηx_i$p]Q'|Ah~r e(&+ k4ԑTqଓ*xt|E秷c2C<J5rǼtdN\>X.gjKj/̒Y#NحbX[OKʱwY+赓ϫD؞,q8Y_۰; Ŀ`#uZ!a(Hd٦vay^mn&j[PL˯ H;˿\|'qTH"|: \[?vp^q߭fOamv9;|P:)fGYloKL8lPЕB7>N]hQZ"vth2 ~vLYn5pYB'3!-#U5q3O_ȅ ~̋vl #6 3~ߩYɩVY~|.l/vgc-TBw`eXc*( yD؍dU,-Vl4fx8]f&Luh[Wz*læ|.\(L Z;Ifu,lUPglqȆUWŏ}MRCFJex~5(UEpH'̀V3+}fc?׹ yC$RcE -@=KfFb;s6A'֐+Đ(|Fo敎/RjI(^,c/&R`η|ğO,>nZP[[ 3^t]Hg]Z(qBWՠ0X,6PZ9&澖^m,Ț:Kuh9*)m<Ҁo-}4P( 3 Zr!b7sظ@☢ں~Dwq}CQ@pSZ$oר#Yq׉d^;AK] 0%b~f?=t> #"aN;z BYXh:"%&ox3z{\ FO=ȗ,K_j1#%wlJA#1ɉ utzfvk Df$^ 6"0T1dP҇+ j!茓u)뛀A}uNBuodn3rF`iϒ# Oqe.C_3ۢFO%3^K5ġz]GSƗEm<@N/aq'2A7X6|4*UpNs4qj{PFe`Y ZIŨ(Xo;}xuڥC+pmd" SNG&^)UH+]A).E+*jMw%:K8v+1&A> иXUu;αM~Snx vJ+,c/4iu;0}oۍ=GcŚ:@g[;_/DkEnQzKw26:`} |fٞhSv_ AGt0QmVvfAvZʒF/M| -0e7@[Sp=0_"0VE1@䭌jQH}~'oa* bP {>θn߆`^?5 e؛ƔFIQ 丆~&#S&k( VZ2As9 tNܒw#n8Q'yck,KuP)La0eoY1 &G5YNΨiZs-fmyGlmܗ ?e.y٬b'-٦2@;f/ I_4o鈎5,ȧ͒! ӂEIH7rCLV|$x"fB =oȾY.GnTd~2S/w?t5E 5Se!)ъ,mtMNsWgHfs\:o`7؜2uz>1@ilOLG҈NJP* |.YF>(0 VpD&{TtC$۞FYdn?N[QCG/݅&bӮcpAe3oh:*$<ĬيAbegāfm_CyvP 9e hz, ,QœpH7=ǏQ?C:q)o4դlWљ–TM*DBo%hᛣ ڼ sɥ&2jװbm8[/Ugb*ęWڛ( ~|Q]N sP"}t7x֌z+׹^B- &z'"^.l;pz$aF61t,6J15]RWy|+z?܃o۵⚷N #. 6].DW$qv,[1@(]>YUo@&~e.fE?g鑬R@v [L.,'ߕ#A v)Kö߂+NcNޮIe"0}>rɰɸ.73|5ka?"Eo:NO6_tGU)ݝc?yQ8<.5 &<` ]@j^3§ ?ai]dF.:\0G^~da&+ HCJ,_(b6M~% x5ufA&5{ȘE/%#&Ssx$K0Xg@.{qo4ɀjRBݪ)j8fL6羷 Ewkr$czgBt]$4%o.@򶲳A,(ZωSKf® D/c7L[^Dd\vV])ªVpFhjx G)KP:$uwG KfCU6P 24h fcKQ.w\I߲Ba3HV-H!s܄wwxG^Vӈ3K3PPoh|- ԃz"=>#|.CK+PLVhJ&-tF62뇹))ڲT Nq:Ǜ5:MԝH4eKĵ#謪c]Jk\3-̼Ilܴ\&E^z]c|䥰] hl'ְ6|& y.SlsH@X#%~M ٵȚ[RNl> 8՞yB>( B$(ß(U[wU.-Ijl: N_VѴt.Pea5Lq"ДD4mq5b5S6$}B n78+UUjޚ@kp]`{J%{ׅɉ.(f2,7z?Z\֠z#hݛ&˿ 5_~Y60l58aVᇾIDL9ݿ%_=fFHo,)mP0e)c;ɺlTNy餆3n \B$vHsZ)pm'G@xgkP_ª0҈ W;M"S^\F*FSssعU4@\7k!.6L]II^fX 5OJ,$Rv![3)RSo,y"G)M Tvi=6X!ſ-oU~|o1[p=xۢډDžt=gᮂ};X@OR;eD~j:iszD2d] `SL4bf!Tg7,`Ff s*(1C>jMe [Ԗve* Ǧq(WJd|Gdn yr[Ob|F ;[U `#i?'ha7دJC,hVV5DÈy[u`FpCW4X3+2| F}d$0YvSݼFW,wU.::C%<(ҽba00^ȃ!ن*iG$ Ex~)[ aQK`MeҨ#~TTw V}n\5VeeG?l.A4t9 i>!p*l3䰚CeXmw8?I 3,ySD n\Q`,undEJ#@(T#iQpDb@;s_IxO˾uF's~)za 3_^9 ~K4=[*CLVN>]&.FLvƳHΥWS3 kЭф%0x7!īш@j]Pn_|cV6of:NsƤg'O/Z9_χ98jm5 ( AWR$+A fO*B*;NUEN"P@醂Ƃ4s+=q0uԆXTwIM?u%1/]C`ZXbIRFև13N.mxRE^@P `'|Lh9j G~3m*0&:͕ |dѕ8#tEA$|D@%ؐ&DLl= gQt}o!V<Ἠ>Jq~֓dp*piqHtD˃=NeKQpe By@ D~Rc_a45GHZlBXG5kQXoմ0\|?ź ;i!6 DsuGgoq;k)9:e\]ujOPxr@e|8p BETsV.̓J >uX ܙS٪bs V~-Ւ!F;uLi(>?yn/}y9ݑ59F:{GW[y0=/mL_rzEpսD5иYXSHdo@]H,(#=)8A^J>>8X2W85>|^t(nu錅N!r||&:2pj r|MI$%6c4 /&?<b>31wL0C m7nvGYe}[*/ƿt÷/<Mbku?c\+J ^x#_5$YzȊҡmO˶6 G 9P[Ri6UJ' i ["SUF`7'[0mJ XVE ]\y*Z;b 8u~haV9X"F,wTڞq}D;1̪1Zr] b*}fHx&z(SNfRkيbMWK\|k\ƶ~ʈW V鼜 ປ-HfHp--n#36[*Q%(Dgc7RD@jn ':p(cN<4plk-ٌ-TThW Gkc/<ռ m{@b6I]Pzɋv8La#\ ߚ;b#֔ƅce#Ew)*Yl Buևk'Mc@T:[J > B5tHހ;W! -&[ tt7Cc(p|W|Yq%&!@(=P.Bg6uF!!1̷BUG5ᾇZfi@F-XnL8u/SYxğM~V.ְM66@GW##h)6fd^ڕ t+ɍP#i(j99:=$mUWlCp>K[ps%iJq&MIĽPQpj;M$[ ӨbiV/' KP9yʍlb$M|@0_,_#DDlQ<#Q‘RNV@ڊ#*o .uq.13a@H|Bi/ʛCHk!^&ۼ\5@XSZsDoL!E *3p;fud9nbk8!% \}.qӃ/u@0rPHhOG7f8m"qB,Jj/#)J᱑wdP8%|]`7~9^,$M)hUݢN)% ,VQŭb[]rB&If'`NlȼYU 82ed/.K;|P5`f=J",3^e>L6wv *ٷnODg'h=oXȝ$[: `gd67ypP31åf>T>Zrtyp1S; oQ~( $jsW)3xh6ҮPO oBdyIPGܴѷؕa{QyZNkH^+0mHx@@gӨ5×*-~TU*m @u[9Ww"GQcGpΊnf(">5|sBQ6QLF8ZB҆J.lQ$W`>0>uپ͋4tZ%Ul:ʽ6jWSsЇY2(h?eWaADcfoGgZwj[s*M|EKl>~.josCXT.e}E<<u~4j>c-8 lQJ 4gw4EF3~~Z+O%L4po FA7,7@{]PWDWQ*y},?XfO|!U"qJ$VŸx^U ];>5%4[y5={}(EUgra:>>!xMЮ׷Q~*_'J5nmX>-nrҽsPx/iaP _@@/0I5lE­Y'jf$$}zkbPkj4σQI jP0n~÷ LCM aJuG]´``,Ԗv[p)c \x[λea2:71x'rlŶ1+$нu +*)9.S}ZnA_BvDwJ]"tS.gfu_--/t+A*ȠY^?{3^WApf:C" 2eY鸨ˆ" _p?x?FOk.7'"OQ9N: b'_T ~SOfS =;B+pⳕ sxT)KoS蠓] l@>olj}o<.~#x37}FPD ߅ U|"4{ed~*:2.Z}[MP"GTR$~ ){/Ai򋧏N׺cخ0XsBnsqLb/"EUpg\7hQ +(#N p[t.UH%8XP`ƁM|"Pf[g L65*rM;YNi ZY, S9p/Kޢnz L[b\;j0Jhs (³V{ܠf]\3-4f 0б@-[1Iejgm(GqnDSpE8΅>JPZCFF`f 1oI$p+(98s *Un4an}'ՓS `gzn4N)r4YH! 7qS9PHryp/^,zuUT"0Adѻ.md3HBHWI}>@uPm}M;'l'R>::KUD{:\'a`G(%gz⭱k"0Ѵz9eLUl&% L%)d/unQ~bŝ줼$]"l(Wk5byb"{l05!:>QP2{0z-/0"*x>~M?K5ATIvBH^Z!F$S }9Br Ե@j$qB`.r.}xop~W*o>7,X}X<>h?h3kō,d8inɉ'KM_G{;Eɍ}G-" =z֯d xMvC}L6[m{ˊg1Ԋ-K-#$a+hL0*BY*/&#}ҕI,7ؙݵEc !Hr/#ܭ"I\iNh6 .krUB>WKHP=rR9Z8sJ `AV*4}sb଎[["|a ӛco~>H> }=`&& `_jo!ҩ͟eŵX߬/L:6=⭣8bK'Grށތ <X0>c =JS[ ws잢+*ѬACꊼd.ǰr |.F5C u4j?gj2]iB4$ t{+KTjj@(JC.IN5n`^ܟAmj?uftЉ^)1s(΃#|$z΅ًQ-8 U51ʮ Jy$*i}.u\ F\G7ݓNjdu>8߶G\C$ !O>##wDb [c>2Xڕ׸E5,6A_ձIz9PN29ҷԫHTEo/䃼 a%+Jfwi a>E?$'N5Y<m~,|;Lq(^Ka"FA)ۜGvD*bɱ@Ohk>E7ï ' $-1ىdbOLkH\G±+? !ҰS3-3;"&m/Si@#w`N ,Yr KŌ种mk)dz^<t>*Rݿ>VNQ@E@qXR͛of/*=UF4_IpAיV]Q72ԡ16.Dw+iMțf"WRܮ=$ȦN Qm)'[<4,> ҭ;qqpY-*D_ϿaΞR4nH`OO, \!:`陹0\B k6U54"d\BmW39-Jhvp]>Ռ /!&*57Q~7uZtZxˇ~:s4Xܕt#y nR5.GB^Op^6+.N;aHb~wqFd Tҋ"$(Y?t`zzʍk{%,sY)v.s O3#OJ|ADao<{^eT,Lg&@Wdl#[p @c*Um1-hO@+ df+9] Kw[,!LJ}Ze:GZ7x.~S腙K}#Ua毠vXDo#:𞛪vst`#!'@qkH}J]K:jmv\Noռ*~BM&=UZuP0dU7Mx/ݪpM" ܏crk@CT4]Wо`qv dG8%z8xUX`ŏmk>2!6ɱPo ~. *9Ơkg8$GP\Rʿs_Nju}fd+883UZ 0l0Mw8ϒV2y?#31(S;|xqXZ/ɽ),FR.7=5 +8?Eb-Z{N5b=_.ML\xR_KYȈ!X(nhON_ԴXB1a[Py@[cWY/CsN'A%ccYa&iR<'Cճ Q1-%敜@tK/( gt."aX wx E>M_iD1 F0䨧s_c!ť:MK.~JNbөL=mLY)bY.WAp5)͈4Z!-> -]&4R~BJ|'PIg -;5]Kv=zb\-HP;cqk9 U\h.e[Pi ˃PZd5bG"O,=ɉ _*~wNWUeP$JXtO, (b޲ķ9eoqz%mnsR _.SƤ(e119oIE_7kqzR.*B)B]n<)6-{lk y=ٿv(6$In.n*;'Hj K'дj*\R뭴v;FbmiI&:7OMlR (G~~eRUMQexǢHVxռqRKu*7r3Zx5 rP-OۘRL'6[&SE%"iiAM/a]y Q\.u{*Z;hYc΀k'ML*YQ-X1^Uέ 8{AyY Dr0 zOPY@6P\l_ZgY{@PXԤ [sK]/U>%R#5N~_=S='nޑ ,){{-},i:9mB1AgqA:t2;nd,z  )믏Z]غ$`>3T}x4IIit#;H+f]py$|1OA QQC`ٕDृE@.C\5[m >8@eUB*/&6z(蚻QeCX05<baPVY3uGCvDjHhC>=;%±v 4>( Zr*2i>Ac3MT%E i#w7!?q9qO*̬7 ykn@6ߺP 1An»wx> I J5_6N~;EL qVV'!t;CJ`ٰΰVknI|!DD] GG\UE  n'}Y'*ĨA;z%.RfCMvpri~}~9©ꬃ[YA<UWDd,!<)߫6d9=Y@"!ԉJ}hN{B3u;>u< qpxj9`SSOӒ3jb52?R9#B|i5h2_y/Xw`SI|ې¾=1I2)Y~M0ZT^@"neaT9CMYYq^Łɷ=J+c+g u&!Z^Z͔\^՛ JX^Oϧ|Ĺ"ԇ?fVk˞kA;"(DOқal=]UfIɶ/1uN{.tB<={'߬Ÿ O)SRrND UheVXdjYTg\ ve7( =~ZFBH-{ĈIgdԝ OZaL9VĠ@1ŕKG]]$G 0h?]DF*|A*d(L XHXicGLMe 2niP@.Loۊ<  ܋G Z  A%H{$Sk?FoEGB֏J bM]Đ'aw'WAWKsRmdw;iIS#5R>ƴ\`*ԪCAeLQы0I'P}b +|r/cG컴\t`[ICT 6VJ/6n*yF)Ď+D8lAG}Hkc6%mWڴ( 'c&l/Je_,_Bɝݬ>ApFLϙ7+L0녤!f̬_(tߵA I]aB^`55$Q ;}MR'!PMaXw"4TУ _FFƏϳԲ-No]E<^*,I_dBLy~b.;PEQ#߈c@5q a%JEs=oRifWF+ 3.צV ^on-̔Pӟc0^ 0WFCoKOdsH <2ใƯR#n|#MI8I9 /#xַv|UCĊcbq^w+~NTwlY7)lV7U |tBx@/"[3a4~+ $} Hac<扨li0/7/c%ީj WjB IEp Jj}8@2i#*h%M)Y,SK)XFVѳRoژ~P rWu=>:}5p!(?9Y/4V;詇Sw\^3"٤P%QWM4cB; ˏ/ {:5.QcZ6$N)yq)S)z;hg" 8Q|n nyDM^jZ&9#g P䱲7߇/-D`]pT[Fi(l[R@o7:d]fvAGQn$T ՚p7VlCn#uHxSjOEz$M>M y2)ΖS"J&瀫7U.hm̏%W5bzR.F-5&z20Е),J&6#F(\W nOu,⍓D\E%:)~t\TL eS~S@ǃEDnyb/6+;4h iȪ֭%8ـ8 cF>vou}R 5z;ۑ _@Tv0ki,o @ Rui[Wy^ž(=0*g`uvJNڲFK anTQMyck , 93Z?34'u1S7rQkq9(vgCxm`\#*?߽u3 *x`]8uRv%ޮqC+!÷CWDT17"%)ŜJb U0e(㢑j`m?Q<9Ya]:Yyg9 HuQG^ނ(3{+s5h?鿭u:jJ'9?UWqN< I~KZ2\PBIʢ]3h ^%,yz,~:~s} 9aH`&#)v^;:FGw.kCcTքw$`FPX.>Կ2^TIuGձ<{@s|"ÇkMK_ƞ[H˛JO* 5R xd(.(psӰ{~~UG6/x3txeVnR9&Z{`rArS&;tgT)460k%=on+)5<ck]%VV;R|!UګUޛtqEQ!QIp\u8Vq#e}H^-ts pqVK<2og0 =Z_ ,CsLQ¸x0⸕6&orOgw1IsHa\9Cƹ 3P$6\j˪HhD |$U=W A:elOqټP\6JvL^AʳsLsL„%Ans)ݻ)Pj#yHCq˫$nsMd8je(WKmk,f3$wz=6KR!|胮 WҖe_Ll~ ^׫==Qq?)tXD i2-^ 2ZČJ~ќ *}{V.nv:#&S9$$9l  !CPυIGphD\~bAy4wLE=)^q&WH!S+C9|~ b&שЭ<%^)/k' 9'c@XْrFS-Z*XCG23YoQK\växG0fIOacX".*g)=cGgeȅ"kEFYd|||{[YݥK}F/&l+^ʧ!必N>9Pn}4M$Š9tb/*`X++pE4vA%woz'`zwAҝ3=e36|qﳲEm_7|Gq|WXg|'8ń8n8J05}=Y ڧ6_; B  Z|j!^a$S<y=E5ͻ_ռ]sG:58Icg9{K:Qh@W b~5:Oa<p< 2$v+ vcm +.Ev2~CE˓cpG$cƴnwV`M*,e76w7>0C\A!G;jS rgrSd9[ ߃E $~Ł%Dtr-WO/0% 4MT[X0Jr}vƗ4 )+جA8UU9NPDwmyԛt"s3a! qg7%eY(,VܦWUַ+kNfBK󩾾g15xnƋF=F!Pj?aW Ped : 舴41uJ}:xnAent k.qJJkZcYga(#eBRN]u~Ija)H!iߛ9`lɄõT^.WshǔP /S&T'+J 3*jŋEV7$Gj4#{ҧNjZk\9U*^#g;]c5~5?Ms3ɇ۝ː~y &յ` J\4bpQbHKr捘`}Cä~^֋/nI 'Ӈ.} Pd;Ǽ}AVW @9i"*ZeX}?hڄ46TRa5r׌^rN I!)A7@k3KEϕ)\1y=5!Gj%߂-_v=SB.yO-y@jPwHXݤrU⼎|O 5r?lD!6L(tOJH n U.xQ]W3fx- ] Y%tzR!2#ZJ地1(0?1 (՜ӝ/p﨑qV1㷚+*=| y`Cv'CdD#Tt"U+fUQ4cR0O"=+3")!pp6Y=dZc4)(]ia4O0'5NӁĜ ۱6\] uv.\}^‡%#h5P+g&JN tY@6#>DS(.'PsPWuu4?+b5J>r"l Pyf(/2z> p\>-Ԩ5&piƁpMl?ݞ+G^_W2U00KkTf .~ >i"׈Zy}%8wЈ'Tj!̠jCQ=|K K$OFqaLwBڣ (6#S=ϥ}`\ڧ`hU%[d`*Z~F4BXi: cj&}Gl";T8\ؔ&]>էT`[&8TXr/_[)bABf& OTq[. ^bqF|yV= @oZb[*k@sŐy_*Po*nXyu.;Z<݈fGP᏶Dva׫}\[tr(z&T3p3gm] +MpmWdw:w{ț;]D =o A9iœ m4bwa|7TPWuZMAV`̦ރv)A VIgiLA]t20LU-4sәK%3 %9m`Hϋzg;ϋR"Xjtf,1U;'i N"$c!Y c;Y(tj =,<%g)t^Wpu j|q9<&3O{N!V"QY=V}Ӷpfk澔/OLN @̢jQJ3-*^4pxRU'|[Ey=>ocfb6zOk0~w7+?7q~ ƝhQ`^m_ 7G_{Fe7:n~ȋ=Ӛ`sK0t'll[n,,V6E*}GI =q? "/oXDҕߠ.4zR>m7wbcCo۱b1B5xYl>,Tb"䉞y")%F,Sp  7EU ő!7#Soϰz@h.ç?OMTvNL *ߚE\POqQ%A6G(݉&sex.TЯv]ίН]!~1cD,PZ+Cj3>O{(ɍcbb.ST zǖ$QY=b54,xhT`k 79 E-ԵlRv1d2CC}_ZMQڶW+e ,HHjMI2ԇd]WP3j84sNU`aB ;ކ`$8(u%{wVX[)G0 /l]gP|bdx/ 2[u?q9GS}oԵJߡ68 .rW%Tc8?w\:=pɎn D%ô^zk^E)@߉ь͠' &H!Y*~ya Yi7O11*Y ol2k/eT_( Y-4 ]g>A/[Z k=h)  9ـ蘁cq'!o==>8˓i- ijW) c #gpҩ*hP18hŰ:w;z%\LjBUP0Tra]^`ĕ[ A8}7rqT ėPBU~CokMgFOx~s_G]+#%yihf,S>FF3/^+n<[Iz~*>VnU}̓ߣ<*ڰXMch2-"l3\_q[iDRz59N41(d`!ͮbfS9t!iRgϑ+-# ;m[+@?%!ЭWⲟL\Ckou"jr:Ul_,(4 98a7ڷNM1H,;ty&͆5FGv؁1jcL9cGsT7Вv8;:7mKw&/;_rWR9P^+~&/p!]\O 8`%VJhx=kިqO/ڴݮ `'+J0ڴ34* Άh-b⒖s>oI?׻bZG{ɔ/?-7{N,$t|{`qo˗$>DS?+:cG#^Q2TؕrܖM>p,ͼ#@e{o*ݲ?.>ZWXEINwC&;h&k~I*i9(p-*k-%@SNEiZwY0JzYc1e\M,ZSȔ[i<6e! !ַOW8J[C ]z 3=NtH vpv 9|:ϱMCϢ74iq@:R 0+W|,Yʑ rH(W%>u0\lDӽ0/W5r/aY! SRih#hZ|$%E²`j2 Κ&H=F*>E 0otzS-lػ J8iK 4W'E|䧰 mASk Snȹ7 ANK8rM1,G]pAfzޟJ<{fGlÄ_+21늹HIx K \LFY)E+a`eH X}N>*Y/ywFiv# H9!~'S|7/c R `2irjqU(qr6<%τ zhHU-7l!cvm5j&&Dff+@XnBIFlen eNj^ϻC^Gx:OV^[ )s|%wb"kҐ8GhQfZCps*^ꎽw77_3Z6gtGSPtZM>kO=Fޱ>'N@v37C Rc.2MoYtO/q\Z볙 r@GteVWVJym}{O;F.u K(S! }GżOrc*|+ր$-jfC\Wrư吻у:я*iw;T-ﬗy.d7CҒ//z[XqƗ <; $:3|׹4$pb[ÿc<A"91D鸵QgFL:YI7ڏ^LR \axRcb`LNmS?0 QӸ͹/Psm 6f7X3}]kDM'JkfޥKl"ÚPgbQ)滰#;'^Mg B;Vf 'O ˮI{dsPH~~w,+)b*=EkB5eЪ-F &@fg:mnq!6C/0ә䔂&ln³??$o~'N ពl i06n_jLj!.$6&Dl.m<ii剈\.rZ JZTBiրe򴩊dn%y!i@(I4KWq3o{2^ tNtfP=i/XPi0wRr)*uWbZ'h_űEmQ/ܺȺ>iu~%-)(`ܢ*q|Ͻ!ܩ^3}'hQ6X $NU;=ϊhyHwwMtP"Ixԃ8e9xbU"C7v)ܴqN5֦a!%Bڐk@`l~P[eLE {\4C~Z]f/NH ;'UDH| )JA)r1 J21XtgVIɧxʡ/^b_Rɠ"@I$OOA^-4e>t3St ]`RB`ܨ%6.>Sby߃i eZ6^S6V˘RZF@ԖRy}]^d2,kD|ÀBq#p)c`cG1lY;..1#eyY7gCʗi']Ҡ8Ʌ 5R$JztX{t\:Dj+G`PBc'&0iq} M߳\6]*jې{U9"aS0~ck WS\iPqVUKrr}Me?[l羦(1>A*s)ykMCIRLanX; A EUuPՇ9rVywD7Fk$hȽ tD(j KƱc-+@+}=oO@s[ylWZXo@^˱KshPIB<[yH$! 0^HYA WP-T5|QT)!Bb_CDRrJe' &sa`ǒ1ROJ蜒ǫ1w`7|NiW9&b=h}RL7k&d ̰ÄGW)ɚM ܬbC,E$@J77{]1ӊer(sA֒ .c#sУѴë\z|z;a85-fnP'=K@>Iѯ({K>6g!SH*Sw;#'qSϳ#橷ޕ.O8Գ:{#H( ,C_qD'vKE~[2`+^cbGLahБdM͊2 nCHY&YnfWd몹3qiV*ks&y\[~?&&R\1fnx+&Z곡ns) pdL#±M~Ny'Bf%;a]HAe)Vi=kWZ6KeDGN5 .O NT>o0᝿+xvIC"l΋ @4蘾ٴn4dVθOTq0#S7Ber~i6%_֘UѴW@H߯eئDŦpgrեdǣpxv@%``Jsp>m0}7lC"j.<=q#L7tLpoO*c^@es5+0}mp!v?,QhNOiu <`Ø?y&쁩5dQt`aI+By6\rTJ[ i*(MI RN bx}Ȇ+ӊcVAЙTG7 Ů9^BlD\6(GÁ28D*O o.O)F8jpC]ɛDi}#ThտcN+9QV"\݁WdHgCXW,n[HqMʒX]ŧE _w}?wt#b~z)jC˹ hHL^O$N,0}<K2` 5 JV]ɌaL%k7fc mC|~B#ؚwڭq) 5Z<~lrUon@v_^ } ;ALeB||}# RI[`~#}#bv1"1_zP螩 xNKtGԇ5BD o!TC pU;>Z ^Z9j7rfz%Ѷu~sm XY5t~_=JV\%5㶤@n^Z_.S~C8\fH^ijpA|}H)a@0Y-'?))" . xàOR~w}) ¾0l8"Ѩ]h]XTtfΚ.L1[oXidP pvF/9,d˔&JHb?*缗^um;\}-hiHx[{Ymc7=|v:_;%HQle [zVAn``g5} 9ݑ,MOd{qʪ狭v7h3Ȩr?zDujmWEU|Xy'%3kL"tǂ\a󃎄bc-53}$KN!l=aD!kD %O'?g2ˑy1T7 /WsbTS2 c O}Gњu Vže栽2@Kfiy5|˦ ^|\Po=FW(vYWZRBRb(kjRHwwʅ;xu=,)(RF71'2f1"dŵa rMOCU_AkqAKOB fI\ у~QA{^uOIfLu5ed" '%F*o!#<<zq@$ FbH-R`bg'|S{|Ud&<* `b^4>.<[ tJvٜۇl v^[]l5VI-??jhgL-0:_ P:ŕRoOiu#Ă}UEf!l@.V?oPggrh$S.=BI,!u!CjfƇCݷGx5-e"JucGr^ "dY\fM `)~,%dAn=2FH:-=>,i΄!x5窒qA`w_-c% ڕPzCP},ۑ>{䞗\pV|e"1v1r(I Dzy,ׯ:3+06y0O€H3.5ƣ'Q7O {n"DlSo20P=^M"O1UIlLtNHJS uJI G$#M8Ht`4/6Ttk,{YXcfM(1GF"vn\a+丅 ۢN #{:MR߉zX†O SѺ-ȟ%2a1wx }2oZ5mGtT_P[8K#,N`IɶMq5>:pn6ʎSV̈́&Rpq݂51C'6,ʣ%:]+sQ7YyLf2/~4j<9?Đ shh^-W>b4mjf )xۙLUvL>zlý+慄@ߞKnUQh&=6 n[m "@?w_? *7=^Etàx<+!(4,Nfnkg&`Fj+i =/؞ ^CH%Xs0.8qǓV/5m2SmyL%7[c;~Xj \(6y,c@f.4*R`E ㉭c$Kns Pf{L\97);KFё i |ZQČ>z:6vz Ƀ{.+ {J<̻ybSc" kxQ%`JRrmESshBU2\jV_M Bɦ8+5WMA׻6bvF:c[͋%{= ;: OiDȉgE;K@a7uC@H .rA*KY( NlIrw~VyixB\!P~[NvqE6B? G P|Gޞ>a^'Θʰܜ8Qm< iKqbVkx/ܠҴ3NϺƛ-ϥ\9#1Uȸ8[+MD:̍ߚ <4b% m59kjHo9qTwFX0|6/y+aigd _upv)w;2 a"B#iZ!]ࡘE-&gM6&>;kܯ{cP-M(>/%00$\< q8l#+Vi *_*mcŃ JRVМ$ LX!ia3oA`Fyc [y;xmQG}&dUjHB*B{73FogpX0;dYJ I}gkZԀ{]x,9>O?-gO4e1  X28;Z!;$2]|'HJ@erhi;ؼy%ҥL T[MO5(}>9EwZ q0p(ENgº%5CEEרZΘCV6KMVYћ!*Of%B?R5/g0GԈֻeՍ^+e(DR]N|fϒ!8ɭ\3̇}"/ffi̮J5U ]{'% 8uln1}2zJEDE@> 8Y]Lހp[S"9Zl9!< i٫ݎ%n<磽Oàf<̧0=hhYBNB\BQJ N-Xuf)wW}&%yΏpb]+dRizV(MFWkH $9~kXlH{vt-#]5G'WUeՆbU 32϶^УI5Ma<=؄heߘv$~5P!>"|U8$*Ki`]gIɑԚyo5dHKn: |Q&Ϊ3Nybr`!^K 3uاB̃s7Gq8bPS;BDž: > ;7DŽVzHW3s3Kp[/i]xx(|oC{ɣ١;&8dm@z Pf#t17XNơyN^4\VPhCdtE!]bWi7|[0@uLDdX uD0f#1ƮsqZ؉$p@"QY&EsXp;@-/5BFDnQvuRց5ɛUκL{ADim` 5_Gr}gSG?Gpe/Ia_cZ:U3/]9L8/ ÕQ96酯ݮhfq-yOXab!ONsNۍN+O*Ca:tf4,aWVxc&z.7;MDUWj$YECKZnP~Ϭ&zVk덲,ݼiWOgw C~!4+#]7~".Wn>_5 @lD1S>z.]>_4RuIqq`HSpwaIc^TM+‡?BlM_)G$.XwAa6o,Uz;9C4.',̭_ϭE#y)N2#;6 {>FW(=M\OAb0Zv!*D{a-(^"}wAX6_]F}-4ދ];^!LP\`'5gq"pu ӰSBon£0wH N" B޲5vJ<4ۻ] gus]+È}?#f~Cغ8lVNM5t)ӵ.ARhTӎYK,^d([>eG$ HA^M~Q׃{{ɽu}ɾŪi9̖z挮*eOg?M[0wðs-/$Aؒe @ <}̏¥_59yIQ!JX;r$%1*u&Μ_qh'l}v)NbPQ׍ȋtfDIQܵ<^ZatSU*,B:) =ajrI0g >A* EXt&<|$O}tfZwlar[ *G7j4EԽ'pVߴ@ntIb WkJ"1Ǯf)O'Wbnװ:9l5Yç!6a ?3[9N0I_1|ܨP\.I:7,5Oޔ[j֙pƗ-Օe٢c*yܴ"TMBd&zY _v\#l0jdJ{Isc+T?rЖ {,0taʟ15|TRmED)U$ӆe,Cu_G!|U2XRO _P }@Y +Jg*v qj%Fm (͇w$rFDC [?ƞx}3\ _]pIR~^#Bll"K !R"w.lg1 wI wk:7v'lߟtGdܨzC%;u2$MEhK(EMa"6mN3i=UHlKZyj8&tK +8UH!MI'cfN@d,S`v,~Amt-+- NaJRj\{n滴w,R:*4 1P,BjOMAcX~s Ljm^u2Oo>8x! KˤzP:(dVl8 vw/%ite5ͮ -?@NEtxE:p|!Y Zo6SjrD3dҥ&>[;$ uT?u9bR@ƺ5 -ҽFZZ/^G=Bhg3!',$O,uIVΌ&p5"(XnNtX=MJHZ so%[5ȳsCtLRT'O͓#5xȴLIihf$KĵipŌ^Ɍk =NyNUҿ&3`k[>)jqXQyGjEfԤt6Yi<;{&0a>4%= RL$VZς5X3#GT~Ӌ#7 &ǣ_V0rvC:+Ev}9X}0ʎuPq٬S !ض%݆$IU'f5<+m|Skb]v J?u1܅=l! d{Nee :uLum`@Q>Alx H^GrdF ![{eƍTdy|h?{oYZk"Z8a!}Ǹ]͊Xⷾl:JM Oke{+OO3K)`P*P|S\ϙ+2>`T{.ut#c|4m*a7)Kn+/Pj}53Z?ܥv#1qYM5/툆\yBZ*qBUد]#zق7+Rp?^P"ԧܔ| xqswM30 jlyz-yFvX`UWo7<]@"E pRDAng?Fyp}.n s X"0.;/)mV緡lPҦ;h |7V 3V$ʷ|.2|-]o$T %f=ཾk*I&1Mo\*WTѦ]VKVr1uLoAv'|3Dg@;EԷZuXY_:/(X΃׳]>E=Y_"4Әr'dne#`UcDjIA}m!/l=Lׂ`bwmv&((;3IDO1~%(N 91 ;YNzǩ(ǖlIj0!b7Vfa蛶9/y{GĚ(SZ3M"2~m*oյ>a"3Ik1߈]mVS}[X_MSf)9wzĢZ#0|vixw +8*tr'kU^1ؽ: cRO@pGW?#:Gpev'jRݫI}#.Y~LODXl|G/LVwb5*hؠF-E15NsGD~Y})fڪd0Y (ÇQɩ_Āi !C/Ro2XЈS$X͑ |Z>6w["Iwepd<0W ЦۉSJM7%rr%لe/][=lڂp$\0 @75HcҼ߀%1N~#wgZ+%bg5Iëu̳ 8.hgBhS0ni 9/=BlhhofG)rFePw7f{9w (p1u w* !j.r;m&#*)TiHOm6]×KJ8Nv;?ON?ڵRfALIl~7W8qg(4V|xIUdC@DWwv_r<S_q˅炬m3UlFV1 7k}-$r`}FYO'6$g`]*6Ie\az=,aҫd4kΝU7GUހs|츆aͨĄQfkq۳m9CM7XFqGOUHNfOi6U ' -*wXr4 φYR~ 6!z]̴f,CW'3 +5%ӰX{Onb/J )H-Yay޻zM>N"IcSCHyҊ*#.)0BZKm ռWJNg\&!6ezg"bsv@o4Kҧv? *vu2}ߏIO X@+mk O_~sAy4o^xQDyF 2R_^Mxx'>nPv7X~* VO)HS1GN)LF??0 hJ<0 ܣ"ŜOy>:EZ%K-5w B 6Ѫ?FF!xȕvȓގbP s. 'Vڢ*7IZkoK.%| K=8tHwc0ĴD^]UIZFX(DX;F/cuT, gZ2{1}GP/[}5 -s+p/snX>E KN1 렂`)YlInP$Ct=LG.= 8y9'' )q~WBwi8v[tؙ*'Bɩc5h0֞~+igF;ne}&HRbM%B"c{!T}eϗ2oäܔ].RUnJ Ԡ\'ʂ|nH,6ȸ-%b{BC|@Sxz\}Oun АE?j!T۷y5׺wdLQ? _l7[Ը'c?#!8 XvY%`հWiIO~]p܁)|tekh 5%W һznh;vzr,&A7nEH ` 7U֒+:wIwBeJ;] ˒ϭ0-\VN?Kd X-3PpSdPA7BAv=\kEHN(!wU[Д1>/޲6 `R|kʮyD)Ԣ-/8H'2 ы eWXhSWZ \Vlg h\U/U>uؠ<Ϟ+/nju A{4s5#LjH^?n"GVG`ZMݩjUqXxHX>!o^8yoeO MdfM[zsE3K5Rq%35K?m@K}rcd c)#*'g烜H)PV;+oR!U,IP@9G1|HB  erS++K;I:p7W.P]e3sDe>6"]0)gD@"{bqEst8Z1wƟ}!7&$\03uEjD+-^'0>rb>y* W D&\q67k4/JpW5tF-6l"n˴e}‰F}yt|T"FJ;nȿXռ8gsGdh8-`N[i~UxA / _'wt6Wn.J!& x,͵S Vݱ_ t8t=rhxl^#XAEt[#p]1,LgZ'4北ȇ{UX1!Y@TbN>6ƛ?oXݡosADjqD>VafzYF7􈚕JyMY}[ˉ{c!{Aa;!M,\ܴ,#ր"޻<;!`MON5N!)Ȧ>C* OWNbMMb<=+t&Zy.f)esk3 |y2*W8G LNss~uפMEZhjvbҳ\v-j-U{>d{ᅪCc_4ҨծyV pbt$`OjPiDa5ު^"UDvq7dJYlf9NoLW0{hxPy#b=zT[3=]p-g-©kC,xmuff\p23m{G$YmU;켚@21ڸ,jvbu{[M3z=9)Fpq{}W]FfиUߪ*`B7K0&ߓ;|n^#NOFY^ 5Km#D WYN}Nq{#hIo7"Y%w٢`qm{(,PkD[`ZsS ᵟJ;ML32ոߙܖ&%ˊW[ǟ\uCa{fKb;ǯ۴&xJ]=CqVâU/Td?D_t8(*'J֪1*_M wvcE/.a]Exc.5vX_W \ltbbuE.M{K,xG8L"αsp,SWzv$5wX)(SbC 3 SjtћN~~[2!̼k^ic#EF~=(U,zEjhθ 9a0x,!p X,{gsA345b2OgU_nuGQkn$f! rn({ژ6Di\CPÎ3%Dų  eβ]=&OӉpH?f>g 'Qv)S-Q_j ]=~F4N@Jcʋܺ^Z^*bR= JǺ+-ܶ4hf Z)Lu+W45wxU7rf*]'KYv=(^H8ُj  HDAq348;)#Tm6qǓ槶X{"`mV+Q8Ш9j0/kZ^\Lx"OCӗ*Vyfx2}6=W^~'&8piҹ8]cTQ()}p#=֘Ӿ!0}F*ܷ)&*,'q"rɍ_S]]ٟ;OcK]h;uiAbr:'6-)WWc#emRUCZhgnXۧ V/+7YB8Æ9Za&Atؒ:}@2{vu퍴"$yl>J~FJ=6/A%ח[?Y 5\DKvv>)j gK>b }em͚m8I3%RY_A+"uN8τ<~WuR+ Of5H1%XmsĨ?c"e㩜aoXnır'U6$ՉFDB}1&x[ٞ(%c:=ZIJ0RBD0ce^*x vtc],Q_n.3p̘ ^*7TO8r}zt)*D,NʦjY9Ƹej}FywZ:)g\ .v|(߃B&R/$u$&xPS"Z);OX6au7|%r[.U#`?jȔE691i8@AIC%C|~pۦV2Xmm:Pžʍ.|!zP[[xv<颉 WLTMBLl!D'MYw?Ϥ}dxYSbEc dGSo.7AЩn0YOݧ<ځ6 xi k8BRdōM $ڃ=).6m:gE*3K4h]݌eG4 9]oRt!Ԍ}i})qjƉܽ0ȕk&螛4FT&z,2b6(EmVX4PxwfQӅ]j/Ob/3\%\N J[3)۹bBҮhte wpm_CBB(bk@Day76dIBUn9:f!IDh …"8 %wͳoSȿj0@ 4r2PHc )R&\Bp#/UX2':̌}VDK@wQeffZp@unnOⓇc,)̧I&=hx90/bX #@uj_oIϛY7c'wu =qA(4 &3 pݷsM*UJutYpOCUt]-ڤВjpd?tuM{<IJ|U{,[6\ͭ EEt2w^BjXvu)2_z8]\S~| j`'ս9նZ\j7Dz84]Cul 5Lut6^2$0. Lܑ;!-@jֱq<Xh LY!x"FBoN>x"z LTcBy-[4Ժ4;{5:ĈJ"٤5eF](P,G jĩEUmD0؄V޷BFaQh)NjlA f贵oýAή1am&*;f>;&mFJa?*!8!S#O|R"W7 'BJ[n(?Ogc5vCF1`8Eу2+m%vP'h#EZ.A L* g6} Q/]4z<&'H@ *a<zQɂD+y]amKGMyʊN92Ss9븍m2J,Xu ʲmY`\:}\'t̩DcoèB$:FE~AŚvg\h^mCM/Rg1\PF[Z4ZrHi2Empw,#IjIt?=ԕv*+Nfm_~EޑLwkF֮ٽvַ QpH}$~AoZI'ꏻMYڕ/D(a>{G7Ŀڼ(q_wji2ѝ&\i0.@IKKž3YXPjx*jE*8Dž"ew#)_g]KOIN ojHE`.hz!v6{[Db; ZU @F;M_;| lൕӢ4(f|d)CzS띓j]˭Pkch,-<^)dƏz9#8Ju7%_"Wr?u :OjRim@Pgf;S (7so[ q@q*@w Qu_AzA {Pߵv I@((7K,޵,LĜ/4,b|;S _R ^Ag{Z{v"X *wiq}y95#Z_%:n)ӋKʹ6bƲIlKy%fY(Q)vpKWxَWgcu%6UC}1V(,J}m٘:Ǭa =5w-QXHeeXPg lƮ"`8M?bwg-&# 29E42yRX:30P 3"BHcttg_9UxnD9VPM<'}Ŗ&caB]Ni<JA졖4 #f/F)A2x:C3ҰqHU.[љ vNД/ s!6)$qp0g>,AΫ,6sY@k\ZjZZy]#5ӯc%*轼]orfP1&êLdT6@ZbӧRȴ).H#ʦ&_R~\&J!fc%P/s@MoN=T N,Y"ƹ|~hWY‘pTjwuMf9ݡ0P]cO3u(%"89Iyo 滚*('AE}M s"_%ȫ:oc >]oj(~ 9(Z8K6d]a o2f"8B'O,P9-Bxk5_wz; 0b=zprUu'WPJuD,˸m(Z 3jbtiCznm~׎N* Ͷ6߄6-;P+)+r/uɥ!~dD[N-\XyP|eHOZsmO'VeSEσI?5,3.qr#T{)pI+-P!3r \DŽ1~wֆZKtkT"Rbxȧ!#>gsS$Q|뗰kTe_I8/69 '̉PT7 W y=3q@}PPۅ r\5Feon;\ 5i(0䚧Վ3)&by-=8I0x3x>>nbyڌvt&R)DzI0@HZ]"<[{Վfy!CbpNjԊ4a5DT/Χm5T3RnP+Fs ӎRiQ+qXHѝ.atX .ߏ cwHk36y!'EᐯJzт}" zQs1WҀK敋;u]oEDZ9wzW֖\A@w>b+JCL>`P L鑱(m`'7\{!YV˥zoC*q,f{Px *yϨ'(#U$$"Kh)bf'M8wɪI-c080v u1dHDjS¿3%&Sy#+|W\pOZ)tzRٌkQ@>V֢ciA[7G7ڳ4#[1# ӫ+)wdZv6?TX1*$Bb&FBUC8zG߬ͩ T 9V]ZWJS<$ g /" .+ݕdMog" .JORp=h*AzP&Wub.c2>m8h XUj:'̀V}sAXeCCÃIԅ~o ?_ʣXh1f Nhkk ~֕gL5h{t'R`:~$9A!Pmh N?t4ǡ{t^p_N/z=pT+.3ԻzT_ TBѪ]'~GipdTr !ov*$CzS;hjo@~BDܛPb&La,Gl? Ĕ 3ýŏz]}qg٠#(x.=8&}axaMƉ8\[ 0_b.4CPMdݥB )  c4ebP7 dcd@!wZJg: o5'FH:q&}9ź1X.H_SVE 6C *R8))MC8R to 0*?{|zgg^3F䐭E֦ 64Okꘇ pjOF|nٷ)IOUt\ϊ%%E%Ϩ"͗r ī|M=GM# [҄]@Skwx")`0ޗ 4,_eLrxzv?zkQkj2if"4bDE )Z\B$d?6aE݉>7Sރ(lvfŏ(\C2mH/|=5:!_dvv[j̃h&gk{Ż @FڠEό6NSyau RWŊ7ٻjm<ܨ*Z/󿗠 3Dm`lDPCޣp_2O' oD!@ X;#[S}>TSn6oY\æCm$@4цBA"FV4%R !/pD{v)ٞ2h%rn]/*Ɲ7DX7{ Vj|DakqN;INx@J\KPZVѢCu 6-0x^RˆfK3bU֗@.8jjߠE #mP9;jK{+D݄TP8D"RȐ1V!j7HIry' S R<>eJKJ}U#iz)C|Q Wdfh(mDӆ;cyB_3MQ t[}gRtpyXYTVgIF/&/[0u e@uah/&0֖SA-QJ*l/z?6{(4ik?X`#[h]]7%3פ@u+?aSkNkدG{vS7Eu村k $372iӕ#k";Qoo]5 ^ }R '2kf^œZ{~Kp!b@a|dD"dN|p~Ձ`{1=uԒE7 Co?leY26$Od0%H3@C\2d5KR9-!䮜{Cqұ[S?tB**}oà".PҘhx:jo$kp !򒫀[Ɉ 48s#P}4ΡöZ2~\M.HY'YZ䦻 T~-NHӒl|9L6G2<Ôˎ6M<|-⏹T*JMqJC+KG;Īq#Kuc4= 0)/>˅M@y̝pRU<&t +YEҴlN({Y})6(0yLM4BeĈ#kWǃTh%ZtBC@42@.3"FgIA">F™Y^XH&TCOl%*ePMzp:,*WDH@]Ґ x0 o'f?YJMXZ,4B3ؾgJ֯󟐯mGG-˼~%]S y-AbO2.VQCaKW#=;KﴩFt!hMRf̌]lQjIhѫ ƃǑBOfG &9(+ν](5tŲe8ջCt3|6$\YiF$-o}*yѪlEo",;U]sº+1908 Uvw(lwT 1%_v&ofRD?N[\:G:pTFYG?~;ĩs/2MNǵ>V;WưtdeX,dK[Z4NhLhC .1/gR]O2^&GC G N`Bס\+߁\鸱4ztkS:^xSHѻ8/ |ܯE lQ$QG'BR:_d3Wb5a 5\7`:~f9 YaYK}'5XdDܱBA ȁUu~K.?^G-eMUr+t"!jm߽:K6Դ[K\[O\>}L0Ļ:m)4!+= 5}y#gϴ*.2]HmK/* 9;PSu,ivێ:OV8RwS7"s9 Ϗ{ >̈́!.+hbl1/F_^Hoj2 $Fنոٶ?@bXՖ|4m5\Vx?|Sy!,_`/8v h@C]^ 4˔ItqOe_KͩSJϛEhlp xm+oh6Ui([WJZ("n Q {k+ 0½rK17/$3=AcCN59 .YUp 6BDkQݦ'/2U!b;IrF9m)h-% y6??o2WRk3wFshUCLk`:;,!\b*aw݇WlyKtC!RrkZ8蘭6Aݝ.ZG>=<b@-oqӤo6=dW@>*Vji0;7,v 5w>{0Cfo˓@N:A\DjH@ć{\Nied1zO:˻܂5uI3+)qJZ/sS;uc) Q'ݜRsoNrY3jbX3)K)ygOT 5IZlGk :RC/8PI83a/~FE anG1ʬj^gOA}MQDidX0@8vo;=E@c/ cPw6b'Gx&DGHȾB [-`ƽ w'΀Sl#<+pUwԷG"ˇ3ia*G #Kl _{JDUfh >Y6|:–UF6 c/a!"$;ƏQD.Ŏ-҉gyP '; XmCxp]huq+Ӂ ]۪ !F{ss@=/!ϰMAG0usR1Y) &V8` _U+19l>+d;/eWEE;|j]ht( 1J*(C\bGX5=F,mp3C᠛' w>Nt\d|Ro_U GfQ+-s|m&Bi*k6~0fAeSGDOr˺Zw,ƃ:WuUo C\ΪyFsh6=F>Hȥ^IĦtBms$p0<u-,vF ,I٘߸4vtF,T`hL=6j &'S~>|ebeOp=ڹDlB/_,b[?V %,V y&جe gn@4ٖ{x,G{0_)1!ci9E6jRQVEtF\$;d;RlOVgפBqL ꉷ2Oa Zc<޹3j.{^#D-`wbyǮ͆wGsI+{[S0DtOE&E(UsO$앋zQ\mSňX{5-R_U z%SORPZ.YIi*peL4+32ܼ?\{#sO rGf͗ؕJ{1n 5rߊ(ɣQQ Q|wrk9؆rSMM/s]V=D 0R`C)g^,8C7E`¥Y Zcοi 1s=J=W]ES7=nZaP7g=uJ޲l_JS&~Fp+͇dƌ[PFq Hz]f14rᜆ?]umSaHtCǂ=o6(FIc &)A;昀ڔ _FEW9(=*M( cX:>9X,='ʇԓJ"խ;l/y#u^.}+qGw+|4RKJQgig0?iF(9\|,1*`p|X:+%rAf&h]QHrJBN}!īxqB X6%ԫ z~Ḣe߀ (,˨|t8IWތ_n`O@S "WDY)tZffP"RALhVNkz7FTqG \BƆڃ!EV- {{pF^X#@>=wG=HZ&׾t^`Qdi+"$ݤlޥs68gM2}o&mCBOr'$,@2#,qUxs5 Uy]3b|@ ۽!#g c*Bىfb1'Cj|FVo3?춲]S NjI'Z5sK#9{V;82^%c{%Shڽk hq}d$s^do+},泯D61qfziQ wqlWl:Od)wg5|t{#k ]x)m uޝFQ?E:a ^lu Ӏb?qa!VІx>7=S_unE岲Z%K^t nUYL͜uɣ}.qSJ@xg=A_@E'?4&l $`†hQb~njO'Rblͮ9 E&COhA5?W}el8| -,1Os; @Etl-lS)2,?2i.W&< d~!N.WeOpݏ&lc=84J_29sWv -#XR^ 4>79֫|_pC1rM!zt~(sp |*qbELn0ڈ [FUo̒%`:3Zt(!LoMʉ"1μ-;ߚO\m Qѽ-i{k(a6" Et^yl[#|J9wvR2l\]p0N. TMM-1szKHXwGRW `NbU8gxL ͇̯g~;)԰hT%8:oϪ~.QI. CvA<±zg(=fH>Vax sf*V4G^ s{MFpZZ=T^PY.[RwbÇ\'Z wzcskw &T1NV mȀ5[g:SXV#R}x\4PI=4ӦTb8$OcwP1&L/_깿=8t9un[?@)=*%A5*ÑPWjg +ultg!+ԻV8U-oDX.B# =nmPܧkxh66?e=[P;T*:?]%m6II].R-9T /Rѽ*Ӣܨ 2$=YNTA4MRaTDWBXTξVn!3?wM6KDs\Jgl`eDYE~89nwp}Zn@/E<[Lâh ݜOx>oQ3dHŌC|J (@,(E$T-^p WS|y(qq"'tlk$iUj7Xˠ%-Z2"c19,c/tgՑJPO*2bwXktWV)Bx*;֯o^#dB$k4hLc?%jfyC.J'`;3Pdaf2p3[^fF!.^:wݤaOPH õ jn Hy)ކtӳVoG@ C91y:|_ZLXIF)"_XRm!S$HV^FaTU~=4MW|7>`ųczӏ1 xtO[s6{ TnZ џ)"#;f+ڈVP*)0a_ͳ΂M:vullI,}]+^;3`Ae ?/#r;(x.t^u"/ vm-o! /1$&yJD.id\hjЯ+דD elh5`O/8|tΎ=bV.W yJ]-d͛0+ih-Pd|3M+dyPCZ@6˳IglK:ƾL5.WXaMYYjWIw,9ŇED -왵<4/f4 1jPGC!J_ YǓQ#5Gӓx R# ʎSFʢ;KP#7F0.]Wp9mLQH'|43j[sIr:]$ %~ѽ0o"Hy;prP)x0h55`,B ´[Vci;SM .E"9xu'w3 mMN+k6^zU03 v&L]P :w3뗶U_椼]NuiY7ILgx$1zUISqxywf\M 8;h`"bHH%͘3#U:2"OW<Ý_l},GB1p¼|!f"jXҔ}Iαy@!Ld`jDfٱc; Afv ߰^!sbU]G"D{q5osg c10|}oQDfp>|'RQ>O 82m'/a+f xGnFz2Iq0]IP9bg%͎l^Rl"$􍐠Oޭn0fb1K_7ZzhsU ` 6>_ )G[tDw=ڳYU+C1Pccԝ3{Y0xeL鉆+Ѩi= ݺg$>Um4sрl-;U0 'u *U ŒVGZB@8?fFo0O1H]] ta]b8y*e%]a΍+ t2g_>K<Z60Tԩ<EZ5}>#=APk5ܢapr_qm`+؞YD|ٹ<j5 ^ٽVdVjyH+to2,wxE-Q+"5~!dq8ɭ稞+>g5gyKUhE GNG9 8we|m47V;Uul8{}OՃg>5aVy,W]]0d"4eMECp c`u$?JfֽC!6<Um{P/j`{xAI$;+FK:]ql94rƼjx!mb>Ǯ9i۔ARXnݵuza! 6U@[ԊnpaGQ ^k% -W<1W_'2k"`ǖB 5r&SaU:H(fB.,\RY:&y ʽGO>ǒmWtd`lDi N'#1i`xAkH2o73U u@3F!p'V+©z.DueI`B,QTELN9 GnI3t¢ r5'nӳMya=$T{4H7*ڜ;3$!J3BcB~ks8Zϝ ?gk{%+C 6ۮh6Cq#0'P*ci=rt1Z`ZW2Ą^vaRuQtѩϩa(R]vA0*Y9RPxΡs:9"ĞNwK|QMj6x7*-y0W%$r7qLK;_f~*ٽp)eyZ);Kz, 7 {4Yp V\ rG= $:D5(~U8V`316eU7H N.y̨b $&} n=5{STl{ D|j5xShmQOלXWTrr&옂ۆό.@wǞzU~w+PO y-? 7n?r [uM'ژB" "țK=ͭH!E m!2_sƷ fF܌,pjox܍ ]ǜ,* 1MzaN|tv)Ȗ $,[t%j _jFzMbQT<|~{d)uRmr|oN'.wn@xH*s$cKk{G=)66\Go2Ԝ7Vi+J+Vp2/KmD蕈;G76kQ'TR wJv*y'_Q%:Z䏁z|D&ϒ/>pHGܐ'hn}R: <_GvNKAjo e|t_R ta5Nv-59Φ܇pK巜Htk{` H~|t`)T`dN\]( LƧ!Tu&a~2bi?$HQ#^y`o9GS_22Œ}\!2(b^bQaRS hl䩾ţ.̾ekzIZ¶^6h2ʭR y_: ZO֐@74@q7Q c=LtwG;6K8th*d'w f(q!72aq͌zj촫b')>nTj><$^"uN+9rmﵚhAW[ %g=y?vSu`wmyL7=R9l FReԓ_:<>Vz >Lg]BJK<h7}piXKU&J*<6\r@ e`Qǥ-ϗ R[`g⯧/*Aj(WAL"Oe)V*QdE? bWvOH@W>#֢u T&T) 6"jw4sG'yKDisг0Qbrk-X5OG ڕD۪)3l$ +zĶB±A*A%L$سI2wXϧbZv3>"ϴUyDrxd'`7܏]%ۀWFg"/a[2^Ü𼋭 i΁x`i5zM׃qraDBH5V1eP(㏆уT65n86sH.otIvԩ9wᷭɩ« 6y%@c|DAuZOgsTTam\]oxK"jZ \'U~cuTSZ5p3g1 ܴ۝v JdgwOx@ DVk嗶PzgVkZ 3zW==sYsg3|/ۧP'U[$ Z3p"m>y!;j u] >*+oפ0.aa~Nr*T{t9EJuP X2`|;/{l]6 |%X5һy]ٙlz, A23buݖ͐5O!XfۘO_FXWX}5x G erj)7AGW/ P8#!̳>c6l Dypg9`ND&\e$bI},AD DW|ډ, 51qV>BYѨrs0D\ ;#?t;a .FPKCNcY\<+Z^9 ~`)"qΣ!؝Bhb)dgFFRn=y l9ǢvZMx>R9D{:cBaW)qԧXެkf&g`;-*@A=hp^Fr(B|JA2xPFYO-b[[>ſ_f($ &_@i̺.pV% XvP<6P.m$EJl Ta[_[ev%ГPR~ C&:$L'΄EoCrG{yJ`̶YCJgK?QCM,D` 5]4!-8y0ųQj!X';&$~ ]ۧo3$KI](5/I`b.#fRIa9L]@P/r FWr+ {v'pK!6>[ Ĩ]TSzUOr |װ\z߻'$]Ivi;w]֒me &iĦLgyInoXe(ې\.čw,$^k ==HK20l|ZA^KGǼd=Q&_ia|[w%U(S3EPs:^Ɵj1TCցokP$V$yY)6EV^~n"cY쀕cN@J?q@7  `5+j}V ch2xFff}|ʑ`hMZ3Fp$ysWݷq /dJ,W/i\q_V buœ|08?PX6 QQ@hU Z ~hEO!%z/t=t0ݒhdVr\Mno)%.hyðUD4" 4V{~7WDŽ%ⲱKin _E 6plwyΣ-޾Ny=<0z\=ɥb Oh[/|yCº:*ȵ\ja>vY70|X=]H|hoSH _ #e}{nA߹_<2blr@ ]4^υ> M_m\C9l}Qj_d~ `/Xӏ~ mcXBّ}Y*d;/FN|$Z hkaTO 3l(#w~O܋!OP-(-v/rpT `P+R:HlYC{\ -w إ7' ^! 3enrswCxQtM( @sIW;?+kF7s ^&X鲭4paCe  LD85If&X K\bruRPAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT ހ par2test.bin P#@02C4>_m@&{7er%~%33]S`vaa36>mh|?``A: ։mN<29u[5dJA=mh,-F]3vb6V>sey9w8F9$~l9T\j'xC$okIߋ}9coFŧF"84qcί3`V΂i@R 4\rg^lTţt2gwWTHG8Œs/w#R%Iq6`MyN%O`c>Xϰ(T4Iq6d惖մ@>fdQU,L/Neo<oxe'sQgPC|&n@7,q4'R2i8јs(F`AF{FӗӖ]3|}4l-u_1F9\vkiV%h^%bg9rA$7nEͥ| lhdf8Ȉk˸DKY5g(/\O|E״hq&Bmo9z:UCGqf+SCE;&ԪBgPHpO֣}xf˔Veji,6f]ahw8S?:$"4 |':}xiFl\9HFQ˽OEld2SdkQOY-`wnB]M)BUwf[CKƢqRhp~ԑBN ˆ2co]Ml@7B[?R?׉ӄ|; ?FrJZ;ܔc]rN _&Um҉mq)ʹC adY,#\ŻVk}uo#:Q9ڝzD!Nt!o"׸f\bɦw-/vX8^qaQ-8Fyn GUX=rX;y,6̌gUg C7K/p/{> u,[;]I 812bM* ~T9?c,bA}^#[lXΣ)uGM<ҊmzrukSي᎑Bz{(ɎػmƒMO=.TJfM+$ڙ$1vߤPˤ/؅N jS-n'E%NRGS=?2ܐ6<0нP!RA}9i hOZXV{kpBR;>Jf33ܳuWɨ~X%ƒEbmWb%QS!rZ& *4F(2 a=nD $KׯGwfnɯz=֭Owk=Xql|:WXKKLʿS2-@mJ-"P9/ʂgrkuS2X!@K앭aj9;FE # :c~G3OĕG~*OWƝhm,sy%݇[I(ݙ@ , ,ADn鴟3FlMI? fLPkt#E٢ÍȢ7}r*?_7 'X\U#OtEx99쿉M/3|P oGOexa D`+I9Mt ]N {6jYx=>>MAߗNUPKԢEZ,d}#Aj:6Gq$p5Ş`fc]V-wig o#I L'\/|]_Ӎ21+"B*!A窒#}S!g/gϠFtijcq%٭  ꡗ{-עIbb0[Ȯ@PPzg %vYqCmzHG7x(Ho:mg<>ެ0q+?9ّ0.eP/^ |>Tw(1"^ѡ&pUŘGYɻg̦4Akc_K7 ܐ\p+, ~.Lb4+oC,i'JC^Ryi% k@%ƛ]v;&hO% FWCxYhF }{3aI" *?O\c PBhL6ʗY2eQУ5cZ!bLSNςhŝHKSU \K_Ye γE+&MutǷHz O?5x>%+Q9-rd2s}o+-qJPh" Y] b[b3/0DB U oggyj22U}tCB';0}W4z58#,Zsf݅T-qu 9fEpOۗf8|S!;/ ~EG3:٧`~4ak {g<2xN'?DT48|7-kK#BK  r.FYf&hT+NgH2F =ƕl TfCN€M٘JjV'Jdp>Z5`!JT!s4aTȃM9:@.Uo*IF᭹ݛ4_/W(I aNrސT&ꅓ洼òNzYZ؎t_jjEnߚ@kb^$u>N]-lB RzCEkw/IRB4o=>_H!.dE_dw2TRA_Sy#;v6Fl Y #*u{)?C ܱ!4e PnB~* 'SHj 3zd el)7QҺty$8ڗXCvu)+;292/6*AC]5]Dsռxb)Pz0Q)vv*fc월qx'O}ٖv&: E׵?%S /U#.U,_.\y8%y#aI6 *DI_C/ ǻEEd99IJ`"VA@ܣUQYpXV~yV)8٬M˶:*hs1ojJqt}a@E dN>}r2o=Hr|:hkc+L7t!]ƛsE6Pz5O7=sơ=< R@X'UDKy J)v)r3_0Q7Hγ-蹳PͷK ; ^HKf[/w#sm 8뇫}/mΏH,}R`[ްɉ^WC+wm󣻣ev?2cc,0eo)!}cO?~Ea*˚|Y*IEV;OwFam P)$_K炥 [$l[SJ(XI& >Bm b{Ȝ-wNXH5 #@U .E!C ydHrjF ѯt!a1Seact}͗- A?.F1G{OJ@R4~׿S $EcZa:7(ĴV~1Y]د;W%4NV@2qͶUÍce9hbqg x$ 4u`>GfʚktacW!Rl,P&kP^" 4;1cRe| X2g͎(+@%O-بppTT%uǝ[3) _@c,cct7Z lEPBu7a|`׼$fO`fs7E2bK? 0d7SKNA,ZqAeأ53~m +3Mmˍgh2gmPm x5_Z[Q]Y1=(ii'fJ[&=amy$IPf͔ӎ#&o #O|P1I4P1:BzדE@(4<>2ٿZ9AǪ[#^.+Q່mHřƑ -Q Ͷ#*}VfEq[[;?Xwe [NjVZ͚Ƕ!PoW(\rUb$mzM'+uml`*ޭ>YTVcwU9s>X֓:_ˆy/t#$ŦL,aoi{v p Ȩ* ~k4 _a Bg%96qx+Q3مYϋ euAVI@m+`M ʫQhbpC)0DMl܈OG?wfJ]: r.3a*ξɈ rPquSqv(ӥ\lͿLsv5?^+Ր>j ˑ . _gRi*jյ̎Buf?Kž+<1EbcuD[`Y-)߁z wOS)th?wFExqr_%|ov_*оQ_d[V!(?u@eΛE]vXX1TOR2h5&2PǼ߱(_L lrrgᇳ 8~7B`-|?6$B*rYwqD_"w9 BDnh&N|.Q׶lI|tZG59ͳ]9_H9js*‡#{7/Ăpi>C:\o㓤{VpjHYLqNC"9EX92ro-1)}iTOOR$_M\&\mPB!,0GxKg\!MeRf`c6eX9(&DzA0צǦXc!F·ZK&ڷfI_C \pYc zԒ'`RI:vYIU 8oaaZoh]Fel)m0 v\udg|̌:{yD i\)I{@8)q~?kg\)m?Gt$|ch4bN;NomvzǮ򈧉P 4JaӴn}όgzNesW$ɉf7 {F'osTQr4XUQIL1mEVOi?r:jV]G` Ýb5 Yįݤ6Q#'+= >(b21 ZX>D"ċ೜=8٩3QB*M/(S@Ϋ5Ԃx˜A/yFdQ3ʎ+T)xU_`mdYrH *ϼE?uuXZ6:͔0`3d'j^SD\5%`7mM`v+\%!3TB&2peG{#2P^pٕ<.(}XX\Xݿ LMv:'R5C%zy>1㻦s-`h'^ ]>MBg+4&>CDO5@6zpGIvA!)2Ѣ{:5짹Q{_(.<\xl\VvGzC#'LR6e &!flbUrVEĮwx6Rv. aX]Xx.&\lD: ,. 3 ,d`G) xqXB!+> =sPh"Irf o}̦kDךoG7A_p,[b|zz!(!!:l$6AiF' 1{LL'@'.Af "c8)626IH<:"}zj x8d*bի#SLɞ2FvAn2;A nzioA&]{Z)/S5ꪞ=Zjt@Mmv2l._T~?>30<B<.&)/j؃ƞhv|!mŋuwx)IO^RjլYzEKkcUkj=Juz\cӈ3w 5L)gjĦdğqpTi2 Fy!.1mqסJQ\>_04/$Fy$IZPɿpo;\uͩRk~Ӄǫ Ө0$9[M h8yV54 b*OYskIIsO{sȓiz ({^KֻǪ# @X4W*>V!;>7AuD[y7:Kvd(gW|\ ~6xO ZMjtu7]H_;MtTUNd;~$kp,(Rd,.lHH[D1(_hVl "z4ԣQOd2?¢pwXIh fR#@YvM̧ņ†OL);'1:u$^ϫٙC_Es}gb|dj*q  ·4c) K:_,;OCLr{b6 =CZ-dEX͞F baA'Qz J ߅m$s; LS_q߼{q+!aE*ǜ@>s|$+k0թЉIg\kx@~+:mlrIF4XrӡCA~I~ BN*b$o[iN8eax}&Y]2+r,uMEШ$W%\ Y9jJm%H__&627Q8 +&߫ݖ;\_ٟPޅ'ި(?eshO` $Ü=wv*xF~xh_K_"u脊8#R `4acsex :(-2m>Y1ψ)^x,6k ˩7_]c !і4YgXW-$ 阹_ 'CWUI.ljս*oB%XI`^*4'A/hl =áOs4fg?Z\3ՋhpʄIHK)z` 3y۩̧p3@qm$0;ko]RTfGLjżŀ52<܅>=`N'ʯ\+e@}-7` 9d4QARx{9 +YӋ{YNPq !:y;Ec e-964XCvSN`΀yTyn>GcvQoӆ?jn %4Pa m&<#xR >|LPH `0fBȻz eys!^) 88Q6sZp4 k^G7 %id4^\6^5-|T%D a)MCD;SoOϗ8LK0(9 Mqpɭ+n;9v_ƪxlPv'3XUrqђ&YmB Ur=q.t65EΛK醣'o^;k] hANyG]?FI%QH|se,0 `A-(I܂ LJ윓ۅ r ._D x {IBZ"Gqu(@zۚ.%u R٧a [% Cp>4'ߌK[_a&cMžqr/^fnIRc! 3LeBЊ".P. Qo3(LX:/_r94Ю$K~k@*L4eANMoi1ERT< ovҵoΞW&O[ Fawd~2O[whWPsB]s|UrJaLsXjRʹWqH- 5illp:hF?P2"\JuDNs=hvUI2vpPa26v;Ô?R{oӻ1" Dۃ|f1MX?p$"b9yeaB;=oI# O5nЧ0*jߍB)fx>rroUN6qtAlE\BBO>Mj^H{|@P29+B]%GN F&#*<vhK;Z$Vwыd(ǸJLrMJ o'$2H-?Dhي} bɤO%]GЎ{r eS֔s`IVCm"[VvS4𔜒b"Ud?YTS-,<o׍K\~#~7$Kjsf5˃Xcuy[37 i\OƒHʮ$+qT)-=?^6}VfSoU}h #|^S191@R)|'Pg%*)"fe}hG/ʹB*e>55d r Ŗ"Z#Ɲ,ݻY;:|R)bV cb4b0+o2mńZj@W3S!/=^]3|!@)5IE2Z{VZĺu,Rs.5Gb"Vi*P;8tr2<iȇ%gtWUUB&)Z(0oqE Q̣J~nQ|ν~"iNo| 'u *y6K>,-V776޺,ɑ;^[XN^0k_A[KȈd _C|IU3%7d .ђdْ] |ت@>uFA3P2\{'$s?x~m=t ^tRuv(L@q,ASE[ȿ0RM tI|hq~s&n9wK,~'\+*T73ueuRŚ<:LMugi2—mg5£V+Up@ VۀiIwΚr'7N^&U}&EJLyP 獏n¶{ܕ~>odpгn(=}>vƉy2=_iuk Z+! #b/lo nOV%6 c1'"^&ꪪy)e |*?N ]oW=[DDh&s^c,m;QQZ <_ BJTZwf NY3T*KxLQsI̵ȭ_heO]aAy0ǹAsM#tŸHՈ` DP,\(^E{2VZPe:c폜C?Y,I1C:t+Jã7/R %/3?*׬a;t.["=sfoRjt261jR^-t֕8% .oOWB%;(u<@3Cīsn/6xKe }> rWpЧl0BpFl͙w,"Cu3Pjw)PlQP8-(? vjL:n_:{r=Źd;kǁbbd;Pr6yQ;* O68ݘcFkdejQEp;(a~!&!!ܾ hދQ+<~ty {[|jiќv(PB4v ,<\yRʗ$E - Sx[F%akxG KMźLMyI=PKKi4lk|#uiB. j~{-M?E/yKx7n]ޞE6]hfb 5U(ZEiܔ%ᒔl -CCou;>֡- .b ĝA=N>n~jOjҏI#t$sgJpFUA6εƶ#]YPO /BՍpe*Z8ChDW1]QĘ#4IJ$+ VNI760+ߩ`"6 V8QJ@IJ5x  \,)&w)᱐;9 8uϑeװ(qoMҡ ]s(1q*(/>ZsJ;fkr).|I^2QI3_u˿zT@;ܶȝ!PD>jAaOыgJ"?OnYP&@42D4={gV`@IUjwbh:C$uOQ{@Q4Ggu`ʎ"ڋ y3$ܮd(mTŒEm,XN'h׳<8uoAᓙ1>+!0k/ϲxRs$O1X `>Q9l[0Da3& y&}mx\/eor$(B#%h rfs['%wy|wj/ײ ]j|,Fh %@{ pG=I<&a]'%Z[%CRiӜ]81r;?Y!"& 8@Aпf~$d^Bf1]] u|w#m oLoߒ)Sd&mmUGBQޜjm^pȹԏ+Pp-0(2tCtOnf⫙[-`݄o:,@VbQ8mĽM(^@oѧpHmYMĹN]QlX4Iҙص4v0G ,Y{b!Nj j{{kNQWHbNzﵢhF)mDZs&fjPr (a6Za5ڱ#@+MȬC<6(]W B7ͩ ,u`$̇Y?ԇ,LPAˍR ᶏo">K8᢯0RmK=NQ+4{?($Xm[|oqZf۪Ii 7XXo`*Y^ōo,u;9鎋uQ-Y\9p/v6/dRs[(8:H#$Og䣐 $+8{I՛^SPBwI/:;Ŏiom2|Hg4LLp܊aP%p&;¸,:m av'ٷM낱}8~ @"ldn*^$zo@zy,IH#P*tHFeUxg }MgtbN[:]W5 1fheflff8u4r B [*D49"(,s-[Cۨ^1Aw~`(-yOD!*@hݸaEm.D~>B{e(YJ P|ƙ)9e/`׏JdE!̼)dIC,Mȃt1nRtACIIu;H[N ڥ5Eê d7˵O^c B>Z3Vn@yŚ@'@VQ$m !½\h[IZQJ!IPR[BMV 8 n[m ힳ#D'op#@um櫿ƒ4  _sғQ2f_x[u w)k NRM$Knpk4Uq&-̓ @fZ8LmqG%̼n2.ÏRDEPg2>#dBW*W(-XxAe3Ebah`*OԌ9Q]9{vV M2uL<!$1e+6Sv-?\*gp]hX"|]/npRjԏxn -̲'_#QJ<a-i Ap!9?b q7t1#nv'OIf2w"R0>DÒkQD~ܢiD>WBWTY;S:@J(ʔ35m/X');ˈ&N#}L%0擬O Nresgb՜Ǐ.ޕrgt3KFj ܆PozQZ*(7 ur]=3IVyS'W@HkDLZYEb;m^ kQCMAYswNe ePݲȇ5+S^Lg_ÊM8 ܬCڥq Fx$* fgN 9ƒC'S6~9 I#Q>ҷ@Zucc-FJTEJ*7:ODZd!)Le[g?$1k󃮃OHUs̉.^%17##D/Yt ^-fZiXs1"I/RtJi Sn2oA`fɳ&P[f45,ZѝUwt67C>_gH16\څkpU2|?G4/Oa(/"GGF4SR)M:J妮E-!o/ItBمo8+MҮCE ͏om~D{"D)%t.E5lev)ShW=U4^l|ۖY "}J᎔H7Ӓ"ۣ=*\"E(}zIH2ԫZ]N͋C==; {ZҞn0p!eH{E r._ kA N xC󏈨ໟmA `́fR#i8d\pk3xy"W۳]W5UJqd! SJP1Έa7E&Ni9YS,X`EaW,rt1>l|-/e26z)k?_W;>^ v;J,G~m.e2_WX ˿k2[Y$¹s*c6E=p/"hVLoM *Y1谁 \s< yvXi/T_*!eZròJ9g+3FqT:[I[ƁnU!K[y^ނ%Z8o0¶t4^q=ȕ+'d{"> ; ]t0.Fbn3ς _ ѦNS I=K`TsV˩#.~q3a2ov̶f|NV1V-Z _NH21fɇ D⻽](lC* ۻhYB*_n{%X@j)Gd ENJe&H?:&`[-ފuP `|DC'N5wg̢7@RQ dA0LT9Q灆GXi)@Z,#Gr2cnlUia' UڗӀ77 49P[r-HuWXbhC[*-'j_ !vU҅㔑/Ik(Sǔl#ޏΠ6©uDݲrNDmV*/%o QE$cxn|z^Bbt/)gZNL.'_N fPO~^T҇ZVj?Ŀxh^Zt: ~ W䷒j$p11Pj S;JK auJ4}Z)NQa6E\ >Irp=fE*(HKPT>"hKI{ wf[G%i30#%;rx=f=yR$P\Ejn`f0 }!* Ƽ}|YىfHV֥^ )!4\gSՙ$ZBe7MD=R%_vHy(wOx;%ş;m+zUxY2KA֧w=uTRH:f@rYAt[%ލ[Q|6379V=˃")h@Yrt_$ۋ8v3ל2gW+vwlsiEї!98XTe]Z' 2 U&5+a2Ю֎1&./PbGu+Z)8G`@\ϙw9d@&?\TMeS/T\(P%̤!^˥!voFi|^5xV+zHdi;2]'VWž8mTqn6Orס^Sog1J|pͼcI[{(R;>nDLa}y+X̯f?!=cf>[ND.=Y/+Ze) *+d8n<ɜ;;şm`7]Lr$} aOk̳@fH`3Ӡb^?7wo4k'XK*t % N Um9 T~; ݇b,gVڱ}^r$6kNĝ,ElCͳ5#G/Km>H dbsqkkÐ\פR3y¼v& >@*QQK(f5@: ^jtǃ ]G00Q.@ҥK).ߧkvªVUjlr1_YrnGVFg0ؽ'MhB`fio*Y]2|"hBˌn/<ŭ$sNdJGSj_K|/b}ʼn9kz,}aͯ,N=qGi Kw)ivGVֿ(-J9CL:t ."qHDRn~6x&PO[S<7+,@MK>ęfM2;[W>3F=}8yy7;O8c{ոZ仩\G﹃LdE`81\*FI[xw6ks6,c]泄Uo.TpGbk*)v}qN'[~,^8tHGʹ!ؚ2}a3s[QI/^U3T|p# 27Dr[YD7kDr\uSjSWgsc2gϒc XE9G m^ࡺXCԃ:z#0 _ ({G ?^Wi6zkDaЅ7/c#wjDyלP*d1eWu׌h FDD,? ajgV!Z9^l0JUE(g뻶קpUg2l9,h㐰󼢌v=Y9c+}TBg_k*6Pj|>Ȋ(4p17=3ɜvF@!嚅½rZl^JL1Nj᳝q.L%3q$U2n #뜓k{^9c'Ci)E +mαXzñ2bj[1PP}Bpi&jaYd腍7C|_c750\i1ItJ;V R>!ft饍oKɫ Yj K$#b1!CK?߉k},d0Uf--B_l@FX+S# L)n52#/YN@7pڜEu<,B^ACOc  ۧo[*#d Ŀ| !$$K2znx@W9}j M}(i9z:ˤa5Cd|$HPd:G&ht*Q>kUx¸pؠBS)ehEӕ;?$%)?ž}+ ܛ,iS&v& FA6ᆦ?׶@=<@rgVV&u8`:y)~B?xh+ 609?l&Ҏm>!Od5H鸰jd#|rOyRS7O R []uUcWHey0nn>ež) L*>[ljA*i ܂(F4-ֆ?La&] oU`7 J[R݉`t6yluPe}uD}?N ] ;UOϬ:$*-κ]$55Gu.}05l U 򇚺glTV7,3g.0Ӌ# ,>U@cb:dDR"n@;* /q42+7 &;=3IX 2)i0}h&UIV7JJ!WP/x]Y#ܝ*"ૉ 6z!!86_o#rF3 "H3`@@rZYq/҇KI5| xxBs>?,㞑s@BL-&._NB!00चq/սď,‡AKn(]IlsMT`X\ A-$S sk^⺿#gt\8`v:΃z"qt(ē'd>o>pei t rj%@F_F [e{7фncqUk I ++|'-/#=3l|,qpynI|b'F9Z6eU"|%!]6{_ d2Uy-Y'dp'sg 5к0#Y, )J>oV ]ɾ ҈T3?2h`ydcGWKK0q]v7@OGx lW{FV&BZb2*}r ZTt,N j4$E0axlFvlfx`F!\gL],L%bYkVj9~C:…6psᮜy6f,c}K ^QxLxfsSb5 8D䝬[#@kLFnJ"ba\;L2WEJNغmrmp7LPc*6׵tB]NxiikC)5u}$NW3v5X>:x| i-0S(73Ԫ&6[!jlu.f p(LyW`wE03EcA!g:cb7 ?|R*׋kpĴ[~WLZ*㓥Q,4W%W5b*17VY^LCxn7RۛAnj .{$ʘj;A61vB KEYw.U]־z*Pl?-ګ:L2ɓ]ܦg.Oy/(h'K2Bj&㘞)8}p3k( a">q|p-Ix)9%LBP {BNk86[YW黓YzڀȬ ݀*lOg]f[J5~27L֋B)8KrD}Tz6-\?q`DhK-a2|;(VթlN@(F^%Ε 1;ȔˆXYᜳЍJ춮;WtQokY^C .H|2mOuAQ\'/#4sK5©}0VFthA|AY5 Z@5[xa 2Reז~'c|ηwSJQCa䶱*+ Ek FIO͎Cocg[b\TB=.i2@Ul#``I`!LaIA4Rn5_P%^֩e |tI!h#iz8L̃:f0 ˜H&d c$G Q/.p^h;V>Վ\譨%hyF!$,mSx^yז8䍿{Dkw GG:{)[$m8sg&N%C[_S^@] `Í0ůQ]+Q4A(q;=^kپ~"8{sإ(WY_)?wB/?z;Ġ s/U&Tw ys\KI nڸwg3_0 i %uuPALRek"! gZ ;;h1 zTBsIC  S(vWfxoE D_4E0LeT{A cYCj>HOr i3;ZN2S:1%z|gwaᥚە49~^"Y3jrbR1 pcЂ(ǔJ%yKct=}{r`,yIXȿCA<5_RJӓRa-cwPItEy}+>ïJhspa0dĘiLK6<& rI+6zfn>8 e](ITosO < r^B7ƫX~} 0LSfe.Xc?W Y=9oc|JsSA_0) |%Kyʡ-D*u6,|q-'A Ë+)%;OHhtMZגj2C6Y =7=\,oH= 9f2u8 O\cbmJAv^:~))`F+ P0B*7Q4Z9iwHViWESH9BAl`dDP1;ɩJ;(o4kmjU!'2\XǎZaC^F;~]mKPp + ܙK33Mqϐ Zy{[~#r39gltG0"ק@ļD+1eZ-`rxQc!kJ!bVمK n5WQ `cd03/E"狮wp'ż9LO. UZ|mOcoUc8e._Dۊh(f2ŷSl? }G- xR$LF=Q4.}әi"SP{h`N+}yn"DDnV3PhfHJɮ\c*CC`HuÇ `/)y`TqVvwdU wL< *9lr(C Ik{^/AXci^kG) Sa 4%("vt p2JmPf#yC{?*,lE8&eX;4Enk/%ְ=0῍)rb-QKZ6yPd,aC:ů{#r|ŁH~ YC+LD[]1y0U3h΀iߕr*D4/8 ޘ#f6#xUi miyu09֘hhXsadŰә.:' r fC)?e7@cEu% ߌ5¨B̀{LUjşAz4$ۨAY;L6lGH`bztR#Bp91)0&hEN^LC&t^EM;P@ǥ 2 >qڣϠ::]+j>~bbQª "[R.7FBP{:ܵn:J@5ts=῕)Kx H਺50b’!zFFrm1-a$3>A}4]Xxj:p,8y0@_xL8C}Y~𚉚U.T;p6l2C𛍜 ꂉՎlM<حU =(@!# ?0Z֎2J?5e9 LU (lKS_gMcWm+.i%}!م+c#fzS~m+GׅD ʏxT Tqy=E(a<fE2콠S[Y@Ǫf5A% 8 ﱛSgǫ֢1&}\1Tw{7fy &Zyݿ|nĮtR:ppM>} 'Rj'@/`\hЗ6 c^Lz5<3N˭P<'-Y?m.9!P:ScXR$G3$"wg|#nFF6~Hmu' B2p1KN= j8=M"ht&2TD1b,!!⤫8rd]ftcjHi2PD>@GJ糯©>.am䈍԰/z8eKF6B!T㓬Mrj*A*rg&5+Xh\-'䈡 IL64\G$>w S*'_"as|M m6.v=oRSqm .&6㛔{_1֯켃xto M`uFBIEGU3֫3E.rGག!7,E͐NٕavFse3E\T6)o<,߼  -R_t<* ˽ zP@''QB?Jg"s{tPeCSDEhNdNʟ8\yH0a>#_*>ߥeeĦwݙez»45߾|Y%})2ƲBe=t:I5dHz۩ X{f@| r`"Sl(Ѣ9Jz|\wt-,Nn4lNK]Mj:J=f.՚eK?Zb=D TLxU5F3G1ҬerEfL~[wKPy`Zr,XNxQaM>5Y4OUcش3_{-5=՜QQJ׾u[-|\ hUZPL.&q%iwxG8=3}CcM;b?̤ۗ@ PZq`N0Plu"5~-'nCmDWF|+26aZ$zl>Eh?F|`{QKxUfzv[",sc}I~~4&'6j,CeV {]Slq2Y[#f|(OEIC[8u"Ynϸr}poNP<롥#ݨ+3RGL1Ed :T!d`7*]kDekQD}Sx<]I |0idS*B~z{-tqGg-n~T^DGo+NDA*1ݐl:F$W)!hggta`ڔ&wj?4c fɴ@)|]Qg~">؆v4 /}DB(NJI%?v xeE\U=HZܣn+/~>L<Iq=hّ #f0B?~2 K 9=*f|'벞' x4'{'rLf-VwNSj}6S@?hʼO%<6vYucLH/ȧکnbx{΅bGY9*c %.c6ъqkPVqÓ45Wu=hY5. \Bh: 딚_͐Te}AV]?s(Bhc47L# շuOaE ksiRDV8\lU텐 QfѝsԆ|R<ʶ>IN1\qg30b 1]AixHTpdxi ΓF5q<>Ԛ9MT5d[[3dk<[X$*u:o}mSDPY'³tMG3s"j^VKn3w RLQ]SK* ;A\gn, G <&֑ Gd7֑"ZZEc!+$ޞ̛tjE%~+No]. Z- ZN HQ]zY{ XTaƵW)K1@ժ &n WzZ4v;]&^}Đ@BzN/A"lTPjXI.E<$m)LaC ($,wGHI.f3pB%Zu T|go+#N=;R:@]Ϻ}~@+%μ3^GfT$!vӒ6Hj 'ׄr81]7XCj [e@acd;V33ÔAc7whja(N.Sm& JRO ̈́~IfqZc5kG7v#!/PjZѶgΞQ [[Zg[5Kys߫|6vaXP /H0=/ZeS|n0H}orv{Hxe5؋i2GZgLƒ WoYzmI~%9/ӟE_{ (ɣTiq~MYE,%…x׾7ՑwR5Gޠ?v&X *Ljïu-I݉Ep 7~w#_ l R qJcH=/vk0ҥe 7\iD{O~05)7'5xOжw&sc31|+zCr6BO=Ǵ)Y❟句3 )eL`1Tˀ>\\@+b7o֖Ն]Zt &.Bb*Vx塯|eW}Ë89yҫNlLք sH9Va 1,g>1,!^1<`D2rY 5?LAUY"h,8X$QQӣ?\%Y2ӑ6H/y0rW"CMfVlzR|1j-M8((ܖ$(ӽ +Cw[Ȱ z$Rs)ߤO.Bsm]%(!22L1_OKWV0iViN'zG cfʼ$cP>^DժdeTb}aXZ!>=zo#u>HBߢ6,ټ-8(paYf6n@]/ѷJ KXUR[!|T9 \8pU,=LuV5~惰HN*j:BN;C w'5?z''tTb={FbKo*͐ {QB7}1̋FyE' fuΙw$ 3E3"b^!KbԒytQۢرpc.7J |'T =*PGDʇ9Fƃ) BY2ue fV~ Kq$SpHI$hX,i~ha79xG '  hCyaݪ{݁Q8OK0ӛֈdt2n rMLQϗX󚁛` >HP;ߛ/E̕N]:Diݢvh$1 Z08(tZ*)uUԾ"bD}'%i@1M 8l6Vm-JtABD-pj B9]()ۙ9jYa)!#<}2 oIB}/MqCK%E{r+b05G0tѕ ^=z#h7^y:qt Z[|G\Ǥ̳СQ%r*M8;(#6jYhj$Ks;9y]ijRG6Xjm , 4.w0ԵjDh;e;֡O?&xSR^Z`؃i['{qeveuĨ[Or(QO۫:.^xK~3? mQ$qIswmV=mQV\&-fM9L)|Mxki( pڀhR7w ѪƄ]c%]t+ m7L<7jA8"KOZ&܌<ɵ#[/*_sLqvSߨp.D+X/#Wz0;؇ ELu ,Ě8p q_-5AcnM` ~xa<4(}L|6ٜ\LLMCQoY9PC?f6@J#oeE*yl(? vG.zMS&Ƣ$R 5͙͟;w䕱nR<55#z%fV&<2Kh|j}#nLX]:yj(3,MiƾPN 0Rjja}o`ݹ!t]F3ǁVN0К(\y@fc@怳K+OvrJ}CVDSJW]RqņP_~F82vE>O?xF7WX8z ץ; =g .Ϲ_cx}_Cy`5٬ (]HIVU䴁 TWK|l>a{#.95G/%:.c\?~7cYC_*UՃ KM@Cjaomg[X0UE=Dva(x#|ePPEo?4&22E-WuzZ~eK ]NkA, >NuYwH!FƼ^*y?ĆTWޏe bnͰfd*Rx ۙ bp0O*@UoQ{ /FND,Zgz,AWg6Żyo|{26t2sZT6=l>3Uhr7 n߳=%1AZ6΂e252vUZnk<Z܎)iÆoA^#.(vKEI4&Rf@Xo`m~."MS2Sr.[Z*'bJŠ-x|w݁k]eӹɐ!B'dRM/>vR?!,FyVV mw}3)/sx{dV+C~U5>$ ~Kn-R홀+w*=vd";dwՑ \ 3,G x̹8D98Chj"L[Ϻchki J3tL0ЀԹˊ~}h"Ǧ7ш7kQ ӟ%n1.pk nݵ=;?R$rgfg4oBn@e`*W{9a %܃;."iؚ5/4LGJǵ7jp&aKkԟ"G{pemLKZBcP^RS/߸]O̩%9bPrv]jaUt @EI@9b hב٢ī0 7*D֙l |ڷO7ACrV۴2D՛q2:@@2:}^b:^߃0eChrP|/Zddݵ iTzHiBX^`1Yf+pxv_OsYI}?̢6 p 2J%.\׀ q^6- Ī/S쌠axN뎬ya "!-1M6 "Vbt,$~WC8▋,cVsGD۝SƛW0 1tFj[bPdSZq`Yt+dz~%yHD4%U=^ŘVaEe} cQn϶} (̬ASk0c%Kr`DbX//oX%8tqT䔄et(? _UAJTVYW?.Ҧ񉃐pі)VQ@bBÐr0k;@ļ&hű:[pps%m ?J[qՋH9nKM ңsҡ''yf}5tCClE 7Pw-}=AߝX|٠'zd7z"u$쭭 f>h-, ̖ȇUD<5Hn0.pӄRq<位ToRRӏs.7aͲ?H5J]X5TD<3:Χ\II%!A^UmumFh$XmZ}w D= Hw5~ݩ|vl[Zo?T!kt9O d RIN+X\" Vq:Vk?@5G`m#h ~>f00xMUR񎁛.qrf @ TKUIw} 3RT}Y /oXfICdz<-Ll!$lؗ+huy Nau˽\O)7_;-]Ab`kBBT ix1nc r=u,(W2aԬe5j$߿NVUDM"Jr#·^ƃUh( 49c׌^yl{U N P8#\>`6TR3pᴪ#Sľ<v;˪ HhC<ە?=\ K}PFԡu [:) <.K&_zw?FFt6n\67ѓ:iu%e|ׇP`Ue'a$[BPs3<>"wlrv+>;r ߑ3GqEW;~vpHWG}#@9vK63F='َ*ًXS#L/OM*Z47/YU9,}qj8G*:ՁHSfEug.}<'%2e3I r1z?[39dMa7%T!{S_O Od.u@5Ɇێ;+p ,A]7@,Ćf80ZY_:a#- o5tӘ>l#ՕDtt.}rwdshNk.tZ4<$t#2k&l4H t U V=I2[jYo[CuY'a32 -p25IAq񤸢eOIm sxe31v*\ee\kۑmZߣ3z1dC%i䰲qVa0K5[SghHA J`ƴ! h:AAJ=̲߁4Oɱa h,KЌvu{ws$ofiI7mn|k=~${tyvuM[p:\Ap d#n{/j&蹖"k(Dccǔo~-_wi%=/.e:IK"^Zh;7ncs,ΧPѥC4DvFI_&kGaJh( 3=&PF֙̆d=r+1 [K꩓Ka=jVH_|S%5<3 wR䙱 sX[5J(!3COz<4w EѬHw} x 9gYWdu7L8s'8$WFp2n&*+{P.ZC{'q [?Rk֔9zxØqCeIi뀙m(U6Tc_v.vF1T%n8HnF?$o*!,oaQ~h9BfZ%3{us8N>*;0(msC_WdyV.:\Z{C" Sٰuf(R\M*SS/7>'  v4ٗRy(FVy<,`aH,0Zߘp%ppmJڤ^E2Ljh'F،h.6 "fZ+q_Dj֣3MYML.1:a M!Jx Q>u3$M4j$c/2ws-0L!:ŮJĩ*7I;fA!N QЀ'l_!)Wf@i(jQpJq^+lkD6u(&hiPLWoR?e+m5E}T'otӄϞKӲ$?:G%2lpxJ:D(H-!/ǚꉼ:n 4i;ڶs h!hvf*@0Y48!M\%/?7uM~@wˁu޾SK )\w?Į̊^̦ mM"UFRs.q}4YբXVc!5i̅ŽI3gx3g)T<0)ss{tRce*jG`6;Az,8<2 4 L>@$b%|CIۋ"TO}rk>ȟ.b=^HYmzڱ3iЇ)3YV($CzJyٲc`TeE:9N*g#9 j;ԏ Έ,/Ճ\3mŌ+-oRu"2d&m !~V( LY7=W VXtu ty\_ӣV=/AIw[^qzsq.jDl=ފ0>gpr$i#Õo.I3Ծ#TM6*"FJ`moa3j&L^PC@̙ѻ̻n4AٞF h1k8{a_?^&~Cvo=oì"m -4p/QJ1b HՕ\h3"P#& gܟB蔋~D1ҽ80$X1ӝ7  (4Y׾ՋZڀ)M@ډxTO1nXC)0qu)"/JNhB"X>h "Y8!@j/LwGb@Fܭ63ۂ' ˑ@hqP6Xה\GП)>6ܸڶJHs6R:d R:o<Ϛj6 C)ٷ >D ;^o1ATGO@*oL  .~κ'f8%V8NZ䛭5C cW&IĜ|cYf^kz ͚ qT.϶$1Iى3C$jաu@J#a%w4Boef .Sn>ݕҁ/; W90EF']5Rb]XA VK @x}Q0s?}eu;e 0G#!l}7bN9$mOTPPkq_ݸegO5Ns+1& M .(>Ę1' 9zPr?lv| ~] lǜ~8ښicJ&19ReGQ0% Epyk;&5P-Vh l <)9 Y]hK+7ತ;f7Ƅ`! M.u-Ӧ]|6Q>#sAL Z oG5C6L%f XrxF{j>X?z.VnP՘WHÕ`!aU] xu1{iR;yѴvW_S]r\Bjn)"cK'|H'lOW'1 fZ;kAT`]i;KbtOr;{`@^*S_aQE._n ڨYN~F{#/= .q;V؀s`]?ԙÉ1*`nP8Ӹp;zN`nw:zkHgUϖֶ.HL`~n}8iBn1J(PBp'T> >p";` O+. < @L4>.{٪B\]je5/ ѝ aҫXkЙ?,Nadk̠jHG݁e@U6ѥftDrpf6HYmbˌwUG7(Sx)ؖEl"^o/}t_MAcݩq1j%5Js7Q"qyi5޲t=Z=D8 =/Pa ;j~΢ jA+K ;O]ޫ1B-P43Pů~˜VC9d~N~=+6:b.]NicJ qޤTZg7T)5ԋ 8$?-2l',mcM#eT:n$yuمM{0NߟW5{Ik* z%BC1zBdv2E<o i3I$I :nf1Z -ht FUSl<I=k (z{i7Ǡw5C2v&TNxVA~ 3FC>SHhdD fy xH/ |Ë~ |' ;ÐOrfp:NlHO>vf:5,ƭNԫt:2>K _ty/-y#4Ѩ>1c"U.waޮ4Cg2ە<;$l ?{ 9q82ή ys}&8.U ).DJ x,._sKsPy` F߇  Ɋ.[˙ }O^eN|7 M&ک ʼJ3K6]ȒG0Me,Cc|\ .p#dKzD^Ge`JŎKlsYNKχ{62U.09ӑ c)2 r[+ǸLuTߎ/!>yƫyPhLʣCbZI#kӦF ^'ֲ;o1\d_/ctg䇪72!u5=]j$` r؄l6僸 ϝ6Z*aRJ.I%q:BJu|d$Lƨ yUCat~hXx¿5gn9Rؚ:Қ@MQ뼲:c˄̨WƯya*[)Ƌn) H3 \^w5WD!1Cup`zG=b ?2/YU <1Ȳ$-n99XWfQ<n>~U S58C-mD!m@}k<ęAa3`)"x \u)z)| 45KQSTw`3QkQ(gVqhd75u^j:d]R֡)Kal('C[^^g'U}ծv[ۛaYZy&ƴaÚ}T(A) UDhPC~] Y `0w D䓧iIX#afg3c'$ c[;ή AF,<|zʾ*iseoD8`5A ˳yOGİ~ia&V ,g2&b4L)vTb bo`9/NO%iy\tx ozA`&o 9dk PbbIX'(("aJ%uSM+Dm\:^yF_g\}!Lt&+oڻ:;)'ñr^ncGѨ~{)EA͛f_z^Fb%fy͎۶ŽGA(t*L{!6 qHA Re+̩.ե -{G74^ɥ~ :eq& h!`%NN73CSb*)"A 1&)4l:=NI}!\b.xaFTT(Z3!.M8[e'[I}~Ky`46]^x@dՖ^2CE%/׆ )Qx+VT"M`8Зd RtE2<zsIX?WŻH*`؁jޯn 1ٚހ/>bN)J 5\ m>=2ʙl hiO@)0HbV6C6KV8Ibt4?R$,oDž@ !i{_-_t9"rD$ҋ8M44/a&*1}s5֔&ܶJs;IRь|>:6v?Tmi.HwK\i*ɞ^: eu3W,[6qYnfm ?nƤQc Aa]=25Y|u'~di,>=T:'8|Bo򡽻˸>}ؤM:@>fcI!64}8*(S#CvK5sf>sV{/)8rsޠSbU ǯ zme k4gzspCx (U FZFYhΤ83q1wǀsB͞k3 $͎B0}C[#4HPHz5w)ΓPC_ 5wTqY<;@^Z<3i:?ԫo)喋 'I`_KSAb0Ӝ"l5xO5+]JK5vP\~%7ʁ15w:Yv2مu v_O鄠D,g(US Hw7Fjm,wgu/Kj%zM(b:%9`{bIh]h{ΊS,o"D)vXHmBw1V9{,O#҈Y]RLk +yd BOzgid3pt/{ \c1,T?^ц?0Jt}@P ԞCRN a$;Vi5$`oIKL zƽsc{ZWV$Zb_4pU횋z ʀ"sfH3,uU]ɟb_Ka89toȂ^qx[\بRO33g]7r{ fyҒddMJj-)`>㻳( =F8Yr{)R%nԗp٤Kw^e@@DjU_}6ff$ ` g^ kb4,Tjl9O; i*sg96m4^7&#z[\qLlp0SblLD~1φ49Qq0_"EC. gw&שrw3lm_v pmgɰ?mBz#^vgf1e÷_YytZ{X^ihpkAg?!rˣ!kxEcJlገP.&/j W[$.69Q! .#!7>m1i.SŇYx hgB^膛^8x %`.wZƥB@TbմKaCѹqi3(XCრ0nD}I5`sIzW}[WE=A;yrO'ң;-ٍ`(MmFam(7{"Ei C\ 27)a~+OY;q% }hh¶a hJօ9{n km"3֜t%񯩤ݛDtgr_qk&[7cF/F"kGja05Fm 5 iג!}u#pvt}L2dI3@U rBnQ1֣nPQ okh8N|$W\h6)[Iߤ/#adL @nvI+'*x ܸ{bʂ={ߤM&Uo]e?Wiͽ5$bOn @xr9&mWrڶq^ Wr}'?7^; M㬗Tu#i3iǓ c3,`=FPb0pwLnFĹݼӄ'>*YD$5߫P21V,$fWVkZHޫc(?p9 D Nձko5].E0WepW+a1qYοeUe\~ #^ cxobS^䭰iqZ *ЩFy: u #+Q>|yu/Xo{2MJPPAj*'h`J3z/ӆzg3AXyCW]xV>;aAyRQyLmz%g\5y KDLBtYEw!l1 exOjhRx\ޣoT[X:@ U+} :cmjhab2}l1kqXyp?URp2Ҕ1 v-La 5ڏӍ=ASR׼,-A@+P sXǡk;z#iF?"ոN4jݔoF}'bMg=߯3a;Il X}]>,ܮPnwE;{TN?x ެ &1 Hs#Dr}gw Lm+̔iINc֢Yg I/D鵒1K$̆P[<7*.Gw*mm_#t/CX暂Ž\F3{f%mHziHidK3{>EC ed`%ۖz给Xeq1}}n *>XRہ?{Bs >j@"1umdSޕş~1U$:)-*m';+pa{UY_i+@( z⒨ Cp^΃qƧ/9A i$zVEk" _젤%pxԹ5SJXWbv'Fskh^/Kl#pC13C)WJEwg)'?jsTNK D -q- +=XS}1{NJ_4 UJVe2hD#˰p6/3UŸ0`X[^7r'Ed_!ƯCƳڪ!eT-XD{v PEª\YOY@B,9Z]DdLPT.5܊{H.NM1uvJkԓ JՄ_9Jg*$@64=]+4ʎfp7fh ʖ:N׉]@^UFpЊ+JץI4J8P:e8]UWB?VVj<[rc5,\u5l[i 0!uȕ=%"wp #]WZ^;%@9,x`u,>RԟMm%wPɰUV!I{r>~Y; -@.'gsޑn=OBq@dMװ*hٟrnV'>ʼ+6v:A o ,q"3~߈ ʾZ7ooFN2v*2-ZɊh(%([t[y& 2~c3|]ԉ0 _ٲd!do=~ף5ݮ{<̘5Rȧ_T4?-joZUmv^C\w,ۀ!;YKW1ԁhK(Oo"!ځ?)ĭ[ `]QA|Չ $mHz/8.ļAJ^]dLMcNЌƼȢDbx&c `2_/Upme[:Wx'cSiWֲy2-ϟ+z ilb&"dgOUq o',Slk Z}h}"f_r'V+;Қ&;d@j^x!ҞH۽@3јUJfKǃR/'\7OHz~b7'xgNd$c>8s=QzW3Hw7OFң4ǭˤ8NS:d|@=UuDΘ-޻,)?=!Gל{좞wp~ԘCL-l'Dp" j˿td|8Rp} 'Я7ݏY)$7ì'Vʻ!g8ۅ@'א|G"㭸ɧ\~Siv!ʡV`202pQyjwsؗysB#|(kd& ,&~VGG yS`.>Q/$4E#sv5!+}8Y.Ll8aX-" ΖU'|il$&BKT)?!7A#?&\RkR)yfB.0׷BmfR,Gq?_n).CA7Zeַ|J. m5'] E ZܧӜ&CrBQ8z&lzHYNGOE!#GQhyTc:9͕cԘճwC N 8V\&5=EuhfN%"is&ѐCR19U>⇐Iz5J 稓xЂӵ Ax Qr{hZu]$ ^7PIs˭GHG0jabU tY@Yq&O]CzvgM<"JbA[o:Pؖ}%r؞o!5=VX52uݒ8970,Lw%?c}TFZTV^=ȄT5Y%RKQ)1ek΄ZOUvDʖGhd`Ts/jeyԘOMæ>CiX]ku{x{ظF% YI+!ksuDƇUxlK_7]'fOlZ Ui)#V2Qb`&L[sj7\26g.@gBx.6__3a6GXО l̔exc/ ,w |2md{]]["NT%HՒ)/مg@kMxlW} @ڙӡ|1u_~/֎Kh`A-=. (״Mtq;%!/B2 D^|S ZHbE7~*U4XԮ 0)9Y]$EP+e/z(4uRhZAV>\P|,C'qE Dv׉{1}0ΤEPdf/Sl]I{>u)N vP_Eh ֩d)Sx)؉:,^!L'#û3(!i IhOv_Pvhi{њA9+W fhx%E钕5JEQt6Ea JQUP)j,˻,45i扆:a Fr`kM@Be[u7UXbi܉c3Js6[*?]-r%]T/<m;f{t)or:qӓHT C>>wdW)mv=ӏroѽ q"hcEd<"%%7cqR{QxJM #UdYG#A6 %yBx2Q`-ع d֖#Dʙxφq%$m|&o6~%/ٶ5j\kP:W8CJ΅eK ҳC;m 1=k Iy6n|3~w mtv9$@_aȒ4sK9t*]ЍqM$xP5gbK_H^!H"X\ux)? ѥQӜB y!3=/|;- ?*;"!:k)o"yI^©a}Y/wBK ΈKtJ!!1rsQ9l7:Y [th\o՛qNK/CREcK+M$Ram?\U?zvLO+8s\7{J^C+)Q$sVM Pz6 4TXi* w毪ŻqX3 Z?. __.q N\Ƣە{A3MV䜝ϞUT5 2{2X Ȟbd&[DFmvp/'*˼Iўl<2W> ;n1XNZJ\5mHC] Vі#n/EY2c ٹL'9tHb_Oݥl氀n="(][oTp?u]!>ZyOP CƧZ|%fbCׅ6EL`^r̼@R$hN`AevTClnIhpXR>ZJL lcOpKxAfLA``rxLfy2ވoɩ䐹tqŝ|xMO8-dhFm'@gm!$W ŦMjr`f?i2JaS\>K?lb@nZL?PzjwlwQF?­еj+inzgb MFQo-4GRĞ/J^9WUs[WNJE%PKY Ȧ9ںR6?ma"PX+vUHݕ'M|HƤAOR[jh 7N+آ1d5d~YUrq4.2_qo^㝣%x`Xu<=Ƿ֏uQaO5Ե)[JD4{ ~7+.<^ Xڙ<У;T(E+kLdCPAx|ec6wѮ <4+0lҵ#aQ ;J̮^@k4>i[fDl(z ѩjݞ-BF%V4GQ4GɄ٫l3.'ɺЂ-SypUp_lbs P.bxScT :W[Q $p,u 06ɬͺP~m}Yy̕뎠hXeHή&!{a 4Cxk:G?!:QkׅQ?{"^[ J9kv{9x,ZԞh"2N'v~ڃR ~['Tt"'*2ٿvOsMH1(@)k2?gS jmE9z2h fţ7Tٚsd2=nZ 3B+}s'MP9b&&B *68s s;"i+ⓜ35nuuw'aj9b؄OKՙI9c[Hx<ӥ#,N_ec-:O E )`F[L0X~,g.g?`1>ј}s'nSҮrpF?OV~U6ո)i (nwYq6UW|g*QzTډExRP/D${{&ǢJO=aǀf"  &F iayf]XEKZ <l)YyoHtMg:Xvћo~9͝6pf7֠.9#E g &Tt ڱ&u%50yaXf Ո{.|iH?q2mo)kmזnd[)ҙVLX4+k}S_;Ey8ÃTh_2?6sY01LUŋl}jܔ2)r '9aaJ+TWxJ}.Jp7}oz# &>*b]ڽW\He-C;)Hyub * uoygtKib1{=,) (GcfQ2dcXӳycxahoF 7嶍rub|HPK`Mxʭ ܎ddhъŵs/̒5Cld{7of=MvAt,Ͻob!GK#rgxE;PaZ o$z t ;#\nZ}oOt ~=z,Ӭ%SB,ݣ 92")+x\(3+uT_ ڶŎ ~AA,rtٿG$=&H)}?(wgw=L=(n/V֗7E9%U;K ^F&rYϟsv/9iBu )g!s/\Wӊ;ːM_';nvScޟ)pcq nXl8:SyhЍp¨5$Ge"j$ bo5ⰢjUkg x:a2*%Eh3vYҕG (aT/%1Z:6&S]U蹩w <Ћ l$\Hc=(` 0@v@D(A/e-+ iO4k_)i3AurH1%I"t鑶Z[wl^oa_ 'ҮV yp'U9ٲ@(-j+Hqyf.kQ|fӓQ >V)=,ՠnJL&ޡ@)f& X)ɱCWI~ -`#8-XN֓28wM,hp#ef  uҹπԛe夁XF!Anј:Dv}Ry]z'+W~3S^TgBgcC|UCu{IڴҋR/JD64>3SG:tgI2O~p֠_,y|bBNhmZclݘᘑ錖 :6=0R{2X*E`Kfcc4xɰ„{FfḟaO"U R{tAeڃ<;U 1q?#Ǫ](Vcw 8_ZQJ{ L½#t`NR.t"QcZ)0[ M 4٦Ћ]hTz^{Se?WLTB-{eM8O=' Cާ@bI֥xǃ"ǜ8~)X:XLѲ R 4As[ZsKUIÈ 2Z(` .lj=5ZE&FXa>i_r+K(*7oW+w4morYN4;bT^7 ؏*г#Sf(ØX[m,Xhltqu/ơ#9% v3A:om1 Y;juD7ghs+ #[Ff)!%WRw}>H'f IRE-6_}3ߖ/uB_oӅ*'jys|2aN^g?zk,aMyܰ0T\6[lv/0Y(Q)u!ԈV%/ib;@V6mDxLY0%W("HUc9FwFSS3s)I-?D0@в(X\"ȑ/)2C./[Zk4[-DbŇ?e(Yڲ F% KiE'܅4t9$dJN3"dZ$kPhwk<k90H(oC5؊z㉿.L[Q5> Nj'߬ުk^ )~,$.]B=6ҥP$6bS}Xl5@ţC̒ Jv. oLoBɒoܧݼOڏ&XٿSa*9]Vy@`D]R'*~L3[i+x%jVuF>Q_|2x-Q9%f؃ ؓuLq}%_<)^Y4*!NTYЛua2V)b^UЏmPFҍp]@}Kb&*̋(09M9O L%ڭ@{Ռ=YY|eR}~r\DŽJnbnR.@ՐbW뗇a3OSx*#OOUgp{Om ḿi}7MT.$/HFj?O,eoՁ? +1E޼$HiEdHSE]S K^'v!g{PpEI{Di@עy]!%FX +{=FsS`z]mk&mb#H({\S0~hP0P m㟥iKdOɌ|@w8G?JT{I!ق|<5pRQ(W+T xahkn" xF :hc}Q^wYo!i@*o_[S^ 2];|?E_-;6 !b3B\V&$Co(X1*hN(mC w8jH{NEV\yBG<]"zͧ l\J泤F`qnV -_V7_TER5&tr"6hP@i+SŠfAaL[PyZ>$s-k=~E\o #WRkII lXd~!I"z֭(O!̧0@F_ؽsah+L9.ImW(&o' OM+I$Ӹ"9\_MPE@x\dkG%`j G~ Z姊Q1kKV_'|3>: 0|wX4ZXRCASݸ;g `Q%W!-8C5m XLC})#}ZA ,00 YPPHfݛՏV; -7*̌舍F`=ukWɱzMT_mR׾_jqVGc+2;w@Aaep%^O"}>@_/™ĭNggmҌRrw::w%!_rJO$gÊLY ,RQY%i*Hhg~]֛<165Ž|7B};;`1=z2$wf\ֻ#~ =Ta,9)~q(4;3]}Y<daeCZ&Ki@6':A EX|m;rWYy[e 7'ߴdK!,?`r WzB+w^C<鎏I=2x:0-u7xɼ~>㊼oLiGt&@P@z0!|:9`u _QcMY4\Tplϙȩ̝7{jwtP'`9_p~o18HhY$*bqP$9. є1vN]PmЛVtm)<:١a"[DTj61bb3e&o.ս`_ze I4Wj!^2qiyE`G͡&?WZDzkă | dO`j<ɒtCٽ-_XEMR_i$h":hG\:)1Ys1Z4n6JIKls>qNN%G: ]|aUasiGnlqjGp,o);O߬PqZGͨvAKyr(`K<@) Ԝ懳.'H!Hov 5u\ /7r`Jo@z7˦4p =Q_IVк'w_o2F< Dž[H!(?I$߉#mWd[.FF psz!j16I-8So`L+ewF\oX SNwt9Y`ڨʯxlN -&q/PX!5s*qQGePI6)v{Hi92ʶjo5o:[ĕ l>QMչm+#XMQjbEfBw J)\S]4˪3NXh{Օ7B eNSZt\\'NcRLV=۰y^"ѥMj>}s ~a}LC~1|fEto)Orw)d`}ܿ n3cAk찎矯6/6FF;&12V+^z`67˖^"u9ԙ~;QDJdQId'<($W:btK~ >.YAW晗<9EęM3ME&ъq!JTM`=X/&2HKGlYÊ AReٞ(!"OKr\^;= 7u>} BZ?j_#úp A1bk•> ^%DiLSKHiHp=ϺьA{\mqssz߀?q'Pb-?xY*ռOah,-Y^(~Z^d/Q^NLm)eC0Y,<9}F<ա S:4ƫAH.h%kWEݮ8]LpG%bWuCsՑDP H1@(#YgՒ A(״tRnVcCh<"x4 8*Voub)<ĺ6qѯ،*u}/`ܨ@XZچ4vB' %=BJBTшOOՔea32!;"|cA}ίZ GiZ4}u I\Fnz`Zoro//pKgDoheo4Q֍p@@MjJywLƿ)jOCg]yX1-ꖁ?Bޅ5%q3cUD!3zpx3* nNt'Oh%B$1$Q5COLblN&OQߋȣ*v(/[9R~#kBBm"!60\Gg{[鞊s )q]oSoPHQVildRY!)0.d( ' 7Tnmh]?tvgǝ{хӞ_0*u+Z%!9Exn|Gu-b'hjBpYe%}c턯7h-2}ozr:82JmLɿ(F;HGǘsd@EVXIUǎ ^+cH_4AMDGO ů0Aݿ lmN S;._LLx밈Zݑ-\dgWǯ,aOXMzPc$'.ЫߝUwv Oz(gd~hי :,/)Rr@@Cc-#q!MԪG}i曥dFS'gg,r7bG[imKە=(5tU- ҕd/ҵ9`{rCJ&C fƤ͘ĸ9KV._1O/~B zntZҬ] kY)MDG9lSOTɸ+IR|`oLs 󘏟(J&yF9lg)${@h,ح ,i4Y:6MV@Nt\{0RAM!ŕ#<\*{g8H#h 7}%p,ВX# ߷9m=6-$X+pE Slt-3F JȨlHEGc=YTgodSDx<>C`ian/JSڽV Bh3H| x]wma-Z{t5ЦШ[~ؕ Xhm+s]rw A1:xW0`?Bs)S8 ] ] DB4M(,biVŢ0Gv- bds8u@r& }G:j{Ee_L^q Q_r\ T3P,h!s2g_\R Vi-ulDlњЉLW ,F~(ĮL7{Lp!e) U{&^"ְAZ65.lowq{0 ӎݚ v$'XSki4AeB&pQq9^#>V^J5?#,0{g\ywdҌ@u1bhp,lq5zfZƌo5-oO l٠%9.grQg_]Uc8Lub퍽@riy3[ f1EWz;Y\Ah׬@RL/ Rw(Ǻ»-Z[ 0ZyyJ*coWdJC!|#V>&E>iqDVkz9s n4@ zoe{Ah?H)e!8߆6\5WJbn;!røCcI"VwǙoީU4 )pcp2zN4i _t\^}1T *aQAHM=<%CcA7 z|y;NVT%^3;Blk אPJyM6N,6M/~|I޸ 炢艈w@r<'d4,t-d d&4cK+}6UŝB(-J5DJijG6)% w[G)#=,ֻJTpI@W¦ƫI5_ūX]h 6F@MxϾ'sK"^[/(|5NEzCW7>ՓYZؼ3?ĉGe % mSvWLLCSo&" ńghD,"/p=DezD2cTN%AWb-^ tf᨜VR(U=OE+p9h[H#=\UiNά8! Zk->:b)"V4`a;)Q֖ܴKJAfcU&-G4a|-4tTv4v}9@(d.cz ʵ.n%-5Z& f)cPd@uu-RV-%La`pASW.I %ܥlL۫ )(IC;y3~$o7b ԒbWHdt++x5 OϐhF{W-QRo6GkSvZT 8_04ݦ G| ,.̼s%YtY[BcRYޘ'h-ؠC>,̼躭_ypcb޼np2koZ%Hik53>uv36⻞cA*I[p^lE5L*c4|g~q`\rٲ!s>*#"KبKx5("kA9]XLͭ[&m5e5E߀yVVMjl]|1Y#KrN>c ('m"uf69MOR+߄=LQ`8DP_.pXʒt:թ߆i}onr`7OR0(`-en{] GңtcEm_1h^^o/'\cJ[^1)orxפֿ)(~U5/ m\wG˴BU'r|FLشu ,+rI/A< (v9ź=lR pq) iArp ~iT`gw1lfglYnj+Fr(pحOcDDg2>blG6?hyt(s7oUdVM yK)$0)oitGsLjh=K S} N+x@ [2ms9j@6 ?Lj]v;حl(S9`R>e4lNwlBςMdđM1,NbA:?xX!Bdo5z5$AhըDgx( 9?53WL(nWn&ԑՇ5 DS-yΨ>M&w%F=lZ=S/ZO-o/Oɴ$&=3fWMMXsl` -_1$a$c J䬲=BHФVU>z<[mW$H̘6?^׿oY'كBu,c#GûK1ցƇj,w: h[x`dc\r)Fk_!xB MHBE*O0Oj4ӋFQ*}C/j #O}OZILr$NT b%HNtcUbDSK-8 *Gq{S!gXmnJf/NвOj_0I~v⪀bĥ*CoTAXZ+gjDTZ[4!dHTX\i6O%?xAɈ{VM%E>4.TM:A\DQ&sm2XMf(|+3HhzA~. _B$w3숿HRB8Gي-bjkF{{$HK~UjJ"N=hy2HBP&&U%]bLŀ Rad CeY0]jLTCøaƘ Ul;Ih\hez(U.6*&+%o;ԒVӑ "JNz>ϋXBK8߅\׶-5"eo˸>Y=NN}(C|o^WA%bN2 `r6, (/H$[TiV&`g-79ADۊ.rxWН4f Tx>hO5qF!ͨO9NYZ;0au/~nUR\ ~'Qh&vf"(an.tfJx*ʢOh=P2 ]ib߽-~uf@"듺߻erBLnHMHjRjū&H]X +M5nGoZ }ͺg8 6 F!q^ ~K/Yn7{D͜!V6^K.p`j'tl@Baj~23PIݼnlRo1U3N(Ꮱs%YPc0{ڜhZ^HeT]Wj.=:<XMHG8~ DȊ@|)*GBŒwdVxB,Z``s&䙵,)Tjpe@2!wȡS^YK8f^@40$mCe)SCp ^[g}I!#2YniGa- ";2)Vj%kJ^ ˜^ On+N(.'nx%(aKG H|[4gķYi+t-}TyL/|e=mCͷ~jӦr9gF+!&(7%/1HI $OQESSx1# r[&R+! t7:Lܽ7#[',h̕*вL8HxodTEbd(:)8D}L>T#VVWi SlĠ/8QNQ/GtCu7OqϬq;Ǯf^p5 c9)ijhIƢim'sb#7n^jq넷q㋮޶z3^O| aՐfi$r@8/"Ůrx:Y$bm> f ugZ/ t0]¸ҥDyg-eؒVCN+Rݡ{Ȧ 09&xdN1ߜi_CCRjx.B5jnv7)NKOʅmg~>&2K4f;f.G|3-¨~߬bxo.1P}ZYCkWSg(":8X( +_I2a|.,ռzhj`E6Q;0`0s=UƢ'r/X)•!:?7^\ Fr> D+rSMvopt7gFZߺHhhF@Jp=$_S,"pRe7K# c4A4pvM<LRof@!RY S{EHjixH +:o~s0 mЎ'@4BD3>o?Sb5mBb> Y&2Q3 ?x{7D&+-_F6TULxtT$0ėҭ7N2:fA ZR!4|7Ь,.'ą.q̧gM:i5 $cBk]F^CaujOH:6y^3P]͞z5m6U/!bK]5!ûHG! =Ez! u"n!smDcdđ NN;ᒵolzp5&N߲2&CB/E(I#Cߜ si%%ˇI)[su *]af`1Z2.n& LFE.o3WEr]2.-iz;'=rB\̥5,xT }FǸBfƮ t Vz2V|pXI}ދ\㱤_Ce|^+^5QeEck05w#1E-S2Q;xHB( n^ub+ޤB5I=@&mt.&*嗡){S~/q=|R{F6\Q'$Q^s6pM_s罎%.^$cxs@70NfլΥhasI$HQ@p!a=:c4kњ ~ku_李Xzn3?C y);۹QNk ;.Fǧpylg 5,U9ḥoEv[$a<]E:'k9ep(ZtgbI 3bup! ]]vyo>};`:UL4,/hwx澤ǴM2s $t6튭?ພHx -Em%T/I|."[,)Ј-(w~GWh5#x!{xbNHl7 "Ɓ>OSwm!~1 h56r 2k-yq2"b#:.wk^ >7V`x@wPGD&*C`ס-2L4T~aL>g&/2d[g-1FImѓtq""^./ꖗWC{iFV#G^y*+mcºޭ8L)$2;T6~ t @}Ī*lkZNWK?vRxw@wfNI!8%-%M(T1YrDdʉUsCHΑܖUsK(3?s *pVv?X7@)I8phk!rpͿ2{JEzFȜj)3?8*f&Gbd DԤƀ\9}3aB w BJqx0gSnc[B>Ep q=w̖/ΉA h 46 at#=jgnMeJodx&E_視EvjTrqSUZ*8IU=¡/i x_Zŕly Exal0ZfF=_uR01h֓1iM;/ɚT-jI  V_w k@ug"nѫ\˚ti~~Q_WT4 Q<&S nQ3-0 @ Vܻ@7ʥ&_q#v>Om>9kNH:r҂~s6%YBl n1žv΢gRl^# QܮAEHDگ Fp~Yq.@!yee2 c_iQ㰝]塻>uNA, ?W>@h:?#NtfeL[c;I-Y%qYw[唽UB$I7|]kke3 6YetJbwlC%}.YI~SW&GRRXnPX~EmgEm3x_iߖnJTN<9a/WΖ_J/@Vwe00c*7dALũ>#5eg6?EL'Zz܂YH H1v'@jRN%o)nOqZE *Xb-8ߪSxp6/+TF-/nwГ㇤_J(_::^B.:]XaD}cr[eDC=Ycߌczc|߹l̾!ͺ+ \._s{_rᴟ7Q,\ջQpeOt~+#[9@K8J o;`\ RrD: ms ̕IM"QO.MAZ,Wu\Q37 kI~7z0nWJqK/]i[#vn.J#LT @لEٮcd%"y$iq^"q3K`Z d8ftwKĻӐ")A+ǚq4KF5p]7ȅ+oS76&i?Ii[_:KdY3sa8XY>qlxQḄ|sBGH+>/kw\{ e &5k-7B|2za\lBq58EbkMxR=Ł NuŌ{2 'qTT` @_1fqҟfe `c$jG2,#hWNSw*1p.A71OڪDVxӌPBG[rh9R@ "~T'w6̀\)]%/aQr9" G\?)19>@M3EXHC{ܟ)~* TIc#rG@&p|=J>W_O!b#|aap7ctcx}IƸ OAﺉo,阃Uthftyœy*0 )] /*&ǬsO({c["+GafhM s~*<5 ]nq>=+[Xy> F~O$դڃ fy> {cvߡp*~gcPڀ8Ka0M!@)Yv:4TAQ./(%5)kP}uӋOgޢ,e'3sQ3zߛgT]veeuw r?  ?Zv 'FXP$ʇxU6jt]J4LaC1 pvM鬆O cj'aBT(7aD_СLE`Tlt/uU 8; 'yX?7^k/reb"<95f^5vY!G`Vժկ:CصXPU $&ݧ\m;@ja+Yh _I^ɴSyW9'ZO4Ν'O N ^u]Ӡ$B,Qp#&H~#$ Σ/@ZɪƼ2.ZR[dfm*T$Tr}`z>>Oǜ䰙 +7s2N^faydU['ޭc?{y|1ެEt /_o$ff;{0t<HF0_2BNDt](n ?dw@zk(:w Z!>xU )R͖I2 DIվ-FX /g>:Jd'ɔA'#Obz)kpfC$k,XT{źfװ.eHQȽr$&_N>Rͳ&Ib룹MY*gZ,Y'{:pX"4G>go=?4RFݰ-AQx oHs2v>M#͠: :174X[Ns&1<$mDg-w4W ]{yFCm-&Z mR~f_iz{c2L07=0Z y'Ltʗi)BdznL)gqBԴʹ>WV6`(˘k:Dz84"'Cnw%1y:F'pqOQ$wjNX+C4 Gz͍%14x3n۞S͙s?=p%. $c$pm7I_v:mU5Ű 'zbIuo$!]+FYt'X?rw+qW4 gퟮkbn[B[S$?XsN3VNq궝lWFwp }=< h nxijLV3הnj`$1X0ǛqJ)@fziTzsp:ֵlsdJֻHHMywzcJqOлjȮ+[d3F*Bܮ]@qgԠmӠ-NYYw o,aN#MZٵ~vPxy0{ՕB5Flj;|1 Pu"YWr*|P|*"D-8SbExӻhrT8}d a8N B?4Ln}#sZ|,8\`S8u9:l7fv)B&g=-u´gڂ-1wX'8mNl]tOIc,{µ~1֤*k@ 39l=x%>u'Cڃv)O-7w tBCb`ӛ y cاk2,Cɦ@[16m>d.]~03}Y*tb}pe.Ce>py ʥ+8A*z s#YSLX7|hqw0PuώYK4CNpn]X=pK.xBFGyZf1עo]Oa~xŖR-n6,atK` cwV텊E$,QRxUT{up [76Z]@Fǯ^Q<@"ɇh+ '9_Crdwh {g|WUQΔq f8Qldq6 E:{^Y=Ø?pG==l-aQ6p/|5AXQU%V BECkF@V%H|3\,O6PR"K ~ѨXȆi[|b ~%>}h<nk↴k}yOxG .hB_>(acCL9L3A:gڶGzy9 ȆkjI9I.6D׋[C*I{\\ $Tg$~Eg;lD2OQ&(cz$迒Si:BL}*V'lSGzCH krnLyu.aQ*Yg&" YFBy1ӎH#r&#Yz1WU|m" ZxegquJ|eʄzw(ˎ2-nO4,:ц`QФ@kwm̘ԅ46R T`%"K Ф^F6CQ7_,Y:Y4u,HR/H吤FIy>zO\"Fo֐dI]I63/ %4( @ΞAFوgטG+xssRRf4Y;Jo ?ksQw,]Jll{y o el,z ]~@xN907qh)_XZpVS}~\Ĉ𖄗4' ;4f3߷vB )+vUXp'tB_fs8ŮҙFm}Ċ [Ո'wRˌg5cװۃ2 Z)F+iB)yXйiQuYRrؒ|B*>BnC &,wR7)(}--7uƘyNL䛑+ %]^-kbY@HV+5>҂@p ay/RzR@4a![F$sp1Kz8z@O)kT^>..Kk1$r =ӎOrOf%!ųNGE-mTV1,ҴeA'e=͋ÛjZIkxX2ijj-οFrz"41Cu/1Q~+Κ6AIJNgmCZR:nadGԖL&OA]5|\%i/^SZD'4 6i8sOo`3&Tpێjj8HƞE?[3p|ܾgĐcjYXXrPlaڼK.sKN'm#U \`2p+wLLjc_ Љ.K1&3Rф̮P Lk1,}?(s?ƐX|u\+9;?(B-> *. V˙CmSK|IQk-@w25,R]MSKH}0oUJ!%.K5ϗ.G6FzGl8;AѝqJdK=gJ44c!)U8h\޷ ]ss7rv<ƍ>SX:QZ޾xٹ{sp`uo׻7#Ygtq"Kp*wEK8F67qXAks/H-wKz+ 轁9p{PݎtKv&w"ϸ1"?wܩ%OXl!T.`+i?|2:R/5$YZ"R$gʡvEC%>{w}J'Ab<$͔~>eJNKZ1bl(*1Q B4?C)Vr9:'('ҳ) c.iXKGXO Uɧ\]LJnlk?b9M}EN c-vXf'N) QEQx׉j?eGXe'效/ w-W' =wC/Ҧ.ƻ͊Ò5G Jzm$F1x:k$5 G^ʜ8}O16t}P.㤞k-s̳M$;CD+~'.}dKf,-@Nt3W@΁QfTkE}gw4WG?\ԯt)q -*lvU=Rd8f\`̜a{KCo$Ye0!HI2Y\>S+ FNaxB4 D+WM+#.a3@MiA ɭתn:/ >J]^q +hβ~Ǖ:[3њ{rA?Rls҂Ka){b3 ëb:8  :B-`HDݴC%BvM <_&әWr I_6ݾ[4&է6TO#,T~N%{/%RE:}Fa.,ovͼI"D#nIZMD#3'[V3)ņ/#kNFA^wjPYA{m"y~d&93( Q^7f"@m O4',RƵɸM`QTH0U%nC36'Ar-(/I@lw5a-#y uKB/mGQ؄.U2\P SN5 Ԑ0SNGM[ qē7bqMX4Δ΢9dOF}u"`t,%o$ՑŌTZ,-bh]bgVW#O_jڄWf+Q3H#43~y7%ŒԻ=Es}?m 󙸷;1k,mrp}uOϤ t)~.I) vJNjFԲ`?VޜZZ? $4=o>#Oc]ryÖ́TEN,r "kb#866q:c,!x?矯AAܬiKbjl~Bf-H>:0f gu]GtF iZ/9 V: sֶ.hCfC',A3zZ?~ǙQZsJFѩ@pj+V$Giq\o!=hABŘ ,^PaL3e $ڱr' ; lc Z$8QݑYeYLvKvy$h@ e(",ABPJ8aCdXܘc'tBi1';*\gGg98`\޷k2϶ʹRw^NmmVRu|SAe0` 8z<֫@<))Ʈu. #P+/P ,[%OO/|fnkV3! l8viS[uy'LShxa;=+"b/֜FSS'D3,ozNk4QhN)]5E>WY}б#(Tb[W;`aR=.8~,mpMSxqu6sګݲN,s= >P FxiHy"zL{ mƙ{N4u˰+) ?  D~<^jO ޛ'orׯn52(lNA a-X,m3gf'HYJSpؑhs_ʴ{IY }Ejo _I\!܉9 i8^ފ-[-RapKLf+@6bJHl? |oHUX dK\}Oc1ZV(!!1ATpHl=řa)AeSAsGp Wn"+OkN-"eU-"mR[$M`Z&2Q9,*NQ28Zj?cjZsahqp"ȈʔgO1 7-"<!(-qc(hZ|ov_co~FeO}:f7e#g4(~ 8"KH7Ib*쿓=JGsSb+Ym灮J|Z:ʸ㖚0BUx]B g#ؗxlK)#!Tt"@B| |nL+Uh}c.b]u LwX9|:qy',WK^w~S[&D 2Gjx5kE=..fЀծM&KOi* e2@};͜{@id8ӗ *@v71Č K_ó&\*t|(n>Jea:&tٚ% D/4}W&;\8BpEqz`-vvD I)E"H4t1/u#"O!.LY|$L{ z.?yjBYyً:0okjZDˠ1!FK`oO]p}S43C=ugMҭX?@4.sTMpVQx]=}zu @}n !,jJa&@d*VDŽOjai] wS*~c c{ǎ"w赆 ;[F?wqg6_ZZLb Z>G^2V_qVB3oͬ8G$ + F-֓yɤ*w)RЯ0UG$~LyN\5m]8'9C|dp8S{:&NxZrm_`+Ϫ1$Ҿ^? $\S&x68WtxyeF(de{zvCA 7DRTNQgrʬHE"-gVzYPQwl,vf)d_ppEPF;PKKC3ֹ4'`XU gO@gMƕFDW"@ "IODz6'UՆi*)KMgyyEy/G?ֿ \Q&" V17WMtt"CVMGY$ŊkK#N`cc[No1s<-̿zȕG+Iу zWRnkL nt>x ^@Ue Yu~g8n΂zhQ lj~MQetOIẀFTew%,tlڳuէw5_ [mWvܳ&?}&Ĭ@ ^SŐ1ϥKMc7 jD2hd&mc.ȤkT ,dYtus$B(Oֶ &! s`qbC<-ѽ)Z&W{ If". nկ'[Jv$wA^{+] WzmM?xK cJ"TBٴouO͠ iUrW>9Yu{^ eS6aCԓY:̉279(. PDvc q\RC7{Kwoa5W\]@*W(ÊsP*8i^&|~94*RX ח. [z[ zO2vTt/T4VK}R83 4~ft̬:wogNcg:RKѫpF|j8IW,bqiNZ^'h.yiR,Q/&@S5Xf٫׸~ q❴$N5p.@3 .umҘlR_ۏuU1 ǗD3e d#yE*mdTЍ)֋_C2b?HP%Z!-U醃P'$ ?EFKx7y0F=iJ:bII%A= -63G.6u6 \s^R-*@,B)̏qO߼UDܡj4(_:/'dYqQY{c_Ŝ5|L;M66Ж,ribO)5bK^:D8!I8gl"4/dDxf8˚9jroQA)V wבTR.kQdCǻMNy Q*RWephXf8QЏ@M@V`./ZTrzrX4Gk5l숫h19"R߮_{$d =u&]\ZXM3&օ[P}R { \X~Yq !(2ƴ,s{j~39ШcBK,B'ysXŌmN*{\'X F0 kR$h=9CձFe_ rhJ#Y ]?GO=-'wU!-QWD?|Kg!#oͧ;|Oc%* +eؘKNK2Eu4q 9S} NK$;+1PiX 6݁\TԄyt<:ʸ|Fl/ak)|mu܎djj<=eMN"^h5VVr{h ã\qK JCfdeBxQ0 ܦqxK:3x%7~.-,r OT϶],wO%9Z9wޭ@/]TPT^! 1cDZ6󲙤)2vߖ(d/emi<'S̻ENvHfBrdlZwyЂ;cϼW0aqO\$ oY6P \<*!Id R+!cz&5S!\ۇޏ:ڊVت‹^WSN|#ޅS:|=dvR'N/oqU4:U[c Å*~ic#ԇwV 5I/*u'MŰYpQIZ?ne!ӈ%^XMT- k|G]mO 8fmAm*G+cZ9NB-&yO-PI pk] $*GN僃x&;9rE>[Jѫ͍@ xHf5Z3z<09c,O 6)sĴ f"Z0:e-kוXKr6҆uK֪6NWzMZTFjz\f;=jO0DI5{@U-n!R k *z~O=PBۋz>?;SŹ 8'Mh:v0[Ic~oD8ُjti( FInRo)L9^hCSW/j?1w*T / :)o6wԟ>Gf ?4mWm0fD/o1wv͚O}m*YGq;Q<Wܕ6Et%`x 3{6ZLrr{,H FG.'p"@}q^%P"JLQ*S܎(ji}Jy.0$j`AG_Q /+YXypAi#Uaup/==8,0=F(0m AoaXGtR{HWH@`WF`w|=!퍈yѺlm[wC3T!BWDD|_Ji_g= sB&@6tqK;&6O%9)n:޻fvzJ2f/BԵ0jYG! %5Z3uKzsHWKԫ3w(`t&HQ9fn.rSzΑ aX o܆hL;&W [aKl9a=ƅ@^1SHi%(s #~z9ȹu*Yz0p S %7!mvZR3S( F}A8S<^q}j 71?Ф)FG~AS4ni_b-MB(bQTśMӤslՠ͵q^lk+ckinu﬏ ;FAsj}S:*j48<ʮ!rtDwiEn.A/+a(,(ƧqFS#AQ婮 ++Ʀo4cw sbB4v6O([xUE֑y@HNWcrq0o_A1$e b'41e,a`H'\ΩʟPr@ʗIS7pT'SQdz %W1` JzwaK1xh [ kj&y9J_!CoaV1bQ/zp2%UM# YVb O^s(rचiԁfW lF~bu1VWlwC!\\O4Sm<^X ل!O^.. j||shor.ҳRL5eY\\Md/7L: _s xi_Y,w/s>O72Bs!Y"t;@^v#қTqI_|a?X#In?w 4mG*ʼns){Al&fZg>_êgH9@szh6Z6܅&$B⏕cX+$͗0ɩuճWlA+T ϴ~b߽"k-~Q /z ASSQOi{&4/Dh* ܞ 8 >ހ par2test.bin PGQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2358675 SABnzbd-4.3.2/tests/data/par2repair/basic/par2test.part2.rar0000644000000000000000000031000014625637207022721 0ustar00runnerstaffRar!- 9\* ۞  par2test.bin PSFBe>z7[4O`i7*/VJ A Iܚ2y*A07n@o-fiG`YO^ 7->+DJ~{iE& v>#/K!pDkM7Z#\X|>*AHi񉯭w@~=i!7*y:b+^l>'LJ%Irin4dvzSҗ)]-T%@Q7+ln@[Z% ̺(>+N A~v蓸ᶝf c~6k|ɛ;3>Jl )Z ؀i]0;eqf4#BǸTuY)C TeߊV=\d/- gWe?Й|v&#I v 1[RLs \J޽9mmSPd5jB:[˄d-S6^۔— _WFo 2Isv6>az2;?宥Q`D4'^3̿܌!KC.&~%ŨϟYM t#KXB&Q7lPv-lk $ )"4y.:OS:ҟQX8赪>R1q3B`t1Vjtu/ޒ6wcZb;>\OSTo=Ԕ7A*:oMY5%.U3 1ފ)pԄQ 'sI3J9ЅiC˓%NGjrr2}mS Prߘ/KxduzN{dw g4Oi; 3CŋߞZY.<=P# u1gSYV,V8nL-Z4.~tm~=yx ?!)qH?%jLt%um, F1JKk:切x eoP?h)cj`SZT:xg%znOyin%YAF[Y"7 vflWuW9TơGQlZT_ /gEn}YΌОLs?4jcYI4 /^8|'T$h02~Y?re/vfe2Ӝf [:TH۶՗s@dG4lw ci9_%I{ ho!{%}m$U_.~0 k%aN5~@F8&. w)Ԛgh3?vzQ Zy!K_ԝ5"NV&gYDyݧ@Z hֺ1*Ylқ+O5~i 7D!S?OgQ ߷Jr,(U1P3$o8p *(.Yb/vP?I8 IKXYx*[;5@3d \Z&mEHBǟ6gEa- 1~p`>Jb}˘j?/J}{=(ц7M=@697ЅL?OIZG#1;#Q soC.&: !X:أx0bבyM'Xw'aib ׅĘԢ}N \a;3.^':jJi+sVqfhq409#OU+U<]IzghN:Tbb-̺#LXJԨ]ǚ-'ɿV{Uy&Ƨcvu^8IfR|kwyc̦rsI^Pl?4W;Mc5}HkuiOju]!Xoek"aX?4*R QpUn`\NPyzs?ȂDT\7ƻeUwTqڍlOnٽ&{?Y~^Vb/XDu)*Oq7oa =xSLI\%(`1q6LF>rp:Xq 2 ~lOcLP^c3 ;'wXuX[]0ס(+?qa==䲻Ү8I_|yû[s% gJ"UFng3Thc'C=?!"GʷC*RmM]z;dt.KI/M8Iwm8K+O.h8S׼\51tqw=RLkUӝX"|UP ^ m ӽ69PzAt\j;T)@RGOrӓ5Aͤ;]Kr>W1(ZA,~"v׳鍩*;t>,DQ b^|Ws;Bpۿ P}/`3 Ob3=m:4_O^&r|\&$ C!I Z{e BhV)V}^M]I^kp PS1_5C^v)vbwFcP3!׺İuA(x^}3$6M&$˞Gm|MT C?0fk;xD^`6ʿ"GYPV5̦J't!p+sw[~ C*L+ݙb8E+& Ë0>'W@ %"UB.2(s3Ǹ nA}ѕʔjZ"(sY!?E6ߟ"xPxkxc,Mw !M/5X w+ K9OZ 6JRU15yS,B/3hT*&pҏtg RZ{]8sQB4bs>]=,;D3l}δHY&J՛"(D^eɕ 4v':,i,H0H h# _C.%dzi]&NepdoM+'ncil؋c6^/y]!rY"*Ee~[XRѥbpb_)]hIC{3ܭF>G+ǘ*R7B2J;ݜ^^,3YKX8_̯LMNyhcn=_ ;÷#2*\ޞ'yku QXٚ*ʹ #9 kJBhQH╜ 86sX͜iK":5!{܍ɑtl3Mn<'|&jR1bEZ?Ɋ)a. ygh6 ]Efs,okLp\.~KY٨{)d(hxñ]OEXp6a<5x& DgDKeG#ZREqKƜGxcZih]4'*ԙ ),{U ZoGaY9α^xc 理4h/y]tU;7Z {s~xќ1*O|=T'=/nVX[Yk˫*`{O'm4LeXn@!36hH JwkS?!5AlLjd@ I}[f4|YlTIأؑ>0j8" nu4"]|ɷjNqt!QVq^WcOOoӏ"eGFAyoLqʛf7|HYzـXSqv mjvs (٩ôΊ\FI'Ɍկ%1Ec\6Շ1 6j@rDqmؙk^Bn7  6k~Ar7&9Hq5M`Q8:ў: M }- o x72;vjHbS@BK-5kҖplP?'8:{IUHvuasYK$\y} ]~ E+FUǙ,.\Nt %dEXRR] lS*.dc! 36wFV!U0,diӃ*S\_5jAIe,KI* :sm0׬RjYJs9|Ζήݑd{vC#6/I!A!%.ߝ7- 1I5.` \^MlA4yȕS h~!VSghygb~HyWP5Yd6@Ccc[s z<2gCэzEQ1bb5SO_)or6 f\,C%+T[QPAc 'yFݧ_I. Jyj&A)y2x xǜ%,,S9: >|S+j@MrH3-튗$\*ۖa!tx)]+7?K ÂxRt?uM-\b3Qh;oBgMf]7baa8Q>]O:yvoÃ:#F 9 AbFdsZZVN@1 G.'/L<3!h`|76.e?:Ec !u 19P߄ _AfPY:z z6*$UVvz/9cONPKSZ *=bUXU6nt<%.QnwJ19]KST.N |GxF׍TVpRalG" ÄYt.180'Z#PP5O(m>-HGڬ7k}gjUu6'c .S\:u d\)ǝed`fH$DXb?t^*DVbE9^򀳨suq;=OCWYs4NXxH ;X07G) R'b߆*yetXh?)%x +Oi8p0%+ߑ4fF6gQಝa|ܪ|} M]Pbv<0$-I^sBᴽH:+ XiN +ŨZj< N.ϫG*%T_ y3DgS1LCgw;yxT/a%:L%mDEL *%uָXq,w}ATuP଄^z̎|Xmi@yT ᚭ-;ta#^qvwa~n [FsL^};Si`+1iaxF+>-{S-Mju?]z[ȋ5@tgak9WPԿw":EHX1bgEA]w oduL.WFi.0;߽šzێ!QѪzfrmXMk VuBo؝=̫rrdY{0Lc,41 2͋$[j40)Y\k;ɖܡW\rŏ/U\Jr+NiP=グ` ǶN>r&k25#s9Sw=m#5# -dƺHh0$\@YjsdE^:hDB2!AnZKV3F9}iCkMfi%C ɆeVdǞcV?'8u r`/aUd@~ H[ݕq⒆kG .ԭ^6-1>} ڜÍ#*'T9Emza VFWΔ68(a8/w3jd:K;L~k9k'ӟ:3^o*fk)'BOsh] 4 p4Y ŴiCr_~מPa=ߓ{st.`9jq)_kO\:K3ؒc!0_T!M,v?2drf8BPoo^U  J2Zh8.6.Mܞ';Dݻ=i߸-(+hGOrN ZF,z8@ uL4 sIeYOqTϛ R7q`ڭ!\Jڼn8e+|9 GMq>&My"`֑a$Φǣ<=4R!OOk}ɵHuv`2*m=QK;*x|q(@RqT3WjZN; E7 d2//f)jz]]~rcFh;u ]u7-fNTFUA(Bbp45oD6 ٧ruy˖v3izͣ^MڧOFE5p177&/TG'\N.oT<5hտAkr_ů7{~]r)A/T36)xC`KJ:9\L.CV4>SإF/J.Ŀ}evi)sb Y6ˈ-O0V1% ؼzYQtmVDHZ,Me?}l:!< >'r-ab%9Qj"ѴE%ױ1eMg^I,6S;[4!g!7`RU?Wمa/38 !ozP9J=.fDDճZM 5Ԃy؅بGƣqӻ]NA-/&8HgB"78s0[(ev.zh(U#{l7wiQx?o3ÛaMZ5¥6>;GyQt@@F;q~y{/D[K"'Fl/uV[ەcHz4&poQs=?tq`1A usid$;C`b"K X"9CDž}SB3aAu95[U}O͸OqPrߏD]: iڽ͘t,Q3`oc1KEiG] v;#8Ow5>h .,[d/Lm4*-yoX<"tTk ;жz*I ~wEҌ%j E䈝9JX9a/>#H.wBN#́х} %U2/ p1lP_VY ^W$"[LJKuXMJ֔F<>u'ۚ7w+ orfMe$S(CIB`"R6' )Xha R* c.p@L܋45|tg@tH+/ Y; UDL99s=(gC?tԊ},b2xe(7enWB-U*ݼc=~hu1W\oWΦ?"Ck;Ak&V l )ӀP{k+E֓꽅(7ܹߚ6c+Xa_ ye#R3: 5Ɲuc.g$??PEqB5IB8i _bv]1G94b߰-;hhj b7O U͠1=`lCp~X ]%.&%!R;l!=ްN-: 8?Ehrxr4K{m+R=*qdl!/y]w??A^dI69 bJ4>.?dy g Bx/ `ߺCّf=0I4=PE Ȓ̀4\ a{#B*Ǯ\3aN_8/Dtqho~TG[RO\uAqѯ),Wv2H a oN?ֳwx/I2&$G/Malm#)Æ0۪ !VkR)0/mySzǔ϶7sb̴C| BZ8J9=lZ1XyyU_,e`HCEJ 3*[8pw8BZ<~x߹a4>f͓ LE!GC^r5!1t#w&5DHt!}%IǽEVo *s\YmOv t~Bs y2|/ȊI!7s&ָĘ[ hITyZ4ˣ3_)$T&JbhŢP?o{VXRa̚yͥ%Qdb퐫{aIמ)m+^l^Tfģ;B'h%oL(/6\LǛE;ˣљ<ЕL#b N< #CIhM`rT-ޟw:>mTWX&xP;* ~7R<H0s^aBM-= ~zCR0}:-w#Hڠ0'7?uUPx02ݡ#tN5dg7!vIrTmW*HpHO]#K6Ǵώ%x;od- Xzhƫŋ# :79 ]e8Eľo~t{!NO`i-A>FDR~ /ID'-O1?j1$;Hڄ:ߤه.Y[UHbd`+#dz4+y-CYBE"zmDN+cU"XLyɥVWdꨉAze$m%'-:*᫏JO>_'8IkN pzwbOB +M\JR}pnҾ/Vg@:5񥀰sOQh٨#X'bveֺxJ&?<P t|.cZOn4+b.ޙв)Ygؤ.{:`@޷)8F^,з`T g9F >)GŊx M9Kpvzb2LvALFG, _;)d!2_ 3D"rtVw&9ȩUjg'#.p+n2=$;jJ%۲{tW D0hg:CUcqHx7_pLCjk?ʹ^;0,ZY.7 |o.{p)Ri{|dZ$,GOҞC<CL5m1CnRMbb1m Զ5PX'mnؽ;EU8 0]KMp~}סvOT* qM%ܚxRԾO1YzDnKzRE՟COq5=krXg2 הCw>[^Nd [1QaF[1+W؜"B+i'hwl辶$6Ro֫>VtWB3lKkQEBYHNaL3'Z5 D qZV|ZD$ J7)kGdJ\Uc 3uʒsQ}Q08Xo6%' [>E%6͒f$' &BL6M Sy}*!d /1 Q~" F_0X,AZR7yW8 ْ^]Obn$Od@ĹHI"%&DJw[>('5ϔaR5B#?4s9^Fx du 4 / 9 /&X Ldo#]vNÚ'.ƥ!79l1 F 8>ݒa9i_PdH1vUm2߰,F%oMDOբ[ڮM'>q$9q~fCzQ#I6ɧD3Hw^Gފ/N<gd kȒd沉M_~G~v"fs7V)o_#ɪ=M#a8S|D kۆڢ3aSP"Rbn Y^ U,Ȏt{:#JF84PoKלEMהd:5 D$zlXmd8ZYW2~,\TMI%wWnk*8!Zgm.)ǜIS}V淗"R<;{T:,5FY})U1c *uK>l56JBvm ͼqA r%jTB:kK&cVSD[n7Mb&4^HzAT8.%Px^ǤN0y;b6Ԧ<̜SQhy0$yˀj#e&t {ȋt, d>&`;eH:Sc%J=G21LZOrN!jqqx_Ȃ7aʌp tm6fP!b-Ρ¦'Q]Nqܖ@w<P3+͠g$m-.AWl7="}|7Rkٵ5<@{}r=:tcOŠ |*TrN}5q4=u9H{ҬBegީbm{nz({R6khQ𕯞k寲 A#QxaZOa#/{MЉ9ӉjmNvSTb 3X"+`0'|7/,R):gW$t ^vBNZ {֏`X PߟBO }Y<96 CF89*1-;˟Tؼ+"InxHgI?´lٱa·۫_”;O0Wk3IL*%h $t M"$xaiЉB76IPͤmqab=ˑw}`注4·LϚQ͓ A&y%ZWqGV59U>7?E` z>mow3\J Jڱ*.RdjW9UcW'ZD|Te-P=D`&dSTU v2[y-G"!6txF y.92HTN+E̸m6uEPPxeq!q͜9bQS;U6AI=ޞU%xqJ[۫dٟyʌy_u |ֳ •9ln-]~^{WCiChblF81$ýJ+5*Wo8)'9'aMCEGZ.BKk)kh'@֡O;<ӆe_P3}Ի,~&%(߯3[% VB[A3YFY\PSdlޚ!=}).b>;ՅN=yAK6>>c(n8'1hMěm_Kz]嬄G,C4n{lI);yޭ`ѹu3QDXtV)$ gjn!$sQ~J՚V\1G}fg+ .6oB h6xlj#t\!NuTENLg 1Yu.1\73iEC`7^ʱQk$ \,RI v#z-T:kt;>n4TWEc Nm2jEJa>X>%=`ԢIY4|m3⎜t:h%6"՗6M&S@t7CrA 'n6R˒pGղfhQ2^rRA =mB"O?w<[M rdTc>Y69 *5H.a1vs ʡ=ඟ*\XB@ a̪&/(4 񺑜] ,Fȸ([BTwƽ_/~Z%ꉎ Ւ Fd}a^E,{h[ϷfjO_{7_ jcp+oM㲗omV;++|}BЖKm/,b%ɊcdjAjBRWz _HBe:9;.*yj>b#.G̓jAv-iPe)RN0Dlh E ]$Ceeg]+èPtDC9fQ2p6梼r`N'[B65R僑6f;b/M+k j 1SB@{1_Z) WR7;XRHfޛoS\ͪjĴSH?!Mlz,$ռid,xޣ^΢QO9O4N@*`&@:?cOpeA'>gǥ8' h^ Nc=M_7YBrV 5%ͩ̅sKŧ\g3e|Px:ڡ.nYw>:jU`7,*Eⲣ%08=vaeMpfMD=lװqMGl{#4V~8bY\AXh#jgIe5h߿1|e(HȬkޣOs8ϒ!$ "7חRՖ6~Jyc+Kzc;o_gߋ};6^c]-D] q[-m[HuϹ[O,.|(7,,y?ۑnGWMY3g]8[=\ޙxtݑxPWUtvUQ.(^=? wQf59pK,=^߾CXD4\ځx|Ew'd>İ yhZۤ:>|,ۋGBReZ5;~UF_|1jwT: X0\fŜ$a;=Jhsm{ ̯<>80?Ǩ=F"T1z<(~Kq }'$ Eي5MM.jX* x~sZ~--R-O+=+Kbe%4ee<ɮ[ Ufb358oͯ*toel;㞻8eXf Z}f  JL0Ͳ0dUG fF]=wiL3,WSƴF4,Kti*r(n L W^m-lert.Am?1h9rP iNN5%f[:lmY^R^T~t/ M3&#بCH=E uG!թo#&"& T~QzfA'R0ժȳ<rBz%Z#hw G/9 ݖ xȪ8Vc0"\Z=^|i=Z8*1 l%O#+TQI7eSxҢoSR-w/ D"8Sj$\K^trk¡T޺g>>4'T>'E߮K^{'qAiψ&&9`1'Y'Y^e4rb {$ԃ32Bnj?oA=xޏk]N=b-K:*”V‹(WYۦ~(E: cƮWY^ퟶS)Фfa¨"u)J],ԄH7`h>hܵQ5~'=*(zu+*7i{h `-ma( U4 2E9Qx! A|:ˮS>A>C T6_/.{DC"e K %ZHgtދdCъLU%cGQDD]Q{ͭ? 7O]6g shZ&Ei_ѿ23D?3vsH=~fHp3Ô5% |+N@.kp}Ivp@5ظR(~uY22i[t*@ %"S,~w@R W $npٔta@u[ۤS{D'X yQ}^0T0^"nJnQF C~Յ l?*5I|wF#(Sp^)Jyg%׿xWT0ȀTC}<ᑗ<{=3QVD)d̥$X z.>T7b=3f_fVq [CW$l8 1k(mL"4.fM9pD9x`E=;Q!K|Wo/['ҙzÅ"qBt_MC-@l D#B'NW\p!wn1`5떩/d`¯I ?悼b[ZXsQ9|0UUj7ݥʎ \'8y,A'NPl|5.[wN)֚#σ+i/Bj#3~sɍO4!F~3{6MEBGTGfwmDF~K|4d-s9g~6lƂrU@H8hl9%B"f[淪 `dK,XBbW*񯋴\JTiYKV52pb1ٔ>PvYs!sk)^j+S*E ]3̡ѫ:ࡪxAgs#iSBoH-| ձBؼ߶)d?Yz/dHvLLG 3CEyfQʠp . q<OI1a%FUri`U}:p@lE^bJ:C0qۉ뛔:0q; `; Z۵v>\Ü>˧Q3?p*2'+ - 2'3=긳PԞZ/( ZZ.8+*VFaeRLyў&E׶k{=uOCw9.ʆلQtvТ Cثg~UПӪ*~)  @t]whA, ? ʴXK]EA~`/9DK44)ij4D;`>˾IBWĩxJ!GBsOb0 :vQIu9(HAp}o&c@(VZ]6olXAW~"9J7lVcWCՠOQMtQM6] wER:pI ڠ:U硏8e BpZD[I%(^ݸkk>X*œ%n b"=M +0:kM@3,"B_@(3U IdJR F$qxr< L7żwlz/ac]Q[=!:&mVdW=ק"qBNj}j-YD2h'Uo٭М:{=}O&NPCl9hWgcٵQi8. )U'()}ˋEk 沧W FHz@ WZq+ijF+&J5V'LXhψ"  :^RȎ/TS'[1ZG)0L+ sN'kl q}P/hě-*P<Wsﵽ PS%U%>xbƌz|ʉы-&pL2r(NgC(FrI}PRewVAcYufLJeBS{~ '{fdb ~aE KiANtp*)i%_4Z3clViV.i XTZE|0jO@;톛ӑ$][7ЇP8%{o_s@.~HnPtViP?-g's _K.oŒNdT(SllpunAL#"SJ<'7z. /qwfYdTP.,c%z2[/.P-W Ttmlx{LCr%KxOp\gQ5H}ZV2<[CׂC>eU^c'fT_94p!h5U3m@_;1!}0#{ N/2 =;$c=$3j,5-ɦBъV̀ og96ېi&47#/F\:(璼( Y"q.As|QYRuP_@?L]DpY%95t.YJ~’ɏ sͤt^C`N2Z}v B J Q 0Oǰd3?5uVZG je!I@0`Gn&+j}b,NsjñXw6{m>U[vxEN\wėJvdvsoU\~/T3?WOX#CX;k> G3R> 0Zr~;J ^0bf)"2iwm"H>{a!~,,XC7,|[ L5E >vfɻ]m-0'ps=gN";F@{'j[Qt4M737 ƕY)a-DՀ-It~v9rKXxxA:Zaz@'BB|<_(t211e"/t&mG3=JN>3<{x\`.Å a-s=ֆMae!,0BZ#_$1k]rl=U]ȃ_Tq3J -Uj ±lr*}:-f;Sm%?Z!ҷ5vG@l[s^8|=QHFh$hy'a0bԩEfՏN(`0Y STB;?Aҵ_P;h4 pNk?n,δQMKb:Iy*)^zwlM5\f)u.>OBo5wCV}@'b;Xȏ.]VT膚n$^xݕ4<#v;y~cu5#"ρl;ۋŊ+pl Bkt-z\q۫)b1*E!EBdIbܮx( ~܋.#R(غT县SSI-tnxkEaR{~^S1rxAU[=c&_c4bĩ\kik]f58%nGXZL;4:o/ ))?ZW&& ߚ+B.'Ϛ#ՆQj&u ip%w?Zac|l~ս_!-#:,Ojrean Ew7n#Es/]zsm+`"i(=, W\RM0֬>Z@kʴ&zokm8`ohԄrfm&M[L r.j J>Vedv=5u" v+94KzR<|L*cW$Nu3b ¡]jJ^㼒w`Ğx|fL;Y6z(CŀE%v8KϦ,`jmGϿ">xG-8($Hz )He'.⧿̠VrGJPrV(V:i.`0C'h O6@XsWAei؂lXcq^;y<*nrU͖):URUaмBlD e¬1*8x`HM4)VQr˞<96*h!(! (ం'3gwVq"'@(1{}oJ{4=y>(1ęeZt28I)0!=fۃv.YK)J%@ [P=U)܍?)F-%I%٥erZ`oݓ>RZf9V4cʆǐ(ߐ'B]OxJ 0h5 T ZTFL̜g)kItMڸeF1 fRFłEȞJ{!2 2ݲB3q̨T#Iuh LnIۘ^b>_:M1] c@۾v6uLOrAעlJk<>c=,i64 |R}_[ρ) 1sukO.]Y9B"&8 Gv ~cm?T!%K9BpGϭ*!8EvO  ~&ƚVh>'\Z @D/3?S3SHs[̀JE$(Gu+8]HӢ1:"H9^Ơ8 ػ_N0U.n\q=~l7vRf>YnNk^=SWu#\NEPݽGWovEw!O{(?Qܡ}6G;`H:Ú5ˇӸH<`2we>1uR[&TQ)[R:ƀik'NvSg/V#D8Vxg3ĄNCR5$]afcX3Y2⃩v!`iEM,Z`: óH'M?`j6i'RJ8ccց J76M+4XW4^!vgaES)tUZH}ghͿ[>~Ul#Sn)QZQ򽿏~-k&ڌipF tYtcrS@OI8';1ȹE[Y^S8(h'ӌ6E`fU#' ȥѝ睭Uiw2^%gF} a;-ԥ~F8{` E(mq0ȤlVUM#_|;e՞^ʟ}hF|(ms^jcKmn萉F)JuaTNB8Hb,ofs\sv,~3]iZN ^Uu̠A9J#c8:.* _;e_APHZ.#\셗_aDèW1"m JUK~vqxۢh/R!v9t=R:HV9|OγUXUx?LH&CD鎬D 5Vb6EZ~*% Z)Mz(8T57^t%_7Yp<톂#iBGq>_-Y]rh!o(Uh/௠(ՉTH ґ/_رkaXs_%2OL;0$Um,63Mx>K>vS9Fl`&v(2db=rGAk.p-%Wh3l@_~x;Ykd 6&\nqaF\Uʃ0"k/+˧Vjaib,;"xZM$ҎQB@\kC$I,Yx%6/ï?K2¾*>R* ֠dvbLW+H"ql-ީ Bg~/.8"mqΕь*sD4 nph\qlA3(HGINb#߇P:ţ@umU]+8i5I$dILo .!{Y$q#joDW_d@{OV%vx=ap˴/M ߍZC/Eϧj? `"%WN= Wf7!Yܜj qr'nwG7"!3Yˣ>nb䧀CVBJA>7̪p.<2jǓiDW`& T(fq*75UVUj#6~ԅ;d"-A2S cІ,U: }z3bN{شx*_푖iP@9Wu M;)('37Rwx&V g<IG4,&&\YS"p@jjz%lDLN*IqsLG`bR6`"ljZvF [臘lk*u!cZyZ}f I7p5_&*V%-@9,/6=b{o6E"r|em2ITs1#P?x*lIqM'(v֊s9F*@SOqM}xI#dd.Y#;\/>h"3xf6Àd!H4.9~:O+w$׃@;c`Q*\`iSC:O LTHc Rf)t=虛ZhJ/H'Xjѹف)Bs^ˣ u&nqDž͚< ݱc9 ǹ/5a͗tw =]ŵA//ﴚQK}Sig߲PC2p\8=71˕42/ Ղ5{94h2C~4Lp4ٸ+d_Ha"k& kaX*[[O 4-ZLfZ˦j /txTd)VBu_k +gI4qyo8ٗ0$,x \/jlٚ)%ͮjZ"dx):٩pT Wׅ> Q'x5DRh/gCԆA R>=nXs*H9YzKO\k WlTqB7,g&8l҄HPfk)XՀaNb ʊe,(dd ^ q:t00bC3VxmF#.\6f2li_`}bCC}YfY! ?dBaZ4 mN*t`;Y~XMQk#YOل(Aa y˾PoetɻZ:W?̍W uOjwb*o7Q:W8awSV !>t9%eL6p- cYgpy}-d[~j؉6l%\#ϻB=XB䁍|H͔Nlo9 mPPX*ATᄳX^ =Pl_ '[Po xt#]}ށش1; ˼U6FٖXXxi6dzmMsSDX3l?Ǐ'J *&ͼ-z*)onP4 &S1")G-3׼b J'(j.zS@hQYǕKT a=GةDl .ӷ^ք;nĬ&`<4mpzYeirO ^ۘz/R>!w0yVwjֵy˒%uC7""|!2HCz(=Bsrw @54Yb3ELie>w,"zrHӴ߂\Ww~LX {19]-qPQҗ77n}J{k}x`9->owLx&$6|*-M[k7weS? `R5~$>} ϊ(}bg>:Nm֎Z䖅a~=M>Y&f9iu+=['Zci_hhLbe&E<6<:A2eԨPۡ8mb~v"0:; Wִՙ˶aSg w80NU[/^&9溃LXKvQ:3> =UG$;?V.U.?QAyF  _ Q- $͌Ľ@j&vU|"Oy9~sj&0F }8.+ (7gLt= 7*[T\i`Zn baKsu*2FsMBpQ81*da['}_c5/1WFqɚ9W7XHDQo1E6V~:ioW7#-t~Z̭<}"5__ju"5/̄u{d-°Ht^ާ: +ʍt5(wSm+ׁ2{AB3D23RMTޤoj0 3gS6eIl"ؐ\|DSTBBc<G?6=ZY8V%˅}sh$FdoxwhH}d̍y#nAz J eKt7sKe}fܽeɊIB=qS,{ dELք;hg=4$*_HՏhJ$Kt d *&DzAMwΓ&) % b0j2DV,W^j_ өiglDNMƫz? ~eCFdn$?]Pn9%w31 Q@׃<dY)Fs.y5wNs@{7?b2*"|(}PŒԛj^Gz;kL'\*Og~\ [Ʃ"8ӝOH %NMwܫCwJ I62k$gc時 7} 8%O 9f_2ךּb+^vfM\ !OO%F@⳨eP?5t\MU@TlӉ(U&eb\?|ܞt.žLϼ5:%f/m\Q03,Zb1*\`2GKP2+@EX&!18=2@BU ^F./˔uQ `vd~L<9,4Qvx/hyb/km."7JG&RdV a'ݧ])`qC5qR#޷ֿNb"( ^Q=*M] >KbkautUօ5]pN>nU@ '38y(-e&JTɜq >%m?ut;NFÏ`x8UG.S휥"F5b3ìl)\\( &9k Wd@W.` pT \č+31Bt>rh}i;Pt WoTmU50@p@y1 Q;_weq&䲵,?>84$/٭婃s.ҚtOPEaZPR$Q~ϛnϜ$6s58qo"260xXφ,]CS)d-+{l(x' KWLR˞¨D[~ӘEYM~;t{0LOvk'GQd(zekLذKx| H\|$-+gT T׏b4>D94;G14BTQwa[R<v۬pt\>7."1(Pzf/$ GG95qJ\Eyo75v xPR7kjvyzv7>!wVZH(9V(ww_ϱ9`+ DnjW6`O&;6ʠd`i(4&L7/IJuǗqTrE`] a-w@2\g)VE3;TBf!cR3TƑ7NBVj&uvf7.{@E?8cD]Nyo'Ӯ8򂨗VvԷL vĽ>Jw- %U,SZ ^#X%::m/ uFp% ^Ts{aԼPAo--'uR\qlvڶ]E(+rg#z̿[֗‚TӠ N?#)GX~;' 1j ܀VyX mTN^warE)IS[>X!m|wFl+v~7!a|5$(؀}ȋ9׭̶'|V?_qd,)6î֬) LvC/JUҬr3*S]<Da%w~YT4;> o%CwڨBTJCu)B :à *&fp WoRsGX}iMQ$>GNOZw(Ic.mb*vNO(;C{ 0=N@v3 {ae#7NUP5=zpJs5o1Дi ӃusT5 {lPjCp3;)1G}lZen6!q; ȿb27xl'|[ I6ԯ>ڝZ苓ukwt*DiIL;g%} u+sOq9Lq~['ÈsD*قHT\` to|\U(/I:}l/#=u&.b|k4Q떀2)6 ɹ;UKwj$-0ڴhkK8պ%vto^_k_r"RAL T7-}Vٿ;K_sE FrF}U7_/vG 5ۂa3;{/r:vO*0+tQ?gC[&ZV)Li1cnʇj]D@J (XqB5Ę k}*SmPػTx\DaV-P` z(rVz^.E:M%_5C)BgژDpA z[_Bx6b֟_a:Ayw0`%T.(+ۡ۵A84:);:Ap@δkdqܨzbXq!{zJXPN} Y]R$}8w2:Zh6H7xrpW4h;`/WDJRz)I7gZw0_'M'G4{.B%h3"!"ΈFȀ<Z&on-.GOXT?0LVz2 bzSh7tHɅZ E/n Ԝubi3>w ]},m$Urل+ClaCyJ/Z٤ѦEvkPYnep RWW]a5^qkմ^t /'k+j \W3 Ǟ`J s ^f:KH%]X+aKv]A[KONY|ˉr@duY]g'i/}!;s:~,r8gIYED؍kVS Ie!¿dU(kN4x,mA~"޻br!5hV=Mݝj4:) *ʟc1LX] VG7r2A p+:*ܮ:Wj^ !A՝.3;_!jug76CDq\bꕲJ?nt4 ݨ#(kߵ 9%R9+yHZX-$Z\Dz1ə~Lj_G,p,$⭯3BsUYFSzސ;J9e&wR?j3[/&t1ZGX*eyQ% q5}.4ՠuU GܔdwPdc!6,ԞؖB)d 's;qS;7nxVx2F+kS)/=M>H\F3եy᧝}VMٔptI_y`yd>ޜ@TiknwBMW2_=hՐjuT$'.Rh'6O5HsEg2{ԜQ4?OR+h) x GYl +`&e-s!+zXp*|;c C>~wS*Bk- F>/; w&!ˮgwc_:ߥ".ѬTС%3=L8%[:_R$0C$#bK#m{5h1p;y! bbjt἞*&7곅;RI HÎ)H_y!,-"Xc 夞.;z!1.`CB8 eq&oϷl C節*eW% "7kLM7 ⢹C(YZޔLS 4#Yg4̗#qOU)L {-mk`@/֜%A:]^%-)oL!:a\v_pn B5h8nn.C ǴN_j^\`_d*K*ù/tbE; RJWfN6 txYBI'v.H&KUx~cJo@\/qZV`#Hz uٹTٴ޺DT<2f ށksF=MXzglDc 0PUC#ȚE!x#gG$uD[xvrM G57k!mōG{Hgs`]A wQ.eb6 q4e֜`^$8[-dG b-b6]8jT_悖}y7k<"fRLK;/?3=Ǎ(o,\Xm屳\?:oB(1SL5ϺwetBtіz5\̖1ir|Nc"0rz~jí?B6 F j`/$X *|aerU/;&w'E)5(zd|40!s+{etқF%qN/S϶-6vi)lZ~G%GK{QW9t<-p *rkevD:Pj@kBueHj,V~7Қojfvk3[uW,e|l*Gy, !c|~ (1;`jQVOz'z|La'Aǐv*+='\W ugωK0KtXPX_p{Jw$=@rj)y.zv1[p̠h~pᆧu {( 1CB3YrLEE15q|uf#zwn֛ӤQ@wgbr:"TPrJ1wڢþj˘]UAExd f+/4тjپzeR":e6[F~DZ ;$vuY 8r*kdž& R0r>QA Eq#"uz?bH`"u-}!\=д>81 =o^Ă ([_sLR nm!:K-@A"Q2ŝ9*FW#rMNѻ‹$wOj\' Ϻk^1*-#/lfU'E~83M2^-h,,EM_r o`@Z&Wx0zTA@ BF:rkKyQPvY~nU:xhrvupJҋ)ѹI3Nx~uD#ϣ!|E?hlRvݠ·(vypԼZ݃"5Jɲ79nQ-5$X:1@Pcv6ķ1\ e&!cXUOګ+^{q8\ڥA,~QL<"LP:̫ӳ/ϳX+(kwh};a a4t-^B&Kl՜ ˆ z1"Rl]jz8^SE^yb M^EOQ_諀7މ;Xv -m' D܅mFL>" Uv$Ğ;8: =@_jhqk z@eoOBLӝ'"ώۅyoJo|y,$UQg)K-;$jMS)ϨC%gdL&Cj0JUY~0R8&@Lm܊RI[9~+ՑEenj,7\n-=RP !Rl谻3CC3xGkNG`x\FȋڰТom}Uryep狔0 j_HB_E.jb=Aͮ9WH!!ai 68|CY*3P8#)98O'Ϫ-*[ gi;}#?5}\b1O* _ t J<:dΙf=%:1'Ri]ӯ4lN0vftJ5vE*T˯&?>3l<ݧù*sp5h }o`"v=3qkΛњYF$ בY[[kTT2Ҁ!w=FXB식yop.ʓ*݋SսN^u+q,?k?gI빳u x_8E%bRV ~)AUp$[K1a'⩺l [GD)iz꿑չw:X}/^跻P93O bj]s+QRn⧑΍d6tք#bYmdPQyܛjD@jWCkĶ>:iX͜$i_f}imz$O q"Y(@(gSro{ɎEGGA?kp*|fQ}SEV*<1I?W $"%?oH)) o`Y~|sP#KGƕkYB2[|\LjCbiTP({Aggy9#ZƛP)_TM8U9 f?*x8' ǜm oܕGj !#($]ΗXۉʸӛ樷QK3r\sc]NH,PhgF#I%`dz"Hyמeʹ;PkKgٶ/lg79N V`m\n,\V=Nu`Kz,p <$ [=n$}ࠫOhq1jꁨڜ3Ӱeg<(i@F1XYMhJ!dh)WQyKm';g@x Vr\$R*<&*P4 7rLl!Kg5UQ(\jβ\Rddͼ'ߤ>: y[%X >JX Q<(3XA-Bh]G!9i=OhmQF9<+9{E- 䰺OY>4o^уדvY9"h}#/?'@02D3>́^&I1[_xӻ@DhCWSd9:1Hl7P5C栯$$qB#!p,ipaSz3ݽ<>9{dDBg\!}kGӗeד9įҸvA;+Z 7cm83wiAcm !kԖU|W9Z!\MC E$ !@/fvJUp r ,߷$b}#T >yӄpl?ޱdhم8j=\ )gw鸠LGPeԖ? (R*nۙ L.-$ly3y:+3oZW-Kw%>tεWޗxϹ %n kFcj/ƱYLd 0{:M|OˠSn1BS5AQb 51f4hPyfHQ})vM-V5N PN\&i ÷Md^5d+% @xm7?_a! O}XqW<'XlA3ۄ!_ByԈA3_26aRp`ιQ˵W]@s{ÿj OnrP(V{t]l8F82"nDΒp}m0p>}FJyx"-TGSjw[j|#.GX%1Fmst`A]{@"um"NaPu2%szLZFuL U\U:.ec*Ǜ{(}o+zt;ЌГW{7 N[ `ʀFc;N#)βmqe&[y32xA8Xhfﳄ. ϳ *m7)ls~YӬHQNp pMc2xKwo+-/Ԑ'%2 qF\}6gWǾQ޸֟821ް@,"Ҟ?@ =ob1 &De?(o3v>ݫWZ#bIPmpW팙LI4H5[PR͑\;?"疥o$ȎPRZ+lu%[a `L$`AĖE, 5>Yy"mD3:80Pǣk=xIJ[ڮsJ .c#-(_; ӯH 7K?LHs@6]1h;O>#W>T78qɡE3bY?ES7AWRXݘ3t/Eu_.(MV[=.r]J'gмM1AWsluv'?WV:'\0#e] ~*bS +a7 )n{,: .dpXoM#,3ǵA&FhL,` T]w5^ia+ԀɸD>{-`{-קT<29Xnq Թ }xIl@aOfDLD.3~u`7Mq@ݜbQ|<MϜ)K:*A3]Q"5A1N{rpɷ8ҕe sRQ|7LnOH 戊 uݷ8M|n^qiy*NV/sJzj-iI{O"o("˱qIW\R@cj*g `w0&"rmΌnb8 ,5l_n  Zp6 lrj@w7d.GתƵxVG+a=Wʠ]HzRJ>TWSY~h 0>Ȳ%@fLU,Zg)[λ ef pzRn&FC; ޾wGre E'{$&0ZQV  /=.H;R3-C. IH vCr[?ͅTz&lUSn;ZSr;q.t: 3wVQ ?5"zV1 0frPDpXlv1A#LE ʼ5-DK,HwWu@<{'Ƥ|J?!C'b`4 CcA1 l]~l #v?o neWK>/s;-QuwM?5dO&dKcJg [ZfsIk8~jjӨW7=pIf=r!`Yޖ].Vw)ޗGip;q-$xRgAK:jۥPϯ'QQW DExW>yQYR64FF_l؅mJrЕ.[GxuÈE؍lB3\ y\n3M 2+b֑5 UWݤ/\Γ-u@DG)F|%NZTb'ѲcbZāT J2={xMW]f3/P6ve8j }_F^+ I^/mW܀DKS 'z1QjI;I&nw]D|LKPKJ7 K2nm+@R+s}g #CWpA}me蠥+|HnCoi؀qjVV#b( plb|s) ,_?tjH7le41ڝwp64<`e#Ѩ^$m$"}us=!ֈ4ŏYhJBIuc$\81m#ʭԌ.y"$=Ε'T^>4q2_]{}kL֢$8eG FeBb9>LFit4DՅ-(] 0qvS?A)'p>Ɂ A،CM= 0c!"`J':g ph7F]G:ա昒i5eQsIl"g9I6޿E.6½PS `,A-ZEyR|0odNK)OfnN|WoH&}Sť9D{ԧ ZnIO$yKϱ,ϬWap[ GV`)le$M%[6P>3!jhNG`2h % a3ż JM={rv8f_1oQ\!bpF.$Nmc i4EcM] Q`nj0;>v{lxMDdŪ;>LEE{ ../15'&΃2V`gybأMgS y"9:k!VR7? V^,e1ymL㖶dXs yǓ8ZF[-*Y9D.rBx>͕ҷ̇XdmT m::Ja(xq5K kk`CEq-}J+/. sE)_N# NT2aC!ܙ#\QYLۗ˟ }JIn2o+kj碱`KO?1@qha΋Tѿ^kL[(X<)! B(!(GBI)*VRПOQ&ۮYҡzple bU券c D+̘t F;zB|'u'0d ^PRc&#~Z6x=COj.Z:gA6誗|3GU^"boPۊ L 0eIAU^^~*#lҌY /A1b)Ll`dF)KSZۯ/x|O.ۤ'/VC`->,0$ϒdf}~Jts p'-ς3_-&":0=Aayt֑Ԝhb#9A2?#v#9f/YpdhJI䩘CE[ѦF#$5ؓx2׺nW'Ⱍ!*y.oxpסhK8/\l ]gpf-POK~r_dZDFbq-?4]boTEBpwӴ$LA Fᢉn /چ/>U`RV]v'~ɜX#*}Z66cˮFwt,QU@jVZ/f! \)ߗc9OK_>rj(iksN4$#^h( N]l/h:iv>5YZպh[*h9Sʜ]/BM,M- %R VH$gV* =K}k(vI78MҕUF"\]$<}.7&J(-~G,6da}t"Q<9g p]֙m/uUbu*ydž)@H+B\Yy/4㺞\aE}sjWZ|Z(*1L83#B0p?Gh(ǖv7"$NL5lgz ?_A;jNWls(N|6]Y[̤H:ZoFZ=$< K!ޝ(q}}g(NΝZʷԾwūqj[1YT3( 6+du}}Ni5ï{:32փ5G& z>>m~q% 9!ca@oL7jAPc%˨Pt f)(ؑ;ƇXsL.>f5H8Vֻi Wr"o 2E"լQ];F!UƘĬw$o*!gȗZڞڄ4Α(L>:'q'9ÉF{PhƤȴoG|w< ?ƦQR#o-⛺Rf(DrE;z8,҇[ Q_0v>dd[ 9VXr7QDNcϖHU1!L92%Sܫ,ЇGP^X?l}Y7.ީ:L*bX`e'!|)/5La1-'bBTCsxM={2XDվBUP#08@gR"YP,'ACSܳR_5Fش^*Flk5\v "D|.;|(<]'S[DCUclLu ] agM$W{_5g LkNP|A_XUaz0o I)y%(A nSޝl۬c@JN WpfN+n ̦DK@^%1ɨJWy$a9|6@w?ؾۨ4tRjk]Š7)ނuoX=H(oyC_TdsAO2=͡sU#Iha3LB&OV>6D\K1{"ϋ+栟~A ӃwYͨtXx[AݍڥtB<",4"oc\ u7GQ樠%݉\<NHw4 o10UWW/]} md:͛^%eIk8X1S4buܓEz$(Ny.6n^ p\Bb-a!cakǬEzZZ9&PJW; /b-|O-ChDX}=V|`ǁ|W_NJ/Lq=]"f.%<͌7v]"tlv}} *D`DBZMg޿(mԼ01Yʘf4"/!L2FcZڱR4Fgֵʸ\^#ٜÌ]va. ƥ V ΞG] myvůH81W'p'K]zH(:z:\su$q}a 8dR ^u3;:aN\~Yθ̩sGu]/Gx H}Ww\WOL[k_`,*kLFkheN40@8WT`UѮef BೢQtWjO]aGUU'PMo5<kN(ބgF0wθ\*KPv;;% aP94`kPZbqElXn|x>F0Xf͞swD79n &I;j/Q-U$#1no H0x{7)>lؼ|}[" d|fS6nX~_.OGo_|2ђ x@eR(H.F$J]ȉu7T&haio@Fn+yahqQl#Ӭ&2Tkek|P~QP_J`ZΧ8J9@@]۳̔"9d~߉\Y:,d;՜LX. 4^҆R|x- σΛ ;£f* .g:1Ġ N[ 'QF<Hiuޮofb $naˬ?K"k5ſ)|ʖp :n/l^I2II~,ݐ^"y?J>NL7w;[dՑ~3V om!Bm=}v ~|>dZm5ۿ'_M%K<]1U'2~NyBǷۺ`PU. fVqgPDr;-IqusPx0tXW6/DF+&,U-K_UOEl+MN!/*:eD!(늁*QnX1hJnY(WB HIl<|pNu ԺY!K&5[GFF*t^孓0jKo$9h(]W=[GjzkQE5z434⢾-U?bI.c^c~Xӯ_വelR[l -[g:yn2 o/#& ?TQ9:7j÷^s)nρU݅ܡKHҶJ)_d J=118R4BQ2fz-- pRrkn΃[m e}_GYj3r&#UU&܃ %G-@;.g<2Q^" ?/:-J$uf&[ykKo!pM_xEpcY^׸8j g_!<+NIg#6 )5RaÕB(m7va=U^T" 09wI$W]4t\R]찈2Ȭ)ߟG[jHV^( Q2$b,Ag}&pѴpu :8F#]eNNkBDz"Ap=]yEXaG5 D;Jq Vl )K7YvyK8#v-'hytû([(O# #]Dv~G`"|R C#[wΡh^s]_/NJ-bmf7Ii|se aU g~:qA F5?x⬨=)B(9Fn ݿ8YI+t1HqdS;e:kͥx\Jφ%5X'4fTX%̂2뽻*ì.v$'[hy0yVQRS# 8! 7eFHZ+2 nj@/r~#bb''aZxo˽\ D+EҖ-6pxNڸG )Z#/އVh/)t$j=(:s)X ܣf"= 7L> \0W|dyBQH+/%ӄ+]PnGc9 |V}]j3_ɫߎ:< %9Dفmg ϗKR$7{^ؼjk]]wpwq_ft3B8(#x?l3K丫Gbx(K-6_p5!RMlHXTaܺa) 7!غ]C}Ck:*R4iקU:ΪЁ@V:NbKģ*d=bj^r!;S%*5D({<7f >_Y kc(8;Q >ZT-SNk.`dެSP0hLV%BcBfs{Ws,O*qӽ|C?*k/`P 'vUyO!>0D!7ӝE8jk!7s[t-vJi%&WF_uS?o$WMUX zLH[$Nq+#d3FcTRՋ.㑶G c +K٤QAZ-.u斎7+<^ô1U27,U>R7OGЅMfu9cvT(!,3m=>ؒh^&. nnj =3e9p.[y's eiLX{5EnFP8@_$)l1Hl{$x>zzQOXإrHs&ӳ5 *sF9noBeCG옝(J3}}BX2M~ (0HC& 6D\0j&ɺT;خM͈R,M 3"}EwSa\է]-KMx/<@+LlcX7Qv] ,20ƸL|GzxmOqCaj e{m棩hOxNSD]c ~C٧(ŏy`*v F{gdBC;rq+Bhfd 0uYI]CcE{y(+!"n~JN9*t|2e a39(MPT|r/:T(9E؊pt5Ad pU 4NG^B;xG:$C5.PKLy^B|#[g߲$& O^4#vh;B!imɢ-^cp){)Ca$tw6+ׂ4v"=௪/϶@Awd>TCxۜ^@B?tEbL]̕z;*T얽RZbE"RM2 |IE{jIL Y|rO9m΍zVWe~Zx:L 8YMʖ/Z5RkkUXB}:' 1&>?]SHip_i=~j*'P9`Cyֆ [;ЊlG `G'.z:rC42KфQ ^>H`\Ea\z$HHZrX%zJ=9afd#Z@5@ 0zxL "zp[ D97X S̽oț#Y#&}S|eo]SmL4uHZ+?Qzn[81?nu.XyX ETB/nPYps_M!V*/[Xyf{acE m Lz`?3JiyQzrȨ2\RjG/kgw-C5!DKf:?# v)n*rXboDD㽥X}Km)d{Cρ W|N7"_>=ìt3 &xՎX(߫fp˚~!cBHkPpҭ)q)F؛D*ieضgIZk&PȌ D&DD AOAF´:lWrCRJg?{4zRn⻅: wO.OF93k2$;!fp9u.܀_HI2ۭ{CxqXܺH9* gpFgm22t!YnJ9w< 3R+e[I >6SXjDm6x!3X3Y arUnQn={/sȍ\ӛ嘮|}Ț]jTњ;N pWu-US[ލ@ Z BpAo ا-Aޅ˺2b\-Pp"H嘟k LsWBUqc(+T ^\d7ȕbsSh"XdFƫ 8k%pV _9$.}5[R܏-~tߍI[Qc >LO`5Şjb?gbE#l#LCHB <4 (93ra&P hܪH8?9]b.wF5J35+T^rl怕^1bl.>{BKn!1PGM>w_q6nI4"!xlNaqKxL –ŀvj'k=!8nZ8iBakRyDkJQr E5Eiv~~(`j>9(&J7aFw-0EN`෺hJxS &zx-9G?//L=m~ۗ0Xx|IeVDahgi#5{8CR+KJƜ[&M/ PMZJ>A)Dvtdm=`elE7IB 4qj@/LD@߂ELpwlw/ux3z0ᕌ"o!2(J Zha;\9X{՟XQ;AAzcw2͆'Xs^ 0Or=. e_QB;.(rQ0+O{Y Yb- cb5msmmlJ-;Eѝ'/ZiZ~$v՜gn?b?ow+@zJ~8-Jo׮ ‡ulԽ0~ᦁ.Ű ,kUA=c3 2nE/ j&/E}:¡G+\})"H2%g"M!rvVfHoB 1u>mv]WK.n#F^ٲh8>bb'gl۾R[:r{y@)wrN!9!$(SACΓwqRPSJiUZm=^8 {ܞ\S^fj8v՘Ε*{`)tXBsKv@soCsz$.DrAKYS5~S&ơ[_>Jk^KOl&03;qu(+C`0Z_Gxgl]:)6).Οm /P C9d~rlOwd> '/S\S$EWnIJUniԵy`(Fm #0z&JMԪd_BTpDt o-"<Ū@ǘ[O'sbBJ_ 6D^昖/ b9]KCbݪ:yZ^ZoO,@Qةh] FǻP2X}K) G'{.m=)'?p6Jja약1uF9}@fe|! kR4$:Q9ϫ8F޽Ujo@\P!=ؗNF"wu!Qqhh?-oʧWB<iK#:<%)}Ÿ;[k<ި6:`AQwOQ :KVgVdG'Ѳgy(UtC*%Z l^ۥB"VVTAn+*хߙMduC+Yy ~ǁaSVgݝC\i/BK_:s 'ݑg4H"t" sBkmq>ϧQLI8'zj DҰtlH718IN'hO()Ӱ˸f _!BW0-C+B5 [5Œ錿 @qA}=NC{{9"t׸⬆&ѱ'@âg_zш/;+cHD2 iPҞ8 ½<_H%=j/!{};D',{5O(˦eHPcZhTuऐ9N2Aĉ*eS~p+%a>MyZBDakT9sgAVz,|8V*{nZ' h{*t e}7z%9k8; !8PqjIzVB E P6tW\KAIϥ rD Ҍnfy Uc0Q3yH)K*N&6"F;8Ņ\֔l&Xf_~(]EzQ]>dOlnCZ黇u> 2 Ws"jNKބɳr>b% #Q+)&`hfwN r#n ?0QAjQJHoh,4+ t0l='׊'#cCk3*n6T[Lwpf\_2Rf{첸_ĈD+/w>O4@Sr좞oQQ)$3|A S98"Y5_:(僿;tF0L0.&PjΡjg4J)s\dԧCPP5+$4_P[_9V˜#p܃3^*eBb'm%LֺvKbs<܌^JYo ؙ.^& (.UI"tCWH1]@vnbRPe{"5k@@OOҬp%W1 18*%$`IʤHIˢ[QpILxĚlrwGm2A:$Q~]j7L)BEuu\w~Q;R, a}8S Åm򵱓K`C~O+`Qy zIҋ{XBcWs:PRikLq u$!$0B'*ëpF3 (l z{}QK/U!}NF%J.`Z6pwֲ3_l")o[t*fa6X{`x=\GY}3 io_eOSc5dMXn (Wo꟫zup\ 4]u-o.\8eOOQ(Kex&{X,|_MsuH7LQ3^Hxzr&ix7Bs=ީAL痆:܀\`ѩԩ )D5RNU4s}G= 6w]%onqۏ Xvc`S(#*5v4թ0&8H&%mWz{,cgL!}`IϿ;сoH~Hږ+OhB`^bQJ/ȴLvFo270Ś&uYD[u]ŖB)RV6ȃy8(ea7`x!uv'^WN!ǜ~'$V +E"Y/+ 2IqٜSL]R/Rt#7~V_]%^iגtۯF8 mRsrY{# ,&Σv; HK\ w側ۗ##" T/ X@NVp`dm1igSf/8b"7. $GT+#S2]G;#̥zJcPf73*۳vLTg2˩}fb`_~ O 1'2^֘MV-2zbhԜrv.sx|8&J;+hTni~+qۚMlMSkg9Ssum5ak+KG,[CSDȫ&ZɲX~=[+zaD[5XZ=D” 6bs( F.hd>iCά{!吲Z[~ʟTs|+Q;f]uG~p;B*7=b.y `XH %\D2èFXIBBY---ReN{KLɢZچ gl>x;G\i5nX&pZc1 M/>+Iuo)&;njZE(%5.~w$ԁ^Jҡk15 F'Ƭ@wœw\)ZaTwpaf^/BBI( ?CHO' ]ݣIZ5QraM7s%:R+)d OY纔05pɒ8w]2 D2Ρ`ʻ‰IjmyX1IWS WO瘞Jh$M4/Kܘd~jA+4zY [_x`؉#!;+He4T$Y 퀴 مh$l6UIج)27f(iݍ6'Xı4$:+wtl$Z Gh+D` :>DS4lQv9G{-`yv# RY[i6i .[oҴ+靧kYﲼQQ-&& FaR8-޾LLrrO6j򉗬S'b1fm&Vw{ c0ĉQx'NZʁUu`=s%S]#;#URΒ2 }(dWrr|D@$w]ac-I'K~w  ʬML\C$Z,FcZ[@$.~!cB6Z9wH%lj5@j7EYCD!ulFJGj~{\9>^/6"&4I63\AZ|lVy z+0~SD}" `\)9=ZDv6Ve'D-lg mKΓ>VsԆ h x҆'}~ʧ|Mr箤F/2'CoF]L?i~}t9I y=w1]_'Q['M@PW~r~Gʍ&7TZqҳfSFKJY} O.r{`I18һy ^ L4@c^Ke79MIOszcܱur&'o_Rrޝ9c ]. ^;hRB&8^֦R/J`wUZ  0lcǫhTT|z$|RҢ43%e}n:BbYCw8"fP&CtM:ZWDW5j}1$$28 JzndClY]`}mʧRQ´i6x&beMݻ,XSg/y ! Wi =\QТ{G:0L\G %9O=ioRiŨ'E7Ak21v=%)͌XJ\g/h { y1~B@ ;n]$F㝇sXݹ:l؀ɠ^Xi^9dHq 8V^}~Gš?9-ȯO\ o]g42׉vRبILa?Qɻ5tǐcpk]ڊUהbt3cc[CCZ~)p1=NYf$iҍ=Hn<>ͰHw\h lUp55'!kK dѲCN?IH&\~]IYS*u:0vLvɢtV0z3l&BPFIxMJz4?k[3{v.5_KH I#@v(I3Zچuwv;iBc_∋ǧbNc )nޚ[X?vʈ]a ^\ٺ'?LTä̦%=MyXu9 J^}\audpvċ=QJXpP̮Ee>cu]V]lEm#BJ6 ]̏! B^v[CrwXZk['I/-WA?>M9?)nm+]G~Z9&ރgtȜ\rpG"%88'1OO4 k.[^4E{i$%1UBrDN~#8Glu40IULKv-blwt.ՍRc _Q$tf7wmNn"TW _"sGz}[ڿ j&)@?RDUxugcvpҖ&!JF7īU>ϓfNX=->Dhȏ꽓P]yzXpAFn)7[[rQpP dFZcdB́@Svajظ.M"`xq&6l5kK5z)yHR?"#ߞ BؘQ_ ac j*˕k,zBّE ,TĄ9*~y.TwD=KO._ /-E+AӜ=.I5$XIh^*76$Z.8,U䷤zh}7hůyU*?il!h]v!S/r0Ili[*ȡ F~66J4lr4ҙ\hEVi|"e5((b}d=D̵bHmTX}pܓvO`J:JQ7n2ыXg*b0^\%yk]j)ʕm'L+>x+ȓ 1 ]b6}fe$~8aJn0PxeKx)PrpH[VX@d4m?%~_dt7t}/q@;/ }u끙/eBWDc~ZyB>1Q:NIXC)8Xq8]qozE7|['H+Yk\(˾{u 5~ȼH!w2;-GSJ&Yӹ.^qR/)UY.3q߃荬 pbO? ͜TJ폾%`)J/D%l,{eWU7e!& RVKa)e1Df8~+VvKs] fjBdVt<-Ԕ޶ơ&X  71qgOO}?UI{+Ʒ AJPxp]_ZsB#D͏|J#9}f+*G2Pd9&VLk TK(A5)KԜ'/a$S"+&J)K࿹4 @^2*\ɵ??Pr& Vky2Y%4]+lZM?AAx%nFm7XO*Km%E[+ iВ//<-}oQ{#UFkKA ʋ,H1k"j| e8V7餹tyB}2ψdRhEb~;ƅPOiU@ϸzsNO usTsl%{PdW{]|^ALZU煹aݒ_߹D\|S+4,SUJi̲/n9]ɦrFV1  vL(t{5V$-5AxpL*քJ*s>%}"$mZVS &,aCG?} Gw5(z|1{grᒬ'%`~CP bVX*:0s)gLJ4:}G]i*Pȇ`\ |cvBzm!G{TK<,k{o}!Hj~52[ uqy<]er.̃=^*΋T;شX*}l(.i3BȠْw3ܻD% MsNї䐘赒4erV?qSv)s=uPB76DI^spKMN;Y 1bDl-l j\ 3I }f~Rnιnpz4*>~V5CR#?Rih1ܘрj KŮ- Ҋp_mPԌ[U#o$DHbgԅw Kk(vn־Օb,FƑKtٵN߳-) Òoua{wy{bd]9f xX_bE[HnI&a\ғh&]2P +e݊)Th4 W:0gAgjذp޵9 eĊߖf~E[FhKt ["4-s{,rtвT|uϮ#!l|@VRoUٸ <*Xr_s>hLY#*sBv-N߲L Ԉ6OOƈ(@g>9 $dW+ϖ1H|$vg;gWS_9px/$AZm}3f`GrhJk|"TRtO9ī?ZisA m4]\!+|y݃^ח/1xDՆߓ}p9mw-nA٦3S1vջFuwݹ_Lg7Q:sRP7; ֩.Y&?C;2wAԕ:A672f;l8nZQPaaĺ|&Mg@->ߪ=_̬vFdHn7Hm8# =~Q/d}AJA >:M/b}uw#ڄP&Qrt7 ~wO2@%?OTS9WP"FRp$ia16]j_KfΡ2mG(`ډc[,DRXB.*(#H0+ǿ虰$陋\clvK$dV$ ,r7w$r8TfRb]G-}¨ٮpEvS,^1> hQ7+!k=}oЋl7;<1G"ԹM{ЫCj?&lՊIf/G Z9ܺvI) .v )cN'4QӅ"J0-~k0#JJ#XvRDcvjTh;Un-!%mv89n0Lc_*E([=3q.)=T4Y 2 Ea&i\Bx1=8*uN[*PU`bV΢J!q2P'ބxFuEe*ֻ{pu$wi0rrےZl!~dXq,czeɥ 4?xz$\2&۟6w8lGj*k]n2ϡd15P0;coh1Yq'檊nr+E& + +`ZH3˹h`}x+1CN%K)irI$EʞW-IGš%|x5 )g2<3^Cb wU\G_k>%x7,54G Mq$d4ԀwW ߸WOa6imȳ庚{ↁI3 iQOOpaz~i N__ 9^tI)*җ.EHQͳ9#9o"ARFv̽!4q3 dBb;a)v xd (?ЮazfތC`H8:4\EKTx!#b7ZRz9K\u%ԉǞh.(+3uXol~F]+K(d!IbJ]U \9 )Tyv?$E޹ Hy-ۚچ8rk6@VQm+ 娥Hf2A3vRJnVYgjtGh}DXq': ۋZ-y/9 Qgf3X!Hv^Ws"ɒs)M_-DhD;:l[p,N`2SsUP+@ M+>jy*XғY".i4zgfb+> kjX]OfD,#!0o'`p+$%˿HE)yI[',Jwiso`ebm>AGngU,y6py~ՈW0'ýoi0.S՝( ޕՒj*J8l^ TnN)lOdY$(.*kIp%o?TU30;TQ02Sڊ܉S{pݳT QPylm{r/_6 r{%!*PnjրN b4lyD'}зMә*)3|=ʨ8NŢQmw b ZZ'H=pC1!>wpsS!JSvJZydKM#XPF:sƋ.wZ+0-YsF1Y2^=*k鸻 ^UQ>d2'IF$E/s$ 8U^@-ԳSC{w }vf[F%Ñ^vI!nG14Χ\V%t9Nyy,X8z:TdKS."Ŭ2j|a yxVظOwY~DSc. #7/GEslf<B#  SGmoT*OuP\g\FX˹LH{ %vRmNSl!GWOh:8[tN׃}7GgWyG}p@Y QEd0b= .bgy7K?7yh: [lje'm΄ .YLZ@ T, Ni^S);VFRAP{Lkwmd"jWzr[Oa9Ӫ\2oV3N~0Ex)7PK 6'yK sj|~ >21A; `=YO-Ɠ841 1V}3 B?t% <Օ }N>KG؆9;C~$3tT\?-$>(?z8$iUOG%2m"Zx|-qFthpۘЕ[Le\k!\*2ȟ,?pE_ ĤtnQXobk$HdX*"ǮJnx醓ё` q #9;{Z'?E`CYw^em4ײ5 Z9␔ &Zq#[< ƽ'\4;ԦȊXYVp@v 樁͎]_ш7ur;2~M \U?ZM\{ kPHʐ3BC J^XҤ~h+JjЙ Wg|SE{6t2z}B]\\Z4Gĸ1Va-WwL.հ>uP$ xĞapWpfUwqVw#Wo2 јRqJOGLKQ UݾQh=a笂|_|T\7q~+Ҩ!v^5ͧxUq$學 0/E1;_1q,{\P:z J]<[p#x)}<ΝA~4fRJW+;_$+#J{0؉ZfGtͬ-bpA Є΋% -x8QFGI)o;w#L_$QB=C@W=:JE31zi/cƻ`-|ͮ̚yM eI㟻7 mC`T={ƤGÞBKSp04g¸Ga=ﺸAN^ r`[x- 58`"#? ZNYb 5݊,žצvf~sDžd9ېI$i`3NJG +Lam`B@pD@5F|bR8^:jh*DmAgY*SoK~*,\йn[lk'Kogc: .\}өNϩEyiD&$j JS06 E0L)~4 MotAo#u8Z8e=UU>d 76^;ۢU .J4xPг\S*I{S3X*\R9UQhvƂ$k"&h[Plk=hqZ=ԫP MT~9A+*VaoxE h\S.cM;kFN ru""W`QLe ZLRD'4rۅa}_ Gr>֒GbuoWl*tB|^פ[)vxV{u$uEs[!>R^΁Ч(ĕ0ڧ˃oү>n $r֨Yk Ї?j0Q|W!; $_ )+Pqh.LA00:\W*bRM =#l5SRN'p@uK0rE PM ƀqc |3lKop\@}J;e4>G8S[Cp\&~\IF P7fr1k!+Zgfi\[|4CB !Ͽz~InlvF#VЮ`G<6pI-hQBeCb)qbXWen> 3^qb#2z 9%h(h>nkkOS ^s {7Qסr_;rk*B%82Z*Nfy'q @<}x𺜵s$o<ᓽ[TYB|m;YOkEu9m4/ܦLE9h8iPW*(꼈 !I䇳'X5d8Ru!kkYƝUwT^{t}]<04{ TOEf[l V~G fGMluR$D+Vj ^[6 Cc#}bl4^AMZ任Hr;L>t^dnAC([FEnuA^|*!cVz8;\^Eqn@ ۡe@g"w-FPJN>_&zx&@P qNNx-/GIa̋ e֔babk> .Ik}-0YΉ!qb۲`UceWբPu[WuD(o|B5aLe_EFa0J"J ۍ1IէvK>3@eBg^W9wgx;dd+yƄq]5Ǿ-t7~MIz{JJ.Re`ML\W$@U!sfgn=Qv0<Ђ)3 6r&&48; :8;S蘽 kǪ È}O?X͒gPf.|!źN1/~8Yk'7 uAWԑC2hnnBqҫj<0}Ltr>b=yr{}.NuZ(N3Ne`Ԯ S{ݍջs=kK[›kgFy\eZ:/J" OA>RAsi$;FF]Mf 03oVaZ80 &Щ| SՌ.I+jϪ1< q3X_GF9b7lgm\ XT;;_ u:։*,PSh`<g4VԀgDJC-O{mFs ?u;p+TJM$!h9{L?sWΫ\mF$Q]s`3ӖU u 䘊ĒN.G~ _>@_ W//c"+ӳg!&*yyPߴN&~R0AעS$ʰ H8v4̣vx.jr|<= agD$FSZ1M|?:[aNڴ%m'z Ý} e,~CNARTy=>v)݁lS"5X}mm527ףn||sF /k1Awb@cQOy)]~ċۅB1:jOb=`-I7-:,.7P*$dњ =`  (2mJvr{!1o|I2#{<;^}p[`obo5pn@y?)KSبxgAX$L +2G[$MY=B(ƒJ:~=^DQCԤŌɍɟR=bBm#.L4s-kшc67&vB5is[P7#`?? -w`^Ifϒ!SYX]A$h|?deFwա|>-f:)6^-TӠ1.Ϋe[j||hZ|u?'+&}Mi>YRdW?Z'd`2l"g_fCY ? U与p793Eu5a6 &O] L 25XUou :a=$w3=kcpH=Y&Nٞ !ƛ?ɵ3\ri3KM5!W,ֺ°ˣuNƔ՘SVN8רU&2?h|1i-\W(qrEI@ފ:ߪ=۝] /"P ~DGF2>ظuؚX"DM]<ꮂU؎Nr>a}zMz剭DG:)' }U_ mfcb:fa.(J/5t>L]aZ`NjUswKFJ9)_뫺*u[{7'Z4jBlCd`MQ*H $wleI>:)!O%w;<)xG=lօ&3,^Kn? ve!rQo.!g;eoěƩvV?9J Bk$f(#,O"La;s+= oQ632xyl;̴s%K=U БmjjqNkM$4U-VG聨G%<MҨ<:~(̀])@Q]S*bp`g0v6KoQ*C^o$&/1MՑ)sN3 Vdxvt%y_]c m0f9C! 2؍*@Ѡ˥P*Q;VKM8eϙ`cމt Qd4^ݸ:X8qLͳf{ %,Ie|L-OIe=ݎJHuw@߫xLx[ X&37>7t[n#8WTfj ^t.4-{᦯ݶ? &\"_)Ýd1~L#)o.|5uEaLʇ TjR=5.6֢~ʹA,:!A&[z>nhUNn(ۦbfѹ/S~%s~ }i81&=|| N+}]˟iPu@fpVOHE9kPa-" lVGt>ϋs&x7̥A.RV%kn>ISo#ϰF:붭+] *6~)ݓѸUYߊ!bc̔/e>8/y~%X^4]G.U!Gq{ҁ%E}EHu>byly^2_FvGV<` ņ!sS f{M&F.J,V}~e$%<7 ^ܲ7:hykg.Y! Dm,C+ZPں3]/2v-r~ ! Vm[ּk\J&55qW*3R$&<[qe 7NYK!\+#=dBH@?ыjBDQmfc|04@wOlBeӃi)'0AnkebJILWd$-x y%ϿW0z NV!H+` '׸qKLfwFs`I&kžiϥ5}>QO YOSs|2FWpmB<0%~,n#@21ye*c NÔ{ B0Ց~v[!BuXtܾCޔ1Aw&Ilw`{%яo0c T%Ls =sykŃDQ'o2T:\Q-Vψg @S63% #D{{%L.t`6P'fg0݀k-GqOsxeN?1]XX`;-nG A%y) +qs"2Z ;F'ᭉzR^PӒ>Y}Myr̖[$Q873,45I+HOպ6_ Kwh84HM.$Z~hQ3O)k*J>o)2כxI29{, ;LkWKY: bN.C7vI޿F &6W8ȮiU~DYWz5`"q\&hֱn=❈U}W.spCb뚞 &C̕׃5D.wdM]xJ@lD%> `鐢mG<m};BX6> j#ȉv>aL0;<`$A-9r;pE%SOhwzӤ0tRmY4<$XLϷ0]~G !£O 2=[m SH[7wgF~ .2Mك!N4}E  uwv; }q/#o1'`3gFfz_1w_No Ϲ8b' ՚zxIPZ@>_+P Er\_g@ry4by46>+]@m"z٭-* (M%Wrj` ף:?߳^:ocA EGuGǢlm!6ƺ2KL$A7s|4\Sq:(Ӿd죯 &Zb5  kы4󳈕wKCH' [DΨbA~8sl^{+c.<qS P%y@5 5%96KE7qj8,@Nۮk`3|1ewZ]RE!7PX~VK;u4橨v\X|xls#Z|4&kwL4DFպt]hj;p c3u6xI3^< J^;/Nf 'HD:) Vyhтy-##V |AQP'Է+FylׅMɦ27WiuR(̪>]J,6b5&H"`zz:x,m_ \T;oՂM@cL%2, ='-Jf?@W0ރ Aq}bT܀cݛe:lJD(_ S)um=rO+B;7C:sŖ]mA≸X ' b=u_|?";!Ag5`f[ Y>N V8 )WSavY9?8Uulw6z+(?sZZ?Œ fn8ndaXxQomZ4) VG=f e$T aFO"ɏa,#m7'8{!?5zIEj ؅nusTU?;nV6ou4S;r%h0_. KK Exϑ,37(~"QeY?P4պ*7x2ɂ ?WJj\;yw`!VK(P@Ka큢Ԝ!LTM>.'뚦,4`}{ٚpw7$= +q h\k .yLa)QH!ߺxoHVXKXy_ d>2☶ڜ?3$\;Du쁤(0k$HDy-ƪRŐ E)E`H7NsGQQkK=e$=ssoh`\0F}zd'-YЯ׵b7U:&b۶YtQtÍnְE/փ{%a m(jQ~v8b֍mh0Zpc=L i1K%3G#=ɿx E(ڽg[kHN-My`zjz(eΞ]$n&^EIMa1سy3#yadqx Eǡ.jZWq|U9N'/ iczp-UvBտnI,wGnf\Ց с%ÞLR stLy0ʷW  n7L=Y,eN :f(@fXmȦd|ÖS{ɍ$-W;8H.Ԏ?[]r/ b8sK#!dxDdJإ]o OFGߧ+@Nhg[=ELPqEX9:s f7;VOtz0˴bB^UQ* -m#U7{ZURZ2:=;>uf 9EKIB7uz'510 `av`9>lFa0{fwi<0$!A\ DkB:OV%pbbUaʜ !EX' i@ze)@BۊhNx:<*Wl21EESڢ@HNj/Km  ݫŸ4ck4 C O;3j Fy#>:5BUN#9%&_¦@]ԑ^ԙlMMU QPxTՌNHR^.-(cH+ҮT0=;V cn<ŒN_hQFȤpԆtoAzr\򮭬eS(\?2x RީΤ& l^;7t Pqv W2=ƔW%ϒИ%SJLC_߃G5ŊG S0JFZwqWŅa7(濫Aj$Id hl(Xrd,mQ8M[%oZ$AQ "2{%AqDJbJAq܋kTg [A3y f+FCa걤:*1F>tj/oy䆍n>seъ1@S}H] ^ =Re@MߋB7ϴFn YYm&gJx%R.':k]]}+3R!-#u;{DLN-w#}ȺDm+tiN|ӂ| /ciy÷VG[ܭW//B^Ѵ =xM֦ ,1 TځX! ՝s1GjAEFȈ,όsu!Y'-ɯS+{ ' | v=D*Ad"Ŵ+tve:C,H[|&xn*)kMB&V+Et*lFH?-԰80RA:]L@*LcGf)׸D=ff͸ b 6%~ڳsa̡gLaiSOz;v `'q3{WP=ȗqLfv Y kE 5ǡk%pkApc=Sv@0hi}!_3ѕ" !;td.P8,x%\aRx#BTyhZ YK >S'7Y߯nCۿmQN^;!WK0nN6|f7d/Bka^@a>|wkPޅq'nԽj<УyAe`z}oC* ^G^CBAǽPzVQ굆`f%]\l6Ucŗҝ,5vYSZr6d)^-<Z[S 9"~(E!kp9G"A92Hle\wBB`у*"@vUq7Pp7üxp_I^k!j/`p !UD ӿ7WW.K{U}-gĠB[\znͰ"`8]F[K*'4T߹k_29O1Ǽ3.5)ު?n9!to9<>o?V n4~%0!#l@$q F:$`>BBX~D: ;٢u엓[tf;sLHm1&4 u.#0^Yc +G41`_%FY(WK]36eN̍I+UgGjc; Bxa82zmV8=vo}GNDzOFR_'yR?4f%$8BzQ-ͷ䪴޸L:#FA NBO} jw򆌚Ss L╽&®R2OUPUAY.>BCO5?">aƗ(MVfE՚Xu5?*.|:cdaX8.3@R;xv,6ڟ3vr}F*^\d9\#Zj?x-CH g=Dޖ^,I10^'S{>ñI0Fw۷υ kv/[)3N?:&sGcpXPfmsE*ެ%"C!%:ZaxBS-yܬ_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT ޽. 7*o]KctdW@nRL76 `s0=Pf\t%zd+` O=.5XAҜ. \'!MKa0q&XвOyP4Vrqgj5.n PPۑWE%md*ݔ-#uz>׳V~S2co>F1!1OJ{'mր,c# &\ XF5'5V+$9MoTׂ"/R, q!x-qCZ׹̈u?!,@(opjخ.ߋlH>Ǝ˒\zCAFG g{C!nE~ܰL܂咳?[㞾#&3.#6]鰣#a[+zxF@{Cj/gڧDyGJ$JmhѦY_8/Jxɵ.cApH`%u+3+f$] -ËCkmKbFx%K2{Q PңF) ~zhF;ݙ7םdsՍŦtiQfڢS`ۂ{=nRVsx%fChV e2KiLqahX~ll)}Vk1Yt7\֏dU EZR4U2enۦ$R_D>`A;mhic u *楘dJLmRD:aGm^}.g 4mA .ګXXG; q\ e ?w o_N2%23ڗTY"́wsQAp$ҒXDՎV%X#4JxUiiKzkL 睈 x@St!]Ze7K_*N-t 6#(,^i(gm~aɧ|;3m'ceK;>C:ƉZ|`N*˄ɶz>CJ`@e|s`jwoB9.buFm9OwNf\}r] ~X0VJtzS!Ivƈ Lɹ܎{Rc]YpE_fm1dt=n=`̛b<#=(5g5jSn\YGM7rx9Q .z|#Mjhe"$5lr7 LFً]={IygU "z| ۢ Vɦ"(~}bnbNt֝[sJg!z%jf0,J7XGֹ|G|yrwoNK}4buF|0,$^1=\ґ[#ᬎ]VxEnɿ,Zʫ, )DE%&kqlUn s)'4:08 Q+\BOLgDz$f(:|* +>2o3MQX " !Y~br ?>Dg0rr%V*1 dJF)pPS$B԰IЍlQog;oq6w.y]+(uQŅ{`:7h|_\I9{yV ) ĽA^ ҵx:$K `EƈXZFB4ϳB9n7ɇow"20T&IO+ɠW (>$@8v˫}0sJ4VF/Htk ߄@1ǚTk${cM #W?T@y.m$Eb{*U~-*bM<M8!K#/±^T!p*^mm SV:_?C#+_ekz<I\ 㷅!u t?8~  #X JuzeR))gՍ|#@C%oLYکBj~ bVMu+ZJ :|[$q` g,d+^Za<8bzO&#oC!_ xk~/$rY$|U FdЋ=GWxzwqCL>m8Sֺ -=xT Uܔ=0+7CxOVVBQk1#vGVdgT7r ,-Iq6)\MizUV6fHثjg/v/QL Y( W%;;,4i"d>Ev&`}D,W 9~4F欼A-?NnƐ%]x\lBKv"z*ނ}c }z^2mvì'f?lm̔=t#0)Ɉ˘Ӳ&Tts2PG{mAh[k_gUhaP'$`N WCpOzRFֿ+;Inh "R8-/:Z7/O7?&Jˌb1M 24^<yh+]vh+]Ȣ~v;0FѴXR#R;!W )0G?/x"GXt5}Mɩb> |)zWB *{p!hPNVM&詍lL,G]kć27"a)] 6T7:9\?]\a^U GcF.n^ 5>-Em }Rr\l;C;* 8O켐>G2i 23?-g/smٖu !i2(ud%9n)wʺ2J U {|c8 *#L84sM_UAZF[]$:+4\ ~ݣ(\B{\tDL:PBvM+"KCuv  i$nD=+GYl y[LHt+ꫲrxfsI|h/ U9qr3D^G'ٵ` cY%' > {UkBGB1(`; YeךDҵ?J7EQ/pRh҈^GpEȝ/G_V;Qcu dwҫ} %ñB~s5jrWҏ|,qtG"{$w@6u-+\Iw'zj+| 6Ի5Ѩn0QNtN5p wTe[v/;upT18Ze)lzuZU_ߒ7+ 6Ňҕ8|!Cw].D8.'JPo O Kt^eع<%W6sۖk\_AɐXp*'-3pؙ{ho|LTi%$ŀq?9PN$6Q֍06ăT|boFWU]|*GϯlWy*|i*6E[,߼Shu5&єM3wT`蟯p*1# Ib侠`n+Zf8Ŝxl0DN}=yύm (`b =Vj,>̽"wڙxBKI/:ê؉RRLgIRxѴB.8\1(SL\cVf'LR>Z}0, Mbt`2]ɛ+;"ۋe$s(_WC'u" z(PUId1u'G[jG2;(S%v2HA6+e{0kc k*}b !g$pk r<k$))omHI}s*bNmݪ@G"X m$FNȌ) EZZW/7 ًj^ǫ_[Z+pT YƴU6IpJ$ʮ+1Yѯ JWe&FpZؘϒ쏻UV+[ 8ڢ4a9^mq D[6:g3(Ќmma?x[V+U& ѯ3!e#dR0X2J?1~. m_+)o+8c GxeQÅ,,x*㝬&"q9?D? #5 uЪ/gm̪7r~5T Ni=x0Q! .Չ*=blH1 {),ןt?Ch+Zh"wf~]? S&+?% Ñ8aLȢYK~D]"< 5wVϥ!UM:T&F6Pk  kܠ]?[92fO[V" # k"NM4ލl7ǟ[Gīk~P6җjXv>$ͣ8θEm2RH_Ts~v*!}2jXD :0@IGMjX Sx߰xC6h%rV>oնЇE( 7t?[d^ii4-yO 25'\ΐJ.ϩa>z]Vp/RbDQ(qB\!SOŝ_ Z/C"Oh@_b\w>)eV8ΉG/CL6u71]W cZE1a|fm&D .ռŭc֤wܾr]_M.ψCJ0"kt}$jE ?*%c<wAwpB0w[NÚ{$)b̆R'0R76?cFqhO[nyv?Pݠn~A#aJ*lvfƭyW`A,HVךj??#4_%2ۣ(Nۖ&?fQ' y_o,Υ.bg}~22޵04diuH7[Zq߫g:)e ,K]%$gWgZ9wckuFnLXVdJ9XRpA$ȱ :שbxJƽ{둾i=ttgnz)xR F,)VD:kSە I,LSI^~ +KxZݻ_*5)x(4m$ʂH)p l 'O $?A8g~St+fͅk <fTXfZA< Eu=<,ęH.5G%#l>Jي* ֻgщڌ{}QK,LY!ZWkh4iBeoKVAο˶!udk],30KsI/m ^LPɒ3/uA2:@C0,4KoDI8xY`_Kݹiy@Ңl!>R<^iDl~8k;}f{ki2~k[+Ԝ$^MaEXɩ:T|K/^> W< WM "AigsMgQBbǂ6$N _nV oqU.j%P$jT!~w29((eDV_H z[ԅҍ~55Yb ,HVnG/YAB`Hbu$(x+%NAt.pAb ɫJ%„eiGM=:ګhRLU73o~jwnt-c]Vlx`K=ؖ$Am`?yA'4(0&cKivڿJisH(i{3!OfÖ^[|!DE:``,2nm;shM;sJ{sabsXE%†厔 rLE8 @qSajcx^ie$s)5]/Z JuaɉbRXwaE2q~u;2Gڿ{HK:0(bv.EEnHyg{B,́s9P\+///Tz~BL+?Fvy!- 3 u >fB_@T݂,|{7Gz(qF n3 '=bBRw~S7@M345;1CZatv|\wP* fVљ ^kFsk2ꖤYS7΄p5m.j׻vL$v(+6>K-eń I|+!Qg 1kk݄G6F)4Zo}o6'v+ZBM67&595"d2ᚮ}UCò@akvZ(aj›C/x[u߬:"K P$̮ gEy':ծ.pf_׬µ^0 |uP휑hO2z?S(b=h?FM[)0 ;z%<MjgN)3dgȾhJ$ B'd ȎC{Fu-_bAȐ( A ]6C͘9`w?)c_&YNz 97b ZbD+e`y[W :!ah{84DY:3t,mc-'ih~mޔRjCz0bd.1b1-WC_GqaQ 376k,txҐhTB ܵ8e+{u`v"@3*^\@v %l9@=6K ?Aa a6lyca4W tL4crkkt4J2,?^?{F>*R쵪z"gV}ɢiOӋd._qxP }e_YD~]7[&'c[VrBǗ`#lGAВZVV+t~-5#DKS st;ḇyʝhfz!™POVڻ5gSBIbOEFSB2+?;DggԼ٪9iQ%d^V'߹s\kвi(RQJZ^E$*Жn{z߰d%{"_i%5D:]olHZt ]BDL=A[Kc#hs$5Ÿ:0J=CnLZIqN,(&jf e=Ko7)D`hZ v" 85'Jr̊ >fޤWU[*jl`FlYe&8šz5~I6XjcEOnR5荰{ X}un+j;YץW W8Ad/\'8٩7?EYd] >Ԑ%̞p.HۜԐ%Hӻ%!bu#x~}ˤB-? -k~ب)a'U֠sf>_)<۰u3)Tt>$𘣀E2ZfWspm5a?!lp+w6vքߘtje@튗DQ˳%Xh-a sD'rj%M Wߋ`V-AzƦb~6mԦu5\ev-U d\ƤMi#xCT~ x'pFL =t]WԦw)41&x2Ɠ˅e-f½|kiy\UB[zFa< |%w{n(gC>pv<\SjEkȐv9>>v|K23Jo-foXG\Z{X]0M%.F'Ek-fؘiU*+T-xǀ`z.7"S #ɴa 4*/Z#,_9凣>Y` UV##q_&q-?zrj}$V8 qOa ^A Lj喳3qRmoB.Hb.m DԦ}}x޺X>$%#7A |epܠݹ];rϢ /L4`hl\/BF`Ara%ebۅGUQڊͬSrY]L}{ H<,R)^vlqoZMfh'>Rofں(/nɩxteG|x0Q?՜WJcnn 5).~"/1/[|(H9MQ.Gd>?9pĖ'-0ޜɴW&@w2sy`ˊpM>45n.'A72wMa+ A- ))‚!h,:1`MQ(%IO..}%̫ 4Lv`MHWó}ӗop$T{4t[| 3x/|=-ʼnr>΃cA6rTb E%P]C;U/41]-Dn<ڱUxm:׃a[K[g,‘x^[Ǥ*0ۇCW(X,jn=]97mHzs ʑ :60#*B(ԉjDUOYS}aW$ꥹljJslaT*x}x:_w-]@ &Y z@}I\D-tR[g[R>'GOrukS*)_NX|`G%*7QRp)]ut*,x s|tʹV r v[R *i܁1WCO$ư()Tnkre귈lmYVk>O#/$xlxϞ4֖4b@GyQ@7&P+=T%S^Zl=BA[c5/s$pyja趻&YY2奭OG_h`OKSS͞;I$! ^l^9c3e=O (uQцTm]uR$Qg 0=AHr@,?7eEhI}+F~y & q6/3F/4jb;P|CgDGz0ZjxFZb°q zA^*3'hVo$}>w'}0d}VP )L[Z;c:?*U^aԟv}aVxƙ56|\rΊ+̫O$QSD՚/vĖ3pyDҥgV_s{^:0|}*ӅaoiWvC8 %Cc^WO9;<Չ"p()L8{ٝ+ 6 ύQˤqFGJAOq*p h|*/n*ek"14B^1 fhk`,^=%֤})RrO~* ||@B֒ nQdasά9Q$Md\jY8zpu^t.(G^-?EyJ^onu{+wd=5MfiD.ucuArɏDJ |1gv.VpM^ z:ݢz;'zAcgw.#p6 s~6 4>XJvOp͎+S>@Ͷ /kP#qAfd^gCI p?;J}z:TV5(ŘR>W*B8-"h=T^U!G<$ic?Hފw!ʅf<)ɺH5g*ܤhSS=\ԭq=)Oe'*֬Dea0ïVl+d"1=τ `9&ZZYnly;Bi׺`pjk=^f,qEw'Q <4/DY$2',FNzp.JusF?Ҧ|L"A^|Tixieh].-8HFPNl'P<VӱxһB\4”lS)Xc~4LIzvˉ{齃f>SG*_ă[ ixCA2>Y9 *wD_yƓn\w"S46&ў?)wD:'m1&'KD>,*>_cG -,& khu?jV =pRL dfoIveG HI"nB%MJJ%aXl}^, Q9,JqgTA%.pf?ajsg*4qg_ [q3.!nz+v7kVB!u2ghGOu(v!2 gPs|)C H1| lfToԛ^!C VB!b%R0>Aysa"Ep)B㈏E.TȨ";ElFoyl e{0JW:\ <\;l釆ilIh˘'ӛ^Yqo2h!FeaF`"sڽq$u׊%Ymh>@7I,hUЛ̂[RAE1t0"rݕRzQr#A Z&( 4z# hحeFojb=YBz|육㱡!8DU˯eXĦLX+.qmb.'61$N{Ȗ6 f=\EBC;&-h'9qCkDAunopJ/5DrYL&>_L_p8؉1fKvҡœ| {KY ,Ѓ>6!]=iqw1n7Ѡ]/lg[.Gq_Bkk[YD꟞{dnS8HPP7N5bl-}-Q~9R,,.y,|r0ÆH3&E[} ;{vFwP?bcKFyJ&pu~`e 9Q $~.IR02[m2 NX~&_]XΈBA 쪍vwU7yo"x^\/><-sر #z%b_ r#O"]PDEޯS_r]pMRV(| c{'BbKua<]ck72ԦAlzSTL~'ک G=CI8hkC p5An+чC  6LpPPGzZ7;@9v0ycb]3sY6m2ՇXGcf@9'V7-=xa L43KlM 8[O}(697ac1z7dȨsg9_r6"kx_WMBW@Arb_rI>w.)Jl7KIc&%^"S lroF H8*֕h*3UN4>@8yyi̤d/(@}EfHUUXW?Ft*5%Cj&CIua^k5N wn'ҦE/ot}Gލ@rfINIRCXcDcG.ЋywpNıeOk2o/DڮZCB C>d:%)@Ɍ}щ՝!\@4zrX7ҭ" Iu)an7B9K=A1_ uYtK@.Pdnc̣C#)kg\ \zR6QJKkްT wk vbQH+Fn@= R?c 1B'&) %uv$ВW]|* yߍ:z 7*{h֩sƚH3uw_X5Y>lݽThEHxq沃yd`TDH|٦uqq޿ i~ 9$S*8c޹M oꋬڃ˖!ۺ`3<9 :F^E' 5(wlT esc11_Y[*)$2K4q%1{+cC+&‘:OQ:ҿ޲nae9Ji~i4 4@_)\Tف5clT6oͧ{Xt卜 WM(5nɄ:|^AGk 6Kֻ`M~6RmQBPISx+h,^MjeMCO!8 hLXyo(޹}|&^oOX y%;ѽዻ5U+}b*ɥ <G-:N\rKw)%ZPŀ$jM8?E.̙u6'"jE[΃jKZ2Igbw~,LJ Uܨ'u^  뀁Lc,Bmʑҙt>qR\UmW]86ZP]+Wv-!<Uޝ%z @',u52#=JKHM!̕.d-^^F#e!Rc͹G*-kڛ;ßv~;rO?PM\pX]Τ9d@j(6 &Vh+yU1-]YN祌\E{_REOG5O5`UQ;X$( ͦqi$(ysm~BjVd#2SPíYi]wp\7V"`o>m\ˑǷK= 砃` С}AR)؜&U7J.o ixYmuuԎ0w˼8 e eCmjuxF}{6mSYjBC;rn`'G8&YʫdKpQ4훩7{٨tO)TgZM+chX?4X40 fxl3/}e[t;%ƲH[&+8-*<ʹȝ;#]O;7cu}7Q* %j;Gx>^#,G UAy]jzZt?Ar ~l7m(S $ԝQ#^֝ ,įUM!UbXsMe8v=TaWG1eNUr1*YFK&*YaoZ/zR]lo᜞ɣ$gu_l,IUU^*W3j'^xCn;dv@@Jw%|:vkE@Q;Z>F&Q;.o9y:[dK(M F >^'dWf玚<`Vf }m<>=#ti]CΝK?fcɪ7cw0d_O P`j'/˭Z.Be?SL|$fv(:J\Fgmw'6j\D>7()I1Fia"nQf%1^_,˰~gY7{cKqN]^AQ(|6[LώQޮp 98V|ВSgl(͜lKԻ S,C̬mY\ZDu_z@\>6h9^ ͋0Ba8CR4<_U k͓;Lɇ|f#g{'E~gjrQ҄;z;15x< 9:א8KOS˄)n{Eҙa>ĄGV!k8mkdQW_i=$*jH9dIKyDLJ98fM::U7ŌRAE?E}xi&7Qk+ d2g+nbMY{ECi`YvUlj!WgC#SkdW)t54I) wW6.{F Șxf6+Dtz-䒬ϊ{2jm5w>e"i+BIL<uf}ri>oٶP>`.ZgXG}T|iॵ<#w*~WB mY|wld]iM'O}lef%o|ÐpCOwZNhUlwh<ty@"p(=[R3)W Jn:IsSG67]Aú`%|*Dž J=RԚ¨ؖU@al|O<.i9b c;\O,b+-\‹.n#,ڲ] ''kg&k!Y,J8˭i `eS&d{TK'ZC+6E"̦Y1En}_L]}|Y1BnvnVQh6ZVTVYuGw}L ~ *=)$椅^Pδ% |IPBcϬDy<3.Qcrjh]o Pd^nRwz%Dbb(?J]b y`CnVf1 x{:kq%V\7uBu/ɌZV_/t,\̝.EI? 4b <<6KbtOZ1w$|cr  rʂn*ސźuC _%b L (P.{u=a Q='% p-P" x cNCuT)Xމ2z>[TX+u𳱄n~꼱3YsFpb'Bi._vtTUd#Ou)u7rz[R.>!\+LU_q >rKu:}=#znkmN̼~\+ΘK𣏊Yh,cjд9F;F .c7=N4B(uvl 1͟bo.J,-+֢`^I ʱ*3PK#t w,Q-aYT!gfS8cɔY)Ԭثۭ b{e{SnjQXy:ǧnq}/"]| 2^\4jٟ &):8RHfR]V`bt H48 d ުŅܼP!,S/;:M~T ⌙ӯB:%HjIVSK=k[WAR߈&p "썙/{ Գ>+(ݥIG)A"2ؗ>/" ^ϧgum>("VH‡^l]]4iƞ6˒"4;$9+JP̌C˳gRѼ n Xɯ^hf&3J  ޘ#&'@)ZgO~!_ז9 * =n+ S˹E]Cy3Qe:r, GPY&.*_!(z8B%u]ߔhq't`ϳܬseX&MPbH/ s Ƈ1mo"h+])R.y\:gd,kJdh-I!vp8`49S|xRvzA_`uv4 Z^wuw>YQ NFcQRYMzق6Je`sمlا(uSYᄧ4hn! dt :?$.I-b?C 5S_L#J)u\S|qAskjdNES OLHNRH|GaLIu(d>*☥UZ;BƐؽQǢAχkib&v2f"$鯉2)rj.`鵶5#HV*X`H 4F(bk<~vt 6@导a5}E1O߸]328=Ws|&grDWe.̉א:YRt^'P +}7rUfU=ct- 30إ$`g=${ei֩c,fTE Yw傯XyThʇ4;1@a`Y_O:K>zOu7ں/ܘ/@n j}Ȋi{ٗecڳzI9;C´-̾ @H$M$>t\5Np'+~;@xt(zʋW_fu0n3l%׌eM*UC)5v &HڲAR&Yz&Vi2xGOL;ՙb?^'1o QeR1ARv}kmxZ%JITJ# bGXjQ%C{TSx̯ζ]AKx*U:wZϜjML-m~+U;Z1vVQVg4Z#w^oWsS<5B3}]dz9șaTωzJاRqԣl]m]kyU̗,ϖ;C)1{:]۔i %r.)"Qb5HAʙ7Xrǧ /(_i+DZT՘0Kקɩ&кxJg4Qw^~1BN) Rp~$7qQ,M 7p%>@%ڮ.BE.I}f}P(Zam3/Z}G;f^;|66 Aa_X2!Vʋ3km7w&.K{v7ٮ^'[ 3 J6XK!G<\LOG'TPhT'k^NNS4PVYac\esif5r-`~1`WEp:* aTwsbfoS3\I>4agQyм)K*\v Z8ϲnz%g5 Sw!?GbuL§-}ʻ o<vRt|P4K_˦!N"uSL㰄 T>BɜZ-1}n|ͮ)Hz%yuoVEZPnx$lJ_i"ywTS87E6''Gf@{5~%|qCz2rf[n wTSZ"i:A?GiMӦ6`q-^EO^$Ͼmz\N7;(:C{ΌŎgp` uYZ/bgǝMԿXkq|;6o)bҕܡs$E;r1]lOYSZvkTet&˳p2-Q׹ٚs/+QP7xU[1M&J^Oj}i:ϊ'/flSJ~DsS엱וmd,)l78*hQu%>s i"m&F ,۸š`g)jʿ%u}L^_k`^WcrؿX\ 8 KGo^ Gjk 5 4E1~w[+7֫15'=,I R*p&0{Jq+8x!jbL">&@1CǪ%B{+gU~iX F-Ts7A>(c1] ~2ywvHog,e3>'h,Rl)_[ *9:ъDE'eF# =g|m H&.#'=$ /gj kĢ.yurGSjӭMb)ddj?i2,CmY,HsA0D"mmzVVlAfI>iND)Pӎ`[Wg є-ٔSmncyǻ"*@8joAX;HwMA|be fQ5b5,,_lEojM_UiK/̌Q}iRO9%qFHUmw"1۬d7R= 8 m<i;'^\֛:o!.b3 qjCgelDoI*Dm:K%(H]p}$$``u4ֱ2 pArGmG{be#lsZhw8WV^|\ԅ'h-bgP( 5vEt*7'XϚZeAq3߷e%4\'i EzQ&gWCyw*5\eb$F.^5CsZkgdTL6`Wcl-N"a+n [HO}y=(xIS(b?rio~liך}'uD;ΊR oHȬuwc5gɬe)YԛeiAa % .+@Aa 9ޅʐ,D.FGBCt_*ߒSS٤xAhG`;oG{͎\h`.ql&GJ G]Kg=d>}BX}?f.8I٥I|׀DŽ+8ɤyi~Jm,veg-`4 0k44ӣ]mdM4t l=}qGT4,xv5BT T7'C r(XO!>&9gտ7qHXn?+镄 z~U*q/$Rz@o.FFi~30=OX.#Xmz\:'f?ztNUՇ 3bf#%؅ F4L}n:C4ԽNfy q-c< ՞W,SUDKEXd ODb]JN^HCEtL`%uh_d1e0r"dSxJ5X]g}1Bgmt=%g`YDK=V+v^Baku2gQyQ6ݧ@}uP"73-jdx e;]=+\'Mt0~KX;PdxAf[wthxH<7SBFW%wWlk%\`n_m1/@!aǍ}C$_dW<'FAGWAa\!z5T)!̇H 5[BuZaAsO/ȶY#V?9"th\TAG2|BG0o$uv2dceñhmUA(ɵ $N;7Xlz1: D5|;RRP!=WANo2 M{Ҫ'%b0ݭڧZ+ 51gAu¡Ez\QHDB5@yGWwtd6oទܔV?<djMRs+ #?r-*86;S$Fs-AF7:zZFG Nˑ3&I̶ ~jk9q~a kc\)q#%.FJmY7W\;3(bG'9O@VR~t.dk^W#'didb]ԜcN^ex #SB)wqD~%0 _RHyRŹDV^#N< ɒA>QJ|ia1H9F/v@JgZĬx{xw+Y5gfQ %BAORԠs 2ln _7,>-c^x::O=^$\+f^l滔 ՟TޤiK_zK*_ܢYb3PԓJt_V>DUa0+ &]ΡlD=0xU1|-"2<20"Ν!?;(%3ψPTfL|)ȹ|@ꜻ\WiOG0br(HU!Œa"[3\ NWfD+][NDpz_fQ"yf3&UW<2>N?1_n2.=;4r=QUTR'͇e=*pbH *??e#d} &ID8#D/p3HA\FJOtJ/{@UbZ$>4 vi2~Rъ=L}%)J=˳4M%+_!4Cjz ʰeb?g9Crwk?qH:,C^{d ִ SGus|h=Z!EEC<ِFVʛ8s Aߗui+Z`-}GFΘU" FEoW2ZuvB=RΐYE[J'8阷'䃝)h],@w(|30JYӟu]]?/~JAx9Sp=Q`h2_*)S7b-2K8 l RTN$Z/>GA`u^>FގTAy4FY D ƓKj!XU>*ྌtbc Qr`7}U)ZFb!`>Eہ^s^c{h5M1!}2­ıtv"z7-A__Ƿ{oW%rw &{Sܲ!aWKv˙D`բdņeB o2MA|B iS7xαoSz^YGDQtw0sTsT{9>%)::].–r=rP_Wfqi?[yDMU=TCƲe}f?6#Bu7`_BL8gvLҴ[cP?waV|#BzE:oo i7 Γ_2lX =C0gU`Iq#E>TE}'(%&yprޟ=:#v8wdN,Gn1U`=+%?O]sD͉%koznupf) 3G76.>PT II)8o}K]AdUdwȔ@X RѭM6W& 1Y/#JY j*r($sQG:$ sg2.y3& },XW?МhC YYKϤ:ɳTͮd=V#{oE7퓿F isBϖi1J{Kn>b1i hf=ekӊy\/Ѫ:va!Phu/)2Wx!JAPmZaM_ǎBXc@'O:kL(aS eۣϱ/YZb7n%yl@}giq#X4jx^{6`N M)bѠA^gNNW&`tyUvNl{a'o4 z ;IbR3`jYooڨ(Hةoq7·F&%xch 5q3g_opH6jP2(>ȈHK_&Sc{[Jl 䳬b<]HEDITamM,Qt 5WZl"{$6*BTgTA)Kw܄݇C͢-n"m MŴI !L'ϸ cp0<"[f^c ~trPw\H)w+`nCuPNR 6Ș^7вu֚&v<4R}&)S @hfϠB2bץ7'%P\v` G㠣 eMmgr> ~ &ܺHg%' ,B\cЫ_2@!*bʯoU fk@SN!.JTLLjӇ5{(.)EIlMxW`^/wVR8<sk;V}qH ƣCl3l;(<L51_,TvtChDM4_VUh_qT 8ҨTSQUYS2@|(Uem./K#ykM Xv#UqV@ީ>?{<7XFI1_=T[)?Vt%pUJ@Fwˇ޶Vid TՔpf$q:򱾻fkclgr]A$1OB8k)EK:k΢ kEl5mnӔ=. NGp&$fI|)/NHvWH*=THL^H~9dl%?.I5GrKQWۻ,ǍV3l-/sӟғ&8-1[h zN'M9Iaz-ԋW5iDpfp]DgTg8#Qz343;adny[ j5>`q$[@tݰ%"]1J8tR v: ^pi4UE C%0ՖUT.׈ҥ)n!U%.Rviˁd9{Ժ56% #CRlfqtAtJe` _cJCa}n(E0@OxMonWzZVKeƮzmJlg# ͸N[+]6i9PDks_k^u&xtr[]IMKS%r4-rQ{@ }'f09'EH.5{|ְo*BeOoпvq>m>֤&&1:VAv >7cXBJ+< JdWMɺInɀE'ui1Iyգ}]+ &abVб>&`OvN^]P( ׊-xSo7GA5a\t!Pn&Tg_0gwzAz>ғZ! t,-ZEjFSfF0Sɀw94>?tZ_|K++-{r!O.WX+SCw&TvV9Evc NL:% 2t7C(Xnm4vAX"}nrnpt>Qz(:3,t pN|>r%v.G"p܆6#='y+ M즋'u ίpJcvh'r!v9'rҴHT{4_Rm 1ӟL?:PRgQy7^PxH1"Í8@:$,%˜ӫ lIHChumMSO \gMLA@!"#BaIzEGYHd%AMQ"J_޹C 1NMƃFvʞ] _'$$&?Dݞ`.7 FUs.f~c4kLs2[,/Sg;&͔c#Z5=DstU&> 6e>'|k[%!5HrO8[!1݅c E ~G*( $dֲFc^J>c.T,MtVjPt`n:Tg=Ԗn7.#}=x'*JM׊F7:y1mGkj,+ۣ-Ҁ1 9ڭ/cU hE U;-@?b*Ms/b,4W,p0wF~Stgx6{`%; 6,S-&zwR-!{c a6D?ƕnxVsgpF׫VǦC^?(w -eJ<˂V\3 = tAEi4|qݿ zhs%J}'n=9' M~J*L\ng5ihS,Gus3i3b] V2khl_Mq;̀2*BM W$vCKQ{7{4pPf3LBlyeV31D뫨3X]4j0v1Ev/t]m8xaO-^vʖ9\\W[О R%v[nGł!9H*1,}䑝_L;ݱloL\CBoZ[e7p&:vc:UrŒ.'?sSNmU: us6B d4/~AA' i| I5_>TC";~N@ i[5Zi2h(HoAmEJ~YaP  ǿgb !*~)x1r{CALMŢ~bPuQ^1wHuςc籲\_!Όӈ"OHM|f0a\զ.1Yti3./bNG,u9zʬS/ҙV5hdo5l<[Ql"I V\KlyJNqd!n;S<;'jBT A; Ŭ)91> 7qhd ,T`AnL=I{4}* ϯb>g,h.*S!8C9e?J&6eqս]rR-a]8Iqܷ?E5(OL,  (@\Uli:c8K,0ŭn/ʪinZκ|ZZOGrR%9rҼxh\)p a&퉯"!oT| RagK!tuMDFi5iƕdGa;FpywEJKmQ Bz ;ozԻ*~CA՟lF"TنڼS/oucQ r͈c.3ښz:$PA[v% g~ aż")(!]9T}vZ|pJԭrvC9nlF>m9ĸ=ނó`f[2"dZ\Cd:`22P w'>}Ӏ~8{9rgQ k!{/ul7Hv08.@fs`Dq Z}t%гaq*ө+=BX6Sl&x*yuJ D"N{s^dD/!M菷 ==D l(V'zIs+)|!6BPb 5]+IoyY@~A~ccr<dQE]LajK+GJbRjY/7Dx7O<H7WlyPF(Tf3XƼ(DQdԝJ=|%<۱zKbmIŸNY`wD.,Ѵߢ\H,WGK1UE#ƈ&pWO9ѐUQ7)+T9PJy30 ǒ6 \Pn4 wAF7g>ARQ׮Lkk ewk>5O d9tRPG5nE,zӚG\7XZ`Y:+[yMKҀpSTɬN&rͣ[ųWB ^vײivq[ًGױpKTh-Yb'JI1x>N6m`0*C5 ]ĉ*S*\ )=òvVLgI$01"Z3T]~PF4iDk@zDf<6NpQˏa"{ZH8zBQTFV?v^wYwe ~$?3Û:@=H;1i#+OvRQe 8c)0; K=@DqGeaۿӋ@+)yXH{5j8=Ӿ]xzfLlZ_XBRڼR[\?-~χKƊӿySSk \-<(_¿2l-BZ|Tp(qZ$$ֽ $\(F rD%fhrCs91ϔr߉,[ Y+4]ͯnwж]my?%ok7:#dmK3%`e_73oڌD-(a:7Ya8В |MB/s>bk/; . h$= lBhO"‘Y҅&q zwXɩlGoX~\^Eįf5Ը7j[3=F^z>Z'@`l †~:ȨL\-- 0v^iO 645J}:UwEͣEF[& 'k;Ν@{%YжPk3E.LboI@sq{ @WQ ]3#9w74vطq6&U%LZ()P+~n겈8|^\d+!olD^Z%LV1͘սo|C1e#3~V3nHp~aTvS}N/kbzM\=M~\NiOm.4 A e~Lr32Oi~ܔ.#U{0|"fc~5,Ǟ&E ({>/-Qӆ0O2,`Z,Tbr i2}nkLi%jjUI5 GLjj m+Rr3a]$FI%#_HGld]l}bwĝX%c G @vzȧ,[AUuP@ +Em>)#U 6@íÅw8 !E6Q6\Җ1&ъl @njikd;'VܡµdiusvsGՌ@}&:OlYI'Cih`UI/0+avsjQ^6V4誌XARYA5,'pÎ!5v dҢ,\V6 9 4 _k?%3]{`lއJ%ٯ) ) {\1M⎾߉2OMy\Ϙ9'Aפ.!JĻ~k ^eFOn` AEX L\,&RF[ݔP+bأ p.]1?[2q.Jk:jn|! 5路|ll vV*bLp?-תc8Hm044*S/X@Ks(=t(w w< nOos*ygb.!ؒ+OP+pNK{q2=t2bL:/lJz><I\,sÏI kFC2F?l؊j9Iy*bfa0AW:(.%:-+ J Vzɼ ;(rנ'NU&7yjRP~Ip]pbQs?ӷ~_Œ"'.hE'蘄ZG B{*$dehX@ŭ`A!2] Li=W q1 nw.=,ƽilcZє/P;(~WP KV7~etLn4 O}5fFΈ"uŖl g ri='J`(F]oSMGi"Bg~E5[c:[etdI! z/ة韛=/Ayk8oCA*ޟkC`bƃ ʮ5tnE m?ڐSP2,dBdq,T=`Yk4>l|lb&D}lKj`2S"H62xac bޖ&QוMٹKq5"$Gxr =dh.:ۻxb$kn< z%D_x' 8[/A3…ݨx,7>/R8OVR2PÌkks860jcЯ>g"h(r?!?L]}RYJpn21Q ),(%N>ޟ,&,dy*hK.`߅&?i @=(]L쿀J(}n8WY2H%ԡڟO^VJ,1ja<( RYIJqjQB֠vd3:\^:?Z/s%٩ [*nјCK:W}]npmND+DWb=-c8׈i2[T&Y[A{+5tYӖ}ݓ>ڭDa\厷sDhC֊\n[ׂl1'2PzD̀ -OI-}WV}APe=yS̈́"3 (JK2ŎV63yK)r]5 W,)q+=$z!Ѻ^N%'r_uO#Yg bjlkf]jܨ2WN;'Q^a֘ \gKoNPKNj#wgn&ԩXf*R^;3l[Ly7eHend`U 9_v Lұf]H8t¶eЌB'.CW8#c,nq _'Y׼AFU$՚\2:E%PWjz!и>u{<(z4)VgAŸ-s`vLxLJ }kJtÛȉcO@ Rם6S:BOsM+nY;,Su $ \'Fy_|oHi=b ,FF2J.(j̬k;ier]z6MXTh5 *˛(AZ$.1uϠJcpTx9B%JuՂx$q'WLXܼixQAxT{:WZ4cG4?P 'LzE`}ڐ.6!%wJH N58-w숋6p0YXkIEѴܴ/r hWw C,1NH WjeZrD,HVU٠0\aY}r9UCPQP8veQgE 0n5a8 ߍ3$~njU"֏4b.:SV("OEP"~'n|EDr@/sm6̸SU\Fc9klnx;YXšCNڤ)ŋ`)mKYF[p3Z,⭞`k]'iWrRnL^s:nԘz͖fay$]Xʾ?V)nQ0Ṩo O+Ⱦh0=K'S r{5l^L/;zI>St+Rڱ:Ky ~mIcpvgH]41FџDe|%RzC fb(V-Q3/\!( IG!zY0ꉁQgrL*JM4 њ)>nu2CFx\@ZH vjƮhqg#>ΧPEn9|#$iJT0@ijBsgm0BIu>=a3v1K^@b=O? Atee7I!ˋ9;[e eQa7Lh9^F]{&S pҷ8ƀfI1rFq?HBڲpAqe9P&U1|W\&6 Ʉʊ|N$K Ru馱r #>}ߣs{\쓻s6)-ԑ2 /Lx/͐gt %]FxB [VbU vP%sG<%&ń }X#啋^d*0`6s!&{\=wNz56%Vy>"(ij,ؗQOwxl4(یq%xf]aP3P(d +iwb4Z4#4AhqqyDYI.˿Lt( BHeܓuT nj 6i.nj4yʫ?^~FzMXI78#Q83ꛒ].5qϸFdMBB-4^s7v lJ|교eIf*pn[ҩtwj5HLNeܢ]Av1obLۛ}J?0c6YӍOCu@+sH>I~Ĭ iy9XOecJrW=J]G/ϳ٧M_[%/bԤgqIȰh;=bA6[%4DDU&)[J\Щd~㌤䌆/~0 u)  &1O$J eP3CG {sg.p eFHDIN!9o8 `2hɄyQv/*IiZj8*oࠂsdh-ۈ)Sg;;(c>h$/Caܢ\v6{=rze)gW݆q4xhghg˵/]L ;?c pWD:JF)kz bl"A+ԈERjra|9S1UOŠ ߞ&r)r2 IiG"0&Aߖ~DsI$K%/=LWirWvvHJ<'94M}0řx)K,6 `= 3)8h\BM' Tz-HQI*L)0.qCc0͊* 2UJr&.o{Lkd{c.J *wѦnxC_ʝr V" g.[+z@Dx\Hfn&G5`\c8Jv>)*RdZ+zըko fҔixwbTUOE$br7奾m2emSz$cnKvTs>dÂO(KiutM2lf54;6nq;xb³ja@_z6d sЂر"XN5Dl&u^*H|^j2gI& L5HRJ][1]gk]R/1_A:b죲Qoy~T` :I\,>ka4ݯXmdb?.8M$Aq^%NZ;-=_IbJ)_~O9 (jn>3KL`'!-$+dZT;7nA[G6$#kʁP$%S]D1l~RYvf~7ͧw}EgQʕ9K#$C"򐘾TdTdڼ>Aߘͽ~*<^bƜ4Vn5{*~[SP=1YQ0h`լ5v1Vґ/ Uq Fvlz*']8/Ay [JIo!L`Y&y :U$mHu~.&Г5l7c\ H`>؎[*`E5.&2PK4orr&DD~_<#TDMMYn̺lҢ\Lq@krq F<9~W^kD"/.3w1BV`iCnhyT*Gbdo{-~ka0-߈Lfa~4͓+^ՎkI8qA#}@7a Ѫ8 sO<% Wݵӥvwöܲ'nv(I؅e(j;hEGO6+C8/FY5\WwEglk (2`CZ@YVҁ舭>:ƃ4'~, 8P_=ѽcV>]`0m"=[Ka9)~|>n}2N h4^3<[ z+NSYrnÓpX->VXyMޅx2J% uҷg/ӷOي]ۣs$ %C Ȏ-"E*Uȫ0TY,I'z=dL{O`tl"kae˥qZI2X*R-2RVl CR>ӐBWׁA^7g fs /멃|@q&vrJ9^ڥYfDL f ͯp 9Ky_T.rt䆸1-77{)ؗQqwwEqoHDK9fh &qPlf#-Wuloc]_smt_%ݦSPbʐ#)tuZ:Yt4SDg)"}fER?Ez>5𗝾Wzf`7Mw7,z}Nz5)k"cQt{9ѯEٿ/ g* űWĘKe/ I#b2_bH)]P ec88o?L͕5ͭ7Iw?OhKm~fddY`PĔ.ZaZIΚ0*IߖBiμ)!v_jh].&9~HI$Dѩ <NjNbYf~[ ׌lS#jQŢ5{ԉ;d9}m]# y=TW͑5}aޙçV34ib ~f}Iܱ?cuà;ڏGHp.{c:_cRWMnDj~}1܏&:vmXaJ[dl}Sў4z䩕hs3"\WiH .`UC(!cр=ܫLZ':u0x7r$0HO "_<56hCUYwxV_٫ECE5Қ93AhGx;ԗ@z*B^ܡD6tF !`gcդɩ~/E0ONC˰Jfi.˛i/ŋeUOW6_ue ]"yE4Ϯ`vBiFg_3jZTOd-7z9&:%`t :G$V''dJk4ϕ/"č"c96tQ]A Nsl 1}wv!֤XO~_dy*vBALASG\}xW:lJಊ^I#H "'Lk2GKPN+fwM#Bݕw7ADJxF`*cAQjb-c^> 1F/9 Xj[|K˟x*l Ngxn$fÔC'k@rYsmH$_\NZM=YZ\f"_-i1ޕ),~l:IL:Tջ\9F>1$8nCy U ,Qg:iͲCHUL*+JAk1BT@ދWg=oG ewj(b9Vmv,Z) sʼ`E$]ϙC۩7=gP%u#tTڴwK-̀亗vIMd2ZOKtuYx#_ W^ gZ'lplkDA'`$mƄ |ڠ]g'>}Qދ6f?d%bA./]oɤ@BqȈb0|qߨ(\՛7C$7Kɐ&MOoc3X t蹕6&n{ 7$,Z챦 _f}Y&gV{f\S4E -ruPEVFdPӱ1m2"Y M=T6y,!eHTp`D<d$cD?.7_:R{I7Oמ G GJ)kΫ?_??:tn10p0 _moz2X9rԑ1{xlQuyjӠ ?"I:XxIEǔ+0I4\+XK7^1'łYJmlID;u(Zvm? N-F.mSo5φ.mҚoO',KCΜꄓp9Qf.y*x 'z^泈>!5jc0; d"F9]0-bdH:N߉RGZя Xcnm#fZ!y#,QN) ά{a#kuY(CzH˖F;G=c$LaZ%M쒝K qV>;`;A+{@D(L ogDṉ@(Ȼw 5n9v%n0L.fldϯ4:55" b};6Z3tC*tl72I `x,f-$OxrfmGsd VBu[Z\z=WzJ;Fю d@**#n; vz GYX2ף_]"*ZDS}!%jeR;G5𻠱Wh]oeؘt-ncbw)c @4SaC7iK㩋B0*;nm(B֊cƠtX8ڤfnx&{@_.#m78眀2 26y! .Є1 C r/{wR^M̘Ge&+ڹT:9R|poRLs]#j@$(f$f2L$as E3hrN4|;Dh$A٘3ׅ.&jw7Z.}Di<ەʭd9O_IJV\{[4 jƆ&;>!QaV_4j^]+%D_/ouC-~k%O-æƟtejE!+#\MO%rSxoF J">s=ZUDh`SMU5OH3?b[.M&>|1 ` JTP [GRnn-WkQy=B߿G7e2T'گI <nҋf\dQڶ5F^r#X[|ˤmkUηSa[gL tI=pkX'7ݱH11dY~倸!#vеŽdtC ?X*_c~4 hb~td} Nb" ϧ!P~f3\ɱq##BKub"ƢѢݠQbB P.Dt8zȯŬ R|#J\O$w2Xn 4pՍ*&5A5rCNeA J.FwǤ{kpJCI4`vw9#Sڍ:לrzsb^CUS%BBc;7{kN1qb;-R>.R9"WbIDқUym{#KCh[rk> pt'$ʛ dS.WZHD3ހ";Ŀbvn:6`]3-*E9}>-J77Hri'QwHms w}~ Յ ]-lErNBOM#I8Nhmf^kSV1AvyOIyJ0iIe^·ׂ@/wz>a1s8CAPU}B):!M>5hP"8,[T9} v[^"1Gk.}O@pSZq4Cr,_ ߟkCMBƼEBԅhƐr fl Dby[(}J'W:"MLsrOT`Y=g4a5@ DƖ7(e2<~'e~>"\YYZKd zeIi;,MF!pE <]5L".7[aO=:-/sKmb}ЌﵟWznXl,!—wڹ [v|EꦭyiYwʁ9f2qnQ@=\j#![zG~{ B fc\SKρ/LvFgSy"*Aa*cUGV/`tEoǶvF8$fd:3ߢc@H!N(p4w%,ӭr!P5)i.,ĚןjN\AccKկ#S} 6e^ʏWyhWBP[wdآ( +ۅq}&yx N7/t/j*wqؔHՌ7@bKn7i )m r-#Z5 fM:ss0 4 )_@?|ƴ2:T0<+3IhB4AT# DGHdX74+K4hY~]Rt3+l]H^!I),OBK҄dQ6?|eQ+V[θ;cs㼃pTn@Kh[<#cbW H%Q7zl}[0}#$Ѡ\#VyIY11~]attȖmT9䜐/j%o6TPBFbT+dųY?yP2qm'_sA&ZdHwq0H}NQ/1t35O]< r7t#7uU{e*^'X}=p Ed[PW/*{^;( 4&9D>N|n.Zoy ܺ/ym51~6(H1&U<)vͫza0;`pAB:RܽdC mzT"(:fMkX>čPE% ͍QM3z~i F SMIZ1̃2DljhQ+ }X%*! PY %2Zga^/R-4͟\8o -iɔqҙzr7S Z3>#j`<`3 a2qK1$m _q*OR Ҁ(Ldц$o\sRvʰiQ=pE}"x)< 㧟6iCֶ|: ̮E;|^42QG.üW^Z*m@uA2IM=ms3cu왐iY7;MlՔ~r.{T P >(nz ʃ6\u%jCw/t'Q/hRcgfPoX鋌g4: vP>jGDZ]͉O^_Z#y7(`%7cDXGAZ@^39 εǥNL_c^7Q3[:IŎL#v0훗I ҃cBb%a#͔nY˛lf|~DT\оdCM Xݻĺ.L7S1 t(SWt^Ho8^*ؕc5E,8١Z8I@~Ebpu]ag=R/rWCa {D QV#CֻB㔙bh?Og)hpH%l,; Tщ܎KH[m]v$5\UD'JE JV2鄞bY5jʴY|+ 0K r/ӕWNܿ?BȺǂ3bQ9×F5lQǴpA-M" ٦vN0}O`q^p;Lp-9<Ǘ5${+ޢb7oܰ'(Mf̅N开*MA_u[S w9/yK+]ǭ9DA*-!hp(E8$4.Nm?)ѴuҲv6:cFىXrp3fS^i=ZĻskR,+6Zc7k$T &كE;gvg#i$'mG_{#Ѫ%@SLaR _#K=X ށ2 RA*CGq2 ((Ug @CN|&W.;23a۩9J,wxBk30]gfS/Ͷ Z!P&67'Y%!m& 1O.1ԧ,vTǘ6葠GN uEkb9N!i)뒿V }Ni5WԵ6\VZPD2דehznB0Ɨ[6FS8a:__%A!Y 46I=^d BDA nvD$x)7{TSѲ,GJׂFJn :[5fP&'g{h7/ K"Xquuv OcN)Ad@ᬰ_DE4 dv L֑. 0' =P#wW'򣑡0d:oMXx݊f-^2>@-GDҍ yuYJA ^9aOm MF:1:{L5҇v$keCQsK`w-V RrFEf; m9QƾA{2$q ]t^ 6*z})@^RJqzf-:{P7yeAH?0[15Orr?9EuW(Mqg_l[;/ ؑ=jl EꂶPe6 C=SJXi0PK]?Eġ@OsZL {iFy1U%ҞMN+˲bɧc$/iX|;BSI(hhڐwĖ-!~b۞3%x:G\2;;.sD9oa~:܋}h@>ݯL_$Ŗ+t!}GM@@wd"Iw5af).c $ZC>?cK1]' )"F`jcavndf1뻜=t:Ubpejy\ЯJζ?ӹ=h$6 84Z]ו=%۝+ZB dz%pfuWRJ+f>#S>ֺ+4&[3;b׋UJ{J6alh8<:,MִMu`kQ/A ܠrJE_m|Z6*EJ"X)4Dc}POZVNYj:ڽThlVv_v~nQ1Rn`Jg?P2L2SɂaNՠ|s_b Ya }1J{rkv"EOkF[wQyOZ@-y8}WUQVhEZALP_=@ 4 og.{Ҭlp aLR .g&OrQ%(q4ښɤ3qں0=%X=[&iLXHqF]0}y!ɡjRx0H.Y=%BTCwh a'c,ddu~R &qW7h3e*'ϣ![IW^ʄ.YqWSV }fPj @h 7^eH+8$L{PR3ת:ITܓ$2 >xϫ+h6\e^ 汱-$M%'Plj.Y }LC{~heIh%H?\kk7NNiŏ5DV]Fއ麃c#5czJ Q0'?N9'vcvl*CݱꍜqTT@\dGWS{3.yς2~-cߛCL+ͯSj^΁Ȅ^nz (,A:#mYab*| "@g2h-9\)2Q 40& U갔|=qI.󠃓LY_cUNhc:'YWgP4q+-o+G z. BY `$C ]5_-ژ8C!6n"I$=1Oy"xYAce`OB!AaߋiZ/^77tyr.;M\8'27_'Db8wOL9h$mQ%?9ύ^7d'g/~SC\lƂ,āѡ``cRKJkBywSgB qwUp:Q+S2\n_qӨuϒs5l'[U%6/f3Q]Rrp(sGQt<9]m_n·f #_8S x4ԤÁޕ̐ά!5n &Zw&4obAAVxZ/]V6J 8XYt2~ї}K2PLb'f8- ܠJq}la+&5|`IKS)!KwQ,Ϣ"ڮDJԄLG4/[f+XDA~V;gӉK^&*ҧݱ0gb#ke>T_lQ;ލ9>%@ǞhIVN1уxr2HzFy1"j"ov nX2,B'FV éh=OguʚڬJ:AK&>T{1[hyo [#պ-cFj-=j]tx9Z1h㿮ͅ@ԹE˵S&{ vG>柨d/Pk Ww*A| ڐ dE}5v##3 3Q~~zzsģsİ*J᠘ݎe{I/T#> CC2 qmq"o"{=VYedXqk-3]#dU!2lakoA;֚F,񓼞E\(1+x^N0G1uSAM= ba uA/&ٴ'#S6׳ |׫:Rη?!"܋*6T:F͌\>*UPҦXJsήM'E}c2ԸeXzTbt̡'Bx5\T-ٔ߸~Ѻay8EBGYJFtsi7 Mw'DZ~d– ~v[Qj_cceaek,9K# UO.2Fw)r`^^~Ǩܙ0}P  /2fbh6Dݮhu?0 mGX2q4$.ehV#h]ٽYU5Koj (0sܦhnE,Xx7Zd֌\MjO=RΆ; xI2'QJ9s$/8GhuϯGuE0/[~sϸTNc(wP_PLX;I'묰R+REHKyK8@&tCߧto 8^:NaJƣNŤ ,.00؈U7'A6cUڦ [;"ꘈ(p}W)O4ր =F .|씌BˉBK:hNO! 0ս@7lҎoP=A-oB,P58QMJ XۙqybN0~U|İ> cn/,ԏC91&PXkB(BqFm w#gċfKRVAV@R?]hno8خStA[*GGGI0@q# nq*jJS1]st ;kMBw'TGo_qj與t[ b=,"s4E!ߌ7A:L;jX0j@1t@^AC_YlV f}5rVolG +]:8G ǁ "ٖKUįD͘6n "_!!!̝U 0ἲXſnڄ}FnfwIП & zp:8j腺:X'\"ީwb(*vvqG 6SW '܅'mぇqLg.ٯƑ0_if(cƮ}WÕ2W23 [$brҰͯ&AR siʣr^AΚA#m,o;l $S-څ y|!p),eJS̅J95~VZψ9YahkB$ymb5߉cJoqs틁aq1.U jBˁHHq]AN*9kՑV)TY6dpI=`:0+U @ȨH.-6]FQx ="IU%b -t}埩a|Xl[dدR9577R2U l0SQR.1UOgЧmRAY|E]`]瓫nTď+RN ߎɫ8n^8xљ" X> ~|# 1L5> }-T"cE> zi?`:j^E1̥ gF8T; (1ۆ}h-ө25=O1 @k * SNbo<d;hE]XmRۀ%'x 8Ɉ.B')[qY˜s5ohC^Oo7k+% g ꀵr^֍E!Za?~}]Ȝ~8pt뾴L*nMU"%/6#yk|èl/(o{ 2ݽ_LB%K)7ٌ(2aa yQAIG˖ )u-}Z1`,MR=b+|tRbЬlԲZ]KR ynj^)_Qq@VAmG }85Qn/49"v/YoM 5v] +uVuMh61C ¬&#tj@ pb>ꈢf">菈jP'5B6 (˾r"S)Oo`ިd d"%T-=Yd1pH€Te:qN6 YI-"9]^dk9&c,Ikԃ1!B) _҉vx߱+muբN,џ.V L8+e2S) k/@7Prn֡Y5|f~5fEPXU_M6\;TcAw.Fb:LqhT p487(`+k@HBflZ/K~'3!U :@\ӣpT ڟܐ3qSnNpTNq顴N`xy#X44(奢/?O+ңB‚B,=p<Esy18mp?貎Ҳ:v%-UY]kx wQyD&%U @zӱd@?X4]<-)y8^V}BĪo50Ъ;(G+J‚#뽿5w\TP͂HyС5uM43aeېBh ޘ^N;8.rQTփdY]tT ,\R5 5E=sbMH{P)JF&Gض#1ė g 'er,&KKR:~7)NxSȧ]d$El?DZ9/V@Kڰ9 V/ޢ`9EJwb hF6gA:ˆX/\Ϩ._EH:09Yy#s|Y7ҳq(Σ#9"K HX-PBSvo YX@7 gbOtHګ'Y񰳹UFXrԼPX„GtkA;9P5 Sh>0/ltVBX̓S r b=@n˒eX>p0,kש>czؽjJe,}]^/j괄 oO }GawX=LlH]z;әІ4J"אgLLӎ'I7; #Ԭ[2{ 5|d sl іqZ/;(vӭn\4->)9m)=Q"i翩5v00WQ5Y;Ƃ%b>t{.xVTpp\$mFtVx׌Q3a%/* S+M_DMk.A̬gPm}Xz{1_Wg{E0oNCHUdA:es oY^5D+) x@Q_}DrX7=A!9pV+RrDCIsxި",=tZH~T~{?Ǝ hz؏WkdTh`a T(sN,kc_׵E0^ s/9ڴ`(.V<݆a<$PޝpΣ`BH$4W{ku"Xrg.;ttgdm,YR|4# ]&oz %) i׆X7˩Dݠ. LGBf%\,*gxGx)i\йu@,uk-9 (] ރ&3R;=G8߂J_@60ŗ visoTmS0};[=<7(-D8"kkTLCpl.G2f aXsD̋H-mY1YTP 0F~vkZf"}7EKYN7In$1f()L5Ks7 )$C0[z㿄#S Dml) a!V ks2.-.]W$<,X򛮸1uԾgd2VH @if.r?G BIgt8 14ܵ,]Y 0M6[Sp%Z)-Å 2~1iUSm2QV8~I3I&GA!@T9𠿌/!~ïZF*zm Aô,nŇ]< 6ĥC4eANj*^_Ds3e]4hfm-]GS/9 +8*,ٽW6 ` TTq>M&ZamSx9G{D\*{_o:*e>lQ_VmX?~C?f}b_ዒ#Uj>.O-Qj; 5HAVS~څCUX"pQ$4w+hR18/:ğ*pOkT"4v7<]$p3>8Y` _o\³fV\Ic+vXN!l= ,3ےG(zr-E;{>x}!q贞 w:=RwQ~EsŽ7<ܫ|! WL.5@*Hn0G[E^~I~(iif֝l =.p!m $D;`5D@ e9w{ǥeuZE|W5TbcKI^芿.S 詵L+e5ox~^zka &Pjk{R;~{/6F[V8w7|ά~W#3A` P7!UB.Va$jq!ԧ80bw*"40ΗEfU(v.(8_kCmQW 7%fT ~\g+$] h7rq*bʼn:0Zh0kO1u STB]"q->jC6nRI_e5vO) ͥ柸MC<mbZOV'9eH7";~@Da(HxMAI(á,|{wT?`MTM=H>ǁOm@] "L:6Y*47 ŽhDsjZ"_2b^ //+ͅRU*[EDyl~ F⍜ Y3ln6+գt<.gb q1%8QU:Yyػ˖UdEC\`*Kcp~pGe?ҟb\߼,soqewYRF>bj‡UFsDUI}Vإ;A-f؂n\҅͜n3! ]HGue @̰)PUA( t(a]h&e R-X\Vk Ć赕ToEÝ #67Ϥ ƪC*ircAE JᲴ= 60fYU6^ GXDz|g7~+ҏwc Nf,nȕF\rO!]P`QJ(P6$0*:S:BC-|2Bv}mAd h#_VN F>IAxg T990=Mw㖃AKP󼌚]:vfG#RqgN$RWq!gʷ5%ݘ?=c#Pll9rh8wPG8A݆ RKFT_$׋o$^~J^g\$GYXͽڕT%x\'hJiAr'AݱCD8Kc?wX@2whه('> qWɀ9%Y@^E˔55`zJŇ&;9T莝ya^`lXVf ;)IFsoݤQQU.6T!K+vʱ w[(MRV)cwAp?'&$>JRn8-v5fWRQVq%HE/$lMCR LbB?iYRśr>|/vS%[ Rǐ*1~V>+yxb$(H>NJI݁8U(g/##lu?52csN !(˼\~HƗ;F πW>Zek@-]-W`EpcJ5q;SRhhFQ;TkG3qP{qL@;nDz8Kp(mP}z@j@}EױD?xY[ ОK[[#Ԉ/nkpPjd:iUJV>Q'J+nvlA-ӊ $clb>-yKWJ 9)9DxuɅF8sXo}SUJ9?QL3F e;vgu%ƾ&s=Ob́Q1(9N"hikEqi; CEA+uTX[/:*Z|Ͷ{mv>3hHq," t (MDX5Hxpq} ?elguZzɝS b. PX {6iYmdI8R(p91l8K94g8CyO5ga2z5YO+xS0Wsѵ ¦(F!GXcAL7tÇ,)'PBƁC%ؠig) a1v }x&?~rU!=,er_sŇۚ/_Z={mɄdχ+<#Kߑn?=gS2՜F{RkOw=Q\HKq:¬%_^@QkH'}($YP'sUhAaCk¼aӿ1 bW)SA72'4hɋ9xOFTo6C ~9_5*:>f&aG̚Mwp{ qv{b\o r$=8󧴫ΏOG5DIJn46Txpa8Ck>Y{)"vh$Ӝ$(;ޣ;12~?eʷJ0u^hos-'e xKǪEkH(B"\M/q}o2Ε&#1ȓ*e"蕻y vUЈ(&3Q.YF"\8oqxQ61IY/kQbF͒.#M}be˳Jm^֟: ;mL>'>;U0s쌻&e:ܴq4Z.`]W: UK(C9<;]PSn8Ij͑N^87nG)E3R BBx6|!.S]; }Txďi">lÚQ/j;^32D1SChq7K/i׿}ㅏ{b]FۖJ,@ó~GmkDFN9k\΄bj*Ԍ2kzp7{%9F'BY6 QO7jer $c_c*aS]:ݫ@t8ʚӲ*G>8:o L} G qCJPd?'a Tr8,gA9s0g4bTE285*ѵ*%b|Ьb:~Wk& =-=]Md6H[I`9vZ7v1Q֠3Nl !tXc1țE_&jkõ\.U|.a-jN*?$q l:%wJ&@=B/D)y Wmpy}DA>EX{ܗYe+;;A[?8 Q [4 |2.<*\|]|!hB[IUsHQ{|$qݱD݅ώ^-0@~Wz[yym7Dx1C?u>N|,PF7.rf}\w$ږm?FlhUg7w0- cF>_R^.UL}14!H>ʭȁR-'ңmh!3C>Rui[[Zi߇3#?#xMeLiFgX} hf/ >l])| sJ/0ZZ-֔m'QZSSjrg,lNmӤq @Kښ3c{ 9`!Uq>g qrE&ּe6z-&99H%[S9BV1Ы{1@RG f&P/Y~55FΓkLRsBrnv#IQ> "4ɐ.S0:IJKs}6*PMn,_y 7.Q-0<ҶRID @iee^YEf6p25t{J{\\I(Bc?VEaWȪgk㋺ln70&dN~ׅ}*6 攰gqqTs#Y}RNLkB!2[eIFz?|+.g ~<ܵE"COk馜ٗߏF>K9C0@sM?~#H9_T7xdRauR81#1!#G-3(B; 0z{Rj3v-Aqc*]m 5oqf<~b 0Н|cUAY̺2l1ϬE{lEni{e \E]tpUR^U!vR'F9~_Lo]zC{5oS=M6:ঙ6閛hm5 ie{-^ٟvfmXq冖[#KVXx1E՘ /$첰=v,(W5Vu־>dJ/nw:ЬaӅʰ"oQl=VXOTݼێE[stUq#:pujP1`3̗EHǶ* [,Z'_\Ոԏ=H$8OhP9SY=ڷTOQ dS#@U0"bgkp-meѕq*u`tȘy帎3B.x{4ȨG aǴ{mi=Kk|xIK@?gPqg3?~%#Cd ߕphFo 9pZ"? uZxK[;$ Z"2B lg+z=0܌xMT>EdTS꫕c׌-o|=%Q /p{_h>D'5-K!~i60Sg}6qϊ.z{|w< #DP$CGxsm]B g@Nly`L?:uXE ǝ srhΖ48;n%c;t6zWᏯԫ}jR"ސhj+NFh]`)ŲZo+KseJkfL\eѥWtJcnou+mb'Ar24XJS^3J+-=7wzڸ>]M˺ůJ>î?}&=>H =YR+UVqu ɕ;dk.!WB91ʉ%JeST[Dkv/#!G 4ksĥX)nB݃\UMkB݊I࠵aEJH2#kB(U{PA ɥʡ/XB-/ Xk*õHŴʗ46)O#qH9#*pi 9v[n_%!"11,x`ASq)'tOmm #Ѯ.\Uw5`@v]In Sz5iLs;bk}C3黝 xj \IuިA§ƪ{uN3ȰHfL9-UiZF?Xq/g[ydީ4@%dfV/nt02ߧNg OsVƏ@Emnb<>\ϤfO.JUQ]'vK# f,%ĐvJZ;[Rz]? DO7D/5k끄iO6?)kqĿR(AsnB)X:]X)cM{YW=6'ѲaȠTG7x_;x>%ތ/,h^$i߈ ЬNއ޼  \A`gS a^AEm5o$q6Ư/,v&1T¯F9|b { iWVr%HVpp w8+3r} rzw`(i{y蔕zhߺ:5ǐ2sO|d˸ ]DeY=t&~||-dŭ7x,AOԥ#[ƀ+=YFTt}{52^"&&HJ|GT׈_@U!r!ٸrS#Z/n(GA o@9gf7h ܻc20Hi~!3>-&iw<^r C@DQٙmdq';d1p`_k(V@XK5D+O/@JVt6I Y ~:F͙Hm1A+DCȹf_qŗ\RpۓR*ge҄݅m#%c2DY|g<;)gK:D3Rq}Gc6DyI0X+['zm4F^TP,P"iR}c|/NwEyBt ܨuxD{>لxC:CeT2R\wtU s+hH Bp\j9XGUq6:;NX i ' 7۽oXbi2vtJї{A1TB2/Mdk 쮭6cUlCӈ1)]CH6^I j$QH jaa~:w̭H&+o`1CW2<؉R ]N %4<,YW\WS|G io h(6|ecx[Jtbްx@)ȁJ|# xaɆ)lP>+Ago_bzт/J]d}ͧ58(]ҧ3Nv$K_&+מ|ytY.v!,h >Fۄ9>&n3Ϣm: ,$8B)ߐ~3A7PSlZÚ[d=0}U'I-Ay[bXfT-} pTgPts"dXl|7S>J%$F& tAD|t!o%tz|42AnΞKBYA nM p>ۺ`5H"pp7"O m$GnGelKKbjCW jUǠ\ODjnP^P2 ΁+-y~}ḃ8 X"(J/`\.4v B^uQ,Us4J+V[\cjSE]e:= ~23_^Z2IZpL!:A|nc^3/KiL 8h)vd%|capa!fG+*Sxwkhkۍ 08Ϙ0Y[oe/y:ba~{ch^ ck]'b ,T$ i3g'_ϫS!(堶td,N5'#\=c%ݴp( XxbpZdrY`[݈ a #;WMd(wھZ 12؊^U!کj_mSVcw8zgP = 1R!v(>qT{Zѝb" mk<+phyl^~\8JvcK|8%׷7I`7 'mS}׻#82e7&f7K1 +\׃W)6v'yxc 6g[Ga)e1)8X|sv-!W`#p&+nC7Ҳ^ ŖQb߲m#_wRYd:m>0ȾaWsQB~ACv'uF;V7M?M0 "hbd!hV@仩bpDD5nY p!tڗb\`A Q`C=؃{!%-~zA3,(B I'F{>]]-ɜ#~ iKGbcy b(S註՟$_ǡsjUʆo|Ŭ'WYgD)K?B+j1 I@g^"ej2vz8ƋCcJN2oQ)|UEFoIe2/̅}0^JEe Y`Gm.0DﭤPVVUn?:S,ly_4|M)^{#PJ 7h~$,nwo3fH+aL p_BooW71'/ӨR\-EZܤWY5 G\3C#Ob;{]-!vܔP"J~윎!3I4/D?ʌ DhRzkחJفTy!4 !" CFyyTJ\5^} o=",.~.R'ZA.8i7!.48Rgj^oC2΄4XZn;p.XYЅgd1.sJfA*; _ ;_c{$'P@DeAC:ƃOe"> 4,K50v4zˍIw`S@$%jzAM!<C2C:u9,Kac_MxVA w֗18\cL=4ǐ a[U S*,z68V2ܘHFV*}h kwõg8m(g)3_EvK]#o˧"=8\XvAղ?Vr>Cutxw([) X#/"¼P@sn10,Fϴ{šl,.żİ< }mB1ܼFhL]^\1Q[ r 8-?f9No/‰ȔE!#2&^z"/*F\ 'Xӿ" rN3CqY rUVGM^(6`} ]@p[dYhb5TX07w0u ,7u:Җ;P#t)~Z<ml 6UYAR(L[baF6UU/Xj9gsYiv-yVe8;9y8V]+뀩TwY0/KY jSU5 f~uBV"T4*HOͽ6EjI̪r_SVJ+lP7= _#ߎHZF6jBS :TUB`Q¦l NZ? y 4#(a$kX1!+Bl6"yh J]BB̘ .C⣹)%\^]j֜Ćk1<҇,{N$hsN&=B< iAͱ둀65["3 h ׍U3!Ɏ Tg^ (*~1mؽKZmm{Ԁpkw.f`/NsS64 ~cKC\A ApH:b}˒^lcI&TVJM!5P&G~d5wvKQN=^i2pe׿_,9員/MiYIf@12Տ&8(-^:[ŪH-vYչKCڏ'nNEs,kʌ9o-BtG|v%[ޙ"x9|ƩV,_.aGϟ\_J*k!F(,Ӹ'V{ͨ#[ ǞYh<"oE0vÉK5wO=,D 7Oa{R:Js'z D6[?\'f譮3Aubns;vhj4F9TyDi3TP  FoIQ{|+K{& WsrBT75j KQ }4nǩ]R%iHE!H$tk8ص= RV%[ p+uOSیg$Z_&ӨuFtc:w9ht TWZQ@GrnVD׆^X߸dXwDT:f;xl[;vbʹTg#Ф@IW"u ˶&Ytp[O+FjBxp}Kt皫VzqT'^W1\61DqVʖ2`)s¿i"k5A#*Uv*Q`+""5ݰb&u$I ; R0{}-`~B^g hXAci-trl^ Gtn;#ԉudV3.eynd1rVwqn(*}~Yyzs`-/'WNv+rQs[4`usk {ɾjٶu:lIJXHs~!|'TDc>.Oy'd.k %5mzIP'̳q`3i3wܰ@˳|r"2(3)GP=aV-}{?apo3W,x y0 ;uav$stR /g L@["^ISu>0 [5S#K7su¼΢#v C7e3ūT?L#Pۡ5Wf m(q`R滣OZŒEaawQD(mPL0Z\ys{Vh춝 c [ Y^gQ8T-ᵠ{Whmh0bM 9l k!zP|b :Es):6B/\7AOan=OKO̴UVBRdkw_bP*AI4mmd=>IwF}=[g6Km{(4/V!5jTRnUbdR=kz*~P99ɫh΍ΦOmW%]X/t uo9ozxۀ#3oQИkG~7%PjS7\ *rC :1C- "b6nYc]2 %ɂC9 r>w㭣nmm{˾Q88w&?EKc%wM>ܜRΌPԃ<5"U}:#zi؍ϯ{4CzG ;{RCFDI$jk- fߢ_&YjRjș\W2 #}(R{kGUÕ KaZkTK-:H YkyzL;40kCZQ "r{0aEOEP^]| !a)@t9Ä}3R]^M96z$δ4(ni0^bXkKSɮ zsL*A8%8Ͼl@<]Ȼ]b&1RpZ?[){C9"OZ|3ep>$vg&; ?ܡꃽQ;ML{Ғw],8.z203*ѕb)lGk$4wg8#'I? . +z&92A/a#5}['wrɇef̞7^CT40oޑy# @ 쑋 [GDU8G˜} K# rd/ۊsx x ARR󥶉xa0:g5XtTwU@,ﺊ^}#g!Y~EtQQoDHh3prz8̯m߶u kS%T:ߕ0S&Q=oSP? 1 hK^ʊܺ:krqXZHY,8b,t3 M]ĬƐp3N:K.{%z'vs`խ[oq w\E"zKSpE$Ln켶{*T)o4LޤAR~ @89d=KΥ<E_5Z0$7IYJhKz5FYp[FYgK6.Lz;Ю0:lT4fxΡmN8q*{j\it:,CKA?mC-4s١7.PIh>Z4ms^{ĉ?B"T#Z4'7>B{8 h4ҤE9Q5ϟTh'h aaOVZn T pp ,eGg+-qѫ׷|ݾB6Ll<;*$(Kad&`q$kР.5'1.l^RvO x jE8cfFI%g Zpf.גȋ8艴E(&V^w0򚜼Kh#'U!1dqk]ۄW6Xbr& m5e*+Zx0:+W[Bʛ/b gt lMDqNq7O)Op,P(B>.) \=Z9` ވ.ЋC g8<3ߞv C6'< ./1@YJ}8_1 *̧^Z ڡRo<`Z!}GU [V'E5JQ ,!NJB /WFz49m Р fSW2G~j/5ϮE/2ltUjKJIhwl)5hBHq rf(y~"dʸd=&nHJ.SG5{]'Wz]?.,z[!5"\Orm0'`C> "pqT; cKWP!AԾp||Q^iNXRlC!ĶgA'B'|`nϜIl8}ϧoI*O6%Zrs%KqE ԅp4q5>W6sUAjN *-%XE}=2 he6PukrpP#n^*J޸^.զ8d8=N?IZ+3iE̦,#QYuԭqgHMӾu(t2Y%9aA֛NIL~ý5ʬWPͣ}%F<% άn^.`oH#EvpтbDU`%D$%Xj~3j}o _"^0rep3}xbQBC"L>LJ"^?VZ_7-;c[Oe~&e=лZhXɊXwnrD!Ĝ^r7p8^jIsE1ӎy-:&礱I;6cc3@}٧J0"y"ltt P[@j Blܪ;}kwwS?Y箆ZX(va2;7U<5%]po"d](AA}si #&Z[5hc.HR"n;Fl7̅( :ayB@Մ4R*p_ &,km>MX9*:q8!Gh^֏;q!H(''K?‘N]:0UGǚ8 DVCv֩D;>d4on$5y4z;d2P%̡Z؍ FY딐/#.{ m]2, M֎6[:kq@0,3k8-=OޛGrw+C ͟J5;{>yq1 E%zPĘvYs ̑#oቓR቏ZdEqEe}չ)u_w*maA7;x/fug/Dǜ c,"- %y]iHw[7LDd$g'"mI |iPyp‘9\[@y35L=:hnnC)E{ %GIc^k2? wUq 6;`3@8oga#VIJNz7S Q[)'96?`oF p>w f Ǻ,:B(sC,۴~Hʢ{n.|iڶ b*d2f(W0y#-Р4pF+d~Ka$xze̤Dlڣ_,Mƻ޴*݌z^AM}"beQ;r͍ϥZx'Oy:( ;̐*SRO2.Z?'`(A#[*^*t<rFG;MFd[+}˞q=T 9]0p.#3(4=Ɲa >bޘn C8NxMY&'~Tw( Fa~^"QV?{/uId+/gv= f)m#/_G Ɣ@KV Я w;ĒfUڃp7yxIojP"E6XOOL'' :s_6n|qZe[[>Hor%fphYZE4Au%G :wuL2+H @ACI-kVxnۖ(Ւ`&s n S}b I]& OߓLR_`ziZxɩKϝ=h=8|3f}\_֥Vk£Cc= fl 3[O_NشgσsFVhWLV@:>ۢػU(Dn*ØWR#7+TC@*\6[IRd3mCg!N6JFלŵ5koݯ%{gEڛ^k>v$qc,{ISt}r R7|0R--kQ%YqCgVIjY^ohS6< e5D@`r0)Ok .,ejh97Yk!vY+.gir ,#:^Xj<?g*C `Oϊ]{G<laѲM0f;@fPKة^L7n~/l+}<7ÿH'@ vlo)~0"y>eGÎ']aVƱi?T^5zʏbpHO):c.9\!mؗ}3񚯳y`@u}yߺIRZ<l/紴jb{VI hh-yϖ5\:/Wݥz1J9-N%fsߛ輶\l`?l_ǕX)gQi|PtS%jqv#2OqVGpX2uJvW~Y (0+zaa!ڣ봊ZWSJZPXfz3ƎϮȃ O=qCqs.crK=͡zvYaWx>Y~*E5-{nlJzDl'CZIcctu8T[:H0PU >;6ҹ3iR2>pԣ;3&\ScED-=և_+YmE׹N¯o^4UK~MޒO˨zmӐ ñx SU[7ݙ#`3{Zh4[)2T[QCfJH>_=Ka51A4w'nɨOV,X޾2V-oF@!yYRAWp連E\a9٪^/C z 0 Ba;Lkc$^>!8GV7zOjЗк|H\b(Y!HP\2? Ud/c}`"{ۻp_yLVm˲7hqiH~zzCߎҀ;qWEc;0,Al"jK.Oj0ݣZ ղZ33~~LN! ТT(_XW}fXn}Q%j"ȷ?iWx ?=Dkvo[c!EsU&~=hvr*Sv>Md#EX'Yucަ7$^q&PFL5)Uw.cKSg]_ 5k[Y>8k)!9rSƝ 4Mz`Ɍj@.H~߰4M-[#455p&HY%YCڏp7|bЎJЛdvLmxHNHfs\qjCJD$]x3,ĝI?h Tjp&t <,IWdMj1vAچnž͔_,2&K:rd3ݸ+*|LNj7 ,>"ڛ--;7eUAC -I1.ڀA?QU8ĻS@e1K@Jt1!cb֑~]y+nZ?.: hbQ! 5?}ղ EQw$k5ey*2I9z2Q"R}Y@j҃:B7覡L- х㑚6ۼRFYjh%To&QeVFKi=$D@Pp0^$=kvs*,+ȒUd]m[()-dw60kuP ]*) =qݏ( Ԍ櫸# 5_ˋ]f2 vީV(1jIi8̘3펄")+~)Ach@Qݝ>ځ@Q2Ȇ~=MZy30Gzb0uDbS{?X]ej6->dΊnz8yA e*=<0Dz>}'GAJ >%\yw7+3 O mʕ̪CI"-\q?A>n" ۩,?cb$rA0k4yB8Mza ny-~.jt``~n `UFBHD;.쩔sR+pV! FTN|zM@1>7dR˷^iB=8_,jA&ROMH~XNV}ٖi,U[!D_ b.NJm^r:4-rh]9b#cOuץ͒KmXpboR)uny~nj0D&_^7apKxaw8c8+US)*s; qPd@>u7>KW@Xn;n7e vqDtֺvدhkټo+z+ߔ 1NTYCthؕJZ}<e Q,/6@UiA\]Ș`bܻ}oG(Ja,AP0U'Gy$zQ>K~%:a_ 3E\,y3yErea5*zwIu+-$k$A-$O4 BW?bN\"c7uBP+ M=I*'8 Ո.nZڴG] }zXзS'T^ߌs-c<(')wt _R#%$rONzsRMGWޓٺbݾкcHo5D\Ue+Rjk]&0rv7qtJkʴ ꚡ騳"_@h*!hSߦ9?&?ɹ 2qWi'97. }Oe8B_$dfk8rm1e?/xM8Db M~|QPB况Szsb`}%(*뼃g^Qxl5nm{@Y7 >P \xM8C_W&C poHOM|qgMXd|X _RԞz%\>JY6CBdݸ 8ؿv1 JvW峋E`N9wY"O.wV8踍>gLS`4 I1ɷä벉\P'HĽZKz_;֜N S0`> {9at[Oer^7$d~"C~2O] @_5)\Օ>;c =/)B"(f_ď+1l?QBGZ)hz%vݷjX^w?!~ZoN Nհ>nbCf+6TΒkoqX,us\)Uٸr(Uc"-^w/eE[@UZW,InRs= uD%WBI>h |o*ӽv4HB*[ůMg' _jYh&3}Bï's> }1L-Z} z3/ATZ1 # 'mDZ6i;7=n$yI1j%{׼9'&jGD{Q̌tuCXQf?H#l2aq{d aGS*=4;1A&D}eijN`f+N}y(;̆Q4Vh{ae#I4` 0G/Agݦ;]/t9xf^?蝙̌@S^ˊ^N7h'h=kfnm+Vǥ 鯖??w>y;6֦ !{3?"@)˩-;5#jNZpYݮ,ӀQ0}nVSݔNȄ#*7Zq~9{&ƲP'{ w遰TSpnI'x kw@ʔڽeӕڔ҆<20 y'"χ`v<(:o{.Є5݄O2̛X`Ұ+Bج7Ҧ:he)^2+J&$l0Ҭhs00^l,I3WEOd,X &9S-& ~]lɣ/1BK/Z%>;>bʚLa$Fbj$aҁ.ۀUqq !$8eT&gYIZB~O; Xrǁ|ncx=ԡt_, 2`\ m_oLvrE6+#[.!p5EH1L:O<$3`XTFrn-NvE5mYH%r̈ ˿5ʀc ƆbzRh)Ou0To`9 {ǽ L cYJ,LR7T`ݦ5eX[?I_b1;2ã!BoFO jQI1P F{?\D/f{ +ElZo,:&a]76G>QqBkJ;joq:iEnM<`=!У ;p-?H*8B5}G ^pc*~FԔF[AuS܊/+:jNZh7`)ַ$riC*k\N{P*lȕ1z8( 5ZΛW3C+Zc0: V@833&b];)vK iVuuƾĉ0m<S /GxGL/]a_%<Fͤ7䞩$gCZGЗ fځ7T1Ė8 3>~.Wͪc8 }o/Ƅ PO);$=^i%lxBxSV72 C.jK`Mc=sf)~ R|7qZ+,{6 2H(G>L y%lDB#! |f*H!o{2FP8f/H L}SmAj~{rthfDwhC6Od)]6wpȕYF(u0!NBZO}뷎 8xfWO=@ lMO>tt[PAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT q"ltes~2Q.BMvCcĖ2_YqTf|o!hv@ҵ:"SnQ"VpK;")/a9H;'ŊxE $ݤ]_ZQ ɶo|7Kah7N3B+amhiP׏KiS+W=3Gjx<jBmĽ9pѬ G! =,x-6NB?BewJ8CMBdAHFb6OiGbknU6c_ HS&#F4ſ6#!ӨI|׀$0d*!4( jw reFO CKUW`-1x0@ MG0v>-mS[] CY9Ctne iB~,}OpY+ExIz5eI.@R}o*c#&!G2:7#FC i"kmYMGВgKZ/fBOҜ7FREJ._{1'Tq?6:Z6\H#(ݹdIfL@ Իe(8p|QA3f]n6 }S'i Ef)w˼Eiޮ0x !6h( ,5F/wC! K̅R΀%u'Ϣ3iHdLǩ T!&-7b W((;^.q˾u϶>8ۑԟILܮ ߸V!Xܾ%U2ƾۄDo> {LzhĜ]Έ|Kjrjlq`L} ̡x?1z+NϴZӹ@"K4'0 ugA S޾>bմZ~%zZOZI,TAʏ@)5ne؞ !vFu *p,sG&e%1FxOrr򁚉+ptI5he&9~^F~,(% i(ݒX _vF\G=xw1krh=p@xtȌ_~RqX_VE7tFzXfoĔ8ܔvU,[ 6z29YyaWHTh;90 ., 4/Z(%89w);ej&™RέMt'#Q*ѡ'd0N'V,.ASA<4:3zؗ5v҇( @5(u /6!#zb- حQd+#%(Mw3Kó NJ ٞ.B9GTl͇lؚFef UÙŝ_X/tO$T8 %#95^h,"hE8Ϣ-MARoK%4Qi^ΏD2ht#" EM!!ی0@WMU$b6,V4\aJo՗3֟PsuHM}ud9!l4tpe{>_p]-RgNiXe:@y2Bsbݧ <I$HpBm)wE4=ݛ/T]&rhR;fox1"[1 vX )sdqψGñ&~A39`B0ӳkG 8L\wل١L#+'I GbFPdS?#1?݆؄3]+Xxm`j&mW .R_ 슧ЇGfV&B s=6 YLx}-?у;]~E_f}~E#6]# I2uy.O]1> zzC&7޽;gt7Edv3':=^|r<]ARm n0aza 2O< WY2`JnAވZGz}gc~(҄$W=|gI!`5ͩ [+,A7ӏž^{T5m='oP5Yns98IοԅnhbE!VK\Yy,ZO\>+PlFꀺ# T:!/Ł'`Rn rOo j>C|72Yxx-|N8lm"[i~QQbײ4ʹ%UUƬg: C`瘑NgM.V6s_PW@yPdi+;mX,`)lpoTW t.{@1;_~Nhc jÒ$֛juG9ђ)_FptPb"-azpq% ӶH-wIYh 5!qzKT}w_ 8H<= o:}ep d´fI%AKLd¢! s۔՜>߸)jw lʗA;K"?5ڭ25afA*芝\8˄â:iKv5)[_XaՒ2|KT`^߾diB@FWm_UZw vCH,Fb-՝ʅ^$sFkT{~oF&ĹVzp+aUS֦x?8dl\.-1?qw3^``N aZSB~c!]'|vKYE=!r)aȅ]#7n/ό-&pznCu2bdI`lz:A{Fɖc WvΖF'LEz`KYcH*轄ɷ&4Ep`9VA4v|)/{L+!o(8` r7$b ʅH6!;̕NMNL闆oI tIv\K>ΞnD7Ǵ ԥ-A/4ߒYczSq"Khd|R~>yD 8HGinټo򄉻QO܍|f*QNVO"+}pm`3]ql4;sVٸ򢪻'R1TYUr0 >7eA1LѡԁLc\Њ=yKbrɺoTvvO+^5_s3!Tul]2ݓ,-";U,y3Nj$z6U6q$4NSO.FO#-bZs55'e㼉5 _zgˏ,/0VJpDwܙZ&|3 Db/a^eF)u9kB)ĒcW @LR/xup_la-B3͓8YH͑SG=iy3^#K? 3F'ц.v{8W@xo6M.!ޜAc+Ǐ3.OFV?T~X:<~$_d s ]ag}JqP/ j\qjP\KBA뙓׸U0 I$FQl4itj:zǓVTGy\I3 K>Q>2K7w> (R՛z0aZ;yқQB* *ϳ0\NTD#ͦHÐkB~fkֈQƦpQƊ X4@7 (6LL.EC3<=#xyG=ݧ^;2283E4&#,F7U9. ¹: 8SZQC7x./`oqsgORNxgƖFqH^z||ˁzڦ},>lYRSdYc>mKZAkQRs @N Q:)LLRϚIð_n0i<gBHWr]90sZ}@gC9-蚹iV gyTJ;?{-qsBi\0J\pt:w9q!7ja;tJo-tJX춵XA7Q^XmO1X&3{¾ީkcTxTuN׋ =ԥެ ]r9}?\i {i k"T߳?xq^w]o}+O"]"RE`x^QB'jjEVeìI;|(ԕ469ͥE:~A4ӆ,`@ *Е~M.Uн`r~ȩ!O.CPʄ$4Ge !4(xHD5}z?eLDb@ &iz}O6\N>ZuY6^QBtS')|0[kP0`rqOQ \D,ޤ3 c[ &` 4+Tco+{UOZ,PvS:eɌD %W}ۂU(@lXmzڎCokRJ';HQ P.{}ab*!Zx/r: {>fX@ϝ^yu6+҃Eg(6d(Mà uǯʭX%/Xi;ZIZ4D +LJMx\W7w7p0QS﷚?i.xۭ[%x晹Tke~OYFo0s#Šu|X8p^ )$gL - Xx9W>BkۇxQϴBuYTSJNǢfƛ$}9,Ʉ|oE'(5=̜eY4~tMi7v(ھb|4.y&'PN<[a;'T.;1RwtҾYjGeU+$ li ѯУb/Э6 ˡlx! !|cAzZrZQ"N%@9C0'4l|)fϰMRBX!570'Id;l fQ CYXgM6)~}\$aEkS+*x^+l17n22|BL1"̹!c|Z!]%aeAd$ѣ%@{M ~IPӏkJ哉S%@]W`/V'UWGm۝z/ ]4NXj3O,z}c]f $$HH3M[0O`e 7Rvy'a\hZ_7U9BCf[maNkI[7JpaY8E}]ۣ3f#s rLGesӴJ /)eJ/:O4c÷ۼpiZ@* BX( -W*aD_e/s˕Ęڠ7󰰵j?PTC"B&[AA )-Y8,ڿAM!N tW=?.0ek:0e=HUj uf·To:@(憎jU;ea#L@qڝ>FmȞ;<+\QZ?#sRf ڐ(h5+q"lat[r bD~Qk7IZisjfPr<S"pcv%O8ͻ=E򝑖=׀Ar;ЇC~T~!cdr2!֯&*IǮ~lC_pzSѮפX jf]տ#ӿ35ߧ-;;lں%RL#7V9Ow@_)ſTpSKdC.w_(gN!yxGo4Z/_yIT&OPF0!DPj(ڙ@)jQƶQcJG!Cr{FɭG"XjMP19ԉg@1 a,կSb`ΰODxY+ )#FY |6{=%~xg/n;ȓekE0>ْNB#3@/l]M'Ƹ/<$!OwvÙ*4K˪'%DWi$"ǭS.qb9tԅmwD!EЛzk6y@c\en\={g )͋[,7v8Xmӛsa0Db2;*;8fUm y]to*&!l]MWrbϿ&Q$°Tŧܛ6A3HU̇5Yd _!K!c ljj"0E%o6P.4T֗[|7υ YIW`;n3LU/^9Pw87!M_($d Cs s|ΡɃՅ]AfbAhor%߃K SUNjK/DfwK+T!%+6ql[u[+NST:rEH Χ4NWP&#=LBҘ |B/qlj\~K[|SihmDBeԘ@Ҽ/ =A^"P`Vc۰i"b[[I`l~z >AnZnswDRu F>66p0mԏ(_N=;7&Bםx{ 6a[٢7a=sJ}O8VV♡8oc`żgtB9pI+ -Tr{ӹ>QRaHxіt4zf[ދ8;4m@F#|9#i,1mo~RL'1K/}Prm'i{Px"~I*PnUbɻ/ݕ~ұ/M=mA'䜮ld0* rV+w. cHtn"&O ypqyY b r05 3DtT?-i.rߝ`" ~n  ;HQp&࿚RM)! 5_ ׊&}U0d;gBW6եC 7x-yʙnEBkRHMcM qpxSu7UA,t''|N$U,DC'rZRi5#ZPRK').W6XVgUNI T-EBZ|2s֖6,=`S~'> \=E}q#9%᎜Ϯ,9yI`\O=ԕtoRss.".v 6 Z}ܞv (2IMs/s,8 xUcOMN x=zQZ/30= &'0\kTk}-'sjǯ9Zs;*mkR܋4im9IE8b*ό;4D9.u?G=:׾(fƴʠRo0Q0(ZvnxbWeKB m>"*0N)sJثjoO"$ nhISU<4VhXL]0Y/|o;!w19W p+v^#d`dHx{M8Sџ9)66 \^BX/WsFuc5h~uÆ[c̪v DR,xsu0?ϓU]0U5ޞbԏ7TۡO-AāY|Ҽԓ(1@Dؕ~(Ϟ '3午'I$Lzݣ,uA} g)wjFߖ f,89w;Q*+y\[u?8={ŏhPzFlԷI"2cgj xc{=;-uC2&P^c"/JteVeT:6<,?X-@Yq+yxH  lb#]x ~\omw`s*]QtWVhXۡQAVFML݅(]}1%gdVƛWN5 @;Ȣ2CnMZzStI{ؗ\* lFAMg$j8Im*׺wҳ7%tu+ ~75RXQ%$mHs4 4&f 5B:^w2\"7wU90S>ɮH0o 8[Xf VzL"8mqi>t&X,o7GrwXzspm\"EN+ì4ҭVJٶb!;; tzRaQ-b :p"?!zŸ2ԉմC)wwDp{1]^:rS6IFg*NF}*)7cnWo6(yyZ;_[[6b!JzF{XiI"D-{lۍ}kYbe d沏?tܵӗ9qנ4BeO Tc1A eGMUwQ`a< pLc{yp?mj}|l?iw&"ID>dG5Y2H-)m<8_ڭ#5wк]bӳ^+?9<2ށUz%c~/[ݥK2QQb4^Wk1.Xz/gD QףgsɱіOp ~"%|@*> wg"+I}nn[.xj5Q#ĄCEEy56Vq IЇ(QG 1.lD5U봃@/ |H@ucR](?{5φCl݄oqKaV᩼R=ivE`1ghӇ8Z8BGoqχ 6❔; PH=ä5h|f7>r`Z0<fDSuN]((7i3RVI춓i^pCA~2xX~JRi kgA/Yb\M҄b],iǙ0(fG1f[AjPFK(?65(i$V`lLX$n[CrLe[8 wKQ!w~UfF^؃컥 #"O8fY8`U2܋=A ib0JyT 29J@ @-!D@BWc(iĦYa8=r( ?CPRiҫ라"Hv@\xKɯump`{?/tR7Xn>IKtqwF@Ygݛ@_J;hjɾڋj^%3˺??Лel‡ΙkX+L1eN6s&I9|uoF%rW\96fN:iffؾp!~nC-El jQ54 <)I<ޛpj5W&[h_|]#q>e ?&E緸yëf#Ŕ)~R𝳃P9a$%ޟč/wPTz2l}e7hWKq7Pid|Nt/,0V"y.4C8?Nkl,g*ɕ3M.uM')^>e Z*.g=KHS[%2=C7ٖ9Уeu3NoQ@s܃xeIaf2 /SZ \g: E<?bʂ$)P:ba-R5;ϬƢiOe}9Ab k!%YcjW& NEUxo^NfAӀWػWa%7紜zDUO|{Q!KhGIh (bN7~3}괪]Lƈ_DC*xu+s=47BAn&z!LK?MN̛Rc>*Yt3~[22Ol -˽)X(nsRP~ơC#'=eZ[g6T(uҚsܗh×O_yIps䘔v"bSv0hCPOJ]o$<0@]a#K -6rnZ[lTN\:j}ߑUK34q؏[_/!p>ՌERpXT{܀_eQq^4EGV.xd5+=J G(Zt=!LnoD tǷIg:|X6^d'E*~Qק\ t T-5XtcWZ/Qy5M ئCV_Ú9iE*7!O=dL@J@^T@eiON7hg >V Hg]. rj2OrP_Gr\/BIV^_~i}nzKeE?!%dtCk@BrUf3:P70H$ĩ_?CIj3 Th+#hJ;_K=pb༸!E[؂|Ĺ%"whd`ap ĄSN^[u3Is>Zcdy_#kJϭ]0jXD@PNB=;t'=R_1ZF!r@T$q]u9& ~X/DߑtpSp[qߋ=;{CqG9Ӽ!J,Ao5X}Y P-ߔדR3,RyN m~HOo.c7٭݋]pEy99E]r&-H{ Ra;Ҫ.XF,?EǬc){3$E7 ,u|HnIM T}1L@^[MךRc0Z5dL PK*BuSK4tWR5HU;2"MhÔZPa7;33#v缮,!\-[\<ՓIǾj4m'f6 lNwÂ49e{vUL깺A]5\n6=%fqL_1C m#1qTxl0c|-Ϸ!D[ɷN۟ `3һ3 'OViVc Gfg਽w+ sS%4%A/oGQW\՞h9@%EQ,b9&W] IAsXUr[Dlᣂr(tVC¯Ȍ@Ei8;XCX>oQOr9vny&rO3L4}jIelv/EY?NcBӾIDsm0o#[·j)א'_Qs'b-(:9:HD XT HP7Oi!*E꼔UͲO4k/*N.JUR>`}pc^ǾپS:t4\a"sXb316 L Ѕc^N+J 0Q9 6U&^تyjN2t_NgID)PչK"?}\.u^ $ '!RBfp.⑷ 8 96FHI0XfFl5[L鞍rb0S ΚObHݭd% st>[K=t}43)6r@zCszC[{\m/{Zv 'H|ñ0'yΪ,F$<3\\\+Rƭy.H"+Fkr*)NEx3yRů"C!U jBiS9)^iuaɈG$h|!JO&D@vwh\7 o*+DLo;sG>NiLz@r̟`Dxfh%e,e"YD6&5$^GGf:`z xYSˏ=5ºa-N40 ²E2gRU%@^f,t`zs>c<"Af4{ZJ"{bGD<|-Z]g"ZOP] .D]4bʿ81`Cd&2R lX(rȤpTdBXGQY*_sOjem`gr-kU\A}fX I;TC'Rz#E%em.6V/UguX(tlfa'nHc3LU%Mh-;d5h44Z/[M˝Q +߄RUe-S"T -PfZ퀕f/}5iфa;I3T2Y3`5f?iyT,5B5sMLUlVsC, ۴AV$uZh)h(o:Qwcm~d|3OZ*pz۰q̩aHhۺ!lOfYA \?*i4`įp7wm-;% uN%F NDSKP񍖏.BTCֆ55ȳΙMPΨ )&'` $g<OkH${D)'3XWT˅vH6xe<4Q#ghq׫d_OvBIk?.d 8{#asؑ<HKKzGijH#8&tT-:]-KT޼LjnevFkͫ!2~lw xh,1 bS͉=ӕߟx`}3וB׶;Vʋ*w;0Yni35L$f!G~щb)n=UǦ ->_ >(9yd%UpϐB#E%f※'Uɵ"qnp4Iyd 3 O^ҝ{p^1șv/C5QmlP腎0K钶9!9T{m^׶zꝫ.ixK72~/Y:E$aH%H=m5Ww-Bo.hH^r"fLo|0) $=s1{?̛b^,:Ns3qqߺY: HCpbt.c n ҈<>~Z>k)).)iTMU[=fx"U3jEWBU~}Ws7ɡp2O-0{fi"/C< &MiougD`9 4ѫ MU/=/ f@"(Hk B(t #en.Ii$y!ǀn'|C{ cK$Ot ˇ.5>bɚ P_׷rЍ!bkyI?+B7\@l\yKbS/:wi]ڝ'."v/3 #ۨr a >RhR=(C=Fq+>A.bJur!ֳmP0TXn`aIi,٨KSsU|Lv!l}ޕ0[0b:L.3Y耚lj)b[ uUt,vo'` O~NxHm&+.ճQ51 5>dĠfӯ}Ķ5T.+UDMT_tA.vclv5@%r #tڣ:=_w 袮=Սx _7"x? mg 0X[EYqF54ik>4}&n!NX-4b%\ml0miR{vL* (lB/r|dCyq+ct^IreG#MBY0l=QQdo!FaWdI[-NΟ9jbb},J.'v|/̸zaN2i=,y{\G${VD ǯ% P~6j\rs1ζFgX?V`FHx9[ӱ2,fhI4\.0W H [9^R()ź7r5?!3sWPS6wsV'7)ȍ(CNR(qƏ\1E$9E| ߔX(;@7Ҩ 0g{{A<0WCgS%/݁FJ# };~Jt x -5r(wA*05]^ǐpR)$52 $~1I hpA7L`Iu8JV2ċd5Nꂺ/Aq":bۯDc6K0\ln.jf~6Z ƣOeo-㩥5&[!ե(;hm ;\oCfbčQmY8M]) BpzB|Abqko&9݄;4eX̌ŜT݀êl$AHA:xGZ09=|y_ZIR $`J[DƋb+p/w>'MLUc7q$t]}}}z^[!x>>7]kV 4ZcYWv̞3oF:cTxa,dZ/9xEВB E:skd*+brIC -y.xҴZX*ԒVܬJ6о]t 'Fa&+݀}X;4Ea@`,"6fQkb<" 2p=2UQ 8辑mlW-|-c~)!!Grr:u}Z&bb֍qz.Bc,"COҞSqeBy7ڧ|*B:`($UqEc -c?81 MSNGpa_t\-gSv/ D a1tƲ %O7;?-ۈi(p('tr7 Hua'ʴFPBcE!B\;17xowB ~։)}Υv)!N"HLȷ筃Tbd>yA:t_a%&4'=u\wl\4ӥQ\s[<_KHyY7,8[bCL:=Q)0dV Reg-ʯ0z2׹.: s&._qUSV߬LAR^svol0Wa3b> p 67߂L y '7>7>lrhd2l|o0Q8U**%;<ӵbwxVX^0a UCtVcA}!n'?ՂЊ62}Iy.$#oSAJ%{u5ٻs/'h8 3i!%ŘnLQ{7sڣ[#*4@{i_OEbh!-U TUX b|@F66j sVM '5W|%oF3ΩJō#9T݈hn4$c\@#k# VzW]dzu.@PE` ?30TגL_%;Fd( W.R ꉿ+ [ܩBmYaJKܣTs?S݌a\*hR+b ^'1PL uQ7+t7k5t]NwWV m^hЖ9h~%ZQ!W\ XCeX ?tj)^L./eJn \-(Ig|B)!OOΈiqFR73wA4t0"[rP! b=Ѹž?c4.BR"eβۭ,ު//#V|Өr#:B)~mdV[,||tpr L=lj{u.[fX~)t:FI"[\#dd4fۿ0 Iڞ7t*л= h| Dtڊ@YbB(N80aZVκm¶m(]`:p,| ETXs?M8Zx .~'AW&70R¢#Sr1)'=HƗK'e<0H~BxnW (S<R8+b|Fk^c62oz-AyKWd# 5&ԝ{TęZmN[%pe4AN}e{d[mS%W̢U@twMbx/Æ-W漓;:< 1(Ȑ +`Uԏ^=-)Y,EY@@]/y{*w0z +*38E8ӥR/,h6 ڤ։} +ZP;RtJ ,̢T3fUmQnl2= QY,31.;\ơ(Yo\Wd5$ qrЈF3|#&A"*\G&̖; XY'NLaOw/%V,ʁґ|nuT>mpKڒF #Ý-ZmִT?hƞԕflVHx*ζR>[o_",͞A ;.HW2,:wIrO2szVZje t)cV"ӥ뇤 zE0as#^䊨jeh5H{ryL,QkRpg;*#e1Kn-d3ٟS*aAm,9Aش;DKt'?Ŋk#(";NJ) b'XDpm7!l]-!4`mXQuT$W"Nn(Ql_G4vRaAa<OY{rܭsOS6F=QG ;O4ùԺ|]/] ȗ̇)UՔ w LyPyqOG|OfR~b>/T-tmW tσ_Xe96`pܼV+jT''}|'FNCbGbC.*Uᆱ96'XsQ'!o'軑7[f@ں6A#ņUŠƒ,4zCb╫>ku(e, >Mow8B رON󤦿ᢖ<&o&HG}[T?[i$ljy܂gۈ4N,pΞOk \0 eY8CaTJt@G 4aw klw#CUN&-Cmۜ ӯ!"p{;?&;/V'ԤaA7SfYİP6U{6;Aa9j>N΂] ',SnC, o[74C Z|쬎R4⸝V֕Ȫ%;+ԻBp1-͢~Vd}dgAB]n䞤@]=Xa!6IЯ{> 4.6`N,U=))'"FbaoYv<pv:AX/#T\qF-1;>2QY.|ʛ|QonYCy9 BCGV$k(M"m~_Ω3[-Ԟ:*QNzuNBÔXP6{4炍)#d~5 \]01U< VuK )y8;TǘIxi_E_g:^уFQS-t(4^<6%@QO$F no,ɧ< " & 62E謯=}#a6RekP߳J.6mc,NjiRJ3~ j|t܈וE˵?Yҷyfi`f dSI0?HeNc{ȣ1>s1fIZL;n4p|~wg~Akg ;{v_+FqzPbz w5S{Tp_:y{/OͨZ&zvUˇ﯊eq2( z=-`z#LmnI,0#ƐTUlYD3-Q&P޲%ij6H—6zmUe˫Z), Dhrh(@2H9QJ(%?ʹ׃@eH_n lDWh4L3_Mŗ~cfPڤ{ lBm)>*4?k׾Q>NKğ@鷒xxU2G{[e:zz.;Jm/",7JY;TC<tvq_ \یљT*O$ Ђ/tØ-YmE$̖\VXyޟ";&f~jfςn=q \`_|]i/ȹ~#~n|;Hc`́Qe8 D[ajzG0Ne%53h)ph-NCWkQŲOWv3o(nJr/(`Rx당f;zIa{'gK:UO9!p$t)$} 0zIF^]e {F\-U 67?j/絇㮃G<NЬ8:粅 9NS[!1Y cu|9p*&i(α|50 *4982ĀW}]5ڌ'\+}R4;IMes"D0L%);bԩJ? _%sBRMd\Mx*~K*\,xXDAU0Q>E _6REdםOy* @\c'E? |(V 5"h[sJp|MU8tE*Y{JADSQ1=ThUIw=0ijO& .,klv#8S~bBTC=@-fX{*9wpiӃۺos6=ltz'+t{nȉ@3D?@7 yj,S؂"fz.mnU>\OE%a eS$եSĦPp`-0Ğx&h'版!_{&?'_oǰH6 y R(Xz^ Zó(I`74ya7DsYa~d.^V"PvQ-]mP|$x۸WntT7z}5QF6| kG|HL9&J'%xת]L{hoΰ3f.yK 3~cBkx5ߟFvfZC"c q̦ 8Rc7W8+l'p m +av%@G?/ /?<$hh U{@b%& ,̦jb1sXi)@8+WZD>uam3O0N\{ym鋟5#W3yGf@O"}Z+,Mqn;8rMrD* ؑT,D*FrZDX"{sf9zH+Xw75QS2Fvȷ1)5hU0nz pru1qe S" dy&kN $h+%|̿Rp0Ƭ {Fc69INě1OȰ0о@)VOPgm9Z~1ѿ,Pn$[o HAh)2)lݟ6 ᔺ !s- KpV|Oy) NkڎSCmyt" 7@SXP.]p(\VTY Ccƞ霛fD&tjh1cwO 2ޅ%!8#ީG{i2F9IEXgQ,„hͻSFZ&+ȳXNyD>he"Bl&(Iƃ0z[ HF?0M~Ռ}mjx. OIx<߆xlw"GV(=suAd kaG#Ֆ4 |YNF}&<;:r %qNwoE=[@!۟:5wK~>%6*+5S߂@ߵH' H{UĆRA3-4giVږyeZ)82yl;` t!GNqeDj`utn.۲qa^tMSP DߞzL0!;k(rZ1\vPo-GhUfmdd ^;/%۞$^EZ-᳑@xNK,>BHli1,3y<q/V4:|dLhB[WU{&Л=3mhckS{4BN^k%jDqph:`_qwsv˹k/sxY{OMXBe{-@0i~`6df d+֤#mca`_Kw=Hū7SC5˙Iv &uM 1%F,Tng3~ hfW-Bكg'%E M .~66S`5FK.-aK~ Ӌ!5'r|ٟ{M3/fµjZRW :ݰ౅P \~LxW/Rz`+|AuV}HJ*«\?09]q>8$Vch@R[38B#ު|>pIhM! a@j3ʮBv0JKaxԨ='<B[p,%4V^xV a( U:=,}:)` OJJX [WxȗGT!5V7$N icsb7_Y {͔=@ Fdۤ %>y9 ϶ʾ(_G3SIu8n_6r+lQ _ QX3nuJN!}إ~ Zi^ bQi>nWyK>V``!LNۏ5w& R>`E<]t'_&ǡ~o uOB`^.ݕ%s0?&gx\b]"TNs牉Sv3&* q]Op1%5VL m  Ud)gSOPmւ1#tBL+m}ZA\ň1ڙ-О"쁏xIDY0gHFv~u vkp&S!+-'laBDfs)K 0 9)97\-\{trFUmĪ!{@'pn $y\_up8/a"t"fM`" ]7_1{SOt#glF9g9#E$2C|yt&ĂV?X0҃H=n3yN_ j~NU.*iW4H2 q5:^Z(판l1:Ty)zEňĻLpQi /}BQ?UG%@u]5yEX랓h)v0Kw&7r ~EVAtK觰z871|ʟr).Ӽʐb/pIc'm⳹4UnJ=.a80{wi '2n eTedz&bGq@qsv ٔG}^c& c5+x Է_H[\6;>pK -gO, tuZugHWs?q&kCqVY'M;ʵt;0ڝ\neu5`+p3^aQ2K_VU ?X+v@rZV5OC ϖݼԅ@1J$6ҷLG0QPZ 9▥. V0d΁l/5FH+,0JVkRP@E#:Ȟ"僉Sptm;-Okr;dYH1;L155nC'a^b|$0MxBJj]9s?` \捡aTx@*T|˿nz8֑.ֽL[񂝂ure>π}"ʤ '[e$ْHۡ%t֨LOA`!41aqAPZ3uQl2%e9Ti Bg$s>"9eA{xPAړ"D[x%QXSfzYj~T'M̔ʶ ez+5"͍QԡCY!A 13~ 1ضIja9XMѪ" #kImy&s>z2VQ; %+AW2 F9 &ЬKvK94?ZTTc5znClG1aM,GdC۳SBɋDu9i"Ƌڄ:8qϊ 3έm|0Mޮ"hU'Ku| J4Eqd\^< Oz$1:*V?N[+tIʔK4vtRhbK:؞JYXx>CfJvғ.%tDӭ=JE[w3OG¸ ~eʛVj1m|n9̛Dh!*Woʆ$w|!%Ju"|7MZs7`[mm)ڒ.G˿ga F}^`/Tt@PtsV12(]PZ>h{ 0/6.xUx~qm[ %Jay IF Xmf.@l#0;QMA]Y[ Ĝ{!1F fOR_=2)t:vQDp:0nMmYl- Ihk|p Ÿ</oEb`=NOYV)*%MM* ~p.q3åx:,uU 0W6?#N[n/D? 6tC#]Y(:{QIdu8O u(! &<<&Uɰ҇=>10ft3E4QWz=^l[2$ONqS9+x8V'Ӌ¹~klНܚƂ%] t ^*f% ۚ53vrSu\Z rE!AuDr9uO|y1o_R9v8/rM(>;^$4Ǣok劷zjF6̌ni8y%+#q4zkĵd\Sۍvn 6|D3 ]7Me8 /MDÛuO,H1wFv%(DJ| rM>K$߲_ E׈eh{<$x<%"{qI|]^;l,{567Yx!\9Bp/'IPFO 9bfnsU"- \n LVo;S$HU95ubx`I>,'M Nܦ , W+^at"u.*C}&H ,[͘Ƕj ?9I0݅. ճ-Ta(y ó 7m1S_ {4W{,$Q!)BNA GoLLݴMסM:gGaOd1[u΢DzT,)TϭF:yw9 Cґ] 3h^i/^Q99i8u}~x:+:Xej0݃i'ҞSH]1\[4#& | 됧j pt4۳@yʉ1 Μ|Su,nKIjSS-`*h *kuEϏ̏hFm< 6k}gd@`0NBxZ5kϦ"}F9۫ ?Cb`mc$x##Br@A/` 9[A :;_e63נykύ4h.؏EYZ#J)P䔆QcCfC 鑌a:G<~2/*bJw^ :Z0ؼ P]i0k|Xe+$^WsޗXJqliUhG ud\kD9`ƚ*+sӖ/[^ش~D"UrRb /Es~xo8m٫ =a6zlƟ"^( IBRv2~!Fp<Ξh d/G' F?T1E^2)k0AEX9/KG[zFC2Mg8B-^fC 'V]~W36F\ba0y_*{u z<|xV~ 7L?V[ЖGfe3xn&訍\ǝ#7ʅ#y/׼0U 2E^όFMc=zg^O7QYv,Emk ˃A/iDRz4ژ?c%`$8ȟnց/]y) 쪎8y-])g˖3WNX}tРXˮ^#0i^wwDr,[v  ݠ>_*7k5ϯ[bؽ:t6jpՇJׂ Ufi^&)nOBp昫$["7`>?,HׂSn>1M~W+j)? {-+U|dyltlz#um W\oFpk&n8BM jqG~@pBQE{?$gd :s3r،*m%UICF!$]}e:w =0rvᚵeN4oj!wx0^}u^ti -EtQ\$4*hˆf#^Er@ْ(̱5_qU@nJ,d^Ur"o2r( |ȷ 5 n1)>xQ''PZp_}pmu;dK el"x+3КuC\bh)wHuam.\ߖLǸ7A$,ҿWyV|71+"( y<@BF >X,/\Xx!+PҦ=B F.m7cڰ :w Iw0ԣvqZ8)Կ:Rܾ2JƮ 1Ƕ.R\v]ŗ֨vrm2dDM}%|8/f.1,^/cW}O-G1L@t1"'PR](IVI$pj bO{-\uq1+I5aB֩O:¬^KR!$ m])!M#9Shїk`]`Tv2ϸH H㞗n"Bb#i~f%j\=`ke'a3]?Qwv[ʮZYmrw}$:+.W``?&p6ئt1 o, w 7#8a%ȞqQa2$N RrO9I-0mdYu/T#& D>`wG\5Hٝ^Ʃsxcwhplt3<)/0^{-[ qۂrU~;U\~B-=0\fMb[j6g5ゑUYϪ+Jb(V k;z!4m|m\2$4l\Áv F2dvO381 iYbo%Er;y _Yj)/iP9K[#E0ZKA ?1*xIP +f}ԣwiW،jwmBN r÷2kW\]?<=3lrIɼ=DRKO4אgws ꆰP8%q/(9` QΪh2py]]o^x>~ԖhZ(E)^?N̥̄>\u\u^)o^t k7259A REk憎~fz&UflUCMK[>7b-i^@'X3cQi=H-VmTa10Dz~/Z(7Ȯ׻f Tmqـ{])cxdz?!cRSy*A9+[}w, Tvԫ٪5}:DT:a$)>ª$f=ɡI*D=/oѐF?٨';߅HAOR@:ᦍM[V8]O#&dd$-ƃ;B-Y{Qg[h9ziTƜvB-3 *C+Lĸ倏yvH/\ϰ Q"ZҫrkyPJ%wM2[Y ,~;fݿ~ ›n`S:8^3GF,0_Wa Դg&:t"6G|W yj:E]DNsv~_q *9aB ,$ɔI**șæFPVᎨb#uŨ9RQ85%OxnE<>O6\y\v2u\ ]Aq_D,q;1q};~d݌:6r0-l6_`0s袬[P[O9'YtZ:'TKt8l!XxrրA4"@# HmsbSj7/;t[HzؤNiH&3Qz*NpO5B97vvY5v}{*;h]U|^ꮨ :a|jjawN$XS_^\A-6e_,>$:C92؆&ܼEO@/U7l췣c5v d9[E>gTD!F&&{30wʣ߹u.=I\#@ɵo\,e:M,J7 Gs 5e MF 8ԆZfHg Ck"tMMg6~I41˘>ºJ`8"*L1XXde[eoyY()1teҒpHv1˛C 29*}7چ㗦T]oT),?i[_܌!~}%hw9`|:]s꿶_R ~M vǚ#HPuU\uwsKWW|=4QԂ@ -q9T3LWSB\bb *XUP` g.Ÿm;y-3=daꇣj| 9wמ`8UgTh E䊦 @6m^0d>[t[AkE X}7՝_T&n3oos*'{EOյ\>TLU}QآgtNd^7)MuZ DgZ$P- Êr| G)kgr4lJ ̚l/Љ$$3bg"ɛ IHK?cP˫gb]/cfL24njuH`J[ʮ%V>ˠ=Зc\S\X15s SՉ+]M"ӗ@.T"&CcY(L{E.`@oG޷B4m~~2}uY@͈߿ 4@TJ̍1p~\I6_HS)Eݥ[yEOMKP/EM*^*Cm" F\]V>$CYJXSC7㲯ܼ {mo+fD 0O34d!~#ceyNy/ж"}A$UQHi[y-M_\o xWz`wk6=E "=]@ JoihI裕k4=-k(BS'Ǔ2Y+d=>zsn7V6@KʗN8͖.q0# U+| VV*C?@Xe-`k-~YΛ 9_3v Asx ̖zr$Hg$ɶ$r4kH;3ϭp?Ruة+LT/Xh/`1gWѲÍXYmQst!-FRJJ5V 1zW@1>dkKC+߃>!L:<x^ 1 HAH !hVɔ}øgxUP4u[2 乪$w 2iǨP΍*1Oeebd_mzۥzPpC՞h&%5EH|YuS5U+*A2௶C\u53=2* ސ~Atpd{A2QJL?G;Y\WH+˩zAhR<߆ ļK<>w S+3]ϭ\I5 w5Y(tJUbkP\\^=bN|ڴ V0Cp sXcrjLKiIyK +v|1oRr5/; D5@u^2ܕ! !8Vr4cKb(E7Ed!wa7xFJ4:f)_zWE װǛD*L$AN7AEMb{K -MGB}l -)?"wl"W"@I(^Svim1բ%Vvr$OoSzi&V ]֪iq=%C43eqo?t%pk_ؙɂQh>>2]-JimvN7b4Fe\&/xx![I{|%5+`?bsKMoN\x7l}UfR~O ݦ"-S1k㹓`)Uܶ jj')0h.v}Z~nnP1gP>),rI+?L,">v<}"NKh y<v/,4pO[Kbĺؑ* ZIa[ jLYNү_V׆nW0gY$""&5iPi𘷊/%U.)${>X yV' }o͵qeoT'ѽC tϠ#XV2׵9*ɤ ;ëL[:8ǧr04`-JaqmN5SJwO%[a7SgQǠβi; Hc \ .ȁl|TG[eJ;e(UKyVDqtg VjtnlsHYVC EMn+7-6W q_@AeyAjh%iD|[B9ܧGR`鄜'LL@&:]8^>EBtf(] }FH1Ȟf IL1M޴/ONnj75>@HPj}1,.m,+sgJ +L-z( g7ֽu:keID_3k;J Ht ӧA tU]1PW oޜfLdxzrpu%lVE}p0[j0"J _HWI~aqzse%릪C@} >4yNgcܨe2*qalƦ?r8PPF&aǗ+@ݑ#Qѥ`"?uWâ2! r'[hZ x9dB\L$3sUś$9柠'CAqzwjd˪Cr3>9RF|HQ86R9^0 vф$ u~qQ+Zs U1@[Mt; :|% r08P#iL g /CR~^ɸ6NomAEr"(iM4`YprLgni_ۀf,7_5qtҥY<]wkI[FIF*NՕhFXQif-$aӼ-K!B$НruWXӖ7Fk26vT?zm1CL g4|'~Y( n톝n 'tG|~*0 \,, _X!G0EalS3j! ,ɻf3.hyLtK ^L+ӦFr>Q9X7lkauEWYV5lZFF\q:!xmЃ5ŵUYt^ +:C xm]NO :G$r{2. ⰷgd>.ϡv/t+ާ*` "sGseuiLՄ"zL:?)# KC7Nj"= R&͛t/3u@?ylrW̿an.baj!,vCG>\1৐y|W8q\lUy9[)߅2e3eO8 WTy௵Git 9Q.o2Wەa DEAYZ cFͨ ‡B= 1l iW!SXSOP 2LLºL%ZLc\ޛOk cMC^<) 1΂ˤHiK#z؜{߄Jm)c *h(R5|h s{Izt An#\ ̖5~͟Hn|N8g/eo%Ƨ<$[TFi39/fBSV4phNeitXַUj_T_tbHa0zH] wi^Q?jZ9kU8< L6l5ENE\>$t`R;\d]!T$$4o3ې.'i9"ZlkpmF ck(),Whf^-Gb[7Yd#Iy [{ (?ֺ M#M^Aي RL .tvȋtInH 2kͬ؊*@3t M]rMgLAjgy#6rf 4x BZvFi (mN%rym7K4G1Ʀ U?zdsx\_3lLH orC!4Q0! E7G۷M4IRS,nW]^zwHj. i䙜} ).  Z&a|InDJgݷ[Lw@yydjE+@$i53"_- ]> 8=3? _Sldnp2O?)םթ>|$39Ia5(0:]S]ďtƎxi'dPF_5[MֵjNU\+lWlN,MSZLH #rT퓙dn 4)ڧ.6ȞsGc&+ N1 Y.N 9U|d#[ =WJbtW,pcSyrFp̫C5MR&.D{n^X{Ȑ >244tQvFk7n m]w{`[LVUEe^d8#ߪ_ñtDƺe~ &uTtd zˀ4iX=Rj+U^&==.bY.&qED܀󹮬sEn(.rQW 4cQӌxSѶyTޝa>g T=Fk&>99|^f1AR̘;<;1>"ȯH2,S}ţ36|HdÞEo>{;"χ5PGF ;;Z6j',+/SUd9D Bq:TSBs }}o(^=Ж|vI,]w 8YD5aUjtMX0T2w]0~r+WBrGLyR=KCHŔL.`5lk6gۺ @n=irCJlծ^Ш} j([oM<ۗQ`Lϡj T z'ionhX cEܑ%5lm:>*A$F%SZVQM]Qĸb񈏠<=A,bSt@j8+o3S0n^4bJp}9U.A%@?am(0bS|T4A|0MMf-xvbGڠG+&-~@ hMr̒͆>M==>HAfyJDwovmO X*@_k[fjԘ~)ރ :6Xpw-Η<.ڀd)KG .J#Cw=lmN9.Hݹ[mo8 $33,]Љpƥ+rۡ U_p| rWR"OI9}hm la?F(DUl'3\OQQ)ձo^NFEEjs$ iEj?q5 ;KM;e8 ]Z7unDԸ=6)NXӻ0 VJ5y޴ ~ j,^*X{y*87AQXɠ?m/8v7̽p7T w}_oƸvN `. ܃+7C"Rգbx㐾i](0zEEE:Ilx\W[gnx}֜e ď Ƈ1:+[~"!^(){W*g>E3j݆W$oǺEtyZV~f0`u-( zS*6RvB!&C/s.w~@鰇d>P@CSb??F9zrJ֠Gbd&AMP^cpLETZx&zϪ=y;E7S5vT qƇm6 ApCu*U?jļ8T )`'`_rʿu?O@u \*,.\ ]XNuEʸi/3+TOgX|lu"'*P &"nR!uȪS=M\=X3U( l(ý=&gqה6;uI;v%;:% vY\&Q/}b@  Ԯ.&HJӜ?U;X]DN W,y#WxcƔR6:,@ /uJp4|Vw<ƌv[sM@&:Q4G'&@pѤVj5izǴ]8unV7 2/~ ʛƍe+c3-E a_ Dtė/~}AqJoT4GҮ.r}O a\G`^~ު<j[b?x PcGlh,dJ% o(%0w{p3C)4qu[Ôb 4,fL}<[q1CUl7~clPm2syNni}ܩ3煟:G.!8`8ʄf"1p).ЭUx!q7Uwz$?8?P(OE>@A5"^"qz|y|m_kklku`n,Jlbåg$Ε/[ڤ03|JJHo:_/>W]8 {˜Z7FX55BC'81q[$LGZEmDs*^*bS퇆<[K\,sn8 k 8-l4?3?oǓz"Ԏ=ߏ8IQ h7o蒼0,~u5Kq;1o =  pN9dN F'>"LP2beSĵZ^ĜM 8iRDor VVm䆐S̯(ox l)cRY[&;\E'=}A#Qm" MJM|Gae:a)W?nz,x.+mp= ֲ[")url%~נOL0?!)̇)&C?k|}G kp)=獁M0*W h*zQҒRNThmT9ь (-TC4L5.=5N5>ζ;1lExugD`&e>hueqh #,d4hfa0syB ^:4*r7|*!dYWNT#{B%+_!l+%S5Hs[8Kuޟ) -쀠w/ vk'7AF*TLb^&Hmיeꝕ mCW/7nb$ xuG2*eGߴ35PrFA+f m)AL4_Phh>47 )$e zh;c$ɊHg)S.Wkky$f<νӱ B!9pZ|ͺv~fa ']K>95h؏>⢮I'_4wtK찷65''@RK_V'J6vn^&/ֻO`v%C~"*%^7~{yKUӰz7mU[*+ysNyqR˵?X%ɔk+y@\fwc ˟=4羟O˼i\ fq@RTa0@:g(5T5BA4{nʅCgeﺁ)sN Sv.J[K$e{Q>wU[Qp{ͪu}, hvo>Tr3; ߚ ޲%b匘092=A+FXj ;2^B,Fr!?q>Džf}Ta7sRYGy:Hf]cՊ{֚`ڴ(Ys+lǴmJH0@lZ4g$۩1tg&IsFEZbJ}/F,`V"|E #_ OZ؉|rZL5fIG Q2Pyt^ݘK>F3% S+/o|;ƌT ||0gXeK-0ӳfApiy)(nnQֶk,eT@5#!OnU~rb[VoK#,kj0͝4A^6@vBpF̋jf1 iط9*IW=.B:P*=S:X͹`|roO2NtW;+35ˈ{]9 :& 1g !ckh1t{֋",p<D DЭHV7~ܲ|UOQ2}$؃ziꎌ=>cB3>Z~H%a9Lcy{ݧܽQ7 -Xo\Z\ gdwm̈́Z\ooLLj{F0q8X.Y euFx+vö_wKTq@5 ǜRS2)Gdcc̖0{Ka+4{N2/|rٽټ̉>3LJ'rɞfwOS&$H{@8>Dѕ@1w^z]?;$kR=]o 9{wែ ̳=`ǹl^%oWZZ_ȳxҿWlׅĸ.Uc lG{"iU7242``K#0st^mBt~2y=<?}6cyw?zL!}76 hw*?EER),Y_ ?-F#$-wlu8$h1Nՠy?,c0(YRȫU&\w%FWG!ENb>0E6#4?cGOy}im9 Oq&z=hg= FRdߡV`j ‚l4 ]C]2l^o5*pH,Cxlpk>D^rW=!n*!Y_҉%q6sx'V?+2Bi5öѪ$O{aJ׀$ @pqQ<𢰏98pR ry;<)[O'nؔ~C1U?`4?*sL]ѮBI "})Iݦa ?J` l')U[F4_nAؗ]["CT"DlF&*/w?VhS Ch +: To :*<4*B̰k)3u"e.lcϓݱMk"(|{P;Мf1OiC~y]ǃ2|$U#pN9{=c߀GbA& ]^s-1+Q演w-'*ZJ^YB}+g`rkuq,0¤? u3nc=E۳#3Ysdm_  P˿rKmKk^k[\'F81]S5L˵ Ķ/6gJcve7A7_l>*&(bX^7K:\Ե NANgdWRчe?|Ec!eL®/?b;} jhntFez˛X[n'H{W7[!,y%7[6Ntf1x_4<ڡ6h?Κgt;=%s_8w0>_ƺ1-.3/:o9Y ~GYAPlcӽiz|!c-mvf7Š^,Eʮ] 5.%YL_ *۔'yj%ilpjez1BVJ^:zP'p kFm\;?*f}$th({m X$•oBZVrǎ+ Cչ?gls8NehD-ԧ.`;:,jP ECv= /:11tv"ٴr`+fE֘չŅcfgB8-AVJ)]C^s+0Ap;(G'9j(%&2gdR$k4mTzUЦ=TK4eXH#N n[A84{8UQ+0PP;&[MVvL# 8cҎwYD E0הՇp͖NMFH/H汻ϧҏPHdx;G;憓}$X "*1(`FWeBx{;U5@u@5CG+x2F'搢" X`3&gʮߪOZa3ZO+oxOCbʕerӲ%Pً&\Ԯ烻h[q]PZ&Iř:讳CO1/* -r[!qΫέ߷)imY+55aqxY__1S-xcRE/FIG:.F̮ǩ|i#xQ ;P-=5U{/D[F31&*mkZʿ?f".V NqU"xOpk2t z\jf4f9puZ|aJvz> g`Yב $y䩐+mAȪGmX8r'[YW{.5춰Fזua#õyi"kEhxT&Ȗ+'4j.+nق_U% 3 W{ɍB52!f9e??Kd(&4*}5[r+%!83'R2+u&,̹ 9;B?vƿ 5#gXsl]!6A{B]KL?2X:Ӑ;ƒ@Ȣn x9p0٬P܇:V!O,-"rVtXk7ayMin@F\0b>8 ~r ٖ׌o5WFI- ~lH6qj*:Qy[;*$}V _Є܂j;Ֆ`t@ّ_Y`tN}lmyDHXףL]tP#}{Q{L ӻ"pwpNC@S_>S"$Vp,R'#zvǗa&nk<5{{[Ǭ^5R)<(Gbr[Yr-!Nkp6kG{n05,i,GfhK.Te?\-ƸIߗ>Q4͜? 1+0"~:r/ij{y+o}޶%UÔƍ?\O !|^(ͪX*@<>E+9}?ߎ/ ؛XV@XUY u]zDl$S3Z*7lgk2ORX5Kr)vqKˏ`ZeThI-@Wńl72G\P~%ВCT(9J>b-^Mw_U"O\f 6[H2,a3c -3vƭɤ~ Obf(W6p)F&ꁸnx`uKP"=`H>yZVޱuugr8}.#[²tSq|e*B @ CTgG>ljUjBcR?l?LLS%n&yckW;0Dyb=7^ӜpiEJ3tj&Z ؆b-= a]̠Uh.M}<\}JFRO*,tVY<1(st8 a>,2sβ{|I\xs~UA)mtVαcCU^A,TSk~<aBWMCgz-QճR,w/;K[Pa=7>.WoOX8,\?02NvYݜ+B5-Kmh`V'%M%CTڲ2-.یA^Pֲ yIW%fOpBKQVi6|yͲǗ6Ltd.5C,LsTO1)%[ S~:dq$a$?g8 ^yc X)O+.L:^zIdS1 =5VdmsT0voډ`gRuv̜YZI;cFPnZS 1 et,S[Rrt*2ՕWPIZ0ŽIn Ǎ?7)8!ь(-\>(pe͆x/-*ag=!xޏ{+~MfMڏJ;Y'$yJ9\йJScJS[u({ӊ"A mM *A Q[aWw|"hn4me']V_ZYAvk#43ݜ6 N a䑲3!\QRu<jߑnK Pe8w]e!1As-Zl +-8+?vIEf_#"4_[u2s7ONPVwd˜w$Rt~Bwl:ޞ#h;͘M*9DRVsIy'#iպ}Zfr"xSҔ̬P '|.՞QfB8/DP}[ r7N+;Cy,"J}qÂf'Q8 c.^XNW+A.B9_塁UῘ4-rsA]a;TbYmK3&ā@ۯa{6C>zhJd`Uj vOP]hvܽPP鬀^jV1w߬^]^Q˯#xZMD%ZLګ5acM$M`QtDȜ<ߑl\uěy xpO׈8pHA&8!6R\Jơ8 39Mў>u>2C${*xN C˨tHf¡𠾗ẒӬtpt/7 Hӹ1׽?ָD`sUv|RhVb dq`OrLV Kxِ2 %I"٤مnTM;5G2s | G*WTLGF>֋ 9 2qi^F[3rq gێ[a>%w=̲ <8'4vplIERV2J]\fI5 $<QDX5i^!SKtR2jڢ/̝qz}~VD,E&x ɝJ rikKV /2XDm 䖩)?A/f?kb*Z]"UN9[qX܋nh.P3N 7$6T?ۂWRsB,녱6H?N>}uѤ`Fjv^AunϾd`KgN/ &qB3 ;5uHi[yaH/Sa]tYRpU=M'eixg̚nè γ ^5iMM0 +땹\F͢{:z38h̛UG?K1VM4=9AKsӫboD U~G q$.!h*=1#&,‰mϛ25h8_/>jpY 91.pJn=YbA^i[TLI հ)_hZ+\TqNRMDhx4X/{hpS|r{}L/kM[#a:޳qa*].r0پBM7x5MS=z6gZ;)jUK>82ӫ.'y-[A/>eutq"7';Zviv>HZYY iN-%]q)esIiWՅOp"d@% 퇧 k!ļi/lwj\ .єXn}v\̸fh}3̂&NnTDWb2]uUJ~VuCXRsl=ۥ!>Oݕ ͗:' #a5kP{?F3zmvHL-ÓtP͢I]D6q̽kY #8oW=-A@~̺R6ĶR6 5yȳ{ CJ}/}&1ůjӓW_a8:ޭhCuqUG[5 Ӯ@46 qpC(jFzaC 3 ;Y)ɏ~k?F;qKb>:YPI\ 㦅x4#0t˒wS&fN}8(6yw5OYPMnFBGަ:kAQgnli{|ʭ:`4PDr2 6%#65><Op#,Ls&"ɴ:=~Thc:Rd'<0]!^ 4F滱aggɻ#j:9`YI_!25lMWR l( HB 4:8KY T iҎmV0Vj1rM=]yoWZQN[썤va57Om)SVq|s,9eˡʈ \(#g#Xcf} ﵯcJqTފ\~$Xe҂AI\@isG"-v[3⣙ =٦R.nȥT$X:cBM6Yy #"PC@*E2Fbj,g r'qW\u=5\.W>r0$(-ֆ"?3(jSK2MɚʗŒ_7|({~NTMZaO8Wk[y=*@KSzXST^X[Of&vt׹鶙.E{X4Eǖ {F^~w uNj9L=>ZgvQԏ[2X4U-_epەx\ȌӱxqWnوo&e^!)T¾vGs=?̃Ğ^ϓ35[;~p7 /:Q~a.ad6(ay6kyp{$5sH/5R t p\GCg-#kpRSiLH6VDr]2&B1 mX5|]gb}+y4HcE mU@~5U#xhХKzߕD4rcnD!=?_$oͣ4h!["y! ,].],lR€`+_vȇ% !ۣ϶pbz>)=;?X,cU. =he ,%[ߡk 31rZ+t*@V'LiOVh3tU, z^g0 wy/+kcP\(Ȉ[k!&\ZͿ1VQ2AHЫE\ LB‹`]!e8e1uCG~>`IpFڠY ԓ~X>zW:PJ`%f"VlfO6y*B Ffo{n1Vw:[DGq>c`y)*8.60%g>] Vի$N˹N)>DUW?0+m"3+Rgnw7@,BV%njǓ #6IRˀxOmdnc#e]jcjRkP}<&O-DrJCg' 7|dbfl{Lfo>w(0pITJ4=_OM\AJX ˷tCkT -Ly VHlIM&,K7#5ҥzK)=<8K0E?$çEM5H,d؝ԯ$Go]_[¼w ?:Q#f"mI_d8e9I>D&=E Mzו/o=o;*C8FH ZS~蘂34Q# zM|rCel=|#06.{5T0Qаڇ ++`քv:QdGMgu㞠 `6m 0M,]2g\L|FIɝF#P98MY* ڨo:˹ PK*<%:#y^R^_gus>֧Ĕ W8c3)DDtx#B5 \ˬV玧d['۹J9ۢXNQ[`4kEmty8ssN|<$J];x{,>tm!)m,.%}8X YLw!Nˉ",fH7$N!v=fq3l(N?aMxE ;j>bx2NαA}S9OSJZ!wcf$wٌ aG^7d\(~!48Q@-p>kg)*[ў#Z)JUCYS=6! ~Ɋ@u{aY|} &jUa 8ŇSzoM'>LBN.0q&t+gfN<88=vO3Ooט srɭyQ4T޽tAZ{70'hrÞt~j~5Qa.IvK&^gI#r  ꈁ)=Q]tE)5lص#cs*MP>`Rl6ȵBTT1<eBޣ"iԻǣ0y}U APtGȁb'#E$2)hӢluD2i)vVnW5FS+_=DK9}wa~o:6fz"PtlLpzGkBUBBfS'4P^(á*9c4&E?-g{xJT >v3NЅTֲu^){e}3_.NT \bPFt~̣?1s~)./ =0raY+[oَE&{tU匞7 鑣Ahx (ۿ]|l,Ldo3WikH/eO$I7!jς?]KeH#C׹!"I'؅{Lur1,Ծ%P(Lz(@fe3\ZpTEGȼEK{6F|Y @u4nGʌI# Y,k`~ӏPOI?̻s Lm=Lk~JOwk1?*3JC7L*@l)Wj`<FRTE "B@mxIx,"L|X.aUlp لf䕤͙!Uб+ x XLNϗ0Q6! kk5Pgh #.O϶$ k ĺCMEv,0ƹ'=*}9RCi*f[sَ+!D jGpԞ) a~v+ RMsCuwRm4cCؕ-qJu9HRޟbwirb} :U>s$f)PV J<7gQfC ҉kIRM`B5$QH- g.F,;@=dR)3$#꒡S>Ws$MȄzAGZ?e%Ld}ֽ-[j*/sw 6dwucH(ɦ.p ^{ =4gi 7\V-?:/mjJ8Xʲj Eڥ*hK 277F^I }A j6s#V쩗[t܈ivNtoЩl*@wcKL;D[mշŠT: nh҈ʗaWT0ր^őDX3Cf_ P S XH3Ǔܩ EsGKs N' 4g={^_Y{;#|:aC.I}3H蒃YP;UD2@3{iT窂I.ja0ڼcKq7d|:V$uc[\}߶ޓ>AjTBL%qF#:P2oդp}AǏ˟2zbqUhmiiMɣkx ^ JO k8wp.*-LVJcCB`*ab&0xFM,m5RhE"]L)קb(Z^swpߞRC1lqZ)t󺰣>mtx9͕_(_K%>u';b9e-*o>F0GN)_/U̵>b@FbxuW穵y]'b01Ji=%[`:P+R߇IߒV{׽| bJfAʿL?Iޔ4 G舾-Y5O8O ȄPLhIՐ;]ELsv s!؎ځ,뻣 /S 1͜t6eKEs^SI \rWwkfRK%x!dxDWXW)ܙm $nq|P HJz Ln+ihwΡo'3 ~GE5?;CrIy }2ݥ {Rw/xWXt11/ Z2Jzhh_ԝ\KZʏk?ƺz//ʝ *V0XdeH(<$R@#O.'ax+^SN:9CkVYkx{37i'Ƕَ8YUOu--*"Gh*2yX$K-٫t/h#'ѝH:IY|̟KvHDB"%9%yaFADg'9\k`)jV6}䝪i_?2݉*[e_mFb\~[>X5>D{,:~XR7+:'N5 )40a瘾̮A>ё.iqW^@1MzT(:4o7ϚZ /Ddzt͒rYT󈛺_ cE0tO3*ڙkdnWhc.$oթ/̳\W^{lBqo* ̯o52z.y$Y-qEۗ5Hs#lIeϼjG>18g}2vBɈzV"jf2sbMa-w;OCm3I2ۊ' T*æ~,`ѿ`-O5QCzy",n"#cKo֡$oLI*pUڄ|d8z Y2vTbXҫ|7GPӈt%V];b4L#zk>r'(~]o}N"ߵ/ǚ'YϩGce @5RfA^}~}+?=- iDPO/5d4,*dJB^:nsaFy h-ǝHarʮ]`nzF!UO\ C=q/A8¨._405o]).+IW )112E9K^UK4Fcl KߵXL}%u-y-oҜNZr]-YI=Щ0h͎aA̧l!\3dkUڭ Z; vWFlI!@nPM/X`AqA`%K:s (DU)ZH5M0n;I Y xV5MX+>W*FKӐdlj3k?K8>IJlZ(qA[7w+k`,*>B^T `Z8}`}of&E: 5$jaE/}BX0!`+ **3RȈosSU+Zv|D{c<z9ts^hxgAxL;ՀRO:J-$N-2E yְȲ\TaȀ"rs>U^ɱ7o5*~x3bU5x-+9Mϝ߹9F?Σ59Mc&y +i[YDJD-{P;ߍİV2>m ,~^x`0ҲwD~M`ìKðo#0m3Y,]{:Q ھӸo%Ռ9.ԭocbc>aD)(A qDL] _~XwvՈ:Vj_/9 2Jem0?Ul%g9F+?VH Ll4$j,9ڔ*;op@ "⮫ApO14j \L8|X>,`1MY&4XIm{#,pbûKJ*ui3]v}Y\{]UszƯ 4x,Y+VyB T;ۛ&"0ȟD=-S~h,AyS"@i qvwF@&}%]Ptnv¦gp VfUNAGzYe `U@r|ey "N\eC̆pNeo{]mt\WSi2\E{zl H/޲xX-gY'ӲhZ6Ӄ-$Pd&MB1KYh2h$BDIu&eU:Jؒ?iJ:}2mu%vspS((a"\{)v@q" 2}Uz7qָT7}r>`8\vx`In^Ɍ9~FKXB8g<,#Ԗ?}K ;399I,>[nV uz̰/%ͽ225ux Fj[K.ºG?Tˀu96om@2~4;:ȌQ1 i°+t |%6X)۹=9FONupjT)qN\/HY5<>X:غvDX4Q W3 d.hSOބFJIl!ìA 5W "#5Y4 )0ѴŇg.\DKQ#vx}-gS.stno~JF"r"73!.:N:9 [JŖ'XݻZj0`6),Gd<d0,!Λ ʴO '[ʁ܃7uAS)IS?޵<&GqPWT*lMú7U<,RՈUi춍~N*d%WW_ihݿyp B{26?6B΢뻗їKxæ+Z B6`7]ɑLZ+nc^ci<)bxљPօZ=$>g^b[k[VK<+ sn9E4nB}VErw.[|0ߩIŝ@t)?SxkƩ ~2y|8ܙ 9TLSBЭgI -Q+H\vA`72Qڳ 9R T/Gȕ)1Y ^]]Vdn bGEeMQ3lZnYhb |0_CP˹8,x3ԴXQI( 敔I"YL>/2!T8TO уX!ʢIF4v[hՇ]u7ԹҲh1M1u>QXK>e|Dړ T&so/b&Ƀ_NcˉFu+5^GPUl)oWYZ"jțQy=.%Tj Զ. u=Q!1w@|]ى@??`\ Ur+dN'>Qu^[ ]3 وZk`8ZM" dtگEomᇉ?vC. 9)Աl 7DHR @T; sjdui?ƈ,u=c6I^Oezm=2ӆޔ9@Z^.GA\v)p3 'ǰ\, EpJ=K鄽tc$'B /6~85.ۻMu'VQ.c64SU_Et%OUI e(8JEHWmTx8ahsw2_5sڡ̲@~3JI#eȈŅ 0TdzO ǜ BB 񗬶fVS4x1DॄO^?>3#$"E)IMZuDIK+aJeGXa1!r 646Bhm^r`3uL axd{#ʦ;9#3";{sŹAIX$G>HI~ۼNLmrbohsguT"AM(ol5 Ǐ0SkcIZ @WSѬ%ݻL 5pߩ'+oZl^E?:m}/F Ѯ_2<څm>xJ`m2LDOi[pxpWYJxc-D_^4-@ٚ"?Dx%瑱.YpM#/RmILR{[4_EðU:;R#7[VEۉ}ZşVB ~0 j$(l\!&Ƌ?\ +NΤ`P_>SO°zr )Y!R t(r'Jp0u!`w1k̆w3]w{u^&{F>Qc%Xސirs!i,B%ub  Qgdq)aGk(.O(P.4%2+^K}W kRZ+seHO-`\ fsŮTŨ+kO*\m;a(F G`"h9㻒ج5V{ ag5tݒ_X"ilOLkU{h90-R}SilOZЕ0jwܖX!smmc (]J O} /ǧ=*GJn|_fXYhZw","_"7gHT.r'Fnn} T05m$n|VVH bDܓZ}H3KEKѝzE ?u19ԟ=<-,x$կTh?aW&Z"] =Tgg5,"NDT#aGIJ " \ylNddSeS>|fOAp=%`0FL$s(PNӑNr /RYa3o~4ee`r ie5ޚIO"&pKd.S%ݶmS`ja9xr2@DG>u!uԱmPXjدVЎPtj-9V3 Q.í1g1V庠Ǽ( թ3b4H qZE7sg;Oh%Rɓ) { A:x /҆2? C4aa^-pBNpB=LEi\ߠcw3~=cCKC1DvLsρvy,Awi$i!/8.ьA (^-e觺c2z_X=5Ӻz \_CHqOhWy V<{TZh p*گt;XGK^;H׳5v^wRDMj/E@5FLEj * ~nNmh*5d5=fp=ˎ2AVQIpv}Fi6ƃ 1R-%,(BR_?N|PQžPTefx>;qUi:2W+ 1D=Z#/^ KŐ|+&=-8Y6)l\ԋW||}LDG7î?5pBj/up1p ;Ak[L4vTK3*Km׌! Q ;|$FOf,Z23m9[rikb;5dl"sI.O1MPQ%Cuݏո8]E"f PxF䵏[niYa?W z>+1hP h^"iKTkʶ6Q"ΫQ;]$u?F5,20? QIJ,ca?{T Eb:O$r4[7\^R( \9]eϼۅOobW蟖 #H31E)\ P98>}SKj֘HS}xC5wv.{8z;rV!Ϟ;@][.P{:ÄB],mL<[W{ 3];Xg}}t{)&CdB/%XW=GiSKwWVˍYn! ~O糣/!5I"q'5 c|n|ACx:xcD REܩҍGz ZmV]_-Yjp JE*ޘG o]0F4>(!WvE:_j'X)Tِ{o Ch+}|[^*}߃-#cJqp-L*z ^|t,R@k;fRZ3)Z١nK^P43ci՛6?bt.WA$oE ]z󿅟ηsIKyD&9÷hd02t'@ G~otRx.Wl^Y&l#]۔Wl [q$ ]t;w_o%?ڽz؈e}ߒm~AXՅcB] *d)$y0lSt}͟Q|]`|zdbMSӌH_⚔A \)tmbL ŦMQ3esg8u 3>933q[`:ax6^XܿMoE:ʽx:?$PTOJeKwd }1%mI-5T U9쵻Ń(%FR9pvl:n}g( ' tHB5e,Q6h?rTI>1QX!5QnѨz5D<_g#*7悱 a9NC_]pgWlo͚j %3`S GG3H VVB[@`˝Ð<0Z{\4%ܽ|eL9ZN`HRډ>,ϖ#9teiK^qas=S!|$:bȲDbitGMEǖZ='YW8aMi[UHSOL(b׋qA>}ID{Wt<$If^b{ռ8KTT>!9LZ zX6#k.MAxC2%0g*\^^cax]D'!3K gNH鎛bmye83y_~6-q>h=GLk-e|˦\ ^'QROyS0';S3' Ex-ӤOF0XyI@k҂^Y_я/T1-?fx PIgWd~A&?'S~߂5%Є ^IO:܂~>Yv%knH9Ư3Np8zIU_i69)v<W2p^){d$ 1bOGX_p8o9:1!uzѹX\}?Mz4JW1Vƣ(:znQC!BkV)Jѓ5uo&7p? ʖv(⻞KY4kypSzN26HŃ“X=zPydj}yt 80rmhbgPCW/MbVho ]~ +x5 %]h/SŴ>C& F|q^8HlkBaLRvY(_S> ~ \y{,#Pdr yG߽@!~tĎLte;%8;.I|x{ńϾޫxP2 ;h&D"!C>Ӯ3jEf.8{TYAIAJ[5W$)Ec>ENG`԰f 0 rRjS łTѢܔ-2tRb,8ʠ!jQ |+ ߫7crܧD7-Fsk$4$ۅ C/ |ÑZf,l?Z^g1,FOK@{~@3Y*9?[eu9ԃZCRmK䳷 ]8c}vQ]Py8&ImDuBnC%GӘ)t2~{3=2SƹquΣ84g+0GeBbM 7+rH0͋Ic ov\5YJ`MuTC築F&<ڬAPC+=U*ruDϔ++l-sj:ɤjYf)愡n|m_乿Ϣhrf0u%n̼]gOO@hM43wH*F"A#nE^%m ienl TGvڕEGzjGY}*CP޿$ҡ]nx{=>ۮxa?vh80dl{/c,dbm|bYMnP c?=h\.b<ʿ{1%XO_lP6)|ubO߾&o:mM=~wQU0/γ b |l"u&|3~[?mqg9,umzgSbiZ;PƝaf==BItHVӊ?ElXewc$hr9w0Q`G/8\H(dzDCOp|a) /,Fخx12Hf1`zȩBR[{O[a2w7%ho=eaeE44O']- ξ }d?@-hW[nёeًpRϹI ɺ,e7i]+]ʪqd"55Ȩ)'ԪÒpN=̫W&%'pU<FF2<8rge%VMC'ASdi F O 1η( 3)<`rGYo]6ZSf &lQI m|~'E`AըTD͉bPV )7L&/ !<ŏ>ŭ$om+5">_tw)('w)ʽc@,=̏M^tpQzsAXb5mYa[`aV8Z+27 55Gim姝Ƌ̫0tZ ccx*!_t~HR'G4In8Vpn; Jk${g0WKtF0;j*BffP0e8IN ,>7k~N ~:ʲJߴ6pkx_~sz n`,ìo1J%,blTg }%j> E kL.K{TL/{gpC6Aw}7Dr)Y#&,ңB1.{KTN.Mp=,Pܶ=]w{}t7I3:^Q0'[= *a-b׺ڏ&1?sgudaq?A>3\dž`z3r=<#vX]`5_2܈G?jwâL ^/BȘGx#ˆ5L_|2MN*L>(x?:eOv^D`2fSmI}?BΞ  Z㎖i@ Y$&E){O6@ ldtQ/+t3BopE]( v_å+~`'h5lx/i&zzf%  baN\.]Ȑy`ڇ͵4bG®н,'eӅ茭"W$č X]0>"ބ#RScUYp"xZ6nHl9g(]΁ooy4G&UXQ}ñ䚕;#ErIƦ@|+LTNtqڍVwFe(Óh痐Wy\'r &3 +PBTjX=k[|6@4TXJ!֪&b)jY)*qK Fֻc4`=uyڽ~%sm:c;0 Vu}cD.QUɅ7r?"&wӴu3sOl ,ڈ :XkhFDE]zG7IXMgo1顅#Ck}RAFT=M"" 0v{8<ؕs;XwlGdK2GG6ތu1rl)k)WΤ\b p('Z|q'QրPNqhS@iu?\~cM> jO3.{F9sBf]fO Ψ@ E ׁx?IH1;sߒ( p2|e;s8^"d:>ĀWDZ.PhD䬴b&wR =Pg ݑCy!f[« 4Pǝ.di4z:m"q,#gۃ1ܹS9ao5>6sjl˰/Ql8"@LKYGҚb<r!9m08j|Hl%5?-,ؽd5 yʊh&$ٵ_-4@rp7|{Sɍ L'Rp"TK)+˟CUv9'mhSh5o򒅿[5SZJ4J,&~p*K}L@wIf<G3Njj3>Yϸ<^kL J=%Q)=OĊw*m14'6 ij. * `@#~P4pZ('=Ѳh&GIv\%XM*'1mpܯ{([W:E_5^'Y%<{SdQW#Pi<ޏj,O缮ӹ#S_ ~bdzWY.!>p2DR.BׁĀQ7H o$w"Yl `ZR& SdY&n)?R5*$OSuDeXUsf 3J.:"ҰfZ7P WD ,/kRvMav 7v{ ɷ(Y6r<QH y4j,In]r.|Kx8E"pyiyeI7g; us31S8 J.g:/A=ʂԯ)x1ONJD; j5x49S ;*t|5foε@Cx)3 ^jo:DFIvX1}Pn$^\'@bQ" I?CBG8| `z)(P@pTS8_ɔXݰ|sbi/9ܗ#XG="x#o%f -*o)elټyfhbs[yH\S~tvl:%)TV_remNn\pC%6ͤ+Kcş~%X(tSaAv^zg?E=tl@qwjcK5&>/4ij存8/> CYǂL@_*Cc(#~I.g@G˗咩;vڏ#] {vNPrPwC<; I 1%xfbr#G;(G rl,xB,׺/eѯ[*$4 _G6ld6OVB|됇; ³Q׈:ޛQSx+RzDw퀗_ԕxP>NXlxz39z聺vhJ$W Y*`_ 49"^ f*IѠ aCkZkIVUn(/iܜ1+];Y& W!W)t]}WtR Vq=L,b*hJg-ZI\debab5tb_v;y!0o!6Jyb3Ό}QnFxR{.qگz\PSw:rq5Lna}ۨ׊GP18Q\%*!4> l{0Ahᙐ b$-/vU/S|ϵݻavFtܘ7%["E _-\MaeF j@_߼DfVEWH3%`#0Y~3(b>VkX̡ D9m[`$=QG_!^ G=r/%B`iw"yGI%! P|v&G?J_`3jTienr(r;X&Vo=Et'"lU+c:!D"[Ԕ8,swqe-W- hrNAY& %'VU ^lBr z zfNn> 9x;-K5(A sR;ĘGpT:f P-m'|n5co^NgҎUWػڊǛּ};E~LSK"~9iIZt4Lb(zk'U R=<,;_d~: A{$(K\%B*Nk *6AyxQ!r) Dg Z‹ 6s :#LzN;){-fлB?kz*Y9ɭH Jk NJXI߃mT Js*yQ[yߎ򩨈p`$})c-.h+$+F\ Jlt1O%^%Fkqt>ٍ_3Fї>~ER=8>d5s]X_i [8t=F:$R79@[ɔnk–DJqN_;G-NW5Єleٙ=a+qW!~%.e;9od?^BeW4s.DdarjW¿/)`rd-BÄ#6Y<Đ!RI93T@BIŋi(zLO>]S4JȤ:y08HQ.d*H _Ƣ4z„[Yˇ7?[ wc"7pӾuP{}H"6d Ҫ⫆:u&C$xU8k_Dcfbk2VkanҘ>@-X]@,;v 8B*T2gw5Y$%o:>hii{1$lzH[Y\PRklV.GoZ{F0gP5eLhWr.6BhԮ0/)'lnh@4d3QqE\ v(VOxM-bOxHӄ vO> 3%M=REs/.O<`Ʀt`WpYy)T% rՠ`׈ G^&N1D8OM:TQ rtv9SJPQZaњ7;b 8 cwAxkR}3 hBnbF~Z4oEL1 Đ:$SL"DXHrP Al^.#PhP%%NW xY QÆϼB$EQp}XD7]ZžZSZtêW`*ٝ9ա`S3.>"}Ei?k [e+ͥ*O"1ezD673\9O%5t^kDJ~a}mUJ!{^9fco=ۃ)^Z}M:װs`\ګwrᬢXUPHҎ%?PE=fUsE]+~&1Y:ٖGnZ~~R4>.8nza. wmTU㍏z!YNJ e҂za5?+ᬥ y}uc=FN%=.R) 3X+mᐵ}V :@?ۺSPYԥH kvZչZjD̆t¶l a m/a<,csu3 ;JH3Gwݍ6(aLp$IN0;tޢxNDt0>,G,}vDJjp39.4¢ō's# 7'=0Ub2gΔ=m)٫{CKkٸ%(RsM"` `; <D~XDl =ŬЩ's2k*$.B6 >H4Յ %~x̷A҈y8z v|Bw2ZJ=924Pt͙U 彮~[t܌Bn&Zo+f$C}i2'Ei_ʵGv4 X~N@>RhI3HGwZ?vs\;S< Sen"汝fVLE+eFFG[c$^\T/EdFד8 ̓{/PG|hٟv@jXM*.JԔx4TʚFbCȳ S ډ6X4aI +.87$277:5q#Aҷ|?E>G: L\.%Bú^9Ѫ'=f5Ĭmu0%Xt[m扱orbQpt4 RXU j8*(l:)P\;KE)zrmKH"] aV~L^Ė.0qWW>{ H[ԩLЄ5suL(?1̙-y0{hOD ׆S(/CRpo6|*Dt)͂FyV^ 4 |pvwL{.׬g\QXӠ9@EI=:/X IzY0M=D9NGWn+d{ iM/cFT-tc2h9΁*PAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT PC#B9ihߎQoEEqD=HW8׋t`wtىA]6c'X2(rJA6߶]BQ_LD:/6*ܱ`tey ;he0KZyVrF\,tNrFJUQj*-z@|bq>,#!TLLd,oyEM[dnS5%¿EZx/㉈%:<|H1Z}o| d.s~2IN{3GM|߯ $f ^ Ͼ PTZc8ў#-<M4dݭ.|卫qL^i%-;s{]>]/HU%>u^܍aקInЪ%[hSA lԧ9y48rh5~fQk?Awa3qBUCdTοbհȮ_ vwhzJސRWU݄p!v2B_>٥[\e?dbSiәX$ 4'ŧCɇ.9]P5vK{Ev\1,P*Z֍ Қob,7`byψ*I؜Rf4JlQ@Gfq3CqX#Aw:JvZaeGl3u_}Bg DCZoլ|BӍ/rT㕥PQ㠣 ӯO YWД^=OWcݬ'|}U|}yQ#p[ 6ˢ7s{GL\4j^=҆ۀ\ڢgw@wVjҡ &FXDW =5&$>^{/wpg 9 qq:iQ6#`R},D ~ ol sloE! 4 `EP8pi@?cp+W+9(ƅԁ]`5(o t 69oHj`aד{Dq N(O Mr+d.Dd8d%Su$h˵8\*s9k])!GDllhnrbR`_) (Q9l,9+[vzhkR(8b+dǑSFΩfC3qyͷ'g~+Nh?^Z9a_;#Jn0fQ)r?49OʷC$A۾fhg"A#i!6V+ ļ_-l$ɋe ar]r4m Q\Ο$]Ep94cz炍}}Cp\9)9fjZ3ɐk˒fPL}&Cm& -f5~nvAڢByyr$Svo^F_b*mC.5gaM`Dq.J:4ۆ?L#i庘]hf#DK%1ٲ8g gv2}n2\%f:&6}_)~ic|a&ch;怆0bJj&10txkgrQQP|}SNlcILKq$ KdFâ[RZ}̆M?RVH}NxC6fnYefGz W1^ Vb[BYڞ@uwEtc5"S g9$0[}e8qea;F,o>+a.rl,] D}&jj4Y^"qL0pip|ٗ,!M)n.I_$6g&Uy,(@̄!<(gdֲ%؉5ԕ @'4ӰCjʊ^b,\\}34د;T`!^aka ?-pVmRA1X%0P]yJL+Ӵ UOWZ']"F^⑶24I6拽W\]/  m^qJu}bp4C+&֓%N~Ї(8jZ)XE#U>:8O'GH=;70:=]Y@FoDO+ͥ0KM[vK]Hl8J\ ͘W(yX/1;9y^]?-Vd.h;6AT6}gO9mN'dCD{[2z+SwQfa>wט&M=]AwnýK!Swv:ނbݯ1N r4kEpך_T"A>e/4@XIׇ'||;[nZJhR\܏=ǻX6=+| ~^R+]ǶTi2S+橳FsOuǸYK%<7m|5}rxZ K sn^C _K t>ʅ KJ#Aj7!ܹüs1U'[:k,¿B\qq#exھ|[IM -6By`H!zBgVʜ?[u6w#OgiaIS%,k>tVMa~D{B'b"-I`W|kXU g+p||BD&6^%YZT0GA-֜㑬V+Zwd5rpA-KEZf}8ՆtzqT <kcJzܷ=$SDf_⋓Q_()ˏb_i 'dcOlJ [-[xV>/3#w*c9glxI5lǷS>ա=:jbWE@c{p3 ̡ uhV #_ci^[;㶬 G''?IHAd?BC-"X=3+>h ERjAZYb*-v*Ҩ&_dMu_f:Jg;id.yͪJR|ګ&qFFfVǦ xEfϊ"-a^S4{RE3&]JoC6H},",Q˃=Awf#eRgjN )$竴i0`2 4USws܉xH2?k<<%Ƶj>{a`+u86J%-Z=` _\*OF th om,s{V;OlZ"uLY S_ёoQŃ0sf fEeiy&iR&ݒcqC8N!cc8Ək/"NGDO7BBRdT#1jg^6{jHv' <4M͛bcӳ X.1+9:-x_:Gw[䶳jR^/'nZ3!V ۽!Éj3ۓ]}ҷ-8yR# X. C|}YI3XP.\ ͘:d6?Sۿ !+[Gb(1Vc-qz32+ZTq(T8 Ja`ݾb=6QM'xx<ZB_(LKa|7H۟K TwI-< N+]j|#`ڕcO2(xKy`=o:ķ<:\ /wKD/_w$@ulWתW'!M?kΠkeӳ' HpFoIn*s3M\yw;"k'ډ0G>`|hkYۘED`_/rȌ΢ۉ-*bl|5C{OC p.:C~oG ]]%ƴޱ_)`E`l>BJ:%Ucr*S{2@zDYӲ q)5*Ю :0nR\-2]IE\'tUf/2Lum8b\$P|\OŊ{/!.KqXa1%mpb7BǁRfƟˎ1 Q(! I);0|"O3 .ye !c _cK|Y=tRFwD8,9Up~|IA5ppOV &0g_9*LGtpB*1(ݟ\:Ĉ@*={W%OVI 5 *~/ަG#fv$mfZch:-# , e{0ʓCU-Z)Bܬ 2=#!g,^:bIeP"AP~РYG ۰jn:xDR5OPY +A)f׊U=C?䢥[i'LsVh"gp,NHRBzz ic|.0,x;[dlI|ՊbU!}|HȒPmclyb"Cr+[3|&6d/>ay)/Oa6M U6y&p-h2B?@IXmRO;qMXWFҔ1Cw6 sy9;DʖDlܚDrҐs2G-mn[ >^o_;@uPZGI$x<, 왎o䮯LX44=Vb?:;B~zt zU)]5l"71 "1ph&Kg`kY(3SPVG=yUGBԩy'UDj{p=^ȕoM"3L#E_*4L)|TSpNaW썕@~ s:ڃaT˟ лI 3@G ε}=jxŬ!sDԩ;HD2cg3#ܐm! x9}JdE V>ɧ%E>ڔi\U7HNkfFmҌ19(]R/o2Q䄫MVj]ߜqrؼQcaԫ>RO[2Mt8T42vF1'kInԖP Z PĦ¿ ^:gD0ihEWJ,S5Ei vg[&V4͌RC⃽Q3U&ai6G_XP a/:u>ep@t1Ò~dhZv}gq\dzSPeP=Ulsr,kD +`?gDX/j[z7xX5ópS{RqszHTre $1d79 v@9i/ n)bHQkr! 3v<6PZbzbVe,fp#^>GKv+ܥ 7M,e~ɠ"dւixX^8-m2A)&Ɣ&4Dデ[^>M~Pz꿩owcr0M{>(+iǻ%ҡBQT3IdQ"{/"*j`xW: zr e.C{vV'Gϊc+IaՇ6R-7I+~BvCdƨv+We~*-UP$4Hzpiq%*c4WJTt 㥖(\ DHC-O@~kSVw;/D&DQ۳/^3Oc L/::Β~J$`b7'__7 <Ҽ&nQȏOujJ"-K 9%>G4?Y- o č*qy/8f@Í~R}<#ˁG4]7ZKۤgXnC_uay o[5+Ϭ9Ql T3tt7J-ǃskgM V&gF 6S0-3aSu|F}A\܇KH۔q WjJƃ,kgu"OE Dʛ(S~Zcw`6ð$! |dMP3_ێN 7%Rb;JD%g2 xo{T=_>.?t`Ma̶Et"+fec={1jDp&R"'KpCi6gx6Onܿ cՂÈBⓜ'ס2wHE1B6Զ̋M#7t^*t)'/HWT@`[|WbXOW9lJFb 2P) Tad@-.bR),h&w'tRw,"A)kipNρG671/PVa^#a!RAc/*퍞 'ԝ_(.1&_f]r!BK@N /?wIBC$>2"!`E lp |܈qh(/'-H=KRREI@:ϋw腓3Q{g̉>j$HѦzc]vתD\vEi#]wa<4#&#W%AVv+4Ց [Ł~yiEa ƪ'4|mFm(,C(ؾ{Ż f1IS)lԴ`#X>oN) \ %(Z+4AT(b>rU_߂PjuPF.ܻ$eA\LUs c<ς;l+쾆-_Owsw+)鐞k1QVFyKM'%H 0)gZ. :S|8(U\N"B%)c6hl9?$DM%چMO(ǎ-ͮ ,}KJriF`y4]6i{f*{@Ђ62,FuGA A* [ +dxقG6: }@3FX6n9^PlLټMQr<CzДsIэ&,ˉ7P$i}Y{n x]曱CXăԒK@[.B(Q !w &m)ҚP]c#o; V۲Hc{OhH24Fx-Nv93[:xO:T5Ư\|%Z?4R'6q4j`Q)/?;|dz%qomN8#9hP/@ qSuNdH>N6cNG}[.6h GGi&VHey]~E35NhpS+ U"6`<it~ Vn:q05߇lG >n]F][h<],֋ȋa`GJyE ט7rey7KWܯVFXgzV9\JBܳդ+"bh3 kv7XQ+21JߐfpKļA3'/$BK :ܿ8u@vC;Uk6fk0 A``]_ԅ\K-k+I= X$mvS1 !aӪ  ̆ u̳9r29oQmBA;~zscLoѨ+Y{_ $Oo#hߠ~0vU `}έ|%% @}arFnG9#υ/IFmJ%.:7Rߜ#'8,|$`s~JP֋˨}r!ͥ<2$ųvFE7:d_lĚߥJJc2\z,5?F Qk}zlj~fN n7eB]]Ɯ̦\l#M0PI:T5B 5"naFB"nFEbe )doF+Q5 KHΕbwު>^_ko'MHsQԼ/Ժinh۹F>TspM:o\Co>V|YD ?S ;=.u^~4[ۣ*hv޽m){TD0#RP[7sLM3ڝV5z K{^λg^ x|^az͈Er6C<+Y~`l^I$4PT6=roy`''\Dw㞯%m[])Ҫ杈$/O-&q\D!9$E7xg{ë֙ j\$БMj⑈ENR"07 IcC\0U\l'wRz @b0CT #nܘΉE'^ɲsije0 %TEQN ߺ<1ʐ`z{B(4P~tq3ACۗboP%?5ttrICeo_աGC S0@3UE/| 8@)gẑMwi;<@l-`=~',{٩ZPyJϦ! me.}7@?ceÀiG6nD_ٮX0K$-; 5;=WH k_(##K9)f9PdeH%+O=5Zc`׈.6/@: ̺dte>N~/hΔR #/ $Zqk $`؋6SD :*wӼ_a)dZZr]^F7H0VNNEOH#;<$MG`:+P(sߴ9cER;B+4³0r1k rR (Xw{Ӊv}8,uϬ ޚ0ЌXY; ҔEߧH{E|x Dx3hlgL;4νTe ]ݬ`OC?gH*?*ApZ/χy0Rh+P{uSVڞB;) cUӝMwC$ǴW&2]p[p3{.]qNǪ\1_bJ>hzO- cFDvfTR@<ں?&Z=IȧxYbBpg}{=gĚ.02I1Tv6 p0S8.(n1j3Y& `%aZ&FMoMV__MUǧX[ q[?/TBD[C2 hu(n8?EoXd클Ń^ &^Tܶv4"M?J< Ei {d6icCN_իĂcO\&Sq(?)/e3=ak.^wsv6CLPC1J@ &n^ @z&'C/Q8 V3s㧱'u^ex[',7sKks*XvECB aŽ-'j ȼtKCL 'olĨDbhz9W3?pꟊG[?mqm<|.vHUa+Bˎ!fۋ~MoZ{d$fׇ#qã$|jiN,Ahus'/ wqh| Qnj:7Rw-Kav5vWA[p,+oJXF'u@_ _8C@瘌w}Z`1Ey.ysyM,2.^zp-c\h6VG),d6kFn~P;zXQURGJ>ofȞC|9ɽ.=XbUuPheF>y@TX\xG?u-*gi)t1"渢Q3 |8K>+4'6vMgSѦg|!mSw`R5)(ux(&T*K("B,kB{'U$x" .$|o1Ng^2[0n'_Fth+z܊RI:`*AųJa`ϩju2sN仳qMF:2 =r VtL_耾1aOѻ*jfgi>A. S ]Bl&M제`qE ]M",0ywbW~ӾA?oă7%ֱ hTAҒJ{EE 飤C 9cJkzXQ9>R{1ţSc-n$5_|%a.@0c^hMj2^m ϴv==- |C*kTA/X򜉪0:Gy C;, dՈ- 9eCik8Dk=Z\yY Må;:#Yq sU $[FfTW7G;-Ծ|X3pI4a4b8UBfw[&pl`J~kq1oUdݪȯT%)i#|.jP0KZÎ1yF9 ;. a 6F%T+PS5Ty . { TJa]4ZcΎK;.,POQR<=4rpQ ݐ77pOuU' f6cyHU=WU (ӈ>*s}ⰀUӊΰ=l~m [48^0NMWL }]W>HO7$s6>lu$-l]c;WAtD¬(+QsF<^=;b%Rtzy)F6 OCf;=l4IE&L~J 'U$HW+(ʨi@TǎKDW7B=&u' I ֿHz x.3f!A#\bϸ5dWW1`KK֧Ҽ _٧f^#@IJ#EP5Kw=srrX ;{d'qhN_6TR}uDP. )Ê73G~.6 yŒYΨK8ېM31)6Dէn7(žogKI7gf#!dS1Ef\ RV S@)TMz=MQxC_4G{*W^OU!z`ή V"ɢm9$f:6lZ˽;OV_\ɕFU# ﷊eU%Ct)0A.MAoܵƌ>ϯ_PKoi0>p3/A?'2ɦى8,>7fД2ϋjyir#N.S2 ڳ'o{hӎ3J:JpI# Eo (wW 춐~Lr?E(Hj^O|wvoC $ 0@7弛tv!,czj*ᢚ28 {ݣfȏ$>MDlBB͠><--@77rtSq޷:nMJo/ғ>fL ޢnd6qh@=.Qm.A R:nʆ-]m%ZU aA:w! :X! G;!̠=T?~[=]M|.A/?tGue:(-^Pl*Y`&?t'*[XMu.fhuN%koJcAhh Bgt|=ݍsW['ta˜0_!Q2RT1Ik@*&=A6 i:PSI$"$9#&h#xL9Yq nC)s[LZ6hmYդSTxEU'JC&ϫUG3qQB6za ՗ ~0%/;",O>|og `hsK{(C>˸Q['!s$V%x&QshݰU,dwlduV5+q8ŭ M E9Sd7FsUuRp`QBmH9QEM? czĽ{WDK5LIJ$. bF *u!@Wڤݞ#^~5ï֙@l"ƯcTe8s{n,ˎbqxJwՏD=EL\ZKv;PibSV9aKņ'_S FؾnpIkgcgiP"&[ct@V>۶{⛳P?|mOjd͢gfCլ?NCn^_9Eg{"d![7'Ȑz]!Coӭ_ъ}ؚ!kZ(+&(. <X7d4,b }H23& n%N!ڡW[8gj򷪰? LFLH LJ j6F@ö[;RKqVatN'1;yĒX\ϻ_9dN0*wUٍ]zכ Lc@m-@+.Ѥ!wЩ)'b _'VdrKt |L Emc"TT]PobBA8}D̒ R4N-xV9 ZnHTQE[uZfx`kB`0Il yvݎehؿT䉷sGEw/B5e7쑮|VskiP.T |R}׏-OD [9IF&R//beV('.2Zj0>ج~B-!WٵP6T}'9~Ʋ7mxqS٦tm*[~f7D4[k2>E2tly…0;Mb[uJBjC0tqǓ,_lُ-3|K/3{+%^)5f?:-;|G+e9Up M@jfuqyk}*k&ֱ8E*]Tt! Ĝ| )iؑy2H>ԑJ;.q&k0N]J\0qb]8H`/o%hйpCbO<+ (Z\+ڎ69tB>$q`S3EfM r3mÑyӘhp{k{:c1)9h'!X~T!2`SV֙1wOQb5ɗFkɢoUT{FofpR#rw>'v9YNoSx$fU(džH'jWg|A{F=@)؃Ut9b+H* C3َB0K(u@<_,EJ۾Op+*P'lDŽ+y1CXd&c`b]b Hj+s@Hd8[=lKeYRdGj$=0-cεˤa Dfh}(m]ax+ˏ8kTaHu0h/7vj`a#S_ߞQ]D!Aߏ9Պ4܃;1 SUS஼kbb7(K}Kk<=I=SdN\YR V:M{;$_o0"j F&^ݤb(KԚd:wIOx`$/T%TBI4f?㎂mP-sq0Z4VRTm)1׈:dHׁJ}֤9gN*UFX=!$M3߼ qj#dPSrYC(r1lKF'[Nv0*kW<>͌l2@5S?OD3<ܝR= iMF`ڪzk"oh&C-UHIz\ɮ߱Ѯ^ZG3T\笨>`z c4X( 5ܺ{I5TV|d٢#S}DpiԠz~)e+U0/ك>ڥn4޻(nhhp&Ya@Yi`z[ ㌠Ëgl8DwaTq?:*Zl_T%b.kYe3-'FVSס7Am9RA4=3@#_ pJarss=Is.DD[Ky WਞR1)lL(F^!{2 nftԄXhZڄI>daU0tqS+>۸~Fr@[n6xQGqVD&MnG6:-lQXGv9,XZݮym) *l;l9HZޢğ"L^ G\J%U/R$,'([*RS5* 'uyBZVuCuj1rMAKC>lduk0z3SeТ6V&-JjLݢRB—[Nc4:]~%0sWA[y4rE`{RZ BYYVĈMXRa4$ MdL>=&< ҲR-BTB Qc ]Q:ӝ 0]/~1bägl(\DÎ{30=͐R&v)0R~_8Ei6]{^p,aqB4$u\"%sǃ_>2kB)Q>O rI7d`;t|D&s 䕺ɉP^6ꑑ-܄yVY$SiD\rU}߲M2ߧ8xǝJ~ C˹ JI)aF>3K3H D`&'>(iʲ/ ]8n]E0]@"ј]nWЮ7T,6Si& q{CPiѱ o6W{E=01۝ȺPir-R5 o9H M#c5k܋E/ˊKy {AriƅXE3(ېBSk EOO4/MxI N^ /w[{qxn+j5HYXҬn#DY9-|AJHdy;Lkِp{eƞG0r&J`FB-DӣN;DKifsy(jm$wb XSE=Dfs8qj+vj;`Xc|XnO(<0 p&M puH瓢8}Y]fo{a"ycZr2$=\bVCz{z4!O*'ĪL%DK&:P&/q5FZTtBمXޑM׈Aj$}Y ){EmKz`7 d02wnݪT2?-S~ 3Rm}V ׆Py5_52*H"|ׯ1@ Tj3R6cNKk<(j(L=)ępg%nvx.ԎxnHuvQ8?ڟ(Y듒qqk}5Kض<,P"w?9MZk`̌Y5=~tl~D9.qVYkAdZUy~z-ZpZs X-t(؀x. W&~6ryqUxKݣA2!&A{a8u;ZX)9׳xv>{9YVXDy`,g/H B* V,[OcLjEU7^qxNWK!|(բAЖtG΄&u|@Oz f!ߢŽ+v(w >T %.9Gؔm=Y$%QdI؋ó̃HD>hܔ9{̂h{,1g [93K&2o_3m~Qh70mӼًcZFFX Cdw w F7i\zV\'pt-T=z#Aw˲k!aq́eV)¶>YE1ã$]6^#U̯^bjfɗ"巊ލ{'+'ÙI8+-k x=@|9;#L*+9-MS5bS'8 ~5+Abv(Փ v.67@b;6rsrc j')RR$"~H\ǻ- J^EωML1{6[jn)3HOY.9}eyuŐULi=V@8kЙJ,2s?4o!&dZ^:Uvs%H +r$U@ 9k|oYh|EpkOwZ~!ws5n F\pk$INk>o[ʃhloZ ᾐ +ރ!5 ?6=o*{_ðŎ7nt63JÇ9/ ޑI"ݻh;ufP4ac+N'1]/8T1 ;Eű"o (ut}4m'zn$%7)J3T}ڇ1V n:@짓MPg  3j yQQB4 fqPpWRd4^2XU-7Wc7YjW@r *}"u~|oUlP(Y`U`#xn\QfPŅ %Ao#`\”3#;{&M/ag^IK=_[ԪD Qz߿oNGRn,fڴ*?AC}pwv|)řIaMlBz \糖\E/ɢ`@>G+170S^=PغB^RD-xAK$v+*4jbA?Wq׆}keFxoq$&wA F 87䟃/NJcr"5E1+CȑU`Ĩ Σ ^ 4mE=q ]~JRν4>Gu7;HM>z5,ň*eG yK$}Wx$z;lSF% XFV֟p8ylj;)z5ej{1&Q^@Ȧ,]$ Mp?Rx`8]gP&IIz`s5a+ΐX:`% &64>}ӛltzԌ);Ba}]ahY7Lfk ңlk``mfwA~ 3 SN<]K3$9gRD.t?Cj 2!F?-ٹ.,".L bNd4ūcϦN4 WKʽ<̵xLpZmKT):ȁIÀ7Ig#Yܳ`Y!:Jo mu%ϋoډK9i5=|pP]|z$`jk? HCĩ~'2w>TyGTRjZȾ``qe1c@Y:br4,:Sx{yɹ^CG&-#.Jw#i;[v# W -EfȾbn;XSfQVUV*$a43lkNgCPlu!AͲS=eD!g;I`gL߉ʉkIA*$Ydxc+K$W: :] >XZ'm#fZ'cm?KDʛ~\s+q/03Ah0v?vVB ˍ^erˎ3߄@ws$"U;Na c7 10bRCE'9OiԧTcB/{!]{$rɡ86GAyO++Pu7Jj!͎t4[xQfvk3DrѓZ%>CCnG7MuyyK=X5B`A\NFzZ6ut, 鋹:Q?:V/;:t~\aڕ"Aq)ޘoe{sݥRӸ[a33W7JlK-|ٴºq08ݯ *AGEJAsyUIUXu<׫̈Dzq=ZijW#poOɏHcUv7.[mwDu`X/h l SP,^2~{x^4۠rfP%"Y5{n\ *n+Ua!'ɷT 4 9KQ (5 :?1ax[ɁI[By&4j)!ҲC{{& =㑅:$Dyg^gZZ,v>ew~ vl1EJǬX˚CY"@dx& F@06ADt&-"a.^(C ur'Zy/N?ɣ>ͥ+l>e>~B|=/}Cb]@V(+1yw2*o4r嚬agS4Č}8*A{:5O ޭ]yǦyDyXߣM.)ܚ"mV'~cѬ| "һJΕLH%Zi(*ޱ%g:װK M:Uhr!~(uMbꔵ:Pn\M\|^g}[kGP~.{ґzQ RO;bx2%soUZpʎ0uR WLqEo_4y-pg_꽜Ηq#|ǚ v2&.ZZOǃDhOeo8 ?nC2˜ _$g5'j1~D u\@]\tLز;}`pni][R#!a:3 8YЬm hCn?+9*PjgZX\Z^Kt)kCHvŖ{U؃̩+v̀nPy.b 9_Ҏy2âZ+ў<}m۵pU'qH{2!҈.jM\\*F/F1?k8s6ZDerhR')D*#yk[FmZ43IaJ_?_">^-.sWz+-hF22ߙ0#ZHd%]l iLtצs#<3֢ub~u̗czc+-36=XLHE^ Uz4w[!H-8t Ggw_x&5JטwltD"XPYE UO'ٴ ٹwJ<5=r [G13qQGg,dF1Z)]ҁ;X8)Mv=ʥx@4Q+Df=n mr0JlMu)fi`,`?`d": &J(=m:N0`\E]R[2Y;5.Eh(sEgu\(}@w,?T"ZZlS%C MӪ5Y!u&{3_$T2fԏty;Ir,Z]g–R[ʝC ?Z/^J/WqD3s!GvZ`T4 6:΀'Ozؔg-C"s&L{ 9QJ޺N!p0v8VE<"Y-A۫f=&jxƑh. ө vVX+}N"\)ipCkw]ZGuQ(8i@A" 0"tG Lm8a®O:3Z؉kL^+]ESuKI/n*pv(]"l(dP( ~>N.C_[)\ð1V͡>D%aJ4єל>84jnFP暁;(u g-;ptas&EjŕTsBdKK`8 } d:g׾غ(}Ȏ K^o,@at]`JV`b`IWWue[ ԛ 0*>zp3E\bH(Ju-`TĨ$KHR7iYaƳDu _gF:N4A:5d G+mya\Q=OqjwMF0lGȻ.4cfZ[DxPE `gu@Dc1.^@3Ñ|L Cy0k4ֻ".?^`c!B XW|NIAQUVYzcDRCTILq I kkz}r͉2˺Za~]Jd0G!Xеkv lxg V64x=&4 U*k63LL^縆~nQ\D'*PyK|Fxz _i)AAM;pb {e,`d''cܽ &b*vU&Iɥ7`Mɯ1Qh{иz=\<} dO:J.hdž /Y[bRz>UtY-2zj#[Xkٝ(ZJ:I䗨3[#j++2w{ʦ6 0oF^Z}XeVzn~IigЄ{#}IJ!T[PF}I&8>iW[Ow'p [F%/] aeߧ6S*m+Xm- Bí\7By>9Y7EsÂ[s+o6 Y7%@5lpdM-l[#TRii׍ HǮHu\`+tqPrEil0 U~uRvrrju43.R;*R|˅6|2lܾT@* fU axlqApWm- "Kϖxs(Ei۽o@lςz$ʟ`!>6FRMmI|AufؙFi] R.=~h!.S! Lwl%FYpәʑHvUe`\DGIO_TAX+s_xxщo中h\H &&Y7R$)D6 ^ߐ"XpOsf'X$Y舏H; ;s} ۖuffO0ʗxs..r Vlko)Rq' Zc[+ `݁u^,`U5՟ޞnRd[%J9_ vHmiRMZ^vɮPL.0E ub Acno[e !U(c =q*Xfֲ[G:8j/R[ ;4˚,.1f1ߓtUtQ(C/Bo!c*s86"L JxHQܢ6mpb8o[lMO!Jie)5z_$:mK'O1ϱB^๼t(&ܹ[@W;4q:(kW1D);tطRocaHBeJVL^J/6U4/v>&i4c-\ N1'nЫRiL9TTwhGfKs*i*clΗ[SgV"s͎`*hm^vn. j4C8x"Rj'R˩kF>Vý}֛@0tYi<x˸,AF- ƭ%h0Wy*0zԝ?bwqpuA>rq2~S |)xidkVZ$i>6N)cwkYU_7pšCogEIa{>YtVxv=M6 aU5Z= d>_nu2.\w_Pq}B7#3@"HŒB&> ?043u@E@`O䷸ [?ȿT$1͂)wpC8'Ftyf:j8팍F'AN\2_eoD37;wmoS[E\@,-/$ֽjiH"RSw,B1⫑F q$FZΘt#IDd bmk*zy]sFiZ n@Uj!?)`Ra;>l ['2$UaFo<,ZQ&ayFșʸavqˋ%so,%g]k)]Z!-g Ʉ?,mt ŊkLv碶5KfvaRB)뫉ދl&ehzcJ^ Zd<2p̝mc:RԒJ M*T)֜q;nqZ)IV@{rdv~㊱%7?=8126eWOsFt<X*aJ] -1?aplmbO\תIE1k ↠A+׀h"~Qo$$osXYh* v=ӆqS[€l_[5ke-c{ѾEx]ۺ0 tD]JK|L3Ox+ cշEwu,aӛ^+_È5?w s2+8C*`E,ûitzI=|C'vgbfWƄ~q]dQ&DWdwmH#A4˛}6Q(M[-q/èFrf|_f-\} 1D㼉C]w))Ft:roWٯ,+*: hNf4å1lYDyȲڽl#pN puɼhJN֟U>?rw(x辫0}_ŋJ(fGKTA̜4P˟X D@vԐzI kvz9Q`%,%i=f8Ws*@=F-2>u# } &ILhTcmMUbRGBABt?n0Á zpw_jU%4^0UV[:0 0 JTx!9GVɹ*]%E@e1gU`xOY7N]tR\'1kt:l VPTv\9ѯGZ ޡK1)\)wEJ{X1) $V|Ey~1Y:trULyyXvSLAz5T>tkKQ&Qgp|I< {kz&hⸯ7X8.ܣiDǟ y^E3s:lVчMB \qD8/E%ekxHpCϛ&m󖛓T|>a]zҨW A!n\?<\ADlGoj=:EٞEl~`3 }d[(ن;V:>եJЁER\G6θ;.r2A'M 8\Vd|eJ]8:P ضkg4'bTak]Q&^uS>42Ժ,GhC LcE (=84_]ji/z199vdNgNzUq5Ɲ=.Oo-+JtC·F &ALЕJׯ_b!hUjϾYt}cIJRc7H$q})yb8s㮫lb}Bcǣwlǘs{O“Y?yl)g+QCJma-Qj7jWɬ;N0XHOALVMtP(##Nc̀naYl$٘_ M>ti2?F/ǃNzw" )M@EGdRh9+VªW>!%W(:hס8z|YPHb6igѭSK2a&->ĆN8Gq ŋ#8o喃$,+hԇg ╌q~*MҏʂleMx5Y#w4 гHdF{~\E|s0}!6~@Ow.I0H;U&' Y60lԶiO8:e.~-H[a8ͮNO[hΡ]t E+E7C_ԢoS*!r#S5(4ZSaÿ|y|#hU\h{,tc2G]>P]&O}}LHoz`M|W6B.atIdLcU&&vY"+VOFD3jv[O`΄/l< Ӝ:mprެ ^(Hq8MOSw 1֣91I]C l̬=]5iaS4.PHn"ǮnD b]dL a _-T>г6m8v#\tW>r9/=:slJmz5c=;ɶO.K?Г/t7W䑷G\IϽ܂QIcȟCOս!hs,HIxw#b#;=OSU.-g [9~%޵>kGἢYT j{x/eVQllu,G }'`oh7Pr$h=f-tiw1{3M;thR5< ^B ` : %<5eFO;3[lla4Fܙ<Ն|3݇aqwO֢4^ڭ3;!n*ı~SRth|Ө~->Tk%}&{L9#i,qлJ}- vwK 5DHU]*F,,b͛NLb!{LT~P:+̞ u)$b[m8/z[r{0N\({?,98:yU/wBZ)ŊںJ/WYɰM=~e~'0(̊ qxsgy I̳X82xHfz QΦ"R^ʉO&퀊/ ;LkyM,1Z:93"fi~'ve5X}UybcD@4hJ,BBn[r!9wCסqW2Ign*wʉ(jJ{&aUomS=H83P%}wSDXa&mEÔ\GmeQH:]Wj~W&S8)B/"@::l ج lU,TשQ%$&j70/c"fo\ 077`}4Y}q~>KHApP޾zGU+ivLũ7|̈Nydqvd{?BgČ"¶tPOB8=}:Y9 [jp,9 3ǸpUGfFͪ?5]uo+ Ӽ8pQ ZOr}r0< z* Ҏ!h{9+@Ϻ:,B1θK(ٝd(?ڷ~HtV G.}V^_[T=-#(\%:.-w:SFt hL`6jƊل2QfgP15Fa!md#a+z]%t CnH>G6 ٧LfXC]}#hm*3plh쁥玄0ǰ4(*LYw1 F5&33Nt*n{[ 2z룅o)9aŦ$t3+[FM&ֹ*gIr9eQg/Dwg f՟ ={ltl.2@ܨ}d::le MOƌSTfpY{3L 0X[YB7E" zL pTGkyX}O߈PUɖt]qG tۏ%pSSk34_j} [se7椹`* ߖ`ҎBԊ({!( /-HCYƫ) Q!@0/3?S3uDwk8### ٠yLF5l(^s>' >ߧ3Қ_>K`9#\۠Ŕ{v1SGj0-Y:ގ::Rq|(_z{=(P"Oz?(ouD*QӳXΦAeϔL6*( &iԢL+ms7fTu{ 7kHS} ,0#~WsjwJΏ!uN>|>ݍiojr&;%gN\Kyﰹkt6O*(?y6cl $ӁUvn,L/AikoÑ`4<bª:%SY8ޤno옯3N E+S'k3/,TdWҐ29}%ȌK}'GI43_Wi&$IѧߕMגJV`s 1+_-r4Y@A$a.ʢ#v+Zv1&) Sw11? T)Cry(i$``w Oi%1Xb WY%2!7Ѵ<%mM:S '+(~e?Q<#UBM<7 ] M0xXrR"Uz!8%i0+u9 7 _>B? Ý!b$ 6@ 'xX|fNb3p/H_Lll1!c(s @bR=եUz)8gzICdB('p J 9qWѦnd]F E)SBMlKJO< }?v 3Yt$z2T'j29KCpp/)#!\dl˕`Rt2uIS6YMp|/eۜ6Oyt̨paJpSs@_Z^n^2`JLn@~G~bbLLhع0O`cw"g+K:fZVv?&,6MHbz2+CC ۑ&drُ;k̘5}ssu'ޅKt]dXaM6sl @pxV B#2uB7xPLz٬be3&jȢ~0!d3q ͪt%\Bw\|r69q ]YaGWM gGMoKډQt2r5$˫2  s4UEU_gX~7YFŭ]v Y]/47˔/7( nHO[g M6*aBRj)tZE+ z4sg bD{\^`oevGL%,$t;UۤL%Acv? ʝ)%eSѺ9qeC@ѷAc7DGyH"%;'ʏ 9ϘFI/b(ctq) / plk?*Ada)"7wdR3:׎}ѝ Iά'$\b<]A3eL[v~_eKn S#`w.0NF >VO EChW,jR"( e4?enhCЊgn!~ zn+>=Fbz@\[h`JkDYH0(~'ְY'K< Rrj>W@X5kEaN)a,l`FV 7;}J`&QYI/wtSˤhj}?qW{RHD], zL'NF;$|9ZOD-\ZAja 0p_NɍJTaʯ%0QqiU5~M>b*:o6_(mm ԌaB֏1]N7K5-; TNj +l~33 k}nJJQ#-);'oTqk70˼ Lcis}7 ѬfO4y+s_yϸq''STTMaeU1#x]#߅ס|hDn #֙4GTrZ O9)O=@ Jm-h&п"rF_v>*Es ^f6|aW%@E .*Y"Xc48^s=kVcjCqgnZꢾ&*쉳yV׺@*Lj",ɨ&r{0ޤY TN0]o47vv~ÈŤGIWKðU"У6juqۭlW-[~;\ۧHฟTcm){'iБy0rxů ;mp2O€kķ,361#CmhjdNtz >?dne: }uW])ѪsK|me1q'l½ǩaT6Ӱ{ 7tEBD̑8wmwRpE-T⳿)Rڹ}Wߔl_Y}x\9- *9ҌͦC~=~нskcӽE8 HqeҳFufSyf;#?D~2T  (0ČʏΎhC<[C3FKIH%E6orqEFx8>^Y…~b$o4$mݠ)$Bɼ8fm]np#@/K/]E WHMܪ!bxEJĜAV>-8͢٭G BdC\4;iVٟzL,fźn"g=~lB}!ݪ ~jTNB4jQf&"~.1'G#y%m= hzTr|ʋ'y뙇[vi*0;n|=IXP0j|&`贵YN?3=jv8?STH:*̺0@IINѻT|ܭ QBFkV˧F6pdoufA+'ZmߪҳIJZAeϪGn!fLL]wx,bjhU5RA`3vK[%&? ?X&r`U6Na}΋7bm%*`4IplYDCֵWb QR. [xofSJ#(S7]h%A6cǔ8eydy>7'~n>9sӇ~:Ƭs2̀ɟ 9ZUMGa:CRf",/OԲb>*g,rzHf|k+8a ZE6AxaOsf >ۑG@D7SsLql/-! ?ܬt^ftuuBgX7~Z׈w|_j@R)З?cdUmDF pYCWRb/0N q;(ܸsنt3/䷠@Ur)h5BՒM+gJyg_eT=RF] ͋=Kj C|bTߌקP:D=X ,XZ85WWaB iAރ]L:m ̡ 2g)I#rKAlv*{Ŕ-4m OTSCt卺S8w6Vt(CA9=,k5\>Df>HGi<\]yKE{S*Q:e8Î[E_̎xA!/ tB=MݛE>†M'O1FJ1AYi|-q. JW߄}(fzrbv]h^5vp$"Ґ'¯RMJQ.vL0,jOǞLGi l $>>KQYf  ÀrFEj:f`q?-isuG[,qB_ `ߓaROmc]A_?^q$CZbR*ʍRs ~;]-eN9,@Z.,xw>Ky/>%Fq,kjckv^O7.'B'ά!x#ƍ[.MaTјX>T,kZuev~_WPwDJntK%Ϡs5(Lvbs--#lqujN'9}W'\3b4hsHH l6vřl*Ed-z5a͊kVRdY9.q ]ACAnE'h2Qfy+9ȴlt!3Ε]F7k$kdžGN-1صDs)e+yFwT~RSv!Q33E}`hǛ%aAj6v|.9BZ-t?`t'柾3@9HKXX\bF)s_JVW6"V}xrA 'أy,_bl;-:e67&m0xL퀄`ȠvIѱ4㋷Gni&IΧ"?6BwWQ4j]b uw_B!X X琔KŖe]-?\xaCRv76{hi_j; RЏ%e]jDK^[+<_|'JL~3-i>%>D};o2oV/Jp 1؜3mj.ɞ nVi#轘W i۹PB9Ÿ47Y١Q4;`E~ߡ-TIv t0H7)gS4rGD:כ+`E)ub!,Ff!}Jr7Xڧk vA/b D$7T:`6N S"_Fu&|йxɼc(ѻ;ޟ;vѿ'uLXf\T;ѭ۠f>MT& ʵ\-{3Q8&w .vA\j@eܠ|2DOmSCf,TXbzAv|({nVWe-Wfa*=\SVŇL֟V 󞇆Qpreס@X9dzH%N\>QB?? IM9&gU;gxGϐeVpN?P 2P=RDXAl=r?INmf> w]= }~AHuY0PؤFcH6d_Q%OwJ MScZtDu` :8[5->-уHj1*[^p!V| 퐳/bIRX}2a]M[KDz)g:nj {\G{E6R56<1#PDZPK$t#[PйR{ $Q-1FI99XҁA>TS\28<~{N Cn}v{u]s=3:aXZjc%|лY2_6W_G+Wv)b^T0 攠#0;>>IhYNq9?eS͝)h{iŢZ䗑ԽFQB=8cL#‡4UAηE" 21@F jBbMpŹ|]>l FɬQ e Aq>W *wun"*o @0J*atHu&PuBABqQU[6&W9<. 9ļ ii?ÌI.ʴ'? C)OB'r$ :U ÜT;JquпB3{+[8A8Em(NkgT@m,<ХdpSmJ5MIRNX>ru?h=H8Kx}S$⯀Ҏ6) w K?9./^K;w." er?+<έ` 1jdVsXʝd+"I+Rʘ?"JkGf5k' h@GȆjrp^k?BLeψ*)E)uA ػ-%LvF{=\`m`ׂ. z Ef_n#F7a~.2]>4 3eڑ!/nY@%[8?2/BCAQdCyKӃuN"mwC N:b~pff%ptSK"0:2EFs.™S23e("Cy_Ck&;­ QE9Tꮏ#=n> PWRARtꯀՆ'{wZϻbP&6y^S= P)$ah5^="c[܋Ӓ;JcJwYz-҆k\?\˖/A˙‚7 CܐB^eK#B 8=q#ӯ6k;~HJifl -Ȯ0hZݥ;4Y( @:M}-cag!$'~ԯmB PAZq , d/z9QH}YV_,_y=Q]2q;XԌR(n"46~¡Nt"1#6.VsʓK![e]m결դǙXkTؾxDxBpm>.Ip(>k!LR{P.~NtR,l<afnJ# W<u_va+y[0* ȫ? >*׽[ ks*gs=dB3< ݡ$fLNz9l=-a(A^dKϬH x{ĴA@YX"U&sXv:udS$M/<47Y*@IJG=Xƅ8Y2_ 3<{\oStk!1`˥oMEr0al8p@H`Z۲&u}ulEFKe\-1'j_!f 3P5NcR__n=(U֮KEG" Hť, [J-80: 2Nk͊% UWs2, oW>Y{KP[ lEyYPW^+j^hdW~@k;mg{`k)ő(8ke#:.-L@'ٲƧ6{ȸɑk]7l_2 SZvgrviMU,Hl-<.H1'͌rK($ȗBay-@ĚRl@QecVvFc2f2KgQ: e Xsh7,yRC}b JK9m[ h =X`|?!M+(vRk`D%g"$:PD|' SwKxqfbFӃL%TH@X.h`dFЍ",̣6ΩF6tI4M0LG&O6BWCޏXhQ7_6ŁP= mZ/̺2yHi-&ݓ}9o O uyϦ*KiѲ5^gla:Oj7:QH4"iX4Fs=Ҙߴ/߷#z HȪ&7u*y3C&Q9xNEE[՜J+kEl)o!iY#< 2Pp` 9P&^ÒR Z0ޱ&!V$yNE85UvB!t N-8D9Ŭ\(2vksٶJR6rRk39Pc"Xb+'V糈1k}LjW6SNʰS9USSC&d3 ]B717#/H0NB$i?,n*XM.E#wn(]sd/]}0&γ Sfmn3RcvyؖjX/y#]tS {_o@#B} &!0./ ݍmcCH8ߵm&f^״?dj&U ʢdF9P9ڒOhPYxU㹍^IXŇąm`YFHiR֭Hw5jaTTo5zG9E^F4Ž*<Ǘ /٢YތEC$%qD:ܼ­.nK8_'>Gq.-vzI% &lAtjq$i6~̲2 [q'xW1R9qqZ`Eܱg|S*E)6+dlJkA@~Ů5+Qo]W ZzD\UVү ~YF?wS"`׃uMJ| " t']7o7Ǘ. "uk~&ρ,%$B|IpBۥ>.MPnZ,C!F - 24lj#ROǡ}[?]LH51rܦ&ۥHkb6IzY?yyۏ-mgI\I PBP2c2zeR7id N `Su CI/3YO+puiMҔprUh9_NGz^\+!RTOF|3IoT5p^X%>p.Q3ՄRt=-)!hQ|SiYOI&Z<^uǁbe%?FlUg*\+qv\vsuK`LkZB:mࠇ+a^s8&d*m(*[PUvd]ZXS@Zg{\vBJYѣA~9oO?l728H 9G@n'zV7 h#)@GtnIM )9x^aمi @PQ,LypD}9%efGgL^@Ҏڵ{)nB6&(_h8t(?O֏Cʼn=E s<е,xa4o~!b`԰'Mx}maOHv$?fi:3Fڹ _"_8׃.+;o`H FH*ewoF$q˹" Qw& I MCk;WˍcLE<~T|w.[@x7nV`a &/9?b1.7r& )cC_}ϓvi9Ygy҇t1 mE`~:ci'7,̔h*i{?v\ { at*ay HӲ=Dmh;$I1HSbDPzTӧڠzm=:Cb[ vPJj,ԘʸSNFގfj|kLXvV d_]h׻=$^ʥJ#y&~r5GY=L]Hyn Rl} ^]ckIAB(l]u$B(`'R.7v 676D/DgcĜ<\}5x:҈(IzQNA{Sd@t=i!dι6 ^&|Q^8t8[ qB/) o=4UAӦGP<#cko go[Zl[^ة؇u2b .ed _n6| ,&%9Dzz$4K,y7[N/(cfa(UJUfDFm!° A3BVe6%fҵfC>t}CZNA%;y@^GZtwNjş=U2CoPh;:D!݃:pKzx9.L$gLght8bSfXL8),RIyQ<\`Iͩ_)S~G?4&4S%;m<Ҥ&7!*>]<UY)>!Di>7wXV E`:U}bHP;kmQU 횈D6p(lUêuuc] q nc!0w&d.Ou%Jd:GPDkA D0B}ZL"&pS6":RvvbIKGPhݨ8Fk 41 h~dFqr<7Mcm&#N7"'@kOLMa(i \F*\JJ:+@,XLp܊_  `,`LLXz3N4F#{yWl~_05l}>FV:X:6\\sYez A0bu|zd,EDKμ|96YQ BB ]+<><8C:aux]lI @l,z`B2C3]gX.mrsߕ>/H}/X#uaO . z;4gidC &!kS쯡Q)쮷uc2+xm+H ֮-'G6Ĕٕ*:*gDn\*̌G&ذ/udy"$-%tN5̖0v5Q'z~6{vi%=ep&N:Tqk+=>FFe{t_AO*Ƽʸ gZ)-\oKREïlϙ}8)@4cmcgNoq¨LP&ìOs4DcnҵbvQ|Vff]St\2q\a}ИNFK@.G;FڵQMw6tCe# \W3"X?grH~XO/)3Q}FѪxE\H+3]oYZs4)!.bwP7̻ı@wq%paSj.B`ku ϑD2Y,Y_έ>1`Ҏr ٖ +ލ'&'Y$45LlZ-xMYۈ;xr4{r/@!s/Z{cUN6Sͯ A,eH) 6˰vAT\+of5:=XChwgrY' +1ӬDww 8nj}zCpޯk@Xkkg [ơUhsEl]5)W_kapv% 6`s@r,7F^½f֭yRGlP(j0JCf͒^F.bh׵~=ăFcs`zA4vxu&ٟWh̑a4yH5آ'<^uƒ01-ikgBN>ڶ궣G֯"B`K!uf8HP; {ң4Ի0T!% CGW Cv_fRp%:kav=ѓV<) :U,vHEٿ}]e>1^CFJ9aT{ ]{5j+b b (4 7UrM ;bC9?f` 7bHTU)d<Rm\ 7N@h7 S_s3UU?M '$M=ɀ8ҧTB_uw劖,FV%@ޘQ ev~'ɮF6ye}9)b|vDfB~[uRM{T,l?%aqav}b͐˚ MĈL0m"-ޙ_>Woy5okRݐB=s-燿feW |&d#g1mTOE:L#k~6t$YJyTΊ-߰&@u+7 `jӄp^  z5Qf `W#h*}60dESZ0'4Z=sDS)4߆ TEB]]%sBCNv#-ÓtYXM>ndkn5tحZiJ 9=pDlՒR}=QC7eLޑ3_Xƶ5e6r=یQ5pY9!]W2_ =(vANjJaStJ"ЎvLnez98JZyE.Ә%.jxXڌ*RGRۀ3B'@ht~e\ShWRU4-eWȆW6^2i#,}&0_Y8LPn䅟IZ?40P-ѝj QPa)BQ qBTvX{-AYn - Fz맠K?#Ny0zBҜh@r5-jZ ϙ6hnmKCۢ#J )pyw(@~)i|`a{Q| GK.??jl17IKٽmr|{|PSWcnx aew UZ)ga÷ף[.W;&4nŶC)xX*pn0( nc?2Oˍ;7Lݛ7%N%S _BM]QG[[pr+z[C0Ӈ"nmX]5yp|mBq2woFRtBuLG$ |=5.H;"m eO:YWhf0`tJN늄217Qw(ڷHcn5Ex;w)6DwP&jSumro'mHP ~-/,P}o5m[۶mWJ7]>H+WsQGr~~@=Bs%E)GRJRFZGla=߲bL!^2Joy6.r~P[GRe,\$L*V\ҵI jbqKN`{p½a4Oxfd[!i&e `^ ք<uS#IYWt^T|n.XKg$㺡GeMǪLwqVSH[UK-*>6 #/&c{:=Ƌ"7&I V `^t nOxΤ}+@ÄsR$ v7rrPnNm]Ir׸h*Iq WeM?zF#3*gc?v6&T3DpKGVoLWwR[Hpu…}uoENʒbrԋtMD54$!y(іPjsฮߧ*wKryC՘+bi|6pBAWrUvܮ D6# ]vk2%3Ch+ [nqom_b:wrHAYl΅.#  5?կ ޗDWYx^dN2ўw. ۓP]2Dɳdh-]9u콶<`VZ w:rĜb!}Y`QnC=ޱFkݺd#3䖔u 齦*W[|:] >'B|]AĄRpmP!&|BYIF8$j2=zur b`coMP(3@Ŷ;Sdf`tŎTur [e\D T.8.$3;e伛^BN칮(X7Տ ,aj0 W,2 pH'rz.L.g7:׀=GKѐEd[۲Fffk62L_BYʘY0dsM LwüB+:}qS%J̸LlZ:~/0qe{h!J<%b~ێ3=+̝1܆HpV ׮3XkmUXEqL\5=O5;R+(+~.z D4!%cˀ7Cth`"CY=åM_Yl qhȞPՏaozpQ1b`8vغ W1V;5o7WL[ 4ěKxT=k3!8-7gJj>W7yVnK* .b#NO$zd?w%`#Id#+"l iC`<kKBHhyтfa|9xM=mdNDvi9߄Ú B3,C+2a1tV[HD-B"_=-:2ـKNg֠o45yԡ ufz$ƚ 2v[eC,9>pz)g^=B .gm678v|>ibf/eC~-~5EȜk0jڝ3m{lMŁ yƹ!3=97rJL0ȋ8C`*XlN|D)^mK:F͹FYI!Tƕ-MyɕSa`;,33V?yi jӞy 7 a)&]ۙB߶~L{OGY0JlxQYUT-sj8HPss̶DV)<r:wmLPf׻>tPsO96!d(,&HXu))Ս~T["ڽ{n!,#Ve&VtH~pXIs-K]rY@$"LQLTcET KZ }_>ŀSZL}@&G3;A&M?ӐBHKEW_jiQ]W5=RGn]Qm\ 0%,hOd[P%_vAkrf8ir> F[Ѿk*|P*j{R53B2:5 Oe[LԎ 6?_4/EŚS5!%6eu7ň@B+6&9̀eG⒈7y6׺![}}\ hEk]|dtY^I@6zIF\bOJ Q@:K6%%H_jdy#ӋVD-W Hizo'/)`#s}K_5oW0BV>Ђ.^QvP$Bѥ`Zֳ(}瞲hZ\&O>-@/paK-ydi4R7*\b-F^17Hifط i0]`٨(hG75uMlX={hjv>8lyfCO f%-q?Kzj6}a؂|Vk"7[]mJ-ޡ^wO:6U&q~,>GWݳcp`*+Anʄ>M:ڲ[ȌQu5Kyo~22t7569c+MAG JUzk$:=v X'DWD0gH࣏@Aq38΁S#$W^n@FDåCOu=aOg'[Ft6^)Qc=GT8\@Q~x,Sѓ^7U؆'s9tU[m %MɮcNYی[W^?d,دiS}5>%3X| Q}j?^[I `xKUr92hJڂ^88W\O5W> EPwp%&O`X1 ""P30oFI;bJeP B֎vc3bdɠ{n1`z 7Z->& pso\H&e _ɶv.q|jf{*0kh I)C`}V*4y'Ͻ*)Gu9NΨ}MbzjlQFfgV_9Oc Άw%*UhyAk`&ny~u"}e:%bTۖ4; ̈t+_c'HDOȡ6ʷݑzā?)SWWG7ɔy&,7ٲBD"`J1!FȠB[o+)лY9gMi#b'jlɾKΧU*Mv\noDX֌hXl2 @o^t[>:9>F&dj2M曊փ 3U`Ærv DE CAj icV7Z>0SM[S8 jA΋;2l=bnex0 ɰܓZE:=EJ=L^ܘ䃐 Y>)oF7 L* j\dQevIw:=pmyx:h,+=.ؼX?xc b Mnд/185饢0x`p ?\a>^x_ .ʧDȚyYr;Z/ Mлv"S.E;?|y|dh3fk)@NT'dXoLGcÈ:kquD55$e.c P<.%hW\QΔH =|TSmEBMӕ$7G9Ss h% 6&]sJ=XlT9).5IgJ99}Ws<W)Evp *b A-aݫRq=-[GNQM\-NgϺZ7$DNȥ~}ra *M!')ʗw0 Ԙ1}kt`zpApy~rwG4 |d7l`:/zXrOȤ68y<{b9̺o{1A%=ZC< ƘtX 'u&)?(宽 _[q:-]_v rGܯSsn=I92ҒHS嘃EW#.]h}h(\TH4C+ٛ~SxQ'h(8燐f ;&5Iߟ5%]v<3_ +pkSFt v}lq~SGLۇqZ/&2PNn3xi ƟN$AXn}({ypq5~;AcQZ Mc/ܜĭI I'9/~c?Uٟ&̲e>Qh@M6F?Pr\`= )h$L :z5DPiɆV9ԜgM Yh׎?t>Z(r8 \VyGH>N裀A~qj )nEcwUwخbb7w5ϒCjZbٞNS~0c}8p'Sݤf9ɣ+y*Ggto=,)DNp$df8JPq>4HsO>'%ÛroadRԠ,VUWܔwcgñp:`;[D)g%6d 5 hF/ԉ8cJ\Jv$ݜ3R8U? ht[ qBW֐G9% V-y9@7W:6.^gʎTv,l!J8Dvez!{XqH^NQHkwGz9ѹ3yZyd\ &=EC1 XU(SOjs97|\YeMNrle+t<_Azg]vE il-.K' 8&Ed?(`<%t [p?; JΤ$%˦W?2jK)@rշT8#y.h%?)@(N/Sx{F*c~r4[Hf YA$y9j:?4J_մyP!Ȕm2D0]g|؅^yMRyM3M9IMB3&v0=ׄ;(-/s* K0No%gۑZé+2wg\٘ͣ4P apRtN.4v3Dogu W7,\Jq4:xz4~7v 0 ~?ss!ʨ~+[?Hх݄bA9vc *M}V^eJ Δ4)*["y*7.`zIv)]Ȁa]KΗlȴ#D[5ڢ5QhO1)®_r&APjaJ9)W.ˡQ%>d!M:[CwH@ҏ-~o%&JI,|G}N_~ IeRVBw+Ƶw U['J$jhi)\VL(ă f/) 핍%>;1.tGydts'}rdw%s՞tՅp|2w5sʆ{;Șf`Z.cԎGN;z=X Z .ɣoqJ8,%mc$':'T8^"#R{2: Oz@/HVnݎ4܏Ųm<9LO{]9wuf SGu'w?Bi?IzLuu]ސ/#" 2=Sΐ _u* I<4ݥx+5RеF,Eh>fya߿qd5/h HǛN֔ 2 0h푾W?Vs \湣r?j"-(]z %%wR<ɏ0gs2m5rG> \py" JRd̫'[; 3-C8] MNE;uSy:{[^ dlBoVs AHLs[V,D.yȤG4KʺjL?9MF0Z1S J,ӴJa ?^תh"NNGdh[V~] /k@/#Y؛~/|e)"{ma%oibe8\+O(#-ccV/+)ܥKAQ* v.F4>i)vŻkf:WdvVHP]|پOWA69> 拉|l:M{Bإ a30<6m`=2ΘQ7aJPg5x%y|X09ai5qѿ%)2o5z&\'sF:ȁ*pCeo2yeo:G0>0 E}Y|@Znh ud LH2ܲ%ՊN%3KDAON+r=m<_B<'hl5HUm4 0q7|$sگGhXF+3a$ZdR:)#2mkD4nĚ &\Z1H)zoJgdGawyI5[܉,skE[Oqg37ru6(і_j F@+ ,C|+a[,엵aA(G7|}z$7"j/PS\,]7TƤ,E  G"v,%'~ ri *+Pap·=,=К nFJQ&k{tfSADu!b8 [lkFxh\s2JA8W#%S! 7_K 3,'Tp'yWߪgmLrsm̗BR:DJ-lek̿0wl: kN$چSCO@WYիt=->5br%u,U[;#-0ئZ ~e_-B҅pߎwTN.TJ>=uH_~jװoc:stnbPips%D (O\T×;p,rHu|j{&AW]u?g#;A0u;SJ%5$"~3U# ىBT.rFJ =&YX%c\:dɉoy$3AZ{0sV&<&oSCϳyiOLd)VbF½+4K`,tVRq o{G\Uv%nCi)ҝgVGxFWp4:q #u&On^ p;{;c=<qR dY2.tΫ+GjmyuBtG>r%P(@dY賿w(SB,GF=t4E,(df`*n/bd ^yFi!WU; UuQhŧҳ39 %6Xwz퓉T{%ĹxVB@>)*8eܟ"-l.o62_Dm0 5dg[Sdfq`.2X@sh@>;Z1<Ʀi|,lCʼnYMA .V l4}xBm: 8f:g:T&j w6~W;'N2Wc. V"aB|vER3|bQJ'IcMO^ת8T1 X"e#1*V&Q Bϡ?&K}0,ꂩWDmS0%peۨw'D^* N- '_`*9]:dǠ|AbjahISTVgcl¾IC?ŨRZnǨ(@@/$3OCCPQPcR樃u\{0*3 V:Fd }( -Yz!g]͇oOXvfǹms k?MvQ0SZR/K2$?mP{ * чޏ7ropQHa]\qR矱b.C :oβqmobo 9Ct\]n ی{qN@y&a߮vB/xJ=! EA8(J  &\}j.u: htd~R;r@ o띾OZBSO 1U>smi|᫦.lS \{R =qvVCg|sLJQS,^0R}~ };!Gaٖ<.1鷾V4MDox6cDVQGdXWEN2}h Gaҍ{q k!оU ZUݷŻ>ZtIB.c?0;K%G@hO2i#I4NUSi< +D8y[(_DGF\2T_S"*Ⱥmu*AS~RJ9I2IqlC#*ђ ^y[!&}:*[ޞJB$vy&y+Cl`{iFAr- `$y>1OV 0-BoR7uADH3؊lnyZq&A$+)vǪ0[1}x`o;'o‚ D h~oAD<<JeΙ,?Dz3읚l>o|'JoA%RR[ Cb N&A :ᄵMn/߯U=trkE?E%67ؖkάĦr /}nAg> _WŊT.Np10w罯("K!xd_*b%r+L.Ioq#yyx|' "PeuL>oW n\tB l}H;7aV3B t~jH$ XCrwڡ1F7yB0{/Rdp!+rTB}-he-AAړ}㾿P[b 0K2ßNFɹo^&~OXZ] )(%d8LTW0A VPiI}h0>"BϚ۩|.`_<<%xj|Ȑ"+D6sS8ћAhF鉥n jD(F=Q`Ю䘂+Ԇ?+ ^ZZ++7g#rBߺd[e VﴏU{ŏ=f:p""h)Eeղh 4g.NGLH}EnbywW <`ħSb[JtՕ:$i f/[ ijD9][cz+P :2P҅!nIsGN2 c`Q]o&b5PB`=tƾ׺q<#t]uĒT,sjMz"l-z;h=֕/jqQc'ќMڼ/5̷"Tr0Y0&gFҳcL`3.qlr5 &́:OߖvHC`>x% k~EAzc- _R3ď1l>/1A,gkܞWd4(+@BP%vX?q2k%w+ÕU"8oK/E+\zۚוE{5|xGs`ȎW/}¤0Ǡ{ED PFq ԠiPwᏵd7NpJ=eH@K3P):}0!xWE \/ѳWO)W*ϛH?<Y;ފf՟ /lU1߈ɶ:zk EaBV^ {n{2BG5!q<qi tg _guk׋&BJDV5LOb# A)QdpGCZt6x-YZA]٤A-w:MMZ.vBrُT ڭsyrJr6XE&Y~Wa$Ojeѵ8\^-LEc1W\z" m.qpҕ<[2bﻠӼ.OI+/ IœMVExt3fM+3 =49[޹K_2 ,[(/\4 3Q9UL{S)'HT>"~U& kb1c##ZaWQhDi>2L6&T pL]wBM^ov0gVzǷM$5b ©je^.f+t@'f2iFJ+oIO|6ϩ!mw4NKW?;yE<2bn:Ud#wUr6E>f0IJ7 " ISK(ȡ2Y2"݇}059yZw+>yZY*q H"=7-B\0($b3 \[YrpzXQjlUȥс,p^aK'Q٢ת30A,0THk, fQ[xB 4g w&I=S?88E؜ϰ͈}6*#ӁWWAoKȳ8'VKS8\򍜏}HMQbeN$AWK!J@S lJ(ȉ،x9qo6aѷΥ {۳rf _sGV陗.ּ! []mad'܉6u> |4mvtaٕ܋r:2sd%j4@MVvD50dv"[H-^`=*_=~8!hkx4:{kxjs(#i_*fp>)>ʑkE\![Ֆ.t^3Ɉnv~/t H0Vߧ[w4S.2}eP<8zE:DS1g{K1og LY-"kO:`H*02kVG`DdV/t{]v$ӿw:h?_Ԑ5x'䛏(L]7IN+ڍW&eW(;[mhA/i`,7[>R,H 7r'BL Sd5ni B'SJ`@r*=&S#2f *qs7!VR.7GIT|QۗW̯ǰb{ݛ/J̬f!de,,y̏'蚩  h 2hBlݠEW*t#P_Rt( d|Q:USrыA١~N1^fX^Na}Iea'Y4'*cַ֞3zHR+עxFO?8$V, 6i-\2?sO\%p k IZ@e[I?]eQ{ONe@4IIdᎧ/ tP`ҍйxab_\ڵ=9bZx?]lf]zBi=3HِfX<^ql I&wv[ŴS* !PY xSryjb\hX!]l{fm(*!N)t}9jfL4h(IM"W Sm,0C勪}! D`nEmT@BO7NFؔrI8Lѻ41MB*Z޴ߥbֹNNB5ꁽNCey+Wc+tOy9=  d%i}9u@,&V|QR晆<:r7C-zшĞ ^ F FMDJ%dW n6TUNx+a({Nu-Sp F!Pz%y2. T3(^, >ǀg\OёupDU(zK4S۹lR?)8 U.գ)\S)la_S+k_0t!4mqgWL̋mXa IrvQTHsȍ#1j`! h$[]!d\.GX,hbVo4( q1ĝ>8+XI%Qڃ:!::Q3s~:)cXzA&[-Zd- 0ȿNO&@l0oTp\"exc7tn|$ڏ[,z= SJ"ߥԶNC":ciDze vi=W7e`i< 5pfreC@',f=\ZXq$t6i6i쨴iuX+Y dƄnZϋ?ޛAE˛bQH& Sg=o$Jt:Qn L"h2o_Cy,nfo~ǠpaT9,=Dew1>q(GlTZo'&-D1LjT4^اŀb2.uA+ ;m>`RwD\&ɦ {PŲ`K$OIffAH!|+- Xh${`"1\G*vWE"!ʹ'ufD5^zbTez0":7-q]l׃)pt1` }L74t8 6~~ůZ|jSt,ԝ7z۝">V1)nÛ9wP9a@(}:z434T u*uJ?ѣM,?qC@Mu|4ĴYX-sA+4t@,]i 98(=,g3vy!!eC'mU8rpq^.W}id.Ύ$}hԱ5cpRPW1Mh0ܪ OhMCxwy&7֞ێk?'ߓ޹*/ynaƪen]C,"GT":>5l6Nx]]qRԜf ]Sw Is_e1b '-CՃzdEݷ0{^_`TyLκU8F./!_9 =LEN􂎃hCO4ʃ%)I$_Vg}| lx&VAfrYFG}Qݤg74#|u'rjVl^,M*sz;t8PL6.<׉>ֆYW(X j.8"MǗ PnkENe$/:qB z6r7OX!^"lRw9yvYЖ{ĿᦎN Xi TP`) 24!%̥l|Hp>b==Su!]x0@\hʟ!Ks7!Ӌ c떾vphG7KԬɇKG1<YQr.d{<ɲp~2`30/finb B݆%؀\<ֶX}[5=ycY!9tL]ix.5ɆZdӁ<_iFvI7#^$Q(X, Q4?0uhuzQx/IDazd{򀪯/D)ج6f!B,sSť@L59r7d"HU5^o+TG\yŤee""zENaU{w5g?C}v;:ٳzV:~9l_Ihm>'Ǘ.I)͘DhG/ޠ9pX5^/-TBN)A.jKON "d֨-{n?8\l'2;d:fISƖ6|TH ov ~Eй`: 4`p[1_vD'jl=W"j=b'xjwg-s@gVJx<J=J KPR]aCZ92l^^ >xG;MjG5 bFI ^ȪʠC?, Ms0y3^2?,lPQ#p̼xCuI$dfXCVf*s[;%&X{ܗbmeer d?̆$%`ǖ䗷 "9goO2ȹ̍GMuPc$ph "i3lI8(ICQ ֜<[߬64^iG\}|=[ѡh9IugJQ1_b@5f~OCD}@=.03ЏCMapv琬!.jlpBb<і/D㿢;nl܀d]_볅RѼ w, ҲP#jw߁8g{w=E)PrǤ㏛5 Tǹ0L{d2ݱ iX g:#tpVOnOv]Qbi 6WEb#/\^fcZ3(i3 G"T,.̖6AW|˄X'4GR1mS =y%>NQ@c"El9rpTFZytn٦N{v1^H>?gAgm~ٶi-)v ? T4B<ľ@r慉/[&G=CVl"9WyRmI:c:8~-s35 RvLhF.h 6t^9o6/%f.i؞P=e!ƞ!݈ 8\f>ѥ:J10"G7FWYFdVzl ߚRf7{C}NrYI:_Ng9!밶f_^ h350W.$$%bodq i"!YlçόtkWyguڃ&k>jɒ!T=s=ӴFvA/"}U]8 :`1oL59 ~Uۥrth5w/cƉSIQW ۶|[ZGS#;uiJB/zE,#G k3#QʽH_ߣ|,p1pDa8Vo$ña HdЏ6ν't5XQd>PZ!~`C`^7؊![=7"W{c'-:H[]?Y{KyXCCpb= SF !Bbyc&pǖQiM4s?~۳f[b) =PyaĈ|szgG(y z-n*Bz Fj§;)KvYj[,׎ie ݷfd1B8=m . h[s۩&T$DV5K]bz*BJ΍HqgdRZTtMeСث'& T(pP(N.xLZ6([[uas4//ab'אf0es.2/ߗ#˟?P*K_࿅~1^Bbuفw)y&HQ]B#enȪ*HDTM^"B8t&rnYELuh;d>PhDW 3V̄Bl@>o3+j`X}Kv3@kЧl;TA|+} DB "h%\ ZGGņZb瘵LLzeGQG?սV_GL$c:5H} d=Eg{$J˂ۛ5a}얠k;a{$i WOE<2 0{/ON֪JbI(}/7I!?n[ +ea \'988yr 8r;vHٰ^Fv5GbCn</yť6W2.Q8[#8)j!mfiAB5^`;rKP߶h;q+!C`GJ$>'uw<r$'?(}VFx:&6,K]@*#AZ˫r_fg /WF,`$xdЂP`asI݃ˋJW{ }Cg{g=phXixKG bxn0E7e/d9.S|JY_W_h-q}Q&eңTX]3U6\0?tDճ}"&&3vtj÷GAƠF&V/m~ǭU '

waR 5 ;vI A^S"W0@WrXW"4޳r`wSˈ9k@0(7bR{@H<[jW Wuv0/6)y<_.E:[qY{p0ޚP)ԃ9Ե~|ZUor~qs^}U\ t ܦjܜ[bqz+w$iУUߙ<ͼ׋%d*(]Z]fYo ^LiXK%|Ky4h=&٘ a莒{O{ c=g ʉ%a( pc4Ywf+JjDm'"(]aNkS髋|Puh#mJWZzwD""i淂t6XWg6Q7 h"YoJ8QjͲғP;:}VCwz䬼9Bʨrd&EƆ*@*԰償ˀt;ma,tG>>}EwR6#5dj3<8t7_E=C.Yڻv_MT+LRƞ$+Nl]S둖l{Li,j+]G fyrONrl?SGvbV(_in+Wûi BQ(ir vUչD,eF湖rm^/8Ѱ-]d{&޼i?PK2idˮK`{pN{/[GWwCǾ_qkܣ]) |N̵wkq]Ѹ訳:iY{ˈ+ϛ[6fɦܔf5tG[z*-3+ Q8xUۉ9_Ʈot*gW<;D`sZKGDl^5mswsɠMUᑧynB`#h6؎?3d(vKMyJljM?j]:xՃ= ^o brhnao~c sԋj%vҬ7(K ׿kM RE@,vP>%c8Wol# ϐdn|,p{]ڗ {]r_um x(\屽]J"l%mY_qaK814e>m;ELw<'MG ʙR&WJUI#[Ǡu̐Չ@Fd@н;O! )ԙwwش߸j^vq c %pbZ8!k ޭMD9M|u@Oq)4"g`FJq'O󷿖֛ʱdIB,f0,l3{R˝R +v|*Ei,e5'Ew{{L@S/3Ii9=o?eJZ=_:^6.'N]ޱg'=gpL RbOͯ*h˭lq>8s4 2KG*VQ bkoZkҥC(N6RO*^z//.Gz5m2@&bSETD|KbZ}p }p"OCk\@̨r,4  @[]%٠I+V(j}a6L)P/*}s8Va"1=\rϏ%=׮+yܹDΓ c[`J N&uq.9Wx*'3?a6%}g)=3:.._Qq%X@:QNN1:#G|w#' )~&r6NwhDAFkU~h{ ,Wj!E<k ;K1wrpp?G<2`&W1BHTƝ+ ),9eH 5ʪ]!{C|Gtc˸/ 5 :^¶yުK+-Rnf)^n[]+~M,GȎ\ܓ\f+Dhh2=Md>G##aw n!& gH/ΰ9o=je5C8D1=g5'l5ǡLskyfmߊ (ϛoSO@_cXBOmoUdձQVbb`qCK7HL`a|~C.>h it<}A:83w2/vS0~gm+&Wvr2lKٜOgA3¿/\++Y7ٜ/f6h`N8ԯ)&҃巈0$%j*8E$ *g&k+\kĻ~2>K{'힫T:9q<(7w|ڊ #&- s0CgPlAGd8~p"E h> _^gOq`?rVm5fk"]roW+42â sY4{*nHMsmtOp ʹ:_=^/ <|\lP83O{Orj'Y.!#r<#|vE$_ʰh@o 0uqz~u 2gVG@۠B>Ql] gԆ]RaxGen=}~8~cbXeʑTJѾL҉MPw=HL(0P!OtonX)g1Pe'- V:t" RXpn\^`11'lx.aiL//F% O$seֻ_ wpm]%(:$,#k>4RjЯ}MPH|d!y!pIXww"/RMI9_ꗷvM7urkwۄSa3g\Vj%ڼ5/=j&ߟ?ʊ6Fhʿ%!(X.i1`P8+ҘK)crL F$eqCq8([okW(**_B^ ,hӔd9q>t<@Jo/I%64h0KK/ۙFⷧN簄ĩJ:ףf%¨V A]֍ pi =&KӸ%9Rn `S9;-ɌLU|yDoY5s[BGCޠf*P/tȦ9ټ0P7& ('lH|n U L8kV;tK6j%9U?R߂}I/JK^7r^jkDݟX˕iƊ{FMMO2$!6P}Q_ONY[AZR f:ѹ?u$cdqS֗xK:'2 )R6]ˍQOU<ҘuKNJ|:X[}7䙐% [ac0te>gc{Ct2% + 1O_W]J}itΒގnݜgV TWEc'1Rx&%\gDžF08g(5k*E!(r12vHe2!Wp h]h)2>Mu%cx B84VL%W֧cs-魟s K)JeOҕ Y=Gr(0!1պE19/wmY0 )if/+?`~7w^WTM!?W NSRkrdi/cC 2roc`傩%z "0jI?cJHhdmN%O ;((?i#9,d" N $&cʙo]Ye҂='7\š2k s0R)o sxH>A8A: 謖W$m)uLr;i%N؀#"gIIFO~b o)Eݔ\B,e qGے[ţ偷gUTjٶsCKio xP)`ŭIJ]p=9jaT3 DW*+a)u_f$KT؞Dx5L6n#8VДܛ*t1#JG'd?C'69) e.1 h3Yėd=ڪ+ 8 F4ҥ~mTl Sɝ fU !pޚ>BkZ2#ƹ>\>A-U16l \dRO‹-m׿I:s烽 ;1D%$V}tDb@Nԇ=p}ź:z.Խ"8WM=i|67R|klwa)a^E ƌ|z &c1aܚDs`Z^Rфh>ǽ$pLl>J-47?H #py Xh|[S 4 Ǽ9rYt~sykr2'xN[aNs>57*Z8)oj 6&"iXo˜TMG5R7q~ں C, `ˑig;˫cPFisZ`_a*NM<*D=|eRT Sd"7sLK6mf f֐O.Q+tªf#Q,#nkQW+Lj#8q֦?/6Ч|{éV R*n? 8剠,W9%s^Y QL͒ՎG,UAlSdm"++͹ gv CrQQ11GYunȾ[r/} X]+0Pjp&rG,UÎYYFJiw,ՏbЬnPEmag$Z7jh'Uk }246Q)1d4|#_ȯWr$~ YS*85Yb2!?m] s=׆an2 mHt*$aK$5Vr3=iЮL^''ÞM?y7M #lÃIQ1O-[ͽ7!jT#ײ桜8>hc갲 )UCguSu%>f'JNb~j5*N+ΣwsH4Z\%끒p) ߉[heh#:0#/2ۄ}E67|z@HlN fDTN(y)7fW89/+\+r 1t߻WB*lJ.|vbO'iޏd@ܪ|M0!2>f>EH` N"~&d 򯤈Ήg1,/_l/`yٝbW[n(ixxSf1qHI%W\?'9ż\V^ Er yJ)KwtH'cX=,Y"=`F.!D7חN[ @PeZjM>ÖdsmW<|>m8DdYtSlz_&V;56 @ޒ1b7HvZ}Ql}CU+cD#Mca & hXNu:dPqzC] HOur ;>^NGSsʡwZ~@y& ~Q{aFP]V!]!MVD9 JJz)}enZ!׶wj[d; BgBR>Fj:Z.lǍ,pneMш۸ߔ*{]t=Vl4bFb8AD{H/jYH =(g QLTchmfKVj#D̞(igS{O%,̛n>=}u;{ iu|R4BD2qAs.T> F2 |6x+1|YmyG#(/ aP6;ɇ(/'2Ԑn_z[?^< :/[G1MU|Dp1Rn :y7rqP*$]9/J~oaQVN T Wb$F^?pXWhbТI:>P8E,NJR3B(p#VÌ~^J\azǙpq$^ {2Xޤ6~XA \R0~mCJ=[Z% zF SMpF"9mA L t#KaK;@Z*omɘ_b,̨Iծp5~/՟j 1DDzZ|=0.준p쉿~;_L8$OvԯV_JusA=-7BdX~g.L1"3!f1c0*F79Δohe q-ד|&; @kaѡIc762Qw1,w_'g3պ=~X{Ƥ?=':9sK{Pnpt-9imY6ieKU742g {|{Q-;:Ė{p?8 ЧLdRq","I*m/xɭc7Zy:m|ѭU_JXH Q\> xWN= [6?hW?4Ay}^S?dU Olcy x /X744Cı-Tdc$&uXn]w͝V<\+m{Yl <2? VXzisȪ2g Oθriv;0 q#w~_#כmSxпw T*ݗ;˜cn6D,OV)a6N^ѿ$eC;صN"CgbG)Xަܟb_a Az^ofɇ%C"597q0rWĕ [La_vk#r~Oޛ}g8L/DWQcR4Z?`VLQg,X#@%k-fe$h7.{0b$eڕٺ̵XӒqKѧIM봐1M$fzrI3 &̲ԓqq嚯ZL൉v[<-1ܢ3#58lV#]<&hƜ~|dWBYs~rz8\\,.}+[`QW03R9P(ڌN w/b<"8`r@CYFWZTOd[hsURZ[V٢ZD 0 Y[MN, q`z1L-Ko٧oW}giqi  q>g gb4N`3ׇZ ~sEQQ@ICEb.p- Vyj9)g!Dve…>IYr,!Suб-Yl|킅 o+xRu \!ʍ۠N:a$ɳ(\XRW9= .xK HX|"UڬFJΉȻKOO֧?y|äSy߫[#V NZ Q} RIYBtґF6rc|E,'b4qĈ Q]b U J1K7E#.ŕ(-X*%#ZQ fڋ&EMXWD`n(ܑOk '›{8e>@]aMtDԬ{(gX 駦 ?Дl;`?u_wN>-R7&`IwxF,u$;-'lyU < E/Brg##'A&3`Y~}:S[~l 2{sX?hI;=CU<pYZ\K?qB+: WaN\S;yIiKCd"eruo*&Ӫm/"uEogqF!}s:Yi mgZYAo VDmۄs>73[T`(ܫV+aZML+9L-OjH G5m֗̚iW [_Ë6XmjI"Zޞ<~AVh[n{IflNnO ͗ȊZ{|,>3߯-z:?x -+TI *WF Ǎlž PB] װ~oe㗻gkG u,62n?μυ15jcAo= o@:FN: Ȭ;T.%P8Slqʴf/NX *[\`/0=d!i.V`#ArtC2lÙq`~6:#?tJ`{lh3mS~>T녕j\cAZвRܙoongtF8 N_1wɲzo ,`X-NmRLrK6ԇ ROl 깴m J +y;:"L UQ,}}FF w)ՉL)/~¿aI$h*SW8!r`iNiN叕v}#nNZ>9h|?nmrTձ9'[bM󭕟i}'32 3zL 6٬f5B0QbE87 3W-{(UFp|wg,#0\9l[b.AofVjRA5"QIVAt!8ݍMS!g-l{e%d 3?! z`CJC eGE ̳HJԆ=(p{`e Q0G.nn^YU 㽦ʐvF?}|+SQO&4/ z* ۞ Jm par2test.bin PGQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2353568 SABnzbd-4.3.2/tests/data/par2repair/basic/notarealfile.rar0000644000000000000000000000000414625637207022573 0ustar00runnerstafffake././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2364569 SABnzbd-4.3.2/tests/data/par2repair/basic/par2test.vol1+2.par20000644000000000000000000061556414625637207023016 0ustar00runnerstaffPAR2PKTZ@):"0ZwєD~sPAR 2.0RecvSlic+mejMd@*3˘J(Ť:(vHZsrXc@KAB4!2E<0^iQ^H_[a ;4Rص3p7 Up; \7P[0g)'L~[u.,S $/QE?c=>Q]Z1XtI^}x(7oBUdg=.Q3b_`geA#يNxV. ԠxŻ{V 6<4_fmTx%I"3,Pּ^暘<~}pnpsz5Bc'Guу}I}wog _4GL|Og[Ըo6Y h  &&";ڸ7zܡ DX*+6 ፬c;Qe x$P>C(ch rB )}7=4𞛗 5B 7Kҁ%A9;I ч}=:g?1@Ǎ H(BN=@Ma= w~8I3=(b3e-DaqQw ́ 5!KκfMZgގ<~a͍XNKwR9@ 1HȯHI SgDĶs%"[k,R:toжSX]=1p!UBQ~8g86-©qA,2H trRdw{A~^gC1e>KHgU"Z#\=T'OfL|Ɣ~!#ajO|\EK)L. =065=;/fnb;3@& (rW#NQIWKJ(7D6fia>oY:/[3Ujol_L05>rmT3 G=3;*/e;AKX5FJln9@"0QvR7EkivMo,RR]3j٬708]@Sתu*n%KIlQyzԪR]*p 买2J!<8$K廾qjJ4~f-~_[pKXPW ꐾ}eX=FUZ2Ϫ%׉k. 7;y,@v.eÞu}* VUL0ل !rX΍|!!)n&eyh=bc*oIጀG:b+ 6 .~Y(|3 n]3iu՝[DkW@$wvf s_aZ)q(wT uYÌD@nۉgwi'!T!_t a%{&=q0*1A! A]}DȾn$_rfIRrۃNq -}D]`^Gu,`>vJC0 V9fTiRF!qK; b<<mb9ĩ] YXXlZ@4u.kblBYd۟4 I-0XIT0{7Ȅ$)pcq$63q:$.J귐T?c(2J }ӥQ eVOa7΃,k s/r #'M`=rHW'k[uW5G'%ӭaKxܮ $K1ș?_F"&f(o'"ZMrAorvd%Tx4†84*њ^֣xo"z?WLߓ9EDG1>W47a4֘Տ}H;g$.o)BӖS7,Ǿ*'#W"Nax<]@6o|){ UBUcz:0ɏs\.5ʯ9?d' g9o(kԫhAi(ӆ)]8Tb$(.5}qn-`#j&WzOAsxhǀ_O\Z)W[$&TRօ{;>55Qb 1/" nvXR?;t+7LBs:<<&I4~X eOSBCr+䨾mY'02ap?8:0G1:9-'9y9F`ە*"SXK4xT۴#R8%=U"@ mbw3,]NTHyqm?Rx}ΡM4.nuC;8|{UP-D`ۋ24J2I8 1U7#/C}jƲ++d#:Z!O1[C&8n9q_{Օ y:S>km$p* pMK*}udr&iGa,WZO^s@knDu+wXa]27 P#{=CUsfVyŚQ8b1܌c'yba䠭c5!0|-¹'Exyt;dڐgQʵID԰5/. _Nb`1oO0yLe魪Cr80[ YK./s}mkkIy&bls42[$4ufG{BG:;k/ ۤx.hɲuɱTP̱Wt|;d [yY*^vJD̸>amr&51hM,LH&J;/PnMy!p}NT _NꛎR*To%gt- h&>yc['E 8?}~"Hı{Ie=uc~;29"9Yb"Ңv\[A2)W *F؜*nOy7i@6{:ކKUkQi 2g  um#w(:owt}f$|;qfF >%,\1{_`E=1h -e<+K2}->őZB$\?}^!4={ή4KvIg{|? >\0+ 7Ӧ\ <;ح?o6Y34XRrvd/dLc ,`FU-]ߵ0q{ 9_+'=Hjxο~m!U/B]o\"gTʹJfEbx%2#2]'[ km -`rDx|rVL]ї"j]$}r nԄ\#\˙WHw2:G\(:Hf xnhVy}S ͂H_շ=ؖZNy;1ƪ02'tP] P0! 0 /ɚ>#|i w3&kUl"n1mõ7PІ}C|=8>zA5 Tn$zBwg*Ic֕1`7YfbsI]e-En"y-pzB*BM6"3&W;J sYe4GvM T2& N6ꝇ[76]۹ȟOvLj? dmMU-hd761/g{df6ƃZjB:A9(uBu  kp:dNqE'!b0άeERHK(h4.aokA֝ˤcvp79\ E`֟q:R^DЫNA.TvҽQ9CZ4DkasIӉ$imUdϸif0vĴ! M6.Tq!V@ jdإBV~R9/Fo$$-*5Pd$ăAA~A^Ad(w{hsf܋>3Ew@]zZ K6+;E7;"b.7e&B kpj5Usf eR߼dbssbKay&D2asf:~FsRI֗gY֝x#:O^W 9u'rhyX<7 2J)p[DF2ZT}b t*ZH~akVpD17E~6W>sPwr*G}Za4m&W"J}h#ঙ~C֠ =TPUb}GBx @ +?6a |{sEoMZ}^D>ڗ(5ѹ1Ut}&]VAf `q8'w7]}Gfta ~(8f3*zxGԀ;П9'{rwSiI :Ah7g)o# $M{Yܭյ b#O-zџV+W1/m Rb8=Yp@V$h7sY\̆ k )eE5n2[䡒 1ЬJ+ Ϧ)GmkXha#!N*?KuKxÙ[59'9kjyq0j6ck̐rODfI ,H?cbeRC q/E-AD+''2__`WYR# Uq Kp$Āa+ 2\lnH3X|g _a!LelfgEȉtL/E1:7TjvLIs_͘.'ma&vD<.g^ϼ8rO{|j8 q`m[r:&ĩᖴW*@`:%~ՀvSx~#6ZE(fBvL}D Rפ|>ETdsu?ޤSvzh< 'hӲnY,4]U%VPN`!nT>3-4J,זdIAvC%F4F⏋U}w|_30˶B.x&nA!Nk5%{:D^*drH AH+ ڰ;EnAHݵgxN%wIU1 |U(b5 }RfgQ: 0Rr:>iN†fgbM:Š١t3S}&ԖqϘ?&XUy`Fw+wƟ=mj '1_8h⪠㵼?g0՟&+L/KһScex] $soːuT@ּ>H4Vk\)/g+wq)eH`0@*RMyW%$}w9/?/.䲅Lے0 x{cdOYxfks4@$3f':>]mJ&a'B-}avB/1?3RU$-N;7f̤N :`J呢GL p*đ/O' Mt<]F1htp,BN9c3G L/`{7yo;h9!IoAuArpy4ZAkl pwf4LF7V+뇿<,@ދIBdf*z[ 6U#Bw Lv!&wh oD=Fi>C/{ts҉hEN bz퐄O[^>R p3 B U\ Az}8VΏC, BLoz8 :؟r>TgZ(gMfpȋF/uLW1]$&d).GRR;'9sh3CqIc4qmXVBKm6 9Rkr[KJ}F/wɁG1 &3a=CS+p' |wU2]̈́?gURIKbÜ|?X?_ ^uN%GmyiѰrt93?KD3 S 6Wvߦ`Fx iY&R[Q)5$/|aĹ tS8Hx!z}SD? Y,a#4B1FV>``PdoqtFhsKkO4>Bz퉅R ' e LИP[qBj; ( 'دQqR|;7%d/F r 6kN,ExsaKE5\2Zm:\~È+155e@׀Cl5!NKhǜaf3҆fcsV 1#܊o NN5KMٚe؜]uA\ D0cK;XeO>XWB*s Pz,Xۛ,Vh*B(S̵|\C{!;\~3CݵߪUswWl?%udV?P:u;57Hm l 5IH̀CC;!F/˹Qi[ɲ"!1,":=e֎^|4h;m2Q!1JB6@wzpiT\umlb? Ox! !|43_8{rOU}(rgP& U), #ډ-[E|s^fsҦdNAę>[X7u-`1M {I1hD_p-'> {b~2+)<AgUךּreV&XGa9]Ob %v_Z2`&C*!vĩ_Bfs#'ݢhۏsd鼕C+$G&RVhOsU #eZ[VCZwFy=TCi랐eD:97Cu$[ 䕁Fy=] N!-!u.U]7oNxE\\@ee0R1'"*`3o;2C:}+$_>gGAWn({p̄A"˘4dfoU5dU kLn <ý-G|t+] pWwhQwm@/J#mU$mkvɶIO{pq⋢` 酟7OC1\%L:,<@[ qZVZ:9veSa0U4xzBdR#F{8!T|ϳVN5Hk×0Y6pE `R$eMD4C!u8V1iz85u&aq;ޔFhsI܃ԃXe|#SW{{yVhV~p h%WtY"RXu>%!;+7UbӇ wIMn;$ioRhJx_F9wI,d6;KYo4=\Ai@IG'wL!H&;'%krs]MzFs4f7-uLn'@ oUچ@8:`K;{gNCG hչt}aSW#oٯn B r%<#*0ꤞIrӌ1b ]2t궇b>FVh5BZ3qF-:4p}~vAV>Sr9@9}0<~E,ctq>/ uKQ|S&j?͛_=u̻d6X|(#OR|}Ejuē9q=,j'DZ 'aTuO;Df>dm<|d 2A?N1 FN@cg|S)r׭SՈ]4əKare_Bxr'ye[XG .ߎEᖖ*[O/LXUbyKt% v^IT#yȁ\A2{}.p?p=YVLNHqϼyyPʷ}\fH+^)'U+*)Q1G;AK7sl:܊Z'Cq)o%@K.|6oؕ(ظwMcp1+ĵ-$;#WX# tp{ ~#傖ѰOC [j$\Hۭgޏ9=ӆHn^:|,B%rj\,dXPsK7yZ8֚e G ,MVerEF;~o ;[}N>it_HhMVgv;%BCIdvdZr&Ln>C^l˂#nR1L;eM6 aH`q.5:};^$== D?+=\x6v0n>b|0wBB;${vkrIuք ]M˶X0@hkii]ӵX[TtQOlSbd&zYu$w|7@PZ|Xfp1Z&DtkMT-qwRMp~@nYbLCOq:z 8g[2.]ia-(sn@V8fK6:d2R,;fRFO}}FV mYm_L15\uFKZb뙶JϢ˩T$!k Dn& g%66l+AlE(An'J`A-F/c@sv>;;Ϗ C9TlxCW0(IM3rj7^ |5+odw L )Xwؿi%煡͙N,/VSwg޺d-д(ZG\j$j=Q=Awߪ Ѭ(XxpOS l@/ I#.~Ėbo Oy򞧀jYѶbR!,1|_fIVO#-e5ˎM/(+}OrԿ,Lr>ldI{I 4`VL q'}&9AЌ:w|{ U;TW = 2t@}4E&-~6׼y܌@qbymZX\y"L~R\} fBi{F̟u #*ˢ׈kyL lA"[J(N\ 50!3uC_i!gM+?L5XBknc$y{6E5gbK_)o)2 zŷzB|P&_Ab]rW5ގf- 5~IcZ|ũ6"vCnW8mb;KaT*&N_C+XRLB W>l+ 7Pۢ@q!}t Z^BǠ@7v K^a=m[ti.&'zq"^}4n=g?8U7.vo.o3 ]-y!,TU(!<)#GYI@ɀ1* Js5<5Ao?|Z[%ΙAm^?}pFSj DEۮ/c?RcuG:E*:~saH yjmU|'UI.|Nuԝ+ VT5 d,@w߇+((DAɔ #wRƾ^(y'0]^W \F. )impGdRtH`9%'46qWp.&'0햏wC 6 S*D ,Ųhg!+dq <V>\Wjd0h;hGYpaǗ#jmli`?ڢ~~>!U>QtXp J 3Hq0hܩ@Ω[^_ $0$LÔLwn*q\*wT&n)Wt#^=@q d>FޛW6[fE0P r)r?njf_ THoPBdTaGJ߾ES7 d,Wś6%$ő W5ye~Z*1ﳀ|?o{ ͚rĤvG+tNl&^%Y x2D m#&yJe˭EfpR-ߥ1Or{*R#x dϲFt(um< d,e#GE9iAX?$iF[;c?ߴ#ڌ]-Z@?M?Q^[j=NCOǞR@fh%^/w׎" oeu\)4}Lj'U|ŀ?o!قgԲJpb+񜗿p"cdcvE#tM*9'R%7kIfhhbAS(*jYieGxә79x5r0oaGI$7>px`KS`MӰg.zW&Z_,h}C&$a,8pCvm1!9BT}">&?rϓRZR*z DGECWe:{2xh5e Y>^ fG9bPnk g6=$AGiT \B@(;AFUZvG/uTPѭibgygz٩i◕w6ML҄ S8^C48+.f D>V|/= m2CRft1E82U{8XA8CL z6ou5^<*&ʫBxqRZuExJQ2%u2GHɲ#ü6 dD[K̴ ,TD 7L 7w&ol\_ ETU(߄Enu@ 1\3f[V Fp)|sT7IZNK˜hqR 4yBZ{JבѢ{c*();w*\ .E|[WGqr6vI3McOgO|wPOr˚anjS2 O_M \ E6U|FzHH%Pw}ZGec7(:lqY.U"IF ;};$LGV &gD-lgjv-%PQ@fd;jI-+B:p۠\ڒ ^JP[?-*nԬڲ9I:9Av' _d!p| g*?:BGZGKLJ͓ZL@5gxVne&Yky-l:6Mv3>p#_pIdlӬ*&KXމ4U^Y[WM${;|f-^$>sVbك/9*wҜeBRP`Qr~.lQgC/*ە܎V$jD@vz''Gy6e77AL3Tj;Iw68욚2x*3^E(9ҵAp <w[' TL;"$W/3 AelKb)^ ?BA`/)\S%Z5k0R4`נ>ϯNZM1x99>q5q#y@f]S`[nʌDq{TYWieJߑ|dDl 5w‚'x1 *R?"^,{+ cmGLűo۞H6綑s Pfam'wT9)յl:˓yL\-tDyvvVi민c[)IE{ZqUK,Ҁ)Y 1K+=r[Y)P{[034 cwĀ8;r7X"l~rcN,h_ܟA }zz9 .X ަxn=hUύ~txw$Ul5hZ4acJZҿ\RǕ@/Aw0ۖ> ej> P˻Jjn)];e6pYVi(6  F#eK4^@`\u؝lL&o3)IVujU(35G0B4B{LJxݥx]f.\ f`Xˤ@.)xi4q jJH.0$b7R^xDWAOy+wDC~*F6z݁_AǏwЃ$b^-埾& nMc8R01 _{@[wN!Mqڽx򺶅 H M+:ok '"{> g)qoEp/Vt5oҵ ⼢Z3|EDN3&V|Wy)r/TљIC2ytuUWS!T@̍ʰNԗz&?!KUՁK}wo"tYaY{ ff\$w!xtOIѲIP0Sa[Q_"l=Jn'#^;gY_GJ@_j7W]06p=:.שLҬm:e0@&HHƸvd;BV ]i;Ef%`t|?q&ϵ8tON*.uY}M|$꾃ӟ_3]ݔ;;OrQqu()eT< k >7s$ 9y!ϴżn6)x,m^2G۝@B*ka+ J[30s-F(F,Pg(P[64Ѹ,s}cr͔XDGʆlWd̖Fd1<LoLQ]Tqu.)DجI,,IuZBڱ~Fm oBw^#OARF&ZZ7%Og?y _"6䫟FlXP1ZI>ͥM RmU|?Mpc9W)x߱j=ߖ|0ɎkG_3YvKZy MHI.[?ƛyZ/ )﷾U)~P%r Y7+k9H /`ȃThE+Qx.xUIpX.%{n{`n&7Z{{]qbMHP||S 9 ̛CIzWpC$mBD'V=\Tq3R($f4'~P*aKSm'kLՎNJXKY,\q[ߣsi%}t /ܣ e*gП`*Du=|8eC=~cI.OyvBX1)hzmEI 'pV3l|Jʉx|k8_ZqR ϸ-{9VAKdwS. ˉ%ב>@O*2D"ٵUGUόN- &hPq-[BD:s#Gi_:"ßuh(vK_L9۔Vݲ,f7B4Ђw&X UF 4g}.ebs Q݈`pVm 0gTݧב׊3V4_sIYDfB@lJc~KT W0HK/^|If}Ӕ=EjdN\8Ӕgew%sJRYsyLn;t᥃J/d+raG$fNTRvUv*rFf?Mp5ֲew$GV,/ )&(8&/?dn)@߀k lTܛU'e=O (q(T5hh84F/aɐ!RϞBEH]p$RGkzI޼e.7jO(z[IDXȷ M#*Pj҇"~pn!Jk|}."B#'gҘQINKo;:wQfcY˫H^W,|ٷZfz֚9jڤn륾8z}xx*]F}L23ӺOi' LGçxXHE Js}1PU٩.0`a0tJJۡ&ªY['kW|D-@~,,s)I!mt(Fy`S=ǝ9[$H7iAɭ1 @#xNEyqY% jw$s! @1 "h% o+]X|@.>W.i|&ƃVUw2߱Ը8Ce& Q#Զ0/s Cч\-F?.dP'LIr>wvZa \탫J*a zN.94Tz(M{"qkκ"@ഢPſ˴C).8ucpl?kEH)i%ѺN sR܏ew%OO884gD 닜mAmP*b<0P_v9]{x>[½  `q5$J*Iʔw"jw&&)%tEQv`?Ge$y:YGh@=LZʢ}(T޳-M<*Sc#j]r4 3⮃m$r?y bCHbݳest\Ʀ,:dZF!|&7@ՙ :T\Bmy۰Apm<&EJl*Q:vx b-`h/dL$_m؈mH*?0!o˻p|3?qua4 kǣ I}[ םnQԭm{q  >ЦMvoWh3o9W֠,&=NFwHpɑJ9' CІIz;.l22iS^6ς;%Tì2fyl)MHh8R[)ªHm. /*84lmYqrT MXK-y'e$FR$ZX~y֩=1(yz5๜2{ű1ۅtt \r36݇O} m0Q߬|~cQhh8y} Fbt,<=Qƾ.Zb4$a:$+ j E7NIj۰NAPmLӸ&27R;T Г>fͪ(E\=82(IМMu+8]n3 rl >un3his7p.LP *WTC Bo!F6Q*v NG[D%OlHRɍT^}0X7bD՗XhqTe٥Ac8U<(ZF)ل1UU =<K1mqew%꫷~ @j|[a w1)zo6Zbb@ Kʇ*=ES3l p7_Z[? [DWM߿P /L։ՍCcf]!AHS) F_.ԏ.AKZn[P]b=\zJJ2Evq(2nؾ 9u[ͧ*PO_,NJS$'`jwfd 7J7Oʺ=|m͋9K $M #51o  q[(**`cDEuF}FVڑiww U-gΦcTz-23XW"Em׏Pk4 ;j%O`[ԹsqLxA-bP&I}Gr42M%*2M|MP&^a9g1_b8p(1!y<;=zp pM!Ryuj}[W 'S j! tɅof8\ǖ &Xr07^]?N $ʿ7e%WS3@aojz:9]>[(g {е8M^H-QĠI'Sf; +۽VQQ%X@\2[OL _q"vN>!@ÿ jP2ogG M5aQ{WBpC@x΁+絈*9jēh]UٖSYkHΐB^E|XW3SCkEl  $ Ua4GvEњ1^ ؐ-D:ߔ\5t) qD*H}GQaCC^jmA\VP:}>_X|B8JϞ/r{ahMV!cr,?&9ØL*%ٞ7^~\ߟkjUH|e;l)$\[4)M+ܣ[bx~q-i[C+FTk&+CݕflcJwu8 -Am<*#T~6!)bpY*و1\ =T^]J;IRdz\wOi(/a3f&~7OQh"%J͡A8QCљÁ>nj5^ PN> _z6V"/'5/ݛ9 S[/7#)D~dҲWÕzKnâ7`迒ޝ}Є=WAdc%S[E<+}~xlу ]۠T{S'XӍEvPsmF7z2i7ʉJ%&"sO|=Sn,,yu:Ji /qo2uK̏59ۼ̀=??䆏\ǑRx-;mn8F<~6GMeRZ4Phu62%8Ɠ%!Ӑmwŀ-9QV ?PfW𐟠(ljO~h& 9OV܉Uϫ#Jlr@, ?Tުz)#C\O<V "c BObSF20-7nFUm`zGԣaՁx6mSdﷀYԔ 69i:}r2OR*a";.Z#WbPEe }wxlNkFe`놽0tm8>ۻj}GGĢ!ފ}06hDx!ҭ.*L?[rRchK gV,S")[pߖٺU̿3e W1A"o8FmݜVL._M~UGiDy $V"^ Mf݇$Ӈ 4vjId7+8Y&5\Z0`\KXGzYzJRwE;kb\/#s6;$]^oħU;izk.Z+f(ۢ$W=\K4KSHA.0p>NyLW[)*CZfl?SͲėA䫰#= ƅB YqHTr-m W}zfnj|}uK}4@*$.]0O*0j7.+2YSt#}^&k}Ly-JZ#`ޓGl2Cf&sQ2',}Ld mr\ rUܣ0m*saEF,RV5SćFAa5ufYmRR2s" n>M{$.4QVE'jLq Xԝ&J8L 3@PAHuXgΠn{p1ME8Һ| C!ڐʠjsUt`L4lfy薑p 1ᵢUcCVkLW/˻K}9xuC4l V >H(L}`uSll֒3q3T-λ$?X?4&.kIBIK;h$h; {ϵ>Bb`m1CNkvj|^72۷`g;- Ʒ~ԗIX)tv G>@~Ia77A #z̝BLdKTgm@XGє(D-TMOtIws7!mD ~ӏ!P3LF"!9fU,o]T86B!:=g|Heqxsۨ![!1n&Nq?K9,Yj#H :\Wݐ+-Sn7ZD&2nv)^_=09i~75ĔHܭ<0)3^]M$jb?[p̭dB\q9pGQ! {v kp!D ' f8ٗvXē &r[ ]@ř9q z;qnj,N {D!0JȘVt>X |{X_ٺZqݹjw$Ncl9QVuLu%$.3[fOie%J8 kt&=y◴!qcJ%_Ndğ-^Qӽ3XkSC$n޺!m/],wqro7gXd(Y&}poFSVpx  ű[w~ų,:W;A|}Ot>1O[(%qH}>-sBȇPz^||2u^IX;RS X9J-sˬ#+2hw }0cDf (`R}tTYa[4bLQĂk$?;IYzVRl 6_ЭTH$Ցe)e6o5ƂڭM< sٖ$gIesyA4~!~T% ǯI3O/CdwhV]u{V`[TBѥw҉`]ٛ'v#| wNިݝ|F {@\4( v3 F32QCeHd댦dOqP4.7#_6]E31h_P^֢U,+y:ā+>?+U1{Ş3^:aCt8fo*H&raJT GYA|)G:V$)(Da**&VdoY,_.g|Mo vOM*S{PF) 8+y] "|xwogCa)V$U`R|,s02iP&[|r)$45x"8n*a]>5 H(uU MוѤ ZceTl6IR#gn+%o'{t p;Ufrl+㖶 # _֌b\*db<({zRy\7dQAfNF0zZ E;(Ly2K͢%ELwRs0 IrVcqB*^n翕H[G׎мsPOϦ޽F}t%A^73j[X_F/+z.fY?YVèΞ^`XtL®7ٵy^#dLKM0#.oi5 S˨RQl pCvlfpjDH6-0O$L9t94{yM11rpFGϲ3ͧT\FLǬ]祂Dy sUl1åTga #Ixi_BFy8B ^Ir# }$ 9ڹfGG䤤$iIɞzӏI@1l2"V)%(^#S䘛8K]⳹[yD{ x)Z4\Д^btq0;N"YtӔ~)N?8/ aܗu#C]Dw*Ο=9׶ oUº8D'ki;  ]?)#GL^&W;ޢUϩfmx՗sX 8 : & aU$ڰ X.T ɎeKjE  ۚGKIك¨O+ďCɝ]? zWM"8c˧8pke S K)eQnT$]˝]x&aXMfIרAb~A`l--|n%Jx~>: EMsv=q^J~\WuBAQRajņq? BL^}=:>aVg5 }=X8q c =EL mN8Txߧ\!C.9Uރt-[y)A _^|_"5Tt~*_-Iy=hV ߦ\ /6,ɴ'buvۋP-Pe-cgjyJ)`VS0G_'}8>,5['5^}qg]_sKZe=Np:arVhQdĘN-&_w7* ut.ǵνm?Fr<(h <8<"z]%ӹTL^7ImYB$jW*z8dPoRIFc2VWd)hUr!m]šlPM(pX.pd. )#WcWךL ASO'o{lSGoK1wnC<wbx*@A>#:`d$\nʹS ,1Io-3"MQ=kfps)qݭG\qlRE 9Nsc$'ObU(H0;33eƹt\c`ݪWv}}E6 o< { ]Tk6闟/FbXpMbcHe1}EK?y:o-ޡBTӤ~!CnQ7vLy1J]saCbߊ3RYO]?2B$y4֗uI!4kb<|8c0ߧ:)t̒OFzx&[?aOZ^}YDU?P쬙m)s+AM6fy@ό28=y/pG8%#7T?)>hw/Ȇ pP,OG6U:c("x|P kă 8g* !xV.{!NE?ՠLI..1[qhhE4G2ip AܜW3Z-QDϱcUF^X\9L9 b6ٍ$N9']擭)F;4%|6Iku[gF&>D: 3ҙq`K_ЍȲϨF$tM9vk ts[L3j?q`Z|zgꀹ' Zxtq 9c"-ݞet:<0v=9{/xqەTo}zz>dK -Vh. 2մ&SfD* v-wWrusz>ojCT g`k 'D:! Ht ޶@W6wEfF>ڞ+ ZG!{{[lXw+@6g8'yњX`@p'ø5FX!쭱ܒ@8lX5^FԀ9 fv)dFnȂ. 6B$@C|^hQp sbr=6=ll<\kk1Qި-eADFsNxVt,0$H1R7Y$y8G(B(3)a9@!~å0H9[c4Ŵ̳0Cb:Q5OYD|f /6yiJ! \qyHBg3HۍOE$}5kFGH淡uJfF+,|N2?M.oﰼ=%ai\#G.DC!_M' *E0y<;j(%Knl{+xIiSn@1M7<';۹@`gXp?lMLУ@K)HY(+"5Byb)ps2LrV1I qM b)vK<w_w^PǙɳFHa `BBln;-BjeVŵfQ^zy9#\ xꙻ8i-,ca(!dK,dd%SAyz/0]K?I.!:Fŋ<'oז3!œ@5&f;5=Js@.bQC~0A\(ߓT6H>*lYX2؅k @|o|hT\]Acr܃`YR쓿E2Sʑ :d-?8hS˩&j}LbȽ@- !g YDEl$dy zNM1HG"1^Rcxl@]j9kX~H4Ӂ3v{$*^q;@ʐ_=w#IVPm: G1l(m5h+>f7*^@ *ȌUkVM;UTԤzծPȠ։I:dRAbL-:Ko&|$"g+pB[|0N5.i=hBZ+Y/<{җ@@KjN>Hl'r<~ p{5hOa\ؚ9$f}햍\Ԝv69oc&a+Zk\"hl+&A.=W.cܫ.qٺ>sNn'"\_ԝV&?%,uk"U+xa)#X'J|.[|XNܔc-$WΒ]fc:%I%m,{Ek1Yd[j3sl"Qjt8?m $21 zfAkH*=8LK$YۏGkVКJbOg+ԁrm1tDn![94Wi5&E2}&QdV^dO bRI[tjNybY5O ᕨ8SM `m;5Ͷjԍ#Ƒ fBu!Q\3[ErkrpxJME3ۿ>qO%_Z?_DA8$'⼣uԟW/ CS#@t[CQ5ɰqGn9T[5W.ÅU\ EhmCb @ -{ 4uS6tur({:^V豫1V^:Fg@E}gn< [~R4rWC cL7LG;&b,.r0PK:(^lzܰҞZHM=͑!|_y+q+/kTׂdl7.*RV(+[h't\?HMKfFa_2Kd ?C6IrB⨿J|w|D q-*ނ7|j 4"I^`|¿d1~t3obu^R0r sB;!]/y#M慨FHrl)IAa7ja\nX\@^+:= hF_eyqF_0L ډ,~TW FG;l;q{e~ ա&ӿhREV]ϰpڡ|+QYԉ OHL>(ˀS4y'f)Cg]&9 WCU 3_GGʹqдw2s1q19$qUz0$c#|R8ʃ> ’"Vbkn!khĭ>Vɺ=ۚ7n4p%zND$eS {Ƀ<PG%C-$ΰ݂~;0\f)B u ?~xÝW1XNRLKD1 8OXJiA@`!A%nPZ _zLLO\9Lk3ge|0^ghj `kzO6ee{RCf,Ķw%D-O]׼JUӢC CU~MG% ZK8,#Riiuyk# EZ|IAlݵ٫Y>X;s #t"d%ttt؜kk /O3EL#6s3Ng։G]aibdA%oRR 4omrbzݣR{d9:ھHD*)6_*O eGx*E >`}: ڏ [B{p C-q2R`BҰɭ :o ]I JJI\/4k\IdtI½.#Dzf}D=mFH$2A>zȋЪPM&CW p6M)M,f\9a?(8R}{)J܏ e{?!cvh"[NV2W"|uO$HoV%3if[fPYփڂ 01VEN|;Z ivjG} v_a& g9CQ2iV` Z8y=|vV8F Mz9 AC\Yz1՗bT_}DeіqR`!Y:oNy;+'rhf6[;\x䦽>a*󉆆}HLd?W}j(@Bm,*Zk~h҉^M/u2i[4SokJ>K], D^6Ps8@a#˸_ ysDož vYw{^9{_A80RFAm;׭`C&0=@aX1n蜙"^a:2u_5 H2/O^7KiZ"Xa4"M WU7VܾvU|mC`3sAbE99`Ո_n {y<ĕI GdU,鬂Ȧh1R"7_̓I=[|#B hQz?tG$ !rd9F#!ayS AzP8`0gw0N;ap{阉c3%]gbH"k۽>?Ҹ\.W蟢#H~;$S8GfZ7h@Z:!`e1@,8lkFA)C]=?,.-_#~b%!S,J>ً]R&CAA}# )A|}L]?\$zeCU@R}Ee":$EUaJ' T&BT Ͳ~fD䗈Ng^ Ee 87)22 3j !^0Q"APr$"PZ*Yo39cs0 D)V<>$WeJ7&9:')g Ӟ5)$Iq}{Sw6(Way63KhStx!~` ڨB.i20h''(!Qvps룡s{*3G1y#-Z,~9P<'l}G2*϶“a`18n +Cf=(p^ЖqP ZJh-.P T(r]dv T}GD>2,P0@"C" rkd ᄍ?]T"M/ZiV_A QF(þzޮ#kɞż)CVxDFoP/wrPPQ_<3vY?:k f ^b!I¸OX>ڤA\B`< RLZIOjM /tZHk˻^Y{2YC+k *ǣ@,r Ǻ|&loVfF2 v#fo1`rrIL\y̓}}P?`A,ZIqr û1jJ,]~E`Q՚lxa{Vu*3*Ib;ܽiT^!,eUlZ  (-PÎ.[S͢,%*ɦhzO0w߻Rܰ 3 RXjqvwXb/#@+ i$jd{&yj:.M~!:6L!+[qZ673XO!칹}`ڜjzQ1WdA k0TlL2ݵ-DZF\9iA}3' I- ұ kgnO"WO۱8֔ [ Fkt?oNٛ}~/ -;79RBLl\Z=Cڣ$[E ]%d>^yQ89ժ],?qe,^44`16)I;be2W_ucbjTNݒ\0+x+2SFA. Ž?]"x).Ei3R-9evT2.g*SmDi\[`YIIA>ؔ ?#I"zԅjSA6FV2aDܼ!;v93H-.f~ I^ 2݂nODiэ-`G; {"-j ~o2A,Jv׸Fmc2X^f`"+T &BdCrۜk>J %QVWd6W4zH9ۘ=|,qu ϪGsiio&Z5Q`?#9)O(3 f{r hx )^A;J\}u_<^7Xr #o*+Ď<v*#QpPtN띞D9OmzHJm\LrbB Gz}Vw'e/um&^," ;prGI%QϷXש=Nk!ȞmaѝIY嬄B=`dA5\˧@ٙQP'5d`lP5Ce_QۆR<_I4䍴ՙ^2%Βe7QzVh9hٌ6ؕEUDC{PSGh@;aZ|}aK-P~ \ /[A5F8 ZkB="n{4xAtaySHϓ8{DrH?_u0-@~Xħiqê?ޫXM~ȴ|kI *c$E6AX7(,UU_*ç mtY>^vSB]@o5/y&LڬekSjO?йNwgnPQ|C'>B? ڱ M)ukVU_baQ{XrگojWy20^IhE RHVk`Kt$WFsM论8 :-$7Z}-+ڛa$4@ 7N$GWV|=Ivk`r,N٥KBCve=kD$y 'c[X]y8i!j07dc~Ƚ<с:ܶ?5EVd.4OYuq Q96DHA0.Lg/(_ȞP,2L֦R:/٧'ye"3rmdf;(qSj\!S.ĚOzskߣrd+hq[slI|ɴma1(SN: d2?ݬj>4 Omlg3#mVN[M~jō.*n!ۋ"/m|;uxΒfU$P%}O^q:yo2`ҙ"m2zbW_ Q(>5A-~[2_-TKAD+a"k )Ty!g*Ȫ$?26) ܕy[|̷ č%1>^'W@g Fb{S5?i5E) [`Lq(*#ɋiF2X5AU+lX@ǞO q: u$-y֥ >;-{)M=e ~Sl+'g;(&L֦` &{D9bD77aj]¾)['ovX7d?EyajŬÖ{ZQY_u')K*"Bd0?ena9/9X"@}lQwz.pJfymR~9s@ԂF̱q? Ӻe6eo*q/<-Ž9:9@Q8IT#h+a"JJVe2-ҁnd xN;d$I-pbfo|S@x)Iu 9jUv}7@VZ1pS"Q743s ;rīVD/Č3 L ZEx`y佔³JU%x6FT w3=[^s|wCߊG&`[#4C}Z!۱ڨKi. ai"n6jS͝2%#]7f}SDqkkgWh2"7xO㎹un"T& *w^4Z]c甮hH4^2417Ҽ²+P t~_KEO\|e{Ňh?8%pu )6yRܢ` '9ůbc4UFa-B:U vGL3<"m鯅1̂dbl֤11 o@L>Db-nbvgj ` 4pp B"$˵ G2F9l̇A)Usa՞r*+8Z `` v^*A]'tHak#9>gSɡ;vꎡPt ڭiu(khB0V`#t;_&/-!vkG01<34Ykr41 Z!7efʡwmG-U0Ƌnfduv!@BN+->o4P6ܨKA}ఴ^ó4~v/VeWg-z0]bO8-w>/,2 ,kw,S^YF %qU~4|ﱌj8pJ5>ヤ UM= v.PB\D@Qbfn(MLLT+<[s$IiPq:@bҬ>uz5=t<| 'ɕ7 aĀؐQwPrv"UrǬ6{z3;zz:ȬKR5c=v @L_ D:5&(7JV9~@d6{:L2.B^)i gA5?6} w(5͟PTU` `K(x؀ڜFWQ,-W28SLb*P<ː K',ZMKf] H"CPيh~܊ ̀B/5HMnu\~;Jf7̓cXՌhꨧ८.H@\Olք[Km#4`ZRœ-A'gE(aO|l$u 9f ;NE-x e>Ca\)Rg6 3z-_ P_KӨ]mfWmK#ėc@]p³ ,4y&P&RԢD+9`uAqzb?yyNWQ:q);\*l|[q|t'ɟ)iv =Q_si"w6w}U=wEj%cy̶h{:ь&BH{. ;Bf.-C b Y?& O"I~sپ]/Om}r\C[ E.>ߞ|[$Ptt+΄$<^O|Oj쀇D;@̆. lFs9^z DŽu ӦA6 [Qbyqxr7s kRxOugG1֕SQ\urU2b(x[V8śd 0iS)/? .0.B1%Q–(E;ߑk6cK zc^C#O]EĈPT~M\ gj:ȼ|es|!o1϶۽,eYhNM[R.Xqs{bIFghfӸy[3쒀+ ,o,f"J@XNad6?&^Vwb7DߔBA`Ն[s^8BRQ{p!7-h!;)2I Nxrv͹Tc7Vٸ >bx͉QJ5.k-7*8L*1/ I"AX tVG{NO(5%)7Z&u.~yRJJ7?`~E=/;#[`yKcدh6`RinNlE%0 wu2xAh'Z UD2>C>yr"aYBg5SFyU8Y3ڻ 5Tu@DYc/@:+8)mAܗEL`  gו"D)t<8'7\>[A@(b`n?qp1(nuv E. /SqQC%X='5>NkH04Z|.n?b(튶;cd lm0'&6hl9I\txuN*IR!~NmM< 4?t'ǁ웑ܐ?SSlҰ5GƤl6{l Ef&6$aW?J?aZSPkL0΍Y޽V9>pA&3[}@q8{ f݇%ΟBIGm·9KD!9vߕ~חSJo%CwSL,ZPeС CbǯezjއW|=f $IrcLn(bCǿq hodD ^TKˬ?쥬K *uedXp7A nK*ePKzH635%iiNuHⷢpu$cr^lY(aû ΍,ifZ~ȧlB}P(PdΎڈR9Xݕ8]a.B؞hZ"Q}Y%pwȗ9K4У8;$lu@L 8=/L6%ؔ(2 9jkQ<(Xd_X=|vcdYQ}pV0:Ȫdg;;/~輐}`JxI*CVX6J@ygOՊQ'e[&U:׻w`uh+|Jc+QǨ8BTsMDP-Ylj/y_F ?l"kP<{͖`;ұ欰Ns\'X1&9I_2nwZǡ/liB0N6deRM1 Be@#eNgdii!`+3{2 i{\mZlQPfC#MƟ 0[*zRr=фP'lW{\*|`4D =-yG/nYjȹC$ +6^mN-#?P̟}5ɜ):H @J+LHl˙[0Ɨݬrd+N[2mO_9ïvgOJ0Y+~Vw{iz=|lviɂhE`N|+G,VdqaGS&()SvK HǿT=lU&<&*Qsr0m[zY5\B J\rIXԈE2-3ffAs(b['k?lnJ YFj҃}̻!.F}_W Kt O <;|7+<ۤԸ3|Ǘ1zu=N݀Ya)/[- }tܮ0|%B+Ú 3FW=f֝_BE2m'I]ohIAA߮\Koq,bMAs8"4 ؝O˸R5nܴqd(tΑOi9t_wKV!^FFlU.^z2D. A}"pA40Zu?qnKk! ,!2j,C"]MR!TT$9ټ,q`/ORAK@ pF`X"{S3:j O|*B]Gd t3[J]ʨϣr7هLJ*j7 =fg[Z,7q6UsRpDIr+ tOW% k?FV}wl36clyfw2v)%.d5K9E*n\]MV=^s3B|HQ^aյ[Z? F ҆_RV}hI?Pe ;v.r67: AtnY14Y`6N7J>a] A O6Ex]v,T:#RØ͹SҞPEiK4TY*Rk&}V7n %PTft!PI&`՟+jy? 7h* CU =Y:! (8;"XwD 975f61B>w*5MطRҙzg' weg"!b7k,Y.lɐhcn?1,K[Wd5RV1g>V6g?]DS=lJNU>BSN&-Q=_g>#"g:#>OT. N]aɳdFR>"i`$jӑmn_-F+Pr4xWF_o q# Oμ>fxa_GDzH.SNHkMgЧS vDi,p@{jTh 祉[;p /MŞK21>Sդ-*4BK5F}Oh}p#s (ern@ԬL$;x^KS8yO9;m"JTQa8*e˸qyLJyAspx4Rt{?bka|vNcVDKtoIݦ@Cѫ RbO$vR6>ve3%1'CĒ?%o"2&M$ukeR,RN]fNI[jZپмqߑ,Da;6Hő+xyEXO򆍃LF >Q{bh;3.FB ѳظUhRLQryL")K ;Ŵ4l+9G5 5,п-J|s!0ߙ` A0wXU ϋA k V?'r;,$_;s" Vt DfihʓL,Oƺh.PLYЛ¼'`JRԳpE0gv@5GK|pt`rG'!!\)[L7dOLר34*qǧMyU-SafwxX'%' [ t0[ؙEV0G2<#ZJn#O J@%!)խr1ON^U:8T]b@n4p/O&R՟,a(@It괦ćLAFqdM}gy`$m [n>CVo~1;EsdGR] wߌ^Y;Z1ѩYtq89OAfa0:ԝݐOa{x[Eą7TvwЂ?EaHlO27L*dvvEF*AsB݁A5I mU_T^ӎvL#TĦ-1OjĐӕwsqg-CIl'';Dz,G e(9º@TےY2c0Y\#Plt6<)j\14c(DM 3}YFD [qf-/So-HG]Uy蠵͕452-b6 ϪDit tyYy:*'Rh!ۅ~4u1==Θ*ǩJS3צ$;a7֗hOlx"I-9b{?:YHJ6n~`NvG瓞;[ؠA0u7<$|]R3mEq޳kv[iI[ 14oӈ>/Q9o[Z2DGTv%jUv'1)}; ؿvVp:'VeTuh[oŶR&G ha!睷npFx,t%DDɂ53҈-)G] @w/SL!1_bX`ԝ (yX\i$J̻eо1&8s5`ڢF!Lz0B׽$[-w9s<˼O0 UF}SD}>Qo7o7.P!OX6lcT:D(%dl3^o?mZ>X%a7 p$ $"xˑK>GoxNok׊yY|c@:lzm|0P?ikj,y}4|K֢Vg4tT$5XLm.8G00 atBeuݔ,$gá_TQsD-GKo9th. k (5S㗫~ӱҩ0Fcz?2RLӹ IYSR J@N/*ffrII\|;rCC MEf0cVuu*:'G;txzV"Em}Zif4Cz|ulV|6\&\J<;Jw\qn4T(h9*K2|K#ꘅmͧGY#d]O,(`6g-!B N!N34!xvb8-*"8s?3|oh,;h!CBHX6zP=L]~J%F楑}s$wQ^J'c~`Ar6J "=pt}e:nI ?xr1RN;C =1G:nϡ=BD4?[c( E4H>S$l?c!aVm46֦?֩)c|}TjQ^&c-vjlWzL BaS?3o0Ad(Ax; c?h >[q yJaCGoϿn{};=%2\McɖE=SqPS2_ے!l5ԑ7#Gp&[l],SX[{ ΁@q8S+3HC'ہtc7L ȮyGBc I=Z,;^HК'nFx~wE5(SHEi"S m5 zs$s 4 8G_D3DǶ9[zHUY,fZ@8L65ç8 +odHN6L!ajm*^BqǬnʞyq'S#*d*q t$zfܧA .G is}hu]spLq!%xBTz>e'IrvN٭KSVOJE4V$OVw<-T!B'(fjCj_$lyD!+ 獜VSڊkH/CTGzTvS.M4U*_uf Qy"|oP89u^H)Gxj K$; sn|K2^$ޞ񔚩KcA% h~Ou:2O<(q evHc,Ҏ; [[^X6]peE"Lq1ŮO1:PeBw V2$`h:1 )4`%Af|N>;kĚ +ȁcx`2LI_.V.|/"׳ :@ =Ӆ n8 Ft(y)'tQ8Cfr$oG8ODki,䣔y?ѵ$1W ?eVI6?nuk7@! (UumQӿhɳ,x}kl׹c~%̝cl7|h?2t0n\J| jhWHNzld~Ic-aP. ^*+<̲n)uMo4=- /]kDBmah3Q}AV9%o7 >Z NE?){v[k ibOC}<U|]I}y,\zgJPP+Fhgi8sA@ *@\yJrU EI %ۣ*|V4x:ǿ)O^(T8o0*cK +%>b_[K3ݔvi#-rO-!Lٮ+Gȵx,^]ѕ/.0=ZNk0pz2Xw=Q2MgA$K G gsgf _ _|}b:Dqfya!;iD(z?HGJ=߭d+eoabdn~r-S$9@/m'~N]&U+P~B?6mŲʩX}[˰'d@!NºbQ%g+*x#bclWHn94ZhYөǻK6k\ڽf?uM{Kg>{G'.;vp֚N˾ɢUQ_'LEmQvw5B$HY9?1 ^H]o8> 9}PjRK'^=#:uX1`âB,7K[>$l:0ǧA#pB/ J lxPkS ;rJ+ISc2Ϫd[,ZWD/2N%:gvZ# K(Bm DşI^"'Ԁ7(cK焁LVxn* ]+m|D!f}=aFNm|`Ua ;R7:s"=q MgFzS *U@s{(I!Q*Z4Fcx 5л?Tm89AQ3y!b/3ԍs{Xm?{s4|3L]3H+?`gFgؽ_1M7y&e`.%G (>yx1Q%H|ujX U\ĮK(%spRֆB o5Wpz4c_ @m\L9)ZN]h ‡~'ʵ>jnip%eVHN ']aF`YlB&Q"{fegt$4h~2p8rx:L4-|Ʋ{$qOwK9,% ^=Wn8ٳ_ Ch-74á3E+YKliςyG:aA&nc/ݓa?QgOn1bۉ]}Z.B_eqB(~3-J0:SuO-Gt3EʫuZ޿zn^ F.d^ZOqW\}1:1!ihc?YtRglxx b' )Yfhuve׼[{w{B*Sc3C_ U5gD:3̢\AU;SԀ@^+fxBdOG3>o4s.T hЅi$+3X&AP#c dl( O/8&XN8Q[_949ZsNbJ OQ 8nٯ{iq|.,Cd@d>t(f]9i(tiXb1b[X"oldVH;<)zhn S89:CWFG USPrq`o+EZBX?S?8=)HJۘ +ZM՘0ac@ptL ‘~Q' X l(i7v@/5@x? Ar._i:Qt /YmtPF<&4'b$xTב ؚsQ8$vd@ H1NFӹuHW\ @r+󮉶QQ9kv?xOZKW*IoHˇY}_x$ 'L5] Ih,)PFV< E?&9G!,h:1ɴ{l§[*ͧ`;ul p)3lP6y,a 4*oce (I H< IHJ]S2=K*nl)K̀;VKlZnT Q"^1a3ͮY_)]6`? ټ|=> RuϚ@V<8-'=uAr]19ܡb2KߓG nAa"xg+j9[Zݎ.!ؚJ b{n+pBh<5@f ("l04J~[/WIS #Odߨhlu}=&oQ+NH,NH|-)36a˷` g>.cF'C3A Dlm;mGH#ȾZ}9q

|TPݭ)J4-5T; I9xGce➛kw.&".# Ds4[7e\)[i mn 8~Ӟ"m^AeePgUC&Jzy)[ B^p.G^+,Mu{&gw;NdQ Ag@UG v='8;7i$p`.O}K|ڛHфE7q.YiEAy\<swr^٦{v7Lܛpףh0o "&Qu A۝hYTT(]^נ"qi7xAGWˬUG.36Tޛ~<3¹s#ژ# p^ 1{XksExM HK@k8@Q/46S3w9j=Ȩ.&67Sm.~}ͧVm#8\#gXw pj=U]"T< >ͺKc r)_'̆(D#.NzxTPH@n6џϽ0LQWm p%veHaM+xTT]ݣV&?V.BlYU3~\%CH' N/egiEMλ<zFTW4)qrKpop`/,#7C.<9 „a9ڪ떪VE ]D\llv{/÷I{ bS\7ڙm5y?i>}5(~QP9ixN3\Tmh? 6.B7Je)سS^ZrbNP$ PxfR#3~n7ҨeG'܅7M`gC2VLZfHW#?Xa|QJEz!EInz d|z:>X02LZ6'_J\,:3)Woq,Ӡ3s^iQ}$W'&;ʌSTV!WjpF&̇DR6w 2Z[~ e' ~龛ڂ7 ؀[yakN-eLp4* UuSfh@^^YhPf2<"UQhE)}OY4+0aJvD&ҀZ\R"5oJuvsA5ZC{۵`=XW K,'ȗKeҊ3ߟTm4*u(B`{¾] G#kRg!tPo-Xf[ɱ|:@v-ڐeK`y^8 SAmm(f!@.!d_d`v5PLcmBx5{"9K]Po"GUS2$J/Ś|:2֍F.b4,0`tcV=E`QgϏI즷t̜j>V{:Ez/G/jJKI2nJ:>oJXBN;zEA5ͨúWg(*ǥ߮t@WW4~lnЇW μL)xDVbAΠ2/-CXϾwp"HۑZ^'&~4,P#fL+jx <֘i3gP37OnƸښC\vo\(HEp/>d~KേS:S%\ ibh9 ~ݨM5R+V2odQT #67ӉY + _\ %Gxe7v`Ajkµ<ɷ:TV]wecWXj0SyջeQ"* WlLe( \> TbWM@ YчʮHM mi,ZZHeձ@G8!63YS`!A B30C}ؑ bYy~߁E ivz:Xoѧ1 6n W)"]FOc<#ڙ%K)puΉ,t6[ъ D>Z O" ,#`\2;np64[1.<ߐ1̓J/nJKv4$!`Qqno>Ɲe57^?=?ßf\ .Yg=bD9ڟX q?~[S[*L5fF;46VU#Bޓ̷ .e7K|(=w㌁qtnpr2?iyd< )w5;3voELm}>LqX iaa nfS=00& pI G3=!@QZyF) OX~k >"2ExR4+p,,qaUzCRҟtB){f:8^Wse5_]TmD ,6NEuvO뿷̈́?1?@ ,m]qCg;bd)Ĩ,nM'r"DLLa1DQZ{T-INlp jR#4" shv 泣/<5ȁ4k?G[DqzsfBuIvxV Ì]YT o{?o2(;dr7"ゎR=ٜ2\.U$o.$Pib:֡wg`$-V$QvGAk vKɭN-P5@ $q:zHye1i2#sM)h'Q tpG* :#$&9 I78S0' !g\Ly쏱ѷ.;tnv/Cb=q|8lv2;.jBŧ , w:dn g@l&Ě9ϛ~܂Yõ]}C.P\qFdxDz?5rekP+x,aGiP04TMR) T~g=VrjnU^Q2"t|Ǿ=+%$rYp_]Wr5乘i1QuF^d5T_񼟄{ e(Nx?hA|4IW@kO\mRpxxJ N-x ^vp;Bn q!^q1nΞFFPb)lcT6=@Ld$`ቀOy|ם_F̅GL Mx %¦^.|JR( ݒ#8?>sgdKW ؒ{7_ۛ1vz2f_moaFƅil]u*4Vgv)ue:Bi( At-ʲ4-pRqI،>t/s$:e@6F.*ϱ:Ghi./fw(d ݌T5L`YM'gSoJ'ۗLCk-C\NIES=jV_5aìg+0NK!mȮnQLŝ_` $BZjWRf}Wkc*?#6( 2ؖސ; dYej7:t%f(%~ 6n෗mRRkĴx̺v]+;]j`3e21T3uMcj=O$&RY Ӑ?'5HꯔzYJS,e!<˃HMÅ.;d3)% D41gT-@q5<[|oϐy K7FC(0∠wDҨDFJ F#)ata@tYĉ\Kkh2' ]jkRGD6i0 VC3CRgZ<4vk$D^EWnj^FƏd{`f9xcU#S5>bEI xp^mЂΪ^Xl|y~%>&'7aClׄ*T.G `!&ɓ*GEoR/?*1qSZ58s~P~T43I,xd});* CDА?U#P[CuCF NrkZo(+T_| Ng6 8r#T,ά1Mк=D9.J?>>hv)uS w/ 55AĴo-@M~XiGz@Y,B1Sm<7Gcqi<3(rӳLF8Dɲb:_6*D IW)."dS<^G|2Ak;4fʆ~И(lih`nwĨ@)z /catsoxJ/^FcnGby(˓) cUޡ'Hـ\2# 0rHC'<ݷ8:\;Zf=Ӛ<=!$n``N~yiFp h'܊5x,?g f. iI54DQ#jU=8K:$~ zA۱EDB&V:X8\tgo߅O4PjH~ mst(28wlg 4O;,]P ]]l:YK),t!K@;4;;+]!i٪i Zp!K)p7-CٜaKjYC*l꽈O _e㌵z4Pn5h_e4˼X9r&KNX Pdc]mR_fzmd5+50H7۰|NrlRT~,X-ex&0&{xV~M5{w Ytr}(LʝhceFGd>;LD ~9C!x:\/]b><5BD4I:yyD\<~cl,Lq<oU* orr'_>EIDuI) KM 6*M~ W[x1W-A\/ ҽkU/|V q|gj9n89M$Ik)D@ɵ Okl9ۇ M[0B-X|DPd5QuɧJa9k+lVmpe:BrC<~Eڬ[Xj`Mel$oF Xj2qDd(gfz?ի5u;lp`*gi_ߊW?)FßEqy3{32A/#lNuY_*"pѪjM2q9⃲K:[;(I6 ;ĔD U㢔M wba~N}^ډ5Wq{10cL*-OO^ǝ8y8U- c.ajHqvETjkeĹ!}o>ÀBE7xzk= zJ.|#0vʭ(LA>4Q4DlK-&5ivCd`IOg*%ꁗ2yx@PDs Nah|j6}h0=,/ w]& rM? 5Duh+mT@m7s%,2mU4~{p_03JUB~ӈ"kÌIU|aV)֜toGAuXsJ.-Mƹ_auX*ۅnqV3N:6F')ąRM1g#XnvY UQ% s?3jcM`aB!.:Yǔuq++Ky&$As%|s֌k&/%'# Y[)t( dQD/,cH0¬B@HZݸ;ZRƄuf1 ixo$:~R59%l2 G-šg18Y7PCl̆"il^ؔ.m6 7AN’SnnŕoS4(2s\\(- |eR @x'h o :/7_ E^TDSԋTZ 矤$%oAD:JhW+ΜU~39Z>= f"JqTfX|pZu2 @a|LL9F:D(>ݓ]%:hr/xbAXrO\>tƜtߜI;-}5cnjk _Yo%ߵ rH>*c_Y~>;`A~j=ƍK+g6'rF er.'*>)hሦ"!~KO#veoQ<\Ju2-C& 7RKX'prOfB1ďe UDQ#W4b]t][^l1vi[;O"̧Mqo X%FlͻdA(\'+-y--Ù!햬/uvp 䋸7c -3I}i#Õt-$b=2Tf3@BIw 哹"5Vr<4.͕7éjHy%)@NePc}D#;t!(zFc!nPP#Zip @ jꐑ+ µyÍ T=`WW3[cT.t0wֺ v hbrU\ػ^<[Z)>ѻ ӑ5E &Ǩ'x[dG LF}1iJnK\񇶕YO}:E pAd@m<1љgbpr g]&Q:R:Rd8 H$"צC6ZroM.H,b4gSs2tc#ŏ6T'`Iw_zR򫢟sPLVnmO:|ܺ'oS2Ew&3 BK* WIq{y/2Il j&6WD0w\#w0|򎑖圏ڴj6)( ]rB|5j &(û3mu@Χh^njlDY2ʺJE̳g)>r.E,MR'lS܄0*ysmk"ȳ?c>L*V=k(F;symq]c(VmOy&d.P-mrv^`s#w`дϖ肉JK;=E7H,f:q&T Џ&4+oZPH(m_i]9}QQz_̏zJj@br]ЩW@(U,^!A$9gCzýW?ROQ=>HWVt6 3@̊jYƎ,tdOXTLxEA=Q@5*Sxk\|{4/- F~c~\5:d%\u+@pzԉm,0 U^f 8JqQ+dOrr]pʹ;\bq{D{B>,_k,x׵Gwoz#a"$ /Z,Ig[0)249Et^ޛX& 󶗏2jǩF#7h6tX!&=u ρƘHcy *'$g&pڰڃ=cXtMDA!:V@הKw?Lr~ö mxrY$ vgXLpi*q겱gLӰӸvg~acbG icd(:%T8aٶ,L)7}>ӚZ+/28$R~K|ۆbc {@$fΐ? B'Nf%V>OpwO`(*T(~"($?< z|G"oy'bJ]6}a>eK <9= g0 Xæ2{sH3.[ Wu+!9ڠD6f? ]EFaL皈MnMBA)cd%0N;܁9ǝpIb5\ V!l|9wkxm9D_!#U곉o^) `=R>kݧOqJ!µƸ'FNrQh5tYJ\K(aYOkZ K7y*l?pͮ6m3%oB:}]Nԍ|+HHt7VA׋G (4FZX5n5P `pu:tѩN2؎.Tج n)FwcGK g{5_ƛz(yaqYޔU}7tqoc&4LP:zdCw?}8zajӇ WH196 }BoS:l dpm0ť< sҩ1" P 941!L"\mK|ꎙ͗Î?fl[lTHc>u%p!aPBn7;>s̈́zN$,>cBwf:#rnE:S5f Л@ Pۓ\NbRY}vtVz+{ǮZqVm|R .Ha.υEkRZ{}rb*Hxe{UijS<$ɍΘE{!|fҼA98g8'lvᖀN&7 IfwU^F#@ Nmw<1m  xtP0|pp駹žUNyJR""ښJk} ҜH{>wE\.ӁF>s`kYq_q}J$f Y[ͺ7Dɶn?p $0\5%y{ h T9:C hQ/AD кSzF"Oȵ-/JҼ\FF`SҩE(/v7c%&.qk\`/dW,n29YwXm-{gX+AvuY2A Yv3CiI*!L%ɷ(' `/|YSڒڥ.E=՟!9h]>zrZcjҸ"veÌV;m\SJOZH*1=ʾm: pfSn3/B# +|#)T/LޟZw2lsńYP4,|ewHiKpjEqq5 T{0/MhEC7 =sSsXQgZ꽑Ĩ֠$lqa7 r܂K{D=`H4@;D8N|LYoYTȧN4᷒ J4M|zMR*k{O`!Mt0  4f^?-d*Q&˚ygUͣFbXX$-ܾGuľVUZ*bS5멺B;b??}7k+.5ޒGe'p9F ri@5΅ekX qJZՠGԍ/wXb!fWp %|V=l&dEυ'9~ ^[] k:a/+EX(#gnoIObBIZפfVhxizSq3?3dl[v@F]yW#h b(M0m\,,{R[KU_|aȳ Ժ(Ͷ?u5G[7Bl5en]$3w:ץ d*+BIGլ.;wɝVnd$6ֹы!z 6C[M"ΗˢCkw VO}blp>?8 PΦ=J2 y$~+r2%Q BS"?#8I b)vIij[ݨi;"{f 50b=*NE*uutgPλDoқق,ul 69]؍<̺B3nm֣5 '[lUwm5_>icd guvJ 2d&r8H)-vp^RQ}GP!Pn> ~(DƆ{ٲ;"y xi"o-vM35~ZǙcj͎~[&$ešϝVNErTfnn[8v4DNν2~@3yMf |<g'A؂EݑH'^Qb2k;WoјU!c lss,ᶇі5,$hTK*_z:cGՒE'?Ld]q M+ItFl<9avX&`wϑћG]ya>/e@`t?!d(EX0dlLsH!:unqz=,g%5YO/l]]*fJl 86N?,nwū^T9n%)5j^%O ^8-x;H w:2PWrϔCh9sp 3$Zu3y;chZ7 rhP1}ү.~I(up[{2?gz!_-%S|[Wx%__!r ާj W=ɫy(wM t)8O'! gʲ.[RT[DǮF壦N^N4oi6.*+Z't!by"E'[ }X|XhcTP :2z!s >Qg{ .?w9aNnjtoxQ 3P#yF=IE[9!pGMY. XھY*$QǧEe O387#K2j\i53Wj~neC iWPUefzJ= .Y{Bi~ۃ<"U( TeCGhj_ 9;C^1/ 2@" ] hVc=Rvyե"#41H}2YNA=J>J}x`)^1$#LձʔU6iCݞ= %NoL{Q# &R88|' /ee9O!^/5_)Qt=ȹͽ)SClࡸlkՔ3ŸSIʗ`Ռ!gޏP;+ƕ^s.A-z&2<ڐ/]EyΪ77{R$I4ZAL˟C;]lsL@ِ6 LюܾTPG,6]%ZNZyɉze͵sG(kh݉n@F({m=G\TO{}8A0&Od(B , >;k#vT\ ޭ6Iz]c67!s,r(΄ 'tb΂b [!8JE}~disv┫u]d7]W ?ss=*ΕF<ХXqMF 芟]_-pW@J*E)n]-#;s gJ荗" =xk%qDC<Щ=A5n)Q.X5WSaH`(%@ J!< ΡPؔ@/:ʏݴͷUtcAA0=-Ń"C̃iX}oJv93O~Hv~$*TÁ&,?Z|7ʃmt >ƞs+sS~?;FyUō$8_]qwP49a 4ou!cG}{S^׾b)%f\ܺ(RRb}|`ɮx[$>dYyJ Ď: գUmŋ!(gq1xxUݡeۀ6Oi }rk ?dPÚOoh՞ܨʫrIg\Lķ!ˎ5mxujbַ 't&rA^}? ueހhӊm_̋ď}KhjM9gP6* n7C{n6P'5 Sg=L]CAJoK)3ؖ,mHO@>Bzv0=T';+~6 Lv+jXӃ{R%ƮHJI~J}y`'QHz-5Y]5Q >ҒC]#!<ğxS)ivd*1Oi>6%ȎhT;CyHZ?O}b)&[ :Bz8 v.;YîF QsEG0,ЪUDҔÏ_tt3J;yvn Xt?Z=^-)|ZP+tw)rc_Zt3p{a0Uvc U Z͵ldW)YY~dm3T`}٢a .rwGIE%1m4Bt -DgXbZUwK$ҩ~C9Ly =]kWn FӸU@Xia^$Y j4gidT KJ.=}I0yhՄKv&T]L~{@,I2Ta]DW|LcTVwJb8Gʄ|MTAÐ!qˉ(AhVcq J"( 7Ɔ} )ďg|>J`dqo8hĂX:OڄJpswx`kМ_ \ʐ کr8e*Қ SBpIyQ[|,Fhݟtݻfꟓ_R.k(3JwQ,.W g  M|' *,?g ; SM۹(D`6pXPpJ 0q 4HA2S0*8fPs2u/%i좧*&9H0R6Dwݵzyl粬owg$v FH1wd(D 3y񷟚 }5>_ڵ4sBE 7M\"J]i?|s__DJa\A|- ׫ *Al_?o!/ |ь .[:1e<:GLT!ϬeShQE-ׯ5.4hlz /c[{P).u P sU4d\ zijf;Z5` @aث6th}#nHҳTZhVOҜTС3q56C` qW.jIW3 |A?p{ԂW(bV[p$FPH][>>ʭ$wSx顜ycqWυzv,]?m@%d@aL M!0d' \y\M'eʔ|C*%XP :] ;GEJk͇jWO'o{2kh:4Jm3-UG1\H+a95?&Hq:1bcXoJņ&9#OE_V4zݢ#SIZYο.z~K_R*z%ħ~4* GYUL}|[/  a&{ o | Se0=CWCʢC?zӰG/8s-GO%qq@̋.E--qEpVLybS!~-W_ O}@׼Dπ^_D~f%G3rAkTaw,c @LYT!k:#Lz!Tr^ޅ=(Ѿq O*GW.cv_n+z.cm0b%Q.0S&GSċh|v KDP23_]V 9ArB!mŮhK($! JZ:\"KI/5Dl[,ǿG`rڥ̫Dǃ)У"Ѧo9W|RUզcV-gr!`e^d~.8J9dq߳SpG Wk࿮;gwȈu2/f{Ry. Ym l[܌1ACqTB::1tr(Fdqc̃V~.}&꟩v8S.P:" %Mwkas?#Xzj0,;jx+ymAJcWl>lw3)tT+l ~쎵\򜵷s'4zj}ϮUZ >t{63/d pHԹ` eYn[Hx!?1ΪVjX`j?j‚k9^0Ȅj}B2dh0+ˎLhGݤ &dp$ ܒlwrĝ \gYGguE@pjWib^$)/5>r4Չ5 Dg"މ{lɹFQ䰻Nd~ZCv*y+62/]_7xq%&JAeb_aA @-wnU 7|eHL-M#x鉛jLaJqZQ_+tgc&m1G/3/tI EIwak9eEgV"q;x~ҔlpΩ.=ƈvO4*ygNSOHO| ah R # AH@RBnF`ċ&9@;jo)Ac(UvSΟVu"_v vXт{1쌾A&MNpRJ lZsE%)VO 8S r{>h;yL3jtadu*-ʛ*œ qǧwФrD+dE (XZ"_3!Dqgu?fD$7P% aKy ť PL0E^Fu 5۳仄ݰ(dz+RbӦxm^-n9-N ͘~uގۮCѮF:"AFa❊M L(3 vz/n^^$W(MZϼS"#}m+@ %|,$* Ɏ}8>nwP=>ez~GEJ[,2y' ]^9%\0F5Mfd$QutHhnz>pL; :AI{|#gb̀BZjt+wd:FW>1џ<Ά(OBleNSj MV nބ^-,9DW"n*Yut`8@&L fg37Z~;>PCmDVˮb@e,+Fq%wb&)H.b5'5tąu }I)D| \F!Zv?E0W|)䵘^"oF ٕb'+q3gF`w*_I R QY""aQ~I_S/_@Ft3CKQi/ O\\½W" J| Q2ĉM(׹2J6Yi{%gK/ BeV 7;|SڡhCir >*,[{(bJsc<~}_q"%g(*H3ϘmIi~{ S4oĽ8A\uv}?bl6G5)aC#| "|r1ضZ5 *Kp{0]go-aXY<0YZ%Eb,~JOkT=;\KGdGo'Ka_Yb{#I”!ƀy?*iAzwmQx8UI>)?IVy&9M[d2"PXu Uߐ =?jtţӱ$ėVZ#4Unjĸ [+wI$9|hA lݱئ~^ #/i?G g˻*JU\"&ѡgvxg\Q^"Kȹ:;Os},bĆaM$aG=X:)$9FQWk#)v={84d1t@{L]YFzoYvn䚘Bf| u#=-Vu@y`wV$}H̖_r#2d0_PrKS.`hx _46jt?0Ȓh.2K%@yMI)$7>qP6z=EtD~gaEʓT\qbGW"ng9_|cBP_n|$θ| w%NH*Xi\2Ӈ+祖ݩ|Y ϝšTGD?GqIO|i˒ϑц@Kw\e숾7ĝ 5BsQb.Nb5ao)sj-<1![*M_K %;]Cr</51gɓߏ@ ?-2E {&0~ CT*zSŠC:RaP^H'\L+ ^$v'oc^*:NySw3ij2P~[ 0)B]{u4@~#]D!P'%7y5ÐCݤBU[lqCa#VSSRS͟'Ph(^G3M{}K*ri`z՛[Ɵk!D@ v:b[q~s X܏ E}|!w6!}ۆyy{yއrƍqOR5AW/iqrQ5F;^i1bF64d"XV+o;\A5R 䢩lujenq [/b~p3sRV;:x5%m@6*kLD[YRFA9bFF>]2_n%ķNn%]C(}Oξ= Tr3N 1j_4\8Yj= ^iW~)Hɦ#twd{rlr0VymDE=,dݯi ~_W#M p p|+v^(`{wҫv=lBU+2*J۰14=M>y`&D;X!p0[!WV)iS%>9fB=|V31r`s)[5B#paO GR$ fm<3À|9 m~esDr& $$'V=8?$v=}\1g܋<D*74OPӨ9筁$JZ$'I.G.'TX3nἆ3CZo'=)=x&v<|oi>W(fށcA*b52/8 |҄W=B|? 3:ooh]'v7Ko4'Ԋ6a+Ka[njQ%7۔rz=  I_'eNK+Υ)"Rg- 3oBUjںXy4AVgtvpʄE0\%(./ZJ-/XZ!9ghZ Y w)^mHQ}қ~X|'É+0, T6YRt>,{[l[OFƂKQ9{svF{:$6 jqjwK0XA";"| UMiJ.mw8<[%Z2?!QBUNRK;%,ΌGh=fxz`kGy6o9f޵k4V廷X~+ɛAd<[X2*kfz/Ql;lW_S!bYPPi^„!f~gdRN-25.utOjK-ǐIٹVVE3%'NRԒ'f#oxNvţD8+ .[2N٪kIY$ 93i ΪjLF9rW7ؒػnP{@3%>| cxC+WȎf`- zGĉw^O%xF*c1Lg#fP$ N&%Þ_zF*@};K8 aam" lr0$q+1q[ԙ-S;鿕K@:*ȆkZAkQ&G&(5иتskWiIv(jH@b} 1ٓoxD%>2y2\s|cx2(U^⠁dIrJQx`W6zV~;fr\cUMѨӴN/n݈Hh~ WGVTvG5P;noDﭻg>e1_ICzC)q̹4p]TcS 'oP@va#R 3Zᝧ')neDeQhASX4+Qud]i#*Q; Yiy﹒7WΈ >6iBt3r?%* cԍh-j I}{ 'JmkAR$㆖p8I|[ WYR?Rmv165\܉3+R`+ Z #}/ U߯wm ,g{r諫Pdd f޾@5=3]^W~X$n#mG_uY E!=w_`x{atŘpt4n_sI,06 xScS~\*=ӰM 6S%YK׀CpiضZsŠGJ$ f0O/¼~U umƄ4AA}Cs E$zV`r[S=T>sW@gݮցzjx(aWDbyp/ڥ7,6YI'Q;I"5:yZJ9J*yi(UA'vpK^'3zjM_uySrtj6$G0ҙclX+!pޚ[rw ԿF`:ȳO}~< 674x9޻Exk5<1F[Nz|ִ1fe\qZa*ksT("8Q P! P4^%rBSDƭxŅ.߁u&2yvۅ/ @|͡HCǐJɛHL]N wcr7` d / yEďJpoz#uL%;gsF`Q1bPfobCV}X o#91Am e}zy6OdGHF[S{ç9MeQfSڎq2ͥ>mȳ'}1 g {N*y&Ek&t>`LJˬJ: k .~ վIltk9 f S` Kn¬? ױτiACd#s,ֆȲN"K ;~K72YyLKFgDzaN% P9LyFV*D.?|GH "E' }%ܫ:4 |5& P 31O\R'z^,޺=b]yg;u7nW`f {[Of0X4n[>Wo&X.!e6x. lAnw85RN}I8)=q,)FHr xV-ۂ]Ngς; "—%cd+$Fy0Yw/>N^ #0^w yrIyM .q|e@*3߼Qw^A]("r/1^gO^c Xc\Ha(ҌZkXPr8t .z'9*hs"Jr mUM:?4P.axAꬸʟ7Leh{@Ĉڗ#Կyق^W@45/ikE*E '5o$= œ9%Fy BĸkOSq5ɑIR6V1ǁhaiJ] izQYxڇқ)7z8%Q[t*^d BI{kaO*{xs5KÌ/_ O(˲cmk}X܍"&Jp"F1mPd Y~8Tij3 XWvo\a4OOȊ45P ]v];yֱ(j*5XeEU>Txk+GRh-hF "Է.9Ӧ@c ^<[~^ؓ<$2T=%A0UYH}d9:86T߃x 9{dçQ_ɡ+z瞴ԴMQ7XgL^s6Ukk`/kejRi-1OtuԴYeHcR[:C27$=$&x_aߍv@֕Bu٫s~e\ZE:_;y1JY\hWOl$I/Ry_ 7P~M41A@n5{$@{(Yjy <1}Ngs0*o*p5h^?pŋ)XxA1}qN'&#kc#A_}B5=@7EzoGm2>IVtQd^yI-/[11C* 񯘢BpFGa9Je_A\'B(uz;,p`dt$ {?"06δdV[C,~ ou_` C C0 kJ)SV?Y60"U9؈(8yעO*@,Å~N4ܰU;!a\ab6I#29Ww%tb$o<ߧ樸5pflTٟsCÇdqwX]$ٜ+'yFNZOX%YuC8ugnȘiXxt]M#u ju4D<\MǮ/\ #3:]:^I?B֍0/2`1)Ie_vUoJkىtyH!O.^ˬ+z >dep|(tC,R.4dJ;OJ}ǖpe~yr1?7Uƒ(IrC6e=e+hgnRj}pmrJGH:Ò ŲgU.#2AYMݙ?6T~iyDќg&nFU sLFƦ?ذ͆(e(a(x@$# f͐t_!nlGx&/K+_ϜkŒjxupǫaʜapGZ&O+p&r(F9o=~tjrQ{Ԥ3.R.el8]/ۿQ$&g>J) 98=YGm$>Hy[oi:l5['^ : , "Y!>% /; .ІbB.&]@x#?:pێ<5$BP}l;8b9Un%#0rQSlEldZ_.SD+.0XƼggTt K/L CB h\N|`{8aUܩl(Ljm8jseޟ ̃8dtj9 yr2.ӟyY @ pvX4PJLo`^Y(&?e$FIc^l9ܭAm걝#*3\T>Ӊk"$eIuJ>9:mR~> 歅b^cT:9Ekkz(Pӽ+_Q1}|E4d'}!҉N~of)Oe/,1'sF_Frt#O^9;N jSUX_xΛ+RjOd*RZ ٠oA)/Q#0&$+ ﵊uzlrCjJ GP FURhp?8SUfډoZ<;D8wנ;U V]:Wf֩w'8I Q}H{.*lQ}Fަ)_Fiԣ]#, RF!A GQJՅ{h 愴mVB~QoD3mn^N*Pm f=LYo ikt}hlJdk.eb[D, T *ܮݾ2P"!X-{%jݐ4>'{b33U*ՀxtKG/F{<yUW8cG3 sf3c :*ԢψVu`;M>nlSiIUճޢ HQd5;}5KS| X:-'X)*y&+;[s`p}t׌Σ/2z̭k5bFЀe46j,xǙ'V -KK|PM<ݹ_G𙂌tb}N(ܳKv50"$ZWRm:/Q;Q}$Ua=ɴȫ$y S*SW$>] "_'`j`$+jEOM4U7Imsk@Ta8'jg> _@E%EGl`c ¬4žwlӦuq]`,T_?=ںYj,CRppiIjQL(畝IaU[bz쐚,"6z#ė?3F)&M_a c>kM4ժ;O_TX,9KȺ.U]3%˿OӃ5PP}%p0Ũ#:lgrE_i42@A:50*wd5 ;B}wWn},I/-w^"t-u>]c붇2ƂՎԞnI="A9ܴjq8bʺ/ C W7'"EtP<6|CԅQZ4>X3cecܼq`?g7~\R"孩`H_~R8-hp%O#C\)b6NsI=  e bye^g#g_2M8.fh5dDsu}p{* 7nvZ ,gqC5׼$UD8a'FlnE @VHN6E,pvQ -"նqxG{cZ"@r|DmL:w{ZAPU՜4 :x>#}l d8j+6kΘUBY()3#,˔~aR,(O!-ɲjvJ]Pn }KžwF}`qeXsVg:xRa$D(ir #>9A}],ِ6qhk|_2|rOQ,xFÅz^ dXv{HuwɨC8Sr1/GJ75te?. SrQ4C;dw!@!iUn*Gݘ#L?f K'ܡhȂ`^Y"+K,'ت$݋둼lrT!GIWXHZL c<9zƶ$Kd heCU{Ss/G߱}`'S&lSi6Gyw\`n9a6CeF7]֨Thښ?=5k bŞ긧Cݥ#F\B-~ c ^iBeKD!Cg;CM]+]^?mz%g:٢AWOͅµv|]yrVdz+Fʒ֎v'6Ó~X[#BjlxsF&]uHu(<;%}{-P8[MIi .7^[b`J><,X8^,KӟW{wI2H|&+\π45|/螠~9W*mo,{׉J0U\yJ}L>OABS䖛 dC[pLX+^Jwi^Rܪ@{  r}򥾅l?aigu%Lj- >29HA%ktH(vs5a2)dA(de[㿇M; sǣ(`k<$˲IrmBӓk*jx7EvmC >')?ы.ycVhRne F\o7Au2۩֘J1hF;jyo*#PgVl7Ո0LO xq/indQ >_+R B_c*Oz0lܲq1gYOu8^"du|P>NFӊG·D*7 zkJx ya7E Fdxc t-9“,PgXdgW ] ǎևɒZ+}E~4F&I7OK5!ꭓc 9;ϗɭək5-=3HY)䪙/}99{z#_?UңuMZbBs$ֻd.{ B%I YHl`h@xE1~Œ0T=Pu}d3p(+֑pU̒~-\P;.%vO9ap,7jgM<'R.13@9ZkPp@GYbE+y~e|>sz 7 &]l9@V-$PA߼Ei"E+%$,6?s7^ဤ@@1-b;[KJt2ԏ/xE [vΓ BQn#OMԬz'dߴQ]j.Pa) m4$qSMi!o1.r|m4|\|?x9)'xG׃<3e1 iVVSK ygkֆQ;j>tUӷLT !Th;:a Ƶ@!*h/H>81@U\K@QNZ]& b]%z25rt_00P)?jBF4ـ?dÕ|_seqnXDJl#Iv" HM'pHB= 룟G=sF.`ב*+*s ς6dK"!vЇm[( p}0h=9PzU팤t9P~8±7(\~~drnPr^A?}7-s "N'czq!^,Q;A Ipe-4vLd  4ZY*5{ ;ʚN lu9iD~&tjү/B9,# JSwtwՃtӟf#`*'4bb-z "nm!|˰+P>W[Vn(࿄Kn*Cxb!rm%ƫcV{%s0`pDv}ZyjRAHvyG<#2tҚN!Ksrg>  xl2#KJ|U㚃5Io _逌0f,3SĬyɁ'RLd䛢59x.()Ƃ>'Ʋ{rOѲ 4 W:b)q<J&lT.!Rp֓;v 0mSuKUmH0~/D~8 0q:A]D?؆V#Nn`a#v 'K~(!h_(d(Ts]흓P䮩>4 t h͠::vOжP0aH$ZZ1gr 4ќc 6+Ӕ::`PBV5  YtTGyqS/D?i*QҲVsɨk6撱:}(RE3 o@jLi.DQd69ղN3aI^FE-rh ӥAg,%xo%q5qkŖڲf}xluьuN,JAsUm3\oW>fX2]b߻d(ߞLsǯ.T,2Lz5h5Dp\jFO2!/u8mţܚn9.~o⭨w0;?1(L1`7eZd)#Ѯ!O-WaR,ĉAgp/Wi83vCk$QS/&ξʉ=ax@Hк$"s1wJ+Yam4|*##*NH[0ٮ!%Mѕg/[/n0$"M$Sgq[|I\pdػ V]dE 8A9GVAP(GoK^d{qZ!7MPSk(u> K:j,_*0eo DM uFNz؇`Vk=[Or0Wڵ99} =;RI 9r6^׵ Nb K5P-/tmF&5l? JM|CK(kqEdzM$(J[Vg0 ԢU&?)aMX:sr ;uW:.RZڇia.$L"i;/C :COWo>`cMkLu4QȻo)iG)mXElD!=nnk/wL/B(b/ro#/%tshmR GQp F`<~[ PPZ Ý@Z1,mZ`Gn׊6u鮽]ii?1Qcr_jB۸W4%w2EG2(_yLٓ}s҄0W:`a0(#W'l#8ȳ5U>x j)Hz7|o\Fг㳸Ό.aE a:z>>0hd3bfV)^ 8;MbdnCo>ET/X'K/R,_D3%|窐Ɖ FӬ"TPTٝڥ7q[*>́a'DÑl gsVU$}xTDo 0=Dk4I(Mq \=!m/l9zJ/Lj} ;,6gXE2P6جdY;h~@+=l/P(ojftģ|':`3:Ys/G1y[&It'ANԴS0_D~H' KͲo(یy˰_ȥH@ t oLrkuv@=z[vbn4>+G˔B4 !zw ԑEu1$:C/f`o'|yi\ 4 m^|O ,&ѓr+wyLcDx"D6x5`2n*EZx/S߈ L~ȉb{ƒ֒TW\aL.t䌅[4vLÄ(i yb@?ti6!c-=>t5_p\ZN?ںl].u-)$PUu?UЅaᰂn}ҿaG;%69,*e{N;:E[骮Y^:6e D-!#㞲3xD}"91$Jv-$G?}8%p&/GHKcզ&2Wooi#t2lȵȺq R;/k>p%38SD1ZO?  C i14N qI/.}`]rM2 h( 2#H{[$K4.ܬXʍz6dg(/Vw#- x4:qH(6YhEV́6i?@|Pݤe1 -<*]bc6n<vI }ka.L%UEb ֽDy0bKI Ym#==}yg&̺OZF ٱm ! ؆XEbYnmPo"xCTg5 PͧO CdnB-虾޶a, .ji *6T'gKNh| iW!Hp[و;3 N?eb?ejh$NXS,YL g!75޲^8;iK7bsILXs6zH%0N z}ޭ=, o* w ]YaK"\ny#V"D(n3^^53cj*_] r awCT@vű?+)AExFϭ7l$XxZ{__.4{87&> 6EcCL j SkA%MÝ?&by*lOLwC^*kԒW^XN .UmS~)zP7D gE7*Ie-" ", e(m4%T[M`XsPz簃O M}agp WS'F8(y9 4}>CXS?v(jFd ;]Y!&kPAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT cj'[3jVfdr֔.g0v uBؼOMJwS< (iS̗x"ٚk)ub=SnLJWHo19D /Z?RFN4P yZ滘.I.6qs>jG'9+p`?Wv>O>y 24HA(ڞo #J)q ?gɬw$YDZ(]^TLR^ QvoRS 41%s߰u)G` Z|ۺ]M%r\ܼ%z? 2μ7h?kEk/M7߁=[vA5\ f~<޲,+3Z]n c9q m+@nQƭ>;oFL<}8$}Se'.$`(t'obצkQN3TGe&)oຸ4Ilb8 ]8ȴCMee0?*kTٽ[ RCxR^:\ѫ,Q9Zp?[ vSV9YTZ[Oeɶtmu7Tu;H]}M[/k@vOV T/#J Gn+h*.){; A)g j7k06,=!Cd~ H6*Q5h;iBc'pF}#]؜G;>_3Z暼NEBT&Ɖr qH5i/s*}! aMPN*>kW2aXiSKO^e#ac]MRwQ,dtӓEUa|tNT>fcཔCœ8P1C0Yq0{ixh .ߢ e02M{Ua1*$ZWwdώnӱ?0q[ $K B\5qݦgcdNp\#quQ̌݃&E>P‡(.~؝>2t!2M=U #u^C[I1kMh:ܡ)"i-YMn qց.AZg[UJ,6֊$R\ A.t\e*\>SB>(_NxVI?0y t@NNǨD@=ߺ1C^GD/,.׾, 5xH€c4ETk31cŝUsd0k5$̜=œ N\cOJ^pN^ƚU0SK6"P~M8ql?Pr}AfYȼ4Sd KLY@yr{mPOX`^pc =Jd﫺k:$ uਂ~e{X>"D) ?kX_ќWA l2|:Fj1t(wEG;f:MA+=AmUWJ) %n(+Zk}u 3Էgm›nf}C- , onlB}b5{ӒѤ2-N#Ce\ДsiAA'yl&.MQa[&ʷD ]2f,7KiSIǫj)^ 1/I-aUB}w 7Z`VF]R驕w`qR xq李,[@.Uk^><6wKE|1^}yJ>olHw9D#źć0^\|F=geOeP]iBf+?EjR3h67Bc_D<$ y@B&7j^1m >m_\EgdHJ!ƚ'67gϦs %e/F=J8z{-k9hsI'˭YB(c N5U+pDbkhB OF 8#gvnG~x‡敱Šcg`Lp8zfRf- Y6p |2Rsa,E9M;C׫`~L: ŦSEK[`d_`nh,]9T(|. x2N`ot7u>V=/{x ^Я@uBHqy8Ւ8[ldݍj_wS&qe66-v< BU!V9m=,Ӷ it &merlyXxФ4*P([C XwGzL,yo~薉b}J0Fl"oș" bp9L*4;BnVM0]Bi"Q-RL6a0t>Yi'4 +W)qhv W!n4eƲ⧌sAçzcY)JCŸ:ri׳蜡x_uqi>RAi< :c5Br[|898qV, M9 ##fb!T95pO_,N3bALڥ"V >s zw }mREn$W}cBӪ0ZzFZ:' J~!.0R!af KpRmz9(y䰓YLO RK#RN`*j7]v\K@G_я9_5הk/|d0u]^J"\twxl,(ƭ>&G;/տ#|D߹bQ{MBD!x#cZVs18B[DkK,-qcd]ngG_pu)M$e==axW"I mSz m(qHBc]X=J"p-lտؿ a{׉13]wLe}<;U9ciӖ~Z1' mLlԢsl%m=m!n,pH'q'ٽc%vc4mR ~o} W<k\Jqb5oWJ"1b?B 0T-bxH.T_Dj:`+1»:xX!}pZN =؍I\b~f [za /[E0 +߃HÞk ĺjYd*T=l6ô0O0|r# Um1Ka6GHGsIy=WAWXE #s.]8[a>bT7Sh3Ɇ|1>RM#4SI<i9ʢ\׬@W !SzsA8O&NԻ"TK<'NP茴$*@'+|Y^pĈ=h&LL AUG\G_w5xLa+\w\1&}߰8oAP3--L_VBk>D3X( 7 :0ϑ|u/X^̹+ik2N;uq Pi|UNPTЧiι0e/D@oN`ᆵc%.Ȥ!hYҧ^PPv^cok+;suA]kVUҶTr{@YųO# ؐ&O2YXTRqTGy SlKCȒ_3]L&OQ'Õۿ#d7`>tJ$ 텽l%M5_e s{PjeX/Lo?32YrL$Dl] 2\%g_YW3/"*I+l[t ͊$]: 7VP)-;O5Ew23;jݷ~HX>_ jʢ_ Cȣ>i&`z޻.<4$m3H?P5vԓ'eR E@r41*]+iņ4D)wׂoTs3@㰁[]ߊ{ }ŪJ쯴JAou]6΅ľZ=d8%KU= gd^E:ȢӄÍKX"]=l4l?xnF6_u2Va=srАSx4v] Hg6*^!j{&W7*@֪ ʔr(2nO= q8nA[-H? Y=[88| ,[P&o'o?^3myǞl ?[$b(KUﰠmwW-E#ŎaC/N]nb6=4y)ք;ձD>Ԥ@zBO΂A*ӽNj8uhQ"ΐ ēdhC1n쑏3T9[jDRՄ_sY*jmId<0ycmچJ`jMpl b/ۓd 2ĪCws| F\ Zau,fA_~u;yG5A&~w&+0I}I1c/0|*ᤊ26ǫڐn05`cnWX kR? C pa#K{WOAOttY9nG@1&'BSZ9Jk @LX 5]>R*4y(𳘚!C8k 3Mk֍ [&"GqoXk$7pZR+WQVS ˋ֚04.JT-`'Iߑ^JP/iǢ6Y=̍rz?)YT:*szO: ݧ'C =#y?bX`40JNq`|KV($ȾN+tӳ.;~ OaӖ`7\;/$M BA* ̗x-5eDKTBSGڐәygK[_>MpYFf(E(B-0]ac}`ϔkWvYh6 OnM}b=F&p:8x1N3 ؇lU2*fQ}ȒGN\ˤM7n6݌*E$o tiʶ?7YR aʭo ?xj`I(X'- YRki*M>29Swźh>v}?4ڣv k[/ye\Y}G ]Bh#(͞n:knでCWвhOpn31 $cebˤOWXe*,KX_ gP6=/Dl1 SU)'mrQ!}8FSx+(zZȔ[DxSէfAN`5$A z:>؂5TfjV`󜎋i9a1 pN:$+'>Ǿ yÚ@(&N}AyëuM㴬XOKAG3LpR1yK%Cl/)9WL eڍsi78q)XBdk]CW\%*= ,ȩr &:(= \D]L hN7 jUۙ8m@$XD1Y.M5l~ "rpC΢+$ޔ526+>#{EdFʇvƌ,$d.Ķj*9#T$4|u*ȁX3:hc,\ӈ$>vى:$R&~ۆ1޹a}Ƣ?R%z`6Ri"^hyTFM.;Pr9Yl}̬ۭsO6-҇,Zpʘg;Mř@B=]3\+Am=W7y }TGJY9'8+- +T:{/KVL0+)=[@i".VF,uWsTEvH/n "^YlhSY"J]XQvBҩBJQeuҀ\@w<|+!5crkxH|)pL,Llt9ƭ6<@d!LRhCdzFR|85S"xqm(LVK6j&ѕ .q&ŬR f(a^C Z;Xl,B1c*h$XG {= zyR/x=EJDxZC.* 0(kW4pҙ%Tn>BkPb(D<ag7׋g@1ty. Œ{[Q}:UmO_Ì~h'\FGT:,Z^lmkρ8U>v㻝jT6i /F8Q+ z?!-~ss~mxNqfKZ snjf+{XSvGwc{sI(A(9J:-QL1?eZMY@u40f tj9t8ԓQY3na.sM{y TZ̗W0*sղ Ⱑl(j jqbCЩM[.wS{63X?yه d4p7MWb9Œ6eALx% yM ˅y V̉Mr1 zHLBr+F OZ hoN,  #Y ~dbѻݬȐ/Q[764zwf]{$LRUS?V@h{܋ilsIx^Ob()?y&iX\“N.ABՇ9$QPu&+8V*Mipn"hH\c-g674&2)S ɛ(s~+Д;ES0\r\yg EzUgQNPMh~yЭlIX0V )3܍*de;ԗ<8>Y;ұtXΥQ }prFA&ez07[=U=5Oot$$='DJ>gw8>FWpofR|4g?NՈ:^0ʐK; E9% 21VM:M `*n`%=]%;'VE n">%dfQ^ZRۧGO.n$\6a}⨠p5C7|=&rI2_k3}lcu;x)zgƑ)9kWn#7v*50@>{Nsx{? ]'k[nL-Z`Yrg gž_)+u^^>D Xe{ 7cq7c|H'g"]QxG"8{ 5= 㥺 zCDe;"bc TqOƜ&n' {gsDpVi-ޫ_]e-ĺ/-/C:~#ˣ9|M1.|,3cޤfPD%Ƒq8gVѦjK9UA6cͥ =p̰!g29!&'SvWwiU9wk_.Ӧ.哛_7@ya4g7XpJT;U 7@ f*5/Xb[͏6}Ե'quH.{ j~)"!JC㿢 e˼O@jWiqkABeVuUkᥡB2b]8lWg=DxԩXCM3Y@=36Q‰k'Ŗi}I3f};M.T~LB%@l߹L5m5nȟV$eZj i`": hjI_N մލj.VD/iS< `@4q`KmjS W' 4'C[DPXoFۺy7gPSwyu2Ao:6-!%9EvZf`rz0~`jFrUa0͞ԵTt|tw@r b>2FIEA o% wdў#HuCYa ,iz;",fN1C$VEqy1]p@T3_YabVE$㢀ָg zn2[KhA"|EdEuܟg70G,Hv 8W8NBWwlcDihU-|X=S_\D4GqIY3Ե9XU1d8]/Vkv._:|z VGƎ]L-PH%@֓ZF}鬡RIgw) zqR]k܁R&C_~DRvσ_mTvAfRDd2,wi m܋0=>0cY% }nyQ ts9\Ķ Q+*=Ul 9d2&'&־xFUAr^`<rf_ T:+Xلt&Fwą Q8k TTuF:"4k@^Tvmk5ȑm"j%dQ&gu(ɒ?f y+#MڻlR?w\wyE4o mS~kgM. (ٔOh FDso=nTA i?9hf|~Ю9X9~\QK0`7?h N|)&?S<30 &JC 8;9fWjĐ_03sO2q'0z١b XtoJmGnc9P 1Qu3b9g*<;@vdӨc[]mX>CsiBvbt6; /YOށJF%&W:\eam.D 2牞fL5s1D?skԦb_{kw6ܯŕCdzzA^0}kL־R-ntv$GjXwc%m)eS-MQ,~)}?c: (/әM"U;RwzO+M`8KPdv4!ÆU(p:D-Qz;61 p7F9Nƌ@; [kVϋwc(%v+BO7f˃-]?1iM<-П3:Ћ;Jfy5i1ׄLat%c+B FRfC.O?#SЀF]zRR&UPYϧ6QTH[M%g"۲cIi G2jwr/faxlq3,*CE %fy7.@O| ( KDNFQ9?v#Sg;CS<"Yb}*c8:o<ݡߵ{쌝jo\^YtU9<դ_X4p͸'HD:´Z{;u5$t|)x>ɯ~<.WHvEG[8x iI7kQ2fRj;R͢ }z#5e:r2L?ݥH Ğ;c+Wif0ja  ͛?20Ry:5/"M峵#RurȸtM8y{,w F'|F7,PR&9J:GGt[m Q#ۨT]yso<6,L~+vh8^|_w^3MMy>& `tڤ0D_T"ӏbB 7FjpOR]1Ky&sr4ŏa}H2{R < o[5CF(0[0‰JI2moIֵ rz%a#PN02F |&! ձ1uG fΫ/f 2( cW߸`Rkg&ddS0\ǵP."<* ,WRiPCl*0%^VbV12޸/SX]ěMD&⬸ӽJ?={LOJ!^LTfކ,;7c㫟w3#zٛR2msGjjx<_ *'~HnfFۑ&ÝHAŔJnd.v<~J L+R`j駆?)_{x>z8!,@ 71X+9$dta),οfm8gt~mf 3;z̞U1f tQCI߃Xc݉U-Wk 6=cĐA6vqL?3,jwt }C#3u[11:ŝUe±$lgլ.Ԇݘx9954~G6;00#*vU߱5l{˓p2e;IY͜]b졔:0L`A̶i]?㪻Zʥ$)5ˑa*j1Us|%dHkobUܞjy 0672R¬{f^ަC ,NJ+ၣSdW z86n+{y7-F/+\hr>B3-+J'*xZNum;5h8!*G5DS_QC. `"'{Jki)/d3<3ѲzK@I$T7З{nu$"oļNv } O~2As*Rgľ*5'+q\%{pazSzd^cpj>d$09,CXVOC+!ͨ+XRy/VAIpػԕÌ0WQcx9u&Scr9,;JN>Lɿ0 =4lli,Pg)%+G~F0-40q}ROx%yn^PJ¶w?hh 9M4-:1؇-?H4=yk֒u'S7#~d ۼalL P+/3{p|a4qZ\AwdU2ƒ#&y`cp |rዼټd K"1~%"S 8+Rp[fm0h ~M-T-"bG;u;$Aڦ"pN0HEq%N Ճ?G(y 6:H@Sr2D>Fs'*_ư+;DJԃ@3QKBZ _iC"H \:cdP;:Qԏ+4UdT7+WDG2h%|i&_=IDuB/ ԒjUݏSO]J[yْۖjF̑ q։{1p`p5^hP\ߜ}0߁13Tr!|K{,nብi9x<2uw)AD?1W5ٰPq誡Suf {˅@@ڍͣ2`Ex7_>D& 01'QfIЮ]WNTĥ")R_֜c\L)"ȐGX?~σP/b 'X)" n ~;ɤΐ GJpXH"SG AI'Maͪn?{வade/pW3@.J_:lеJ`_]jiY<d8=9[_Jy¡NנJyks6N㣏}bLNiG@E!/*ڛ(a%eX`mJFp@FĺScnkwbҎ!īo>U(oJj%V~ [Q^C#nF_:s,\]!p^4cJ{YQХ8.J>qWF D?RwCKh:˸eND`;)|SBe_$TM-W Yޫ3")`qm՚=}o{}f5r<'좤㖵XTqM[ed iBIcF!M%Cd ,EP•3&^IDMB tCa`5hs $UӋ]hF#tUM8r/t<\TP<-Wm%yg\`u6˳! 16q sQNB]O0rI Ÿ=mls΂&[4.c]V1&ʫArYdr[@Tm8d&{ۂfa9/ "q糯7_iv,((ܯL8쳍szoP)+vO8" X1fHLDT';6xk;׷\h t,ӱ<? + 2T~$=9b u<e"HtI{3 =W]%Κ7 iΛb[ Q|9~VhѵfkkP?_Uf8g*gḳoWcd@;3UO[H9SY5/ xsp{`Nc׮ *$8v# a]a]KW|UNJ$(s"b>#+-׷lOU;6iВ:+ 'a"LNFy(+Ekd=ƭRp S tX'RGn Y<w N aI\i?^u ь 9"hP+l|'NQ):p36)G`ȴ|th?o5gu.r0Ͳ,(R*T eݯ9O(Xø }0P"QhXO2-ȵKfD!:7o~[lޟU?C\!WF.d;v/>L Or\;o 5^ /G+&//y<!k^'Zo4ynGhU٥6weM#g?82+cenla,}8ƣd$cJZKr|/߂0; 6NƲ.H$łQ gh9ʄbrP*H`Lt=¦ΒsA,Pߚ,-cx5u/A4\ٺ8̯ 9phv!hʥ޳S̠w%YؑB)_Q} HOC7KhhigMGʮ-|J@3:IE;otpJ`hCٱ \p@AW\Gmb$# i/)}^_c.M{>  E*A܉RIkT{)7H{Z aP37o&T`bi)]ɫfUdH8}ª݋kT"Z'mݥ+OC!̽lVbvHpoM_]siR2I;IpZ+ g)w&A.<ۺ PqRLZO~_Ώ{)ɮUǸWH۔Iܴ*vԘP07sNj*틒]UaMpfĬ`2KBdX[4t6B͌=cgX}8p5΁>FCUiۢǮI ,5<ޭpxn-& .<~Oʕj2@ ]NRl9[ózɣYPW؞OY|P CpぽsA>XL`,( i70 d;|$lit,G iޠG͒PXv&ʋRleVS/m6ׂw׻V2Mi?-Rhsvhj-[An :Xr? ?=@ K`>5Åt:t蒩2oUM;gAWINT歏\"@2[dvTfOPci4>\ 2Ri%Yh+cb4hIq-ɿ. K\C9t,Ei:檳yZ}3o0!tW^1F8kJyMf&yW h-) tֈnNZ5G+ RgaSAkL` y3d%vΖzhʙ=J]Ӛ\TJ SЎ")~um)'rUհtNV!yOl#B#n^: L>|8n\ R9pG6)skqG$qy^|{Hd7!C*ЮiʵЌ1/;`Xtm}7ex0Ȫt{FxLV3q[U^I&P/yF="K`kH^nҼY/s68q藁p1_gB oOsH]l4h_GĽwH g'Wyo\*fP5 ^P߯ēy~ȳ՟9Qtd擄Eoy{1?V/ SGs8ro䷰ .:sU#!F^cr[;b5SH^̞ߨm|p`Zm[_OeBɄQmdyhR\w^ūOGzgJZ+&@KqBmLʊkR &"dNAiY`)<5ƽiezئ#+ 喃2F)18eys%r Z v iv1SDK$8"<`H{`"6CSk"QJ9#&7Ψ)7VZt7|mJ_O=Pt]V4%mZ+AW Ě QcV8 s6O~+$(Yq䭴ح:Npgo;A䫲 C;u[.s=B }5\ּK n6lErRn{}myUwP bB6{10/ÎDy`#Z+ zMsp{y^J}hGXl ARx?xs!֔v\"0ϥ)  Z(#ow]Cܜc q&`JY) oj^sTyʔD{_U,{؇C$6=ϐ++R3_3$xIKƄ.Q3c?LQߚ]HY3VRd2a,)yMΊ_ .ܧ֫`X =3w`^r{{WkV r7/|hp_- )/.Q?~h9ba@ɂu;OhSl\g,YߣYLh х9񺝮"5<ܧ"Z@zbC*0ȠQnlYF+ћƘ F ZQF@n7Z}tP08#"BF)D<~F$9vac}o"M~1}Η0Gy<-G{[l- yЁumyQ0y \WM3wO8o/H FQfBEUýtCeת9hB" >VČ}Хb({yM3Y 0$!eSa>9B#\[r'sC&}3&X峇.&Qx0bjł5d>PTY|ف-mӁcy%P=oYm*L:ʹO4ZbZK{NW+X}>ttqm.|\`b(iڏ&]q[b1+Ž!d&h6!':0 ~؅ s~GJB] :UvG{ZMBDֆ.lqNIGm'_*yw^29K *V Zj $d̕,Q 1aw":Q Ca")%OPw9L4ipO8f7SVY;N ̟;s8'#$m{ ?DX})l&107A z8=R(̗doZeP0:tk\}NB3F`Vc ,V.<@y0L6VE4M-*A8gan\n?vqN{?0Q4wF0" /G?݃o3a@4LLP`.BW,yJmnh %L{US?l"dKW* Mj@{[GÑLJg4pɹʏ~I?+lP6lC/¼AztpbQkck 4 ve. I;3Dd@6gv592t^[(rUNv8U߰_\ܓх~&Q{'3 g\}t!~VU a)$>Ӷ&v쀸g1neDh>M(FZYwV@&_H"D3?'Fo4|c#q2.x*/r8SZ@!?BMFK1]ghz9q/$slk=45$s3Qa8L=U£Qgvˑ&kț|N,}#M6ws X%=]ꀔ.5fv@GFQhQKg'ιlFݍ"^.nc ~vk-P62  F߸dO6r\؋zz{ wn$0΄no؇l3:p":~-lvJJyBC0Q/T.ʪX6=A:&QPIvC.aږswfgܓF snNx/8×)5ϞL|dQsX:oS2wwĂ!eHG67Xe"r5/Qk|wˠVLTWSքQ-}_HqE*eG3̡wRW₋(ɺ;ՉYݞłW5 ]?̻amb) qǦBW(igM y}o5v8ު9]lˆq@!|Y8^ho0@a!`]&9] ٟg#y԰M|cgcz#sfĕ0}rQ 4gnl wdDI q_9ȧ82 *Z#ntrN-G1bQkio{Hp6W׿gU\QD>Qƾ+/J#HZ' D򎃬DoڱC7ڳ-ތg];FWCk@`9Eӯa)p|YkF<"J.b̋C:b*e]$As_"Hଫȩ6}.'6煐XhCn+.H\@ ]ZPǣ+TZ y8HRiR`yI0&~1v@2bhgc~[*p*h5J,۞0d"2ʆ(βS.I^,eS4~[(CȖ=n M_RQ v:(O[Kgu7gI[;7q5hoP|&ƁFNZkZJ?=U3H1\F=/y> 2(1i::R$TXk0.8n Mz~0<߱_ x75#JvGgnb6q}a,~Lx!gR/e`ѹ&maTa)űZ]SݐXa!)[̯ڮ1>?ni!& }ƽل.(ї]a:O}&ȔE2Lxd F38ǽsM|̙.pu@U"G5D\Vo*H+ ɔnc^lPvvF&f욐x_kM?VDʟwp,=SEP9ӬGRzE2*H Z6ϸ+ߘ]%,798G)^n~)*:/mnzw5 9Qi9w.NmbIWc] i_Su8DԄ M(Rߗ}H&w NP9xl|>>Ǿdn8|z}ၻR+%c[N32G 6nbCDݩde*bF\$ҡY]y9e=$piCoqkg")E\Jxy F!le m%bR5S 9)բ@2{,hma5$1C/Ěҡa73\.mI[wo8]{r#ݾ΅P|r}DTM!.ٓ;ݒي۞^d4(xbD1bT)X_W]JHR5(J~RNzm" kc5L4;] ӢybXGGd8ĺ3W֚qCiqy{GPDZhypoG^2tNc2_.$6 >TDy։* mR 6\ns;SU(c$E%i/9kp!za骓fLO]Ba9ݴ5QBХԭ3Ka(E4Hח#^x Vmߙx/EcBL"U4ߦ4"ĩ# pAiXjYJZiLv~5M3V"Ǒg>z7ml~ac\bSOaeJPJҵrAl8I-#<$we xS+PO蚆vx;:i"| ݟ(h G810{i;jFe.WQ=/CY4:[w/ousȵ>] 쿄P#Q'HZ4Y6<4t#B8蚋C?UҀU]--+|6KͶ Q 1˄?VD7g]᲌>lg0GPފ BDȸޖ~Z1n0jpп$#ƌ*x~f{YevMx=o l4{܅#\QpMqgKXWYWW6eNWe]Tߡ -ZIE>~N*HI`|WP35jRmi$8 XlkP*!U:t^*7@EvҌ hGGß@'E2;*yAm$Qvo-'u2BVd$]5B`d;.x8$19^99Aզ;GSL[~-= ;UzPH?s2%uZba$J4Lr"2V tƿF՗ɒx]um[d2{&`2(FJUUYUuC'bY1Rh=|OGs[7ӨWRD|:8+͐ Æ4;VX4{:/Yl9ZDnQ9p[U z&{5UDoW/'~زsCSEUrM5qUzKen}C#8N{ !,OP3(8'gl%nmT*Ν6N$d^Z - AHo*|fU2 GM cZPA\33qlKI@Cѩud_52% * ՞dqVtqǖ ld *P}2q5똊֚Avcc 6&\|& %nXZ LEf:ЌlniI(أ(^[z:%4P{ѥ,y"Mi%  %'!0+ .Zƚ_p[C|܈}L `n]^LYʶQqrąU+9:k1?P,Y"F8UK4[.3fPVvAU^EYZħ=*-K9\MQ#v62(~~X~KRNjEKZimwӞ<ɹF216pn yL4:OJn)/oʠp `aaLwg5al,6T lޛWB,DѶCө`~ڴ}RʚEрN}$_MA@}*mK5jNScƠti OYq:-v9Ii/4]:*#F$7>HSD=6Y'b!2*=BH[ KZI2TC3G<_NJtHBpb^Wbw9ɒͲ]#UPSdmɟ N rߤk }uh2f nF%4Fl=ꃢS `9tD7830:EGrg}9_gQ[.6X? ɋH8j=JvDo,Ŝ>Q@l xSr JCV@ȱTuBㅨ6`>p'Z+`1 P8:7 dkUi5988ĹSeVF*0Jn;jl]aQO,\X"w^uo%Zzp6vx-  >L$\.GpT.<AuRmX{+eHk:׽+&< B}VJyWlgzѾtβ: YpbV23zkMFoWl䚶O ڄDɉ.'θfp4Ư!97CX嬮g$#{685Uږ9Y%guU_͟4}5bI}1ve$1@6'hRw-F-{k7zio~O~92;gD֘,.fwF^XY@9ΖoXTxW)"܌2(c/5g\0V$BR8–]̺D;\bUD+ŠmM *ސ[<`#5HޜNuUEͲRGVRt)ıZ-d8`PEXQGb~%?;ʬd.b!'I$7\X,7= jK@iR˲.fr {eZwT>$Z=7 Q' ɪM!jfFPB'4&v_ޓ7BWiђPq Z'4B1kj(PyV*u6Cy0x%g&buO# VMy.bz=:t/JilAqm"nrJzi5(K) 鰇Gn~saPB__[c]#CڇH7T~Hr7ܰHjZj3 ,` pg #nwCe8FREF3IFr&r=R4u+G34j09yg*Hd6 Zw5K+2WΌe,SԺGpZV h8ǰ;& -:q$?Z:_yf4i7%EKJ^Nߑސ҅'؇ͽ@%0B 紜MڹДxQw/ mqe=I,S ZJW+%w㮻K 6Cn塅&NQF3VKɔ"X4pa 9c:?JgEO<15.̡s틆''39}5IS_sP(N_#<iUdXfEk2> p}L2ӽGsOVܒBO>q,p}^{\) Gl;A4+y}K_7#r:B !'7֠ʀgpTC 2\ɷHꏙ#1&U3֡dfE^$ +VF7 #GUoڮhl &[hT+-37 xG:zQxF:1 [Sҍ'(j!MhW?*i wVq#,04_RP2_ ?Qc {^YoRv᠑I{`/h NAK`͙ZO<_I"W랽tϴtb#p'M`׿;~|pB4t`)33O.洷BSۚDs?x [d+'`OxAN2Ǭyosb<\9}tBiS0 a31hA:EBmJmy '%*R&>ڀy֡}Rj5C|'=s =KT]2dUR F@o&ܴS;Gmو-"tઓ K92*A$3ߘBt ~@=D_?_N;76XMǻK>mDIOJP֕y;К2.b~9J y[5]3qc3?$vp[@;2Wx;eYĿ"]˶/> 呧 ¼*U_Sw%T9>DإUK#di"4iTK8!VC3CbPߨzİZE fuy&!HbZ`7Uzg>#2_3_U1 hȓz " H;o8Vݔ'T ED,'sM|}bL ;ՋLL x~XiNKWIF;u_OZ^d #C٣QCI_Tv)@]L_:kb$[TUY?h};L-q:Q@TQ1?aMMf_䴺uퟵr4^!bD& ×2ѷ'1a'V"sZqTl fᇔMҽ|9ioÓv3g Z4> ]ď5)fzǧR(LMFF-:#%xT$wzXA}}0^{C:*#VWZtpR[m[AK O8,Q*4W`F6aD}G5^V=@i uD&v|T{DT*rNkS .s27v`Fz,,rWΔW<\O8Q tjHIcwT<$@)Z!d+iy>OF7;En)Z]-]/fLv6r iKRU.HbB)?!XǪ XBsM vJz+*~ l#M)n$tLFCOV-:S {]83F(hd#fԆ˧l }%\v?Uj_Ғu]33AWy|`tKטc綐4XjkډBV"2dRNY)>Q3! BA* jc\鯮|kylT$K_+eN,ngtQ7m~4女E3{ӌo`:``:B޷}ribN烱HtVz> N;UvC_g6ضmafnX=ș⤮\f-*9*Ǽ_ e;C j%Z`RqKQh'O"!pFf%{,g\q3+LjWyWm oWzR6z\n%V=ufI-?@[ iuWϿr-?Ai-CX}Fs[χȦiàߋn-un-X;q2Cx&ŲwQKfU3dϞ( ȃ4ֶH>8o` 'gw0Pܨ҃43̋q몖R)PI+ѕL Mb˹P{yŸ#]_e+=dABW{.#A},M X?yL>roreEaI./*qh6)10pjxJG z<&xhv&߸XH6{׷똊w9h0Sas |`WwS]+Ʉew8P#ax43*ҙUݾRB#@oBe d:) vU`;܁XT ꬟NUֽ0RJvfU9v}Ulkk@KrJ`جlj 5RL 7bF:Ő'e{ >B{7qWSK. (>XAYW1 A|hJ"Ao# iEض Ĩ#ǿK`3.b/k7=f8t5UVf]g0pY8ⓟsK6* 6ThZSG\i-$q<7_:Мtj'>ْ|xqg:Q^ b*b94W.? iA;, g;{:Z؏HG5O/!\ ]K>wi/c^;0riP+ x\d!pQ6hɰ)B!]=Mğ]m"|ɂǴ%M=t&M\Y߁UYADS7 d8qvY wѮ7Mi t@/̦dXKaAEkU*Ǭ~Nn!Ιs?\rŮr}mj(:1ԾՋ+ M,fSmdP]F\gRثJ=! b]%ݎis$JKuCbgM0DoahRor2HH7\==ɾx~ r%}~\dJśsJ G:Ҵd|nx5C>&v;cqbC1A8 ,k!.yxBYǝ9:%B˞9BD'J9n4&O3<2_"s%0]f…f-| ;2:%O? > gCd Y9FL9u~@7քLB88M/bA7Nէ/+oDe@ S0Պd+_Ve.݁ec<K~9Pg3]Z!b}]\Q*bDqwaWqKΒSd* qO%3UPsַ߅Pn⡱ ,l=udxED#g#;5 h(ā&4<\yP- Q;/VV&~HE1g'W~lF^t+G?RG+{E%YC}咻P s"lxC@I҇a?MEX6 ) h][Hz N;tlԒNBp,',S}A_>LǁEh6>mӃbgFH\G,/z)i0m՚bi(TH==ת=gRlˆ%*U@Ym";,)g:qhR%󖲾LbasM&xGBHO  6q3!hZV562g#ѓ0x]M#_.šT3a=4fN yC?l;hKENŦ45d|BSI=jx nK!tĵFJU@ b 䮓l$ bt'kYoPU&?ylp e4 `*axi̕zYȟiދF5"<*v\v/Z\7(ȊҬ~%AD'v˂#"x>2PGw]76p\#I&/['{ٳvJd+7tX ^kM'1H޼ƌY[TsbQ\{پi,7fb6n~)Uە7h=-[С gs"Eox17 q m|!"lnEQ۸uKΞ;B#wzŠ5Cu\XΒrH&?DPn0Xxݑ[so{Py[ʷF_/@.nʭ\m18OJ1`ceך[R_KG%VY{3Gu*#Sr=FDB;gBk^ F P\9\VX^CsD}1?D25 ^iԩV¢*gV-Ty:**u)>ݸ{76-نG-b- .8k{o)Q<2'.}1EBO/E= *314y=n#*垺ҤǝQ4j O_W߯JypT7fn%FZIyxԂS꿲0b1a9 U'|:!&93a@ټEҺh?@/#E2rqOcǶ%l~y^}G_^x򌌇qC9>MmXיu 5wg7+FE`/df&OYvB!&,qcO|L-b=y[H=9HvVl(eB\Kmܢ^%59B~O!%2=I^$6ɑγ-`, >7_0XDapaM0^Tvm`X-Nҿ:3%n3 e3VRڦyiueե\ ekV3vI>ulNڞD2.+nz^I5&ywwBtٜ֏_0t9!PtS%ڷUo%LVc gWbHPJ 0k[c|.K &E !M/?}v6ty3{8A>ަHd%>7JoMp1CNκzij?oe1CL.P.g@%n9pw\fDf.TS(ݚ94QQKrъBY ۫⢯x82xIz8z^P/Oy4\u_p+x&jL dh *&39 Hڀ>!OȍG]^m 7]7 ʡ)12MNw s֌G}Jɒ$I #9j*2nppU|\1),fɳL<81q6+ن6b啂!z_CI_-5R˲7αTPv])p~ΘA.B2Q;},cխR;@ t^C3 l( ucx)KɉBUTUZ Lh%xeՏ>@]~.:rX@<WC9wc ~Ҵ;R'!YoԪ!!k·k&W.އc]^&ws KF4H#@B-777φoQN t[mCM@B>Nhjgfψ3iLFl=U'/wś`6A#.a6 \ž j=DTI*Akѭh0Ó-c2*PAuVmu@m Ræ1uCwOi$48,S74xo‰}>dSfy8G +?ǕJ/ |$/N鰳1m_-X6= tيOޅї0%tY;o!w턋f|S`4RRp|vH'|eU@V5)UcZG6mмF-;~W]cVO9/.NPBj6\/4B>I# 6ٜN b TXΔ?y&dS!`DVH,p 52}0C 1O㣾?Jo$cV^lfB ퟞ>E} +yuSlҐGp?)Jug]֮0tALz;' ޓ'G.0of7 gƔُYmt}GKb.dqbxCݪ'nhun~qF/N~VB! )m=]'P^,s:[xh/ZDv!$]I桪[@S_8Uu{?|GՔ_[]-5EtWdEEܝQ]c>Ql+`sNYOn2̺.Ni9[bYe K "zzi[񧕁Qx[6MPg(_xC 6}.lzt їU;j<.#ض\KLKok*C{Cn@!=עjy\iA+,&+"t":7Es{R' bI%{)3(}4vffYBR6ߒmc)X/5X999rs1)pPNjL%kSxQs{gx .@Ds9 6jJGp04!-T O>FZndbf- dgT~:pARCv_e8۫kn:7Bl 08>NUf#@'/=64`54Ʈ5./:<{]1j툌tU^9s*v( n? l(w&:?Bqvj8rIxK?RohjƶVG:ײ#xDdH H:Y$,0}:a6tw?e3ޓ okhlL BU3&R27 mL嬑BJg:5S@ WHoB6yjBbXQװ.uMo !(2 T]xP.ka.@%Sp<k9R:yQ?͇{IF@SwxBKK6bm,KP+9;ub.RBR{J9=z\ N]$Tڶ 4iF挞eȻg!z B8r~F]ט)mڷiXAfPҸd6ml3Ƹ_6`Ù!]@0whZk[~q3Τo&4;Ϊj1E!'7;q0Aߐw=u%q k^Bm!nG\5G(^-ٗТkk_M 0$w07Ee! ډD5ܝDfW2=P ]]A'o[w0R|3,D!o D{F+&=T$5GD{ܦ iYmAIڕ4'F[O~-!q@ kM$<o+]Db [ NzU~Qp4I[-ۂbӹRQz=_^~K10x:mW)faMtuO%й2Uƽ9Jo ~g7dcPZh<@A[N%Vp8Ϥ(v:7[|w6k>8 W>HMKfQzO> JPơ[!iWZM.8NҖBQ&|aiIE{c,g%P+D"6C cq }5xC^΍#֓hps fJ&(UIHWlH )V?o8e9?-Zs|kXV/msZ>c[r  !7whjjƴ4^d=%-vܘ ۓֶ!0%M9G*w\YmY%`JH(y>:Nc%?păVs$tL@[Vt#G`=~ocgbgΓT)vc|oH7Vz:&ˀ]ʺ$ܻQ9 (gEZ ܈e ]z=e *?Ȅl 産bdE TWCVhg:e8?!J~30wDk[4D&Ay, iuJ-̷4޵) OQUsbWdTnI;/ʁόv;׃>ý!ޯ-J/#[9oORjSʃɘ9Qg;C 3gT2R휪8 fRv ^I0ϟ/o[J0QaZڤgĦcy@q5akD2_g>B tX ʗg r8>lf_[>x0G/ 7vFC۫?o`┋ 5azv {2@qU5SVW.'6< $<CJFX#Kzқ7_u&*M: @|!fXu\Lj,ObT9-A (o2]OS!$Z1v3T_;s(,n2L.@b Vn.(r?+׻z& iXtFC Bt11yzB7e{v-MٲyL( .97Ƿ.a:Z$0fC=$upT)sƓ);z慵vڹ v@s6 _ZoY 9T'||9GzA -\I(7vba%7b~ruWT;axs SG7hUi`ֲif!؊׌]'o'qKsFL1m\d8ߝX|=.}`&ϔPK' 'Cds؇&+2Lz9Ъؒ)yߕm8S4f6!iHn8z\+P`. }075qH*_s=Yul^?{dqQ@=Zjj}$XD68#DSRxD424hso'O5 ]à.p&jsQqX}) 7b^0e$;k|+ 0oM>RuטN&Z)2펷i^#+}஦嵽&,@Ջ)_9]SdkL9C:Q5#QPm}ɝJ ø-JlP[ oG31ʻ~exJSI OX ?rwoc#"ң,eymeuCcPg`$)9e7T/Pn,zR CX9B 98b!&~alF]l!VVPRx${ԃ e/^icy=mwO+CPd ݜC5ZE7y[gG^0.`2:&tzU,&c;?g$n5i?`E4Q.SG%#J۬vC!wNF3Jv9LX|V! fxiq?Iu `B#>- 9 Dmu40h{݉Ȼ\nE`J_zۈ$=szIk9/P֐(aQ$"Kbhce%!ՠ;iԒz_qn8`{&eWeqgfP#lDBⓆ sMzS0mL;,~+Vԅ9#=Njsڭ;\k=$ tE!=F‹wɏ{%K3=hD.σ.>q5Zj`v4T2sŅUpE$0KqL 9wȾ=Z0A36몮M;J.Av0XT\%jv/|q"j:A|nT%Z͇U߼:I]F##Ҧ)*POMU>JNļ;r~߿%~2g)K!>hX'I n_pV2OIk6A@Ww1{JQ&0XoXYf;c5%.U/^C@踱Zft @OG؂ m\trѹm ]`G57%Gos)15yXt%X$~z s^oZ!d܎IrGAC/#ˢhga~ 0.΍7T781l _gibCy57̪\mRrP*NTY IcJ<L]B}jW:j#-=(2,B\P}aj@9҃f2xQoKOFD_ȃ5]l܏Ǐ]`N%BJCEQTufWrxDO4bVư-WʳzX^`лmqwLp1[&Ru9x66yI;BIrwhWі <%xB7V7?-fϮc*7;Fj8$YDA,?N},9*z(u*k_ڛ;ZN[Wh2b,Cr%&?sa "򪇌 9 om Ȭhe%8 wrq\ Z|*Dr:TE5o9߲^j=e47:~Oڇڛvqj]0B@aPhl\j1A&ɹvoM5Aw78ﲙ)ߥѶAH}iW[A,?w:IHPG. &k_"ξ \@u6(6 BS17Q@ C!!%~"Snj), hR{ V:.Q6(*V=SO_{i s_puL13E生 q#gK:z*7!Rxz%jK<5)8C6 ͡N9Gx#viбF<@ tf - ~4"- Kj}~#"i+V61ȨA ?Ra(u*m*vjuMt܍>a[E=HRWO 0<ڇ[GLP<\&D 2i2{GMZn&PՅ1 %0(Xem^ dP@c^>xЬ^+#{k7>I2Zό'bَķGyK"I.`~Ka'?_6N'濰IuKĻ dp(h"?\P ypTF9Au]چؐA@*%yy'GSkB2{â#e0Ix.H_0+傝 lxOVhC3wXhdL ~>vZGɣC@񾒞n?ɫ\|2P"3ov=t;bqh zrn5QDw\13LI}*;~N}L_OP.|@c3={)z7yTTmJ8:ggH<~2ȓ묟':;H䧹6nXb_mO|Hu~7◼ۖ9ǩRYNw. )/ /;.IBbC\srՔ`?#&[V0w|7YF٬,.j?UA"3 0y:9[uZL ;٤aazk=> @{8g۽3xc2zJ ([┈1Ɂ@՗#OXxT@tN:7>{6rɬCT(QڶF=ۢ}",& s[ݯ` :+(Z Rv,DCm>'qwHXmsS%#=|3Xl_s)\(L`CY.JϏ0gtE[u<02á60/֋=)WV'U$]4"nG-VHE8uEË6) V6ْ&G(P hޗT :`ub a$KԿw`.d'qӚvvIaWs1,%؁\?6:5צ0\"`9&9J"ɐi9S{X",eBErǰ?_V7s#;( .bKPe4ׇUg v%l~I@gHݜ.Seު<#o@3"XwPIoΜQ {̓F2jl `Ӵ;23rCz~@rAhI=lK;].hptx\"qzm%EKk u-7xˀmmzPCPkCx8`r)Jq/ *1} UFPmxt0:9W\4Uxy3f{HrHkLw%r.]/U\`S!Dd, (B%zk0ƗcE7 /fK#7!|\nH*9`}hGkNzG\f=b׶aͣS{Vár$ph%U^zgG$mJ7<͗[S/Ԫ\j' ?tx*)!S9{ݻ45Z:p$!嬣*!m p;VShß{΁Nj6)N%)qqHq 3?טlrJ,Kv<@eYwzKlH+rWj*ti6;M,>gLneZ EHImZ,8PO8g*cvT}: XxS5/Wb03`;ʖ;ax zer2ﲎ8@n[*,5_(i\MҞZy5=s ɊӦ/ALR31e:*yhc:a ^O) ?{ raQ.q r)CxKclFsI B6[W;G@ӹ%Ao.v)WIXl:D( UJOK4셊DTu CpK#J=&#\3C4&B+`@ݎvW%xԶXP7v&5j}9,Z)sPPLيMy*zֺ,. 4MBøjn8C'<8#Ӆ B/(ӂ2& 8$gh{CNu8V|ȦmG"%Z XiLfnp8Tċr$!р/ĊQ/55|n,<קtP㢰6G|H}j|>`P <Iڹ=E7"-ӍveJر71 j/(DǹfJq'!~%IX4lRRqt,) Js>k`D.,#wl\p0cmI bv":!I}sO4c+ߙ Uk7y\idܺ=GáK 5vk>iY*o ,‘+JXŗ!Or@nԡ*OU*U `0Iw.v}ʃ; aNKF}?~/F'znG`,[(2%%:w/$Rg*q8[!g#tԙZE-)gn:]N]>ΧGQq.?= LGc2Xj#H"7`2ڜ˟O_yN'=<=!YL!:!(P UQ|l |3àgNTEob?CCw[|K^+FC,9}~$NLil";/ u8Z(BֻQ^~6sqS[b&W@~K2%B⏣լuRЅcٖ_WxLɡXPTWjn_uu;C1# ۋ+=IDž4|t;#T1iuP("Q兾7v8IA@޿ʻ{ѯE߾t4,_㞏+vGT5^az9%q 7:SMu!ئ+ST$pꯕ\{ ͻhj]dI0YEU |Ծp1m"jC\s̩*h,OI&ADIfDxPiM(65f6ḵZÌ .شnhѫmx\P,(X{-HOѬ@6ޑ]ݚik0x#Ԉ:Rn Z8` [S뽫hatAB@PB]?J_iv7Ӷ["HϳXJ7qj9$OUH-z.(n:ĨDuE1q5P_kMR[k4M̩=8VPq^7,qK\'B]cc{dV]h%{=:޶UAģyF^̝*Ao*8ߗ% j6v/n'n8 x!Mn.d /ܨGϏq`s}(G5塘nbBr Y[vq`DAf4tKG5@陳-V)6`in?wRW§.@ƕCOhC2~J0;N{DN]om=QfM_)<:t3(F>+b;FOXT9}c55.Q=21?Iq5<Sx'+{5ޥqSӦ@q؄[:T U%O%Oұґ~`yVȝgYTxSҭ ty5J A61>v4i2IL ꋆWoc겯䙭6xYIG0 KĜ0j G̍DD>܂ *uR>HK6(m@]@FU./ #@) О׋Q 9,}w-~1T+7o+~Ȅf" ]?l0|cj{>fZpysB+Qp|b-Ϫe#;E-E^PS.a_ )zS˜"RGQ2j?##ғ7PY q` MOڍtRé'E"0-8{_Y۝3@oB 0Tfual/º w$G<%01hZY$sޏ|/Uutf` X΀^ 

ա)}iJw{xY T "}Z8Uyg igetҤ%|i$ڝZXtHG⧿XQ݁A#2iRj-%x7|~FNr%A~aN oF6je6-@@)ٺgRw[l+!FYQma.j c+lrpI#Y7Xrm-9jZb(hr)KBcW=.+l  %Ӏydy 3I*F:v?a=mM\ c1-vB:s%H[%m4>TtotBὀ$4fKy8 ԁդlWMb0".Tiy`iWdK5q)Ll#E憷s^yXp/s'̗@w2V{k)딴k'Nt:7Z.-'Y;tk'pŌ @*@5Jz]'"黈 %JlICڕJX dHe=I#10+[.P_y6Hh!ВX;{tiAMXM;ov^(,uYEGķk*!/p#L}௎Ai OۯeyQސ;/y]ЉVӖZjO"j1|&|QfEզr+قH'gW4EΫi;h7Nx&z?_};iPt sXY92}5C@B `یߋ xF tqmx! CW|e)0dKI_. IH-Fim%-cGpY,b.F9l[|*^[]&;cl/x1 ./@Km߯+M[0l%2/%:^, KNznYW"?#5ҹ3v%LnY$.=,/\$꧂ r^u v>B=VyD-4YۦC,VQulQe6HFz\OI9*aF9vqǟ:Z{Bx&<1R*R,[`_ dqj(TC27#|S;SޞTxhjBtKөdfmΞ ׵OO,]g~kLM^Qjp.uԚ~’~MB/btSxtn?ʆ+, @:a_evI3Y! V-Ȱ/>z+֬E~,Y,56.#.$k%zkpP92oVY\"uX(}>L7rze8vF-(1׿uKɩRvM"3WtbXH0cE dÔ(Ad:7޶Af\aS-EPV<m͗ScN\iW4j.lwEx{u- qp"Ă`)e!8 5pqCd{k8'p>!KcBF"tMLQ,?lCo7}Й+HmoV%L3#@Ю",* "su̍5`}8bs DLJB1-0ʴ{ #ZK?n& Tsp/hQ~1ωnأtA?GgSqXF&,vVre#iz7GDN~\L:E-]֧u>o|bs lZfٰ/r:" $x-{p w 4XT$pEȢPzM6P{x1Cua,M3" zGSI+*%jmd1@W<GoOO~+\Ne7j[RSz* 䀵yTV+obeT 2XLĊcz$ӄR Hn;A"rپ9%>>-dVú{mXDYuk ߶g- .w sFvUYgC-l}J 4( gI׿QaGg 2x%~ŖE#UcI$ dɸ7PҰQ8Kn 4o >NTxHӅGYr/sK.nYlnCF;buh탦 Ώ$DLW<hoR]h$vV !SD os8Ƚj댋}Nt8!C<ò(=c9DR D+Ą8jϬ g$-ńX[vhrE_rlCMؐ_(Z1޾'@m 7-k<,LOb{`#Zf1v6荁Oaf@H֌Q,ZҒ!E[I6x_?Bv|B `n B.2P|>Z:;VOC ,d  ::-z+iO $C;y)% G<ANpsI_Gw{u`@sѤA%E"g8u,=w]8g]K$atdfL\WJr Jߐ(93|BO֦Sf%)[ ](ᷥS&ALf{aK7YFdߡb ^K^(Xܐtչa lLʂ-rظF(ѐ/ 3mMR#9Vdi,tzڀ ߯غb kef `":CȺ?ƭ|z mm68/DMX~z ,'FK"JPkJ$:G)OK# ay6! !i4Yӿ79L7JLXjE?Ǝ4=g Id` A'taâAB'6{ Z% ,25r!](mّL>a#z}Q+!ȇ^0DCeB%7eݿBCV{ Iu\޴?rsZ^PgY57)sqOUQ.ES,v Z{kPZ*: ߣw{UrS ~:i!ӀMHd"h~/@gFMN~-MG974ȟn&Ll\Jze`hp @k1z(X ܀\|)7 ɝlQǕBI*R$Nqsm6% c>f -$Άjca{ZNx f\Z_mX"H z8brL Nޔp6nnt:-5߄ 8B]L/noSQd~)$]՘6h껀u(Z4$+;wCw6RR4>yp6_]r}]NOW[ NޜNId HפO&/M,UhwR_v}'~'7((yUbLEjf[M;;\$+k. rUZ$\|8dӌ{u?l>T=8}`w7<հJ6a@z5i>_/]]<:C2,,ߣh Wv މځi e>ιUht9n^46˚T@`e OuR _il ):pO55a2=/c,cPzʔVm%.s,3H`Y@\LUH {`%*^XH!͙"`ݯ۝*+.F|2LJ4:hPkƲX-\Y~AGиb=4_Oj~`:7˱tq礢{{H@ì]. A:Gf#@뷠wT,Xu ?Vaߔ#{Cz<>3UW.< הַ4p_qs_Q)vY;>0MOQU4>._ĦhgHzP09<֡'{ (^FCnqJ# -Q?LN\%M_Q;ʎH )L `@ӪTE$,5PY%8g[QCr4ٳa?9&Jw-Ɋm^mI|]?m25@&R-EuDU ';UD,!U{ۙnB(1;_gXfL/ $6ٮ/?yƆn/J/7iD}hR$iy X?˹Oz =|A?B$nuu'Gt>.)dg 3M_(r]e 9o$Y盝͸_|W?Cegۂ6G%)&>y)*Z%g饗c[;yG L/MZbG>"̸$xtgL6Ѫ+x1ș7c41dKW #P5dH qC9^ܗE:h씰7'<{ B b+f\md J%[ ֲ0sVTq_ Dpj_bcy_VH3 ulgbɏHn`6 N+{zCpݣCN|I2]u\A`Fҋ~jTHI3q*^l?1ȕBOz!p1ձ+_ݮfO)_qF4 &Z ~`+N#IO-eJ@wLo ɪ <0mfOI( i,?0r*@7p]E1FY~Ch#ON=/cHʞ_#*b3k>0ԲIXƣcvSy1%7+z#{Эyymn d݌UUJLh~(jje:*!/iI X6@pޗz {K[9LLkӧVLGњnýD kzs'$lˍd aKv BSt݇LJJMy|AԂnf|&&#xó^i,r9V7?+#-Ҳ(%H7l^-Gӣ٩jc P Na_*p;޽̼{[fP[v|7@1- Zpfæh8@'~\r!7/4fdƣnpk U3t p)PVLjݸchwZ%ܹn*(BT;UϘqA "C7 [_v4)hd'e\M-I0[Uz̖l&p`Aj<^f?]M%,v !; 7] v%>O-#zIR M6e:74ǀaCr'`i17'(sGe"~̎U`OxH:򏬑r@^se+XuGD4ve=ED󑸱xy-eE,Ǻz=x{KRd83$*p(}>gSEK9qK_!_zP 텺?qSٺN? cڣ ʻP*~-/XQW<\' 'Lhoosb"-6[pk(jv'Iۏ$ǐME@z?#`'Ql6C%7ؽ+md9-Nbz:ރ.v"Q,5\(=DÙڑҜ12fNp70+ Ǎ VD<6.燿Mx>/1?i&(E|!;Fس @@F,V UcNj{sH!e򘱈s6NgӦطsI{@5d%'5n泀ͽ_Ja5"@ ~5%ac\9u/i1f68rg& ap52&h3Ή;XLˎl𱳚BMKk򶼎zca!۩mN41^<`1oJx"GZRrRiKp`C#W#_0l%׆+Buv<$--&i A9E(c[_E.IdmbHu4ĐK۹+̂4T~X`iF6h̗%c6Az!Z%(nlzIdF5+G=PWm+R"_|+35ؘ$}|\mF.s@JȐPc,g^ 6}sb}[S,`YpدEwQų!{7c&L<Ҧw #sw˪_$Qlq˗ƛ`R也2)ϙ<'n-o$B sub)?3e Sf*[vYfARi \-Łs>sa5EC$2Ϫ"R@Q#|uJqf(JLj1Ɂ IuԮmk,XCcRi iʹɠd޼C8R%]Ԉt.fuIm`2G[n͘oGa%C  &z m؝qe/5X6(ue:5r/*:hqNգ|EKFWhk?b9Юp  u4 RTBWIˣR߬!zNza](Nɠ 6\$" Ĵ5s섖GK `_Y͝8\/1wf& y݌ԸFwNh.5;J??eWkF=wsMNx;NIS/+,UP4$G=-0\ |;ȁ34) Ds#i Yk.XlH-PVpr'กtY6 "v'eBWS?0ŅT W#T*Psݯ<||vI]()t>_NxGt7H(\i PTpj<1C!LQ(J^$ Ks  YENj-;3̨?o´#z =݈Wn$Of5zڪy oz'Ã!M4ASRg q=w1?M`jmJ ?uOg3k&= $wHr+S@ha\_3 7N+R|E%dT#5*w0P~⮽J9qՒ{v=X | ٶs vv(FlAfD{4Uăo׍[00\},|uOѮFW*^֫C( iYB" \{+%[rԷE?qL6~dHA]+FU.4ֹ[ i]|:$}9E#8˂O}-7xӜn`~rb)X :1pE5)0]S2?~PAb ރ*}Ew9LP@PKEܹzͰ)tFP=z<~ly b1:vjx%,EpGmbȪwګVDչt9mo(jLѤ#>CQWa޼:*=6x?gy-E5Ѵ'!W>"X(~dk/W<~tI!(uR1d N(;0`c#-?i?$tBqC lB6,%Sgd2?L:Qn  ַA#S6 Km,jsÑߖ{m2Ǻҵ"k=@S8UqC P |5.}1U˂}ݺTi'h]2>B 89rEIS0XG e ᳇_AeQQT1;N(p*{T% 05_&'ghcE^ߥQp'Fc1K~zx$ '0D4sQ;Py9 ^.&šFgR`c}}ͳjZr'#mrh2:#\Fcu.?A's];r6')M_&ZWsLz/PG( ~0^/Hpq4,~BOGbX,kO^ZUKrNG 0](PmUe0"SG[۷F} aa}kÖ[.q$'}9N{(a=?8l#]1ȀF`Υĉ(dkY!aS+wH8:9zD%e<5**̈́lVLC!*i na`81Q_q;oKQT3O_]JB+EME PbMn26H/9'z?aݒT_ x$b:HNݐBT>9.yY՚f2D4Gݳ. O'^uOahUR'˷he~/HD+Sde=/Uȉ{Л*Pڨ4F?QϷ𞌊",HK/*[QQӶ8;VV!mU6֟mNЯۊϊc"Ve/#ρ(5'عUy Ȟ]YN,@;y)EFă^~6\pShyUU4$5H|Tqgpd,7+P勉c[KWrxfΚ8SemEֿx'\MN.Vm<)g;*Q@ Vph[f2=Y^'!g2ſ]vƫ8A za+#U.:y9 E8Qq{hn"u\ܪ>=5_]*ȚԋIJV4$7BM~lzyO}HY^(+f #eӫZ:X64_u#vؐd*.¾ChwIpJbfO(>6ZX5 oϜѸg3;1.0O\pz3hAXWbMb6Ѩi晰ɴMKW{YXdzވHB!n( ZGF@HD\c542N,8P 嗬n='q c;&<:7 [ZKC(Yx'pяԆT5.;GՓ2[as RֻD`W· ݴݔE$Mwb:<׹=\?c$BbG00 I)aĿفǭPm4窲&*k36yXg|}*!Y\ {l%9hsN^ԅWbvG#(d*9XeK)5R̽zep (r[F}D~A(V1 t)%C!`[e"CʘAڪ\H:Z. .xͣj׬&;_5,XuNk|v.c&›ª^ynYRd"I#esITRm]<חL W$fW?f6Q?7kBqR;oQ航m_YBïo.eNJ&&1GuqO9'Gu. g N+7 *?ÕN*jN=eڤA#r•dXVIB3Pxgzb'v'K<UkEByrP.n5c. F@;G zN*s(ÊNq*}GatԪu:/]D7HvOSAjʛDA*?OV=8i,0drkQΜF0MYJψ^F<=1I};{?S:H"nYH@Qv%WvK3ep:Jڗ"kPDV皗/ӃC r{P!i'bB"UkʖŃ4~YE7h2]R{3*Pro*_[kk :CB(="$*UtBwTaN_xȀY󽰍ͭ8}fmJO x(qrC.j+!PBFMWZb`{rYu=t'jWx JU66}(Rz*!l6*cw28ɨL" zj@M̝9'4pHn(_D$-'E.bjZxfm U*- ND'P5!r&,cщocZ˃0pQ۲G];<AI&o !$\r3Lzև\QZ50bAa%q"A-*XQJϬ3xKu)5ʛjѷd]ghU%m_}9^i@^޲X GCO+R˘)0|!NȔc=vc>Q?AaXs~zmiwgoj C>HeKD45w\}h(^1ɻh&qzf/d 8Inɇk&ݱiv _!MkEM]\:&dGLǷd|HMr"gy2ŭ8tuՍeF%A5N ڙ*vrD3QG1|&t",$H Ȏa>3z~w[?rN) rk!s#2KE]`Y_WیNՆG]A,Sˋ8K'X#7470h fD'y$%Fќ\Ź 8sU9H\s QKX,g+`k~3wfS$m4_5Lː鴛MD$S{]7Yr|wkDF$x>JۈrbvqY58&lu-!NFss(n3%f8Q*MC6(^+?+Ÿ\xot yVNٯ\UN79HQn*ֹk-!1lOKvX6Sά7mlLerS5ڊ^6(6ڔhu.cm뀸N%h(C'5 l_E$ȹq/r=A}wLO H$l wQs5s#ʱt^noЋ.(AfΔǘt7S]~{qe97 -6NQVQKz`Ese< `2qW4m8)k9$li(+! 7Ӕ[Osg FƖnvWe A ) AC%me%9p/"A40 j$wfdϵdTJXY Dž}a7 Sszðb9!>ǒvwRGp]ৃ 9!UgQAWE7? |#Ń ߩ|m#8+pW_Ț.\-}NzGʄ19O#yK`#ibނ-I2v 9,(ˆ5ΘUM5cD@ekЭᖾ2< mQǑxq9pU%xzEŨ0|zؚ5>h;B;\kZƬK*=j=݈39MV${"& %x.͸Wxjk4:uFO*!0|}HX1pО`Qu63=,p&tU};j[!+1k(UgoLQBB5}Ǹ=񍆌aN[MlPs8rŝ*4ǣ_5^'hUMzf/k?p :tZJ_4RzoV.6}&*ΧLeҖSVА8ANNj*jN]\&hYCX Ii fըm$tnLT91\O]Z֕1梼jSQD>zO fkU| lA3a![v_ wVZ,su\}XD8 `&ĹD50ZLv+b#Yt[u9#K7B }64T ń UCyB-$Mti8ۊWBWj:7E- !7,p"$fW'剢r. $!x8Wśul`JB0 퍡xߖw@gCo+=ôJOk:܎%JdDөs^"߳Fz?Fau)1&,]a_s%—ؗ9> FFtbcphܫu|XCC ^J(KltM}p9hQu V<Ntp>˫Gⱆ0q^le_218Ա% R'XJҰ@]=JK? =LB~kEu/ f?s$6rYš;zM?\" Vnr3T)jsf <Sf;a!Du*sSsֲ]9NMqPo8;O=[Budqb&'/Gi(^|e­ [-ciw.Êt醙1Njb2^ݰXǵm_X8:2:qvXu^ -nG^^_+tj̬p~q%Ú&Tq)՜]M|Zou1JfpTOnSɀG"+ :O̿'&-Rd]C"^6n' ?wZ4oXlK굎xP(IaeHJՆg~kO*=N?τ~#w* 3L3,T=op~DF3՜pH$17yIZP)z$IgI,e(vL'\s߅a>_OE$!VIZ׽,S)9-Ay4iU' }M7GuhM Ƽ>sZT'y6I !Lhø`yBPyZzT8 ׷-w#(sN b8AFS|Ule CEsd<ĠLoMZ;⇟A6ۂU;SwW.G2 鞑pkfƐE;Fl8xkbųO;qH1JR=#1W sh*>Fډt_[P]cL^'v9B9h# L '$2m楻;⎹JN|gx`YHW`ɂ݃U|stIM[(N׷.8Q| mbsCq ~gswM >gDpq(`}c*{F4f?aa(vސW( VhF=WEnO[2>2cӸ~w96]Jnc>Ƌ:K5¼(5@.i^Qvy C^ЈHREK vAD;F_6N#`Ƚզ4ڿ%Y,m*;>=x9|O;y7ߜJ뤬`t\ N.[#g#j#ѳ{ZuQ8htj!C!~dE?LײdS 6t>; .uQ ܳF}w178;01:;sxqʫ@1|1)^ >jw1ΑbO" O gcSQRӴMe,ڍQd*"H na9\ fGn(;s&<@QQ =BfW{b\-!;W14Qonj7K-.*M**]`Ӆ4AP 7ђgtèa/]Nmv2jSgEk0 &nRsT&:H/@V6%?slOϩү¦~ PGJI:>QFDp F##F]GU ׍!wyZ%BatQ4^:[?MU;|Yʳ&]4D.\ i&2pO7/>#I/gjr: u嵼s-0"-q[/JtǾ!e+] -v2:%="\vg UʗU$7"aY( ?>jOjLC7Iox)̴#߀+kDs|$*q'p}*\#}7bLCEOkuּ-f*@{&[,FF:>6>]Mx{TSTr,l J^FM M19fn>ZX5:W֎ BoKחbHȯ[M+ߜKKɑ?xikSL\Mo ,p) u |^>LI>EpSSJ a BAV+%j3v2UDgNzAq`б"\[(AjHkWG{>i乿7?O[uJOTfd&/eqJɐ.cTE7EePq^"V`qW0W0&FY"ofPA o(k/s锆|t, Gv6 $I@k7MD bjB 1, aj ysjx=a{k⩽y+aGl^2,F)N\y)xnF|?Du.^ݷUB|Ԩ=I  +_ W+߷#6jZrY=zS(=2Tw &*S[]/_ȃ |]6l5qth̽$敫5Z34SI]xc3dͿ t2Hc*=l V}e"%X!+IKc2h~_hڤݤu1z-:AJ&yR: ,5MCGwuinf}"Kd`3(cL#2i,BI Tnl/ џ dD@y@Jٷ `Eiʑ[,3Q@,+; 4U%X2p | ~mo6UXIMA0?%%;GiŧFv Š!zsO"onNI% z3E)o|QL3#OPyDh\ڲ$':n,qmϋ@/\>Ә5s4r;͖tH.:P^Gg8T8WBcFŋ2\"#J%@~fRmĝF%T/l=@|_z es@iMP2=}CD3jg J#!EXVsw#,L~ 2^o^u;e6c<$ٜ`^יغh?%nj Z[dI d"`r>TbH%Z$ݞ^kGZ_"=^&ŕ!@ضB/*IԊjl=_?LWTpo+@r\Q+ralOzXNbe Q^hG0XOF(/Z4?},;`Zk/OyaגJ#[7ױI86] 3^G<^:V)lZd ŗ-[%߷uʼi_!JK2Cx-Q7Rv:pP'̢ClZk:ir$0],H[ V;kTnh_;%L966*JOF 뵽)5g 5bk 8oܙeU VBAi娾.%an$B~M~RP8pNR@vK'up qS(ʽ`|``OkxrKwa?@/M.* cKt_~Mc=Y3)D2$,#;UL7j JHџ8!?> G4># 3/Y`/^TBfe+3آ]3jKUUq~ÝRdhXw(tm>zɯVy<LZ8O1r [bhXų6Aj|Cp_l^:1o=]t~Y>|Y,RB<%yD؛QQ <2)hKRȅ,V i3櫢E.o©@h3Uhd&asYpC ;ʇUr Q_xoXC"DEXf?; c6Zu-)`H@bR®;V_F5ͺo$EwK!¿~3#2GDG@/"6 (wR\wϓ+MvԍQU~h N WNsMHOaEIJI &+Õr^Fʶe|OhP=FIMO߹q"_ ~I&h#bZ$-`6*>E )$?IX z2(; ob9S r#@'??10J1T _QzEN_ҸZ-8h' US>d6Z1g j7X9} j6^oDm) %jvyC+LBػL4?~3N7 @an8z=JXuldO0,e, <9V"=+ݻiLv j2SÁ5)vpr$}z9&b.l)Z8vr SLaTp^U~n>ykumy42?^"4pInRqKA>2a6R߉*0n{)_ ҃Cc(wGecY&= fE?PzJK k  xr/ؤi4䖻9 $7Ȱg폂]]/ ArasWLKHns P@ sj8भĆ)Zax/SU}:cQ X`wɄb{'%v qPO҃g@U!,x) &:518pD'rYҵT.:!ސT {)J.,S;w]%u{p me/T%XW0"CA]xn-2ЍS9RlǠ6 eWQV.\d~=/gO9IsIK`_c \{, 63^Kd+(,qr CwYf@=b  jz|=*Lh ksҭBǶK>0 B:P9ؙTli=0DBBU( Ϝ@NfW'Y̍Ϣ{ wT_ߒقE2 "dg\>u}QvwsJX!)ᜪ !)OK+cGnbgyWR묞MTA]J Nz+.ܦT?( CY_`Gr^dCF>F:}qѾ!1 T<ؔ0JtT,Y&N]Oh8sjy*:\& r,k*:]_w ]c/9֢ &*pg+\)ę!ީ? PL{^|AG@FxGiZq+`R%7V6uM!/s>O8^7bZ\;UM3z vjF}\ҿKIz6pm豁S<б ^ ȐUʋA%!bh"(>y& nqOmے"ӽZ=97y-Fup n&nGeͿ^>A<|9BM"w~'2$70sc/'{|'^su+Sh D|͋=hbb1bRcv} ݸX脎඿"*>r[-"D.VhX*]:$gIP1Dm1!g;N]K(StJ1^?>uu ;ʲz?xY~R= gԙ{{A٘g?-a~_ڼ4_GƱ74[? oǘ1/%G}{ ;;(V BќU>U74ٓ6T`\z.)J>{ m'yAejV*:7n&Vhl0PcMuau$Oh~}B N.$dX ވP y& #_g=HӁ+X8z!+W!>b(;I#1)d5X1qjc*#]f괊j@bt?^tA!?} L^ה nt>p2dwD[Ȟn1 S-.}&{s, 6ܴgC|5ɏFc_DSE(Jzo]]u2'A\(n(IY]&\ b'LpraVʫF[m)qWWNI3qDʈi޹\[c hR ޠ8Z9v(mPoBp_ʛF$O0ٕw1md\ c?uC=[1H0;m{&~y[l֫zGv4G}d^ӱ~Vg:'Nyƅ+9f9dߏ?=}<-V8`DNnIr*޿?t,Cj|Rs%߫G|u8q(cU#:|IU7(1{knfG+Ʉ)$YWv0c5vpoq6:2ex} T\;IM3d'61iyW1ʝ8Y:+V˧ٳ~v2 J.02pݔMȧ ]YXzǪ f6:IyDs}5JHs)uTO5Jq(!bcTJ`}L+svlpYqwd%']osu?ڤ Lgٶr T ٚ}FT !nzO.OH>K#6D `XPmp-3 $oUp˸Gr@f]2 02<L p'ml yP6^6 4A@[]-%A_"2f#=\>M־+Y1opjQ̚`@;v x69zqs(}/BԲP66bCJՈњn]ӱ Vl2MNnzY@NK#[&ƿU/`ԆrH(yڡ'h'%b2/EgUʳgiа3L94; / 3nu'%۳'{?&å}l'婿41j[ REPϣڥNT{ 8-6,!x @I=q[޸Ş"BޣBEFӠTU;Cw͇FٜpP6vZ]5}$[╊^ 4eޚ`tc _> g.I]S'`ZOk:m2e.T'Y A{f'G% ォ>O0'r)|E&Z/C oARbmlo}f_0")ʃv;\ Ucr N!?*˱ngZA4)X?a[R6dwi|IYtW'$wK2R ui)2([uMa bZU] YDⴆ?pqD`GC|]>} f0Zye:|0F;c2QKO\IхG`пYRtV٩T4Y3؊M>>=~m,}MN?T'g)û A6wzz"LPQ!|"n}Kp݆T'8FvM ~4 ;)KM|V"桮^d"KTv֒Z3.R,%@(:+c풲M@۠Hg?N_-W7lb}߿?_bS)Yڴ7B&s/ux6IѝR@l[q@I9ȖV),BXXix+oȡh[g3ؔ59ј+#UܖHIBҍ:w>.9)b3Wx Mha2I҃8w4{֍azoK6[ih^r(yV'8#Q#uDꚋq,#NWL9B@ #/eieCYGXw"!$C4+NLEeP#{ׇ5^/&8O0M3J'&^TMnph'-NJ,"{ȕjvJbaWOc=հ*_P±Ƨ5x28-dw'=>z0v-6Zoa ބF̑22.0f4om\N=V#Y(fe4" rq~e×$[rA'.c???T\q&ێnWDE?PM&ta0Yӱͱ7#VwYBx%'ǦagR~X8ʞAqI,ZͳڲSZ%k xݯA4m ܦK~i@et/Y e_,ɑ %N fV"qs[Uuє4E26e%ȶ,,qe~Ybs2ZU҅P՘ŋZiZ029l{low}!'h2j4f!.G{~O4N_B7gދM=VT=k.w  D&@.dMUojbڪwszg|,x_d(x]bvk(L-8K&q /̥OvN 8ɚ;8%q (hzUc,0@/w+%~hrm/HDБ(yʗwGd_E H4)COz4aY%;R\MRy?*maxfxy!77BDj5cC'j( (vv}0N>'HW戭"IO6Rz5fc[9]JCEIr*II*?YWY.9YQ~uѤngϲ "Z`#ՠ~NW?olԞvܭvh_~[*NC| gK|Y4C{(̝Ηa{xHZU|A6Q؟|PC'R:~wW ]-e}cԳrV&ܙi¶+-q:j~9(EqGz?#QbЧM$ʌݿșлyXc+2*q,MTꦽz]Y)W 5EK8MyhW&ؠ^2jw3KcuiԈQʀx2` lC=SM9VƝ|_K82kCuē7H?_44A@?TR=r8r -oP$;xҚbzXP z;:TpOq[}Gr&ẉ oh:U1/yxn{żø';+MYgFN"3W֐$ZAFmuhSS}QHBG,Ӣ }ͨ`<DK<ʉD;cL(>[ihh52ȃlF˺,q=vzodN7ùuo ː=Q.IT;1JweP )<[7ti]46!2D%0ۀ,C~4,g bޢ.mEh'Tx3#zbǂJz)+3 i' 3o2Tha!?y1ߊ0E)hrR"E]0x3>&ip}NFw]ȿ&if7ѕVB"3uK*Qcٺ͢/r@1i܀H'+tLEIb*Q lA +&g){h.k|IsLqiU>Vp/v'W?j=ӣ* \%[`z2ޫjk>rGi0),NvF;ƶߔmՕxr:c;/$o▰i͌ S5U(z ?)ϮVsǕä#OP\t%c6d2ɿC7B6+Ux(jK{/)'oMJMN`-&B803:{^H k[yՄR  @~>#s0(\"P}+(vҙFkH =b?EˬJpc4NUC*EMYbb\!sn}WՔ߶YS )q*\W4 pKu>F5Eю '821WME7TV*le{7F"Ůgt=b0^X̛gbRnП0e4I ɉŏ&q7h3%iҐ^9j($֖e 7LDOT3hԫ4 FQ&_wgI>{KivɥMAGl"T7"4OJ|*!ޓ(/vnc׮1(q5ԸQFdU`".ZlmgȬK=zgku(*&ӫG9'ޮ˰C;S t,4/M[x t0ӛj$zw 0FD'̤ɖa uhXL DEbd -rҕ'K|G(AT+q\_xS|SV|T! )IgQ?Puv*OX>9IF=J^ @[%E`yv's\d${sTt&+,J]*sjI=ϗˢP,n&>f." {o7Z ue,85$vw#$aX<̮PkƐ>Axxn֩|9dBD{/0))z ]#<iN_+G'ѫ(=Tn$L^u =pb,ybZvE!t J O=O{)Y%fr59"lhȌ% G蟲䫱n3iʟE3nD."bOJZRЗ/9T):p?G%13iWկ\n<|Gi/N2&x2%F]@{̓%?+sct#4cqA79!fA=ɠ\xintgq-z?di)#jeU>ɜ*><46)WlPq<+7EDz!o,FPn^(MW (2CIW4f.3'q<dLWzHY yuX-AN|z/{5(~쒄S+}DLJAAw@(f0ǩw85Xu3*1qDZ6{&st5Mm.~R#^ _sO."g30 xx/]? VSDSw%yCJ0T'|N7L] G"0)?l*UCzWp݀fi*%ޮ0"]q>j)ؐ|#>yH򤂜HF$υ玆z=>XY–\hpMDn 4q%97'6GWB=;ِWg5e2m/bGl-q?L@% ̳CsA╼T5'OQ V3}S!1qn8Y1sH"g.;+׃r<8; tjM, Cob( 7ZNFAA*ΛB Vf$EL1D1Z\v6oK- KR{0^y.yY#2p}!Hqތllžz*g\A?NU0<'iEh* Q-Lrgjڭ6, [E r"-7v;N@F2[h_E 2ib&U oBP `\@Y_XGiN(9gBB Hv"jc(5$|AlDNG: @1v4Ⱥ=LX]k-!R`CYl^зMH@đ2q@kR` /\O=㽾g4[cihr(1@Ô*;&vnOU8[|B .KZG gFmfrރ$M5cӬedϿK<'<qi[BVgS`=wY8%7bZo~_ɥpT ꁽs/R@L9Kؒ4Q~ُ9p6Mlߨ{c 1Uo~|O pC$t,3769<=:/Rgd=j͟`?I;tXGʀam#0bhI{~U<+l6d,n7% '8O5e}>ZumSMNCM+6Sݦ FܻNզ f(ml5Oݭ}'+B2D|fڽK9btqJƬi `2%zM ˳`P(M^!fb%\ԁCMHsߜ$Qgl%,fݒWaN)7rL"8O0R ̡Bt jmy |&Mp٭,hOHbYG'R,bV##;5głA\c4m 61&a,ĜGH߾'>NPgMCUٗHXiSB{.ev>ı1¤v3dA3}_\R<ӂ`(jooe[BE;_Lyj_wEʅuq;_ 7F߾p~LO&9ⵟu'4kIm7%Bm3I RfgrS&I&̫a9EzH"i 7geao@_3.@~.XU>iб ndzc W7R{68PQfY''٠\("d,cYrVyKp>M٨ "1;cl?%)bQ=Bq+9|_œIrA]'h%E:\p.GI侙]^{LP\%!Smܮ炥#AqznCdAiZ5!ƫgřÝqĒ8v)+ ̣2ֺ۠Ih_Moow dLU}Wی,7KM2kxYIȂ^:J<8b >WI̲Wbgd\~Ζa wFp' cc;bL?W9ٝC@ʌߎ%Izix9;Qيpt'@h"lz&9zc'?"芨U"Te޳USV%jPAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT Ϻ< ڦ?H~&8zxJP9h,2?`VwmmjL1O@VfYtǩ#LpTeHE&cCA/2a[ްBaQLhL~bK)eB|aF88@=\^/?pQxlu$rv~rWmv[fqYY~lHԟώD%;u^fi $8aV 6O:4n?BzSQqWFO>,Wn%m Ar.ѣ. 9+hVWлb\,FT4-:DVk)=Xb1n%F<8{RvpX&{eɨzq @!Tn8v"m|k=?GKT}R#OMj, 15"؄`&.QKIWڑ?:{ ""hύDqϡbTH i`c\`d^*x(WL)C8>zH-f\k*\N-\)?+!̤PmoPϹiw"}Td=%[>K Tø4c cCH 1O$U@Y^ DYqD ΍2D},8\/n4_Kfjhõ> lshlU*) w rYMHuZr짔CQd܀.!Υ5C6l aX)VR`vcᴖ99o3>ݯţeGWٱFy_\A l@(2p^Ulkdƿ~}ǺEj c4.ͯR|MLY(,2(l~Ki/8aVᠱM ֐k C&j3/!WP[֟Ux ޓthap2k"Uѡ|x'j]y5HVfzy׷ !5f! rl/bgI]}<`{Ѝz㬢APS c7vZ3hG9p9}m2n)`pR:ZP;k aL,Sj d43G%!PL2|;1W"sXK[jdpv%븊1]49>*u-9xX.τpqO5\cDDO'LuVk[@'YIgЅv$6ICffȰj+5^ȺY ETvO^?PqHI6O:#[A/;1N6̝kSxc὞j e[PyT_Bu: +ϥ &Z{.vKT$ û-elmIr&fe>ѿEOx#W[ix.(a `oI,ڼU-`HfOs<|m|$6H)~}΄K:($W~YM3fMX8`aAۥ̩$P"d{pr0uwve&?sy{(V%haD Kf?}4ݦIeCcPFQl5hwla" | G*ꏜpֶ0Ioax@xhK 6 saXa.3D ֬0Itv[Bφ qwDx,} NOcp})H)uf>Z4 X݊9Kt7.yK9 GJ5U;&NZf$%Ĕ""@Qdr_@ Nj+L scb-{}74?{i —wB? ޝq2781 !z?ʊ&Kqtl쵡3zq{B,3, pȑӴ,3pFFgϱ^;#ri<Ӟb -;1A0J⁉Ydmj|47Z*s|cޝ{{rkƼXK͂Blg25>rT"Z W  b?^ѿ47$H'(XyJsnBj|0908vYELw(9 s$hwqYoTZ)#  &X@Ab,tu\GyhYZip#(V NwNKbHkrLIJ By竻X"﷢ Y.+Kp(ZuAźU[O"ԇِw.)|hHYoa%Ԑ$_#= :F`~=2X)[ㅚl]~a0w@%jGFM/NYO)Xm˭6Jmm;?ī:tˎ؈'efbѼ^>—霛f 1% z/s%$  -T q-|뚇D%&քc]<3 ڢ *hlCMO%~:,f1 6sM] g9&M!8@1P.5f.RyIĺL/Xx=E@g׳5Eߘ&kXVme ݴV&sgPbo'*z2 = 蔌 I,r2~Ӈ?A7wc9Gn[ [r%J~k`GܰCt_N Ѿ[{Cō lg G]}}L7NW{1 z]+;[俟VdRb_`h"Myo7(Mv2Np&N9hMLzё\ m76J뭶r^/K+Ԗ(Qu]DsPOJ, ߡMVJ`-;6 jv0hy"!g; : Dbp^K6hA[}fxmI r^c֠onX/Ƞ~"*JZh6.ɉ9C|gXF5q)/L>8'wdn\I2"d@+Kzxm9?oTZ;S)Ę&ͣ;V=/$ƯAU)a3a#j=>Yi\i#h9N=~C:QTUlإ*?[1"H c2l=W*B Bꛦ1=)<$ozRC`U/ȫ|Vm~/;+πs/hM<$g0+'і\/j&6MeױO:x"=`0b1y{RafKn)j|AsQq-0Pew57& GaߩV4v!}?Ѯ'A][6KR7\P#8"+Ikr5W}][Id~?/C%;\ 8:k:,Em<Ġ) 9J҆(I2 $y zG3H꜂␃Y'/nP7=fWDzkv"ōZaY#*29;&næ};lVZLx@. 4\x|ic蝢ȋl?&6b "$knU<:bAf" Q8B+m 1 H?tM0x*zJس=<1bT o;o14 G(5gfFsٝ{'6Q!0nRS'C;E~Td珯p\ ]7ohҫ7MbطB{mxP[S4'*|2F!> BYD6fN_J$^'&C[v5G"ˋa6ACXM41sP :|PP&[oV$tr Cr G`(^2">{Bto:$(qtjy%lU+j5ڕK4$Rq:7oK(8D+;aE yDRKd1ZV&2`ԳyՔ<"#G`?>]GtĶ%)L䗫q;%+|RA/ DHUN%/i[Iz1MҒ ^5t' b녶vT Uڙ?;„ΰh(zcUWh%S̢e9: 060Kff}[8n72,i?i}(A5bi _Z(')*k}B80tBKH:r4ucd `K[ҕ3h5 ]X#Fm&toQLO#NeB``MPk=exvpͶ>bӳTBfYEeL*h@jrٹ{U~ubW`[$}N'\p'6#7Wp\,KJ0xRd~]| p!:@;PKB'5sOlll+ޏ'b%d Nnr!9[A܎Vo?oAcjR a]jbq֝4sJh dx +p9ɴj%{^ )G{䂩d9w!y#{tftv&1W?hP3lwsZcPnT*˳" OAԿxix:\ Z=qWL+8PTKxmS1yk=*%6j 7>78ݰdlPEFwn_k5wg#S* c9(̔=&) CoL9\jb1?Gpo!y29YhT`iVPÆNO(sKWOS.V8ZhzU6#9z>!;8IJCc/szeEtI6}G|LTv$|tr1t+v,!vEAm;a\,!`Ӱ&_VeBT *3: ƝDR#w0dp6׃qA2g\;4c`bT'McVI)3hzubb]lejhdF)SrMu&.G;dw7j& 8 vzܨғu4~3NlrY=b S cп*c L.$&N\&F9 |7|^^W6"qĐֈ˻^K__>AԶ}< "Ý>پ/cO;piރ8moߥ#EO67-坢24uϳd)8|nAB?Иr;H5Bw`Хq!^`->3dE.Z0KG-3['!w8H;TbA_B.t`R' rp2+:/\,C>FwaۋͩVc?.>D@GAs>x4l\EQjl'!(yu*#<\7{ qeomO-F˛ºSį‰Q^hJѥ:#E `!&0eYcKb[}DT)gva%Eo]:r3qիW" WU".eY-aE9bdu!dt5v"8L(dm7,;:z3gVcuIXF|qN<, QuүŃZ|b#|brwUI;kM\FrgFe<㘶TkC&/A.X6q}lN6/v..l:Qvr`#8ʊm1r\`#x[゛6zvO1zJ@}b"1)Pe#qk19eA!=ڴ@`#?RLBN\ծMlagqW8m+zѰ]? Qk5(fϹr "#ſ\1(?VzTSf{`2zL\fw4(54W2I"cCIA)"?(@dh^.aBLF 2qO}\S˃h_;CC`pJ4@st.(~^IԐ*-Sk;RJաK8uZ'k=5GlEj}i<`x` mꈓh~.SΉ,'XCFkhYrƪp=Dn}(:S%hseԥ{ot7# "n*$yEo \j>뢰,8m_9IGؿQNss^~w5s>% 0WHkU$V5QW(Ucj nW7Oɷ2 Jge*!' `1_ 'Bz#.e !¶ ̣CB9C[DZXmĦeF@IkQtVr^"&>W n^Hi%Ļ>t?{`w"t',%'{~JM' 'AК!&z\Ôw9L$~.wO|Paq!/KJ^Q.i;ڨ!FKT!XJ ں!)5,X*^eD#\m%1\J$Xi{by)ҴYnWK(-vxH#!0tVHڣyE!)BhH"JWv%,Hsg"[ Oe0 N5`^fC:qm3eACOI5~ r.!;)$~Wlʸ2Yz=x"|24(߾2ЖZZ67}͝c *|=>DlI \|*y;6QLJ\3r@H5D7d`0ׁߏeMtF@HJetӿUoT5HfU[CfG| tNTSBԖm { BFrG۾|0.*sx W;P{k |^l 6i}]J(>#Nדm5'Pgdʪt*Їfy!e߸U{3!jO4릾:9o6X]~Cϙ` ʇ aa!;!*%缰΀ wHt?i->ʦWCQsҠWm%Y^ܹh>t<g S*[H⾺B8"wO$QBsBf6Kia{ڪ@IGQ%yu۟>۬._IcPC1 c0"e: 2/ȤHb/~I8Yc4-R\̩yXV=kK 7o"xnesS^ArIjg|Xc[}4W3ʫ^킩MWxϭj@}MhL7z]y.q𑶰)!JD=n4;%Ӳp3n(*¶mybrve$>^ ښ7 *uC*^a8C7r>JPB\ GldM.)'@\c6C<\Lc `ܡ-c JpG@g) we(S!JI)DvL5 sT8nmp+բT],-5XMPK'@8 SpeOk5|s f:@_u] Z$/>|ed+sH XURZm'pc $F3S Zxw@ 7'pJ ؝gr4_t~b]9zP 6\2sx@_NZt(< R0F_v) Wܸ, SD9Ph6t;)v ڽ9@E2e1h%}!V-;S9O  "1obQf# `k,N YɌc%!DlKkcwYsj*:^pG{ѼOIֲms}u7|qaĨ;cസ("` -+6AJlGj3Κb5smgx|FC=kfz9 ,%k;ݬm@*OGTQ,3EjBd3u|"@+bC@,Jǎ5co#b/}-7̲iQ!ʃsnpATD[uI補GX?4xl-͈g ,B%*T{D[&KP\aRVk@UK+u>0$N%=3.'+/i26">#&LZb ɲ^YS@}W"DSOJ^t66ud}0 h:핈ޣq0J%UygȳHolwJw(-FP2aMT%3o_)f@ R+*XkiSꒁA>d.P\dƈ?cűDB< hۨoab|K\Zob[J *C&i ".u0e|^ڼDrLc= ͉jTTށcշ:7Eܙ}Y;2ډpn܇~tEc_crƚ2 kP*ϗ g%I#Vթ{HO͒'$DKOiKmWҿ2$;C ;pwQ@"o!0h j Y8gWp ݾ߂X Ljf|}ΰg]}= 9P =Z97 wWqwq zn 5 hص!B ED9cMScP!1bƄ&cZI'"t8-% qT:e!+_5tvSm>:::Q-k1S9T~ɇO  )="!5r ,5wZ.eJ`a3rw"Ue- |r8s<~Q9߯&5qE&L {Fnuٱp I .4]H\PcÎ$]% &l͡/?=1Oa2$HCݸIsxø)>Q+?h=l|pt~w} Mt=?vedT"eA0g]Fm#֒RF0x&z,)σ S.)ƙj? ᐌ6@sLՌF̓vZ×t=/XwjwnRtV+)4Am׮+Ug|8ýSCmpf.Y|{>^ƍyx?z5#V)-z}EZQˈlc#h`vFup+diN8U 5o\]̔xZU3`CGk.\dƂ|-z6ҫ-QtLv#XAF`;&*cUXw@x`?Hױ텖T^9T؄bpSƗgf'"ƺzՙ抧uBOͲبl*Pם&{ !6%BC(J*z7wjd1] # ~]Vՙ]!5$}@[(4f1ڔT\lbԪiq/U%H+T@ ,6E,!ؒ>5n4^?pS]U=yCə]&Zȕ4CI"ЃҘnI-x7g”˟< 9u-AhTA zmHa-qփUY 6c}.x|7A mjg4XV !颇CbzLlGj/НJHVҋ7诳?µ.[ ?H *|1A6Gu`}JЀ]9_rv:O0 j>yyд\aF= `𻆳Ω3C"^ Q3"y%b&XijSYu6qhHʷaW[j/teSñ[lv2"ŗ:~VaD pqmY-@t{`[ okQIYāULwsNS6 +ĎϰL My"1Ѿ,K67Z?P' P>ta|DS a£Rw>ˣӺWw} A-ӟ{@}g;wE7HN@i?bT P=gFb D,lmAF#UϺAĚi3a!/Sc4|r H;Z}IWN>^b7}Jk TQZJPϠ䆏gƲhg;dQ&z*VS5Ptv²*rK>Uƌ42 G&qi6)'4HR=I g]21b> ".㘎3Ju% i~ٜjBb O6?$kS+ A6Zְf>Rs}k|F#CK$K?a`\Jm:V0v P}*yHO/F[(xV3}4`1pd x婗?;N!@'$[^F6m !HYMS% T2(0cCJB[_!K tBa7dQl>N5fgRB =Y"; (&[:-mypfED72t:7 =1ɞ@Q-l}fB7''Z5([-|1h::=aPe3$2McV8K$G"(YWrjg7qI$T^Tf ~[Hh{R0[m.}-gYĺ"hp3UlOPV_IȖWRۨ; tMLÖ7&*~$\ *|W1 "RDmkV?p8>_,Ҙ}<4?-w˒O)oydq!~ ngn(0,:C%Bw9mv|(Mч)n(XEu#lZz`3wڔ{`'S!9x73)`w_oIXKC-#{fm 1Z@Me!-`Cև"|o hʓ6l5bdwj18aL EʲOG2!֊TR ޗeAuݮM& Cab`CY+Hj$9PsxW]8pZ,oo \h)tM#oJQ~ExO6I 2y2>藐۞s`Q;+ʹ`% l/%͖6d\61e;A$N(<57DRiS<+YB9NFuI7,IB34~oL4Ve<'4(F5=lxyoa=$<uat]A7MPz5G"PoZ%‡ÐSS~WNXFrna_ѓ嫐O)7J!y¸RnPAf= N@g5J<#h'%ߙ@S]9+j[6Epf߹2m5 -.jMxkZ',@s_h^('YZ~ks>P`O{u\+GrETZkPaגh3ż0Pk>?/&qk ɰή  9Hޓ3mSq$vrތpD?e{31 ^qx7U$X#]lZ))h!e LPvN"\9*zQ R ~oH滸a:f_6ztkDnO[ed$9ʢBObk=_%^f yCb4jjcH$'W `xp>H$oh9q8BVl]=mg{ےYʠj ja@BFƚrm6L [jI ~cΆf7Ȩ(Ssa"ɓ-/]D+]S%н7Gd.-0 Im֖hP*'u*~I+ {sO^/֐-RzD)Ǔ3\9vA#kuSԢ3K+ %}pv]Ai7O(opֲ>SJSg3yKst|xSUҠ?alm N286/d)|CLbR/Q3~UѭF"b@*>#[Rf߬ S6զxyyϪ4^Ya@ .}Ưc[z.͵mɤ4l_ "ctnO}I <+sZ51_(K-eqwWQr4wuq Aݨ^x*n9@K1 H݋nw>5?vB3@qS%fqzțg7y챎nXv"r|)V\geLdO'F#ԬGe|ijʣ󠸅iUf i#lCF $kt&Ӊ%sw=mov]GCc)3-L:_ⶭ,}yծTNяA1[b.2P\H-VL)|*f=t#쌓c>~ ί4HMfU*5AAbP&F艣/%(hj:ͫRNiG"(* !-xۅ C^ 5:DP}reYW*TwWŠ@橗}i#2A`U,rw$7]"I@ޖB?;q-5П/.]U ! prut/s /ܒ.4yO[/;s*7./h&(mbkgZeaR쿩XzHe5xLC͡zY w[! v{8DPqb Ɓe߈ Ø4[5fX Ӵ^j5屳d޻I/i0"v$5O%EC e3% o}8&"/4E|k E]\2.=3 )Rnk Q/"܍C9܎&yKy%Kp\]?U.=E y8w$0UIȂ<[ {RFFiISyTy dP\ g?g:QZt@-D嘏م\>I[*a_YZ w9 Q \2?AR( H,d{ 3ӑX)T2l#Zᘢ̮Blcxo_j8ኳjL 5(5쿳۷saAaԩ7TP.~_;h'Z,6Otkט(+I!wnV]5ڍ(\p`aV77e9QAz|`gOn]S쀦RXL4ZiZۢ|m4.H.2]sޔ*++ҿשU-;|Qd|$ `]"[pN4( p[.ho<0{MF2KEIOuG?<#>,j91 GcudUD]bCm|4a F67/Ohd\l*/K ԑH fZd Nѕ?ӊ[vInw6~ L}=1,ZTswlW%=3|;YBy\ٺVӶJH Y_2UguDAa Lb(mZ>0ϟzNu3A76)>p7org>^jL@MJU/ Ѹ' ֞G _ӝbkΟKdB4)!ΗqսJ\/)_,6+6Y];"Jn ̏c쌡]Ϳ|E4jr),]M1F菖#SD97¨ypۧ؁m^/ڪLkJK5;^@01kUtȭ4ZArP ?7D?ϙ uXꐲaN*iԓbǍK 6ڳҚpǔG|وwZd*hxݶ-@ $2G$c5U %Сp0YXl||k *B(W5³J*~\|HJRE;ti#@آiTi kܖgh ;rCbi ˼Aeu-pCeI &#1DPcGL5*MeɩyK/񯪓IW O2K۹u Q7vrl$XRjjM+>&`-Ltp7"fh=LNv-5c'e+q 2SU]ݍ9 竊ߘbNK'҃/BOTM@& 8d^O#Dul$fų7/^G?4ȡh d^*T/Ձ"،gl:{-B[%^.2kJ6s@uҵ8ƊSyCZVz?rfyAA_K?Z`(uàK960&ܨduϏ\{,5#j.< EW§ߜS9l@64-RSPD(j5M{+T2]Gn^Jؒ(o5ӪӓivF-b`>ZQwI p(|kTX,hZ`Abv'IvD( UO;$ľKu0sHinLMdu!8.O.j8i{&Z)3R=dqr)(*-"?ocױӿT,;[)C](!iYGm<*yr6Bj-ŦfmEZA$_=fOa7ʏH\ԫ=m;[jckw'qKCoKpOM|%tM;̇uaHR?LIb@EPQV7JTqP[IҲ&Qe ^1BKsM,>^]@' @M!x-mCbƱS6%# 7i?&Iӫ7- jwdk߃ژY{RjXx{&b'jĒKC@Pv@]~ݢs.);ˆxM ꮹ k&-Nxi/om@MA` % K.C6,Bil϶?kE`~`,)̏Y4hp9J&e!",rTl:aFrz(ӱ 6@,=D6+ Jyîة|]%bn8ހ&Ξt1%"Bno?ULf~>.+&lL҆)%"g⡷>(e.SBY A;Xl&8׋Q@a]bWh|b]Fmq'4  ҨYXYg vyˏ4ؔCo٪CQl͉[|E =jQ 58B eYS^T/tkh9vD\}(xy\^]jq]kC TlG=غ-I'pv؎n,"vڏ]mBLKZek+'yox-7maBczџ!Q<R{sB1FK~Ȃ$] jOQfٵQ8j6ܗki{5VqXK6dG*JV̓!-)MgP?#G>4äaEY jq+jj)+1=gGSxAGRDx\wcxL&{ nhVA3d_6ȒҸ/:_ea9)/ meV~A 3,D6%¾u(-SYyyR"4Q ګ6FfllqA=K \ ]UMCHcu. ]<U am$k9fY1h}k5eIrPpAN7]fx dSh@rۭ^^^& N59q2jB-+Xݳq?̥\(a{kz.;eAe~WYLjv)EtH| }`pD)w wdyho b|W/p쫁y%x17~p;!B]1lr+4,qHѺw.ea2#Gl 1..jWec moT]y `# sI OSE+ư~oĕR}HZs cۮ܍ Zׯ&kZtV{snWF[I45e2<&c$fʠ,J^f^ ݘW>*7HH0h#ݨ/KDMbu#1z&C]w5i^?,>\ElX@k"t"%Tf3VˢƓsЇxUŔiw=wz?~S+؊WIPO~j?p M\nG fw)1hULj$W bf5 "zݜ )ã4 Tʭ#a;~<~LK{jm0]&OU$o'UJ0Š!yN vB!{-1TP.OC\'+ΏV?/t7\؆!oOOӧ O@Aoiok!̻H Ѭ DUV B2 Q.qPMNtF+ m$Pe ;?0׹U5bEԬmZsUp C*n??:$~%Dx8*nV΁GXbL(;I=.~w_pG҉pX%-F88pa6ʊ#wh' g i`&RKSu҇[H'p{!8   bN L$?? ORC-_Db D֜7w*O~`ųK?gG^l >:pKpk}Ul)M%Bh'jXϗqG-EeÍeNwkp̥#q[/:\^2FBx%;.1Ȳ6PjĪ_ s4 |ya2ݐǶN5,ASa|`M4VdW&G" Ne]|+ENԉMI~uj(ɧc ٤&2=T‰ cdb3**;7|8vtvS@ת:@t+S5#ӑ"{\;?eVf"`{䡇{T^Ru2`{$ݱ{꺒%|q:k&Bt_-n1RZ$W_=T5[T\s=e\@(|E.i7Ч 7J<= quyflUy0[JJ*viM%5s`A՚DX5cfMwTd1-"4 D쬮U gކC6ZXx!$)`AZ^۪[R`,j,|35qrxatXD~Q!JbۧJQoJ}pmЙxME;kR,̃U>d7sLE#.ˊצq`h2ɒӤ1N(Pt֤J0VIxU(!+;/[wm7YdgV'-R9˜.9PjlZnP6MTo=s]po$YмUŦ_>e%u٪LUoc*rdϯq G~eޕ-h:{b!?xEBOe_D`&tc[7DK;LB=s0wӸwY1 JT*‚hUM yK>٤QgbNW>B2Z.d,mh?QTholp 4^ƆW~Źq )>~:;hiAisW`j#]xψ?yj5'Ӱp4tBV>Bُ8b@a~/|grR`/ oF|P  bčaTkGY?Gos\#0SLvՕhOZiq2x $2,ƽ*8R`w\A)jQ`Chyf<0oZ)z],Msqi zV$#ν7yY c/X%2\ FlM(_i8[UmfmD3a'!)4NwGQ9,QR 0n$ lb#rK يX{Y6aӸ8QE |HA}Rk_Ca۷ޙ0>P, lIΊ[xyV|2J_"< 2&ǔO3I{G730FL Cn3m*`ȈĚdHda`L{OH,q Yw.5[+']w&hRY: dc@KO@..,C$?ҝIW`] QGMb&h;\"u= Ăۍk=Bqy+VD;rl¬&)-3|O}XQ;F 8..#M׶bfo"j` /?SgT AS ra:$1]+Pɧtdz/l$!9@Mܾi6b5ZnBe%y2C0Yyzc?ܨy='.&D,kְ+Jd޸y5%UKVfk  Ɠq@KC炙t#/j$s5a+Xe-1˻.]{ɨ (r?s8U rE.y35[kc ɞE\\#l)ЕHvE*YCG=">EswqbVr]֜7ǤI3Nj9k_teTupI;q ڞ&g8 cp7ӷ:NV]:-1gTOekZ抣MZ^U`2YW/t j #o|W^.oD왇?²GS=QQ1..5BL%w1TVx"vNT‹Iv\B@ƌ& yGX H] oԞ*]sfsbJN ,5e8VSe!1Ơ8]הV4yD479B֤g]gj$eQ :x,<rBszF~F81kq4Ou+g[Dyq1[I@e%1ND(j + ƀޭ3Կ\R8R({ݣ4YIIdjZn G]z-AYA԰ um ߭=vꅪzTxaʶ,!(7 ͹vٞkn+铀il0W.wĚ5L?t>\ĆjtfbG F(./Na.agGJ)9Q{#}3PzKUIMwi}6u $݄ww%Q],k7k{&oԷ-4"1ʀ% 3h=dc9s}ҵUQ'^ WD("V(}|4t;rE0ܥA8Mx\mz] vuc>FTqb_Tr΄"@5hk}W)PߩB͜%%,פ›!2C͒ezma^=}׳NwT_0%6Z'VRw$H& /.cJ14yNIƋH C x+ \xk*0@gԵ/6Uj4wȜ p5d`Ml͉fvEк `7)Q) +{3uqm>QlC[uW|=k[S# jIo3OٵL.Lp~GiҢ6$ǸTvm{3B*QEU~ ŎxUhuyV\}C-Y7Zg!2E $V`hLh^~+y+1/*9ck* 4jaWE0tA'n zP1O716J^hM:-g64If2<{3> Y3@%~lP\^?#_?{ Ȃ'Ֆu33&NgdXP%8”uYAtv/b!%x$&3;TP p脫(gZNGXsɷ&a2bnׇ`+65OKS իmK̩`: iLlf8\ OkS HP^!;b6E26 & pw hW.VPˑ;wɗƥq|>hFIFpBEwO[fȋ(~BP.!zC展,I*_LI7z`- :7 o^U :kׁ0X$vFʵ?iFDʕ y8'Ma5 le~ *=e;(N Y"z}:QA 4<.GL67M6|91W %^@d,Ҝ" W8S4HN\pSy*A$(JSwx ̳179ܾ8`N2$x7'G 톒^$=UTo?nkH hɟY58v)FZE^ T0_^E>IGO›W-̤샟"vE+v7lAz[튫N~ %&-]m`(hu&r#%<$م@˻0kڐڶJ^d~\}yXE|6 t-P!}J.֐vs <3W#*OKxeqm)g^ɆZ͞ZBlz3jec$o'g!JlsֽYv/(\ZVlλ/a=Jh" H4#r-UI3k4Ԛ2c {?ʶ>TILFR246TK֣t]%h \0MziDZb Oqë^Hf%nI__ ]~%_ꜟPDv0jKhho"zLDtgN-R"PDc o w cTq|tMp gǢj&؀ښeSnןLࢗ͊+ƺWBl1vʳ՟}\> 2#UylĒX..̀H[R5iCG2g0wrVjiRKf:W{sʗ+A7dT~{íIh$0#hdh'*J6ZNxH[ڟDDibg#z9U?e Ν/W  YQ 뾯 bhZ.6ߗ?@}-޺<;hdx}^D>M#uzd35+ ,[ɭrtBEb#O9o")Q:pWIV]m %q/^LCԺФrt*bf\>o„{ONF }cu8(Arfh-(^rFlY!dD6wQHO`v2} *΂ZbǺDCʀsr%aj{zNkBE-`_&ecLTV&K,RiZ-m4`*|(aޡRLgXޓv8TXu=")LM>gtUPkS_n`iE^ ;1I?Y:Y{k!:K|XH/Ԡ "B CLԺj.eZxQe8mPר4޾d:-$<ʜT^}/$=XV6$VQ8^,y`?NapTF;_rmh=Amۉ$=bU _sz`O wNw?65vOf^A(;ȏϭ; ? c@%(8Ƅˎ`Rbe_ۣ01μKr婨d idi}`&^ |v 5":|ѫѱ'%"yW] 0d "ӄDu)3HbS9Z~X)%ޞ?~ 9Dcڢ0قt8c|)i>~jjyŕ4RLt3JXo,mTr cO[NMIhg,3Ji2㗽=iOWyRl2v9*KNÿy]sr?l/nhT܈B{L mBarNs;$KΆЧ%ճhZ @"q B/i[zݗuv Pu -ܧ|*u ч?X#V'RE!)IfRa $  d̙8T=2ZȒۏMOmCy(c[GtyS[xYlfP1QXjrMx2Ölh5 w Wb=U˺H@$>=mhbDAj¾HYV@z7( \ƣ8&) (cMXo šFGP|^~#w'[OA*|endOSg*teQd4x>SCI1)\s0WÏs k{*)^ kV0{G^Pdñ?Ȣ:>akbSxnN! R+Qf\~SW+ GQ}n,m4|Gx T^D;ddwQ"!}moD!E: 118|9If|ƹ+wL9΋% etz(?/*ЪJ V-t'G&/TrloEi VPxSӓKPxH8^fq"fZ'Vz*fω&-zm"Nq |(&g8JQXnݥoD@@;{1˻y l3?SIq 3za&Y:X }5F;\/_ʺ9u _uF~18ֻׂ>Yˍ$Un ˷Kޔ|iT \|Ks 7{`;8OMC+Mhn[_‭1e12hYWLd+iJeLɕ0#f[JJĘ'JAd)pc6L_R1L҅pBלY1f%nct@t=4p2aXI'UwCVNl`|GpVGXxٹ=#au ?/tXa[T49$f2R taP:Y S'B4WCƐ3+Rm\nc[nil@öN@tdO_ ςt&yƋt*?[@lLrbä+6_@=ZKs@#?_Qdb]HA)s7>|TKO kџ>P9"cgN4p^FCT(3-ެ ߬WQaXnD5g~cdD$E:Cߘ&\>GAXS~FU:U~&&ΤVu3Z)ٛV|"ﰆ62N`.SF}[Sr`J[3Ų9LHg$ϋ )ZXUP9vO}.+tLٕ or-̺ ̽ RvYf#49l+2Ă"1P/ TVNRfyk~Ӧ1VwWB~ꤺzۣW"C%›ǖhqa&k(Ԗj۫0hX}A*[Og.ժʱje(&¤ D[/@]Ǚ%l^a.rUFfJ+@++}2P2-s1$0)>,w/Nޛ:"f(P+s:{cnh*Lp#x4Xɤ]xPp- 13|.'2 l&ġ&< }z=gЧoGH˰q` 4j g_R)ˆ*Ŷ%f3!x/>r12xњJ;"eI]:g̋8Ta-ϭ=Υc@= ~@d܇ԐRO~n]աQ%v:xKتd_\A jMڡP!BKydj.".Ld/ s@A6DzT~LZۢo;OLs`\Дm^0$^8Ax0߆,Aƥ{=X'aqsҗev%Ճ>xOC*ҩ&1D{ wKx/@U>bu2#z{#W̸FY U,a;4".ou&xe\jIMR k7T3XQ_*pb}[ ̈́#^2ޟ2PyN D@OL^W3IR$E{nz.ݰ{n*>_Fz7?BrH~rc^x{cXXksٓqeYR,c=0glN>3~k׫!}E?/ .E0I?ܣ`5wQPZ{]p'||&sfr+l!z l!L@t#6tQå|kp9'!5hqݑu)5Pp+ҥ]vÆ7s, 4 + ]0qQ=6aE@\ 6v]2jF[ ^Q|A ]ҺףPO&n|yr7 x6iK͕7'NF!U$b#Gv3җ|;E$ ]NHV$iƤ0yw1Aɞw/q؟c!tDϖyH?EpXӂA-dRq Yᆞnzn<9/=,eZ;r]EN<嗐HQY `O\€[\)WisDQ EoMtEY-7I_ Lg|$gI:Dp0bQ j>(v^G*Ht9}BQ= -q~ַٌP򖱚295chw<3їtPyhVV4J\tUwgh[;9EEWRHk=E؄ŹKFx<9ѹ!E -\3cǬ`'Ot-xoggҢQE 7zP5KLAwȽ QS`G_{8Pk'\4eE%frF kM8|2Qއ}c L0~!!yEAAN\ b6њI:Ne Ok`6z@luK>OR| k d /;E;DsU5JfܕQb@l/,W"e0#a rb`͠ȷ*I@ $T*z!SN(dHWuax4_j7U.O/ڽqI-3h)0: D;x4T?~\e6J N ঁ^"b?/)d=<|#zqSh<+uqdā,9 a[%G_%4&ɰ }z-2dLނ+m6<hFJ$"?MέTyo=JVwmQ0y뼀X[(.s:tl~I +}Jm}/J5AUf.3 S`ոrH^AIpb똺Zl*! x8*.ȿ҉lٲEB }E Qq20qhC^v%T` S`ͮnrE~۲=>jsQE1o̫n%P?ӱQ:g͌pZ) yXr`?{I=Enq^X7;1N`HrF*qUiSߗƕ"J&xS_8#䊑U .|%Ns4QV7qv+%6?)8P@.,8#R7#g*T!J#E0Nb?#B5$ԕN@¨6 7e YIH.KBU7Vӱmڭ Qɖ [OeNN,ׅٔ5QS zI(aS5t_o1։  ) =1Ү[¤NΞU+Ge3P_ޣJ䷰w-ƾ]1 )2B q gF:IMpoVmS)ku{:Me⎸Ga a7*E͆R|-g[DIeBH7h.zWQ}(l_v6Mgԛ==ܓ_ۑDᒦ& %]V˪cS'٦ gKF麫 m>pW m"d h@$vȹ'Ӱ<Xvx__=X|AK#9]ɑ=<.x''LM~ʪ̒20 1D"v ~|×V|L6o5Dю١< )wV{*XFr%t JcJ qJl/ M/SѝQ\e߈]P-!Z+]N5P*ĕ2rkǷ<T[ayȈ1k}ef6K W;GFNw jw(i̘:jg|-CragynUp(3):FM0;ʬݫ^(h_bŷ:@ mgo+ f#ģLzA◛P"=|;Z/Ůn셊ƫA ;Yb4ƍ0=/bXJ$뉠~{_9Q2R]^%b$hήVHW.Lkb6iig7#r>aODJIf?!.[I xд͇xFeq>*bv;P#qJ0"fX^N0{A<ǬtFXᦚsG!yKn]]Ȓm|' 'BR' rq|,0 '̀ F6+RZ% ñrP}ĠŭV@[tCpFC(&_̞ fo3'yJnucgDUU $ 8Be=5kS!3G6VZӺ/I {^OjYB!ۻ#97<_L޺-}6u)8DWW9?)8|! NT2|!ݪP~up8wCPV,Xġ裃OĮ$3@:Zv`8?L:f FӽX 6E8JF&)OQmg8thN:1i%Tp[W D6fb`#5-&R0YW\c!ͬphk7|o΁-neD4k2L܍_ҽRp!_lOi)Y)et[PA0Ki;?%yJc m|U̟D%+è ƖI[$½+ݶ+'OjZ?٣{S%?\fg [ ˑXU&]iwIn6Rh-'.%djN t`jX1D,dWYvy`1Ȫ\'AКt{*r%iYQ_j%*H*9fUoXo$!E/ox7qg8^KQ)˪b_?c6;ּR#9Z$a)z8IM}K;)22x'I0{~ fOZ0.}ox7/hr:`WLuDA?2@Łgʉ]aPYT3E q딬aN0ݼԈB.sKɐFi(&|#F* 39SpU`8)dwXKiB{s^!X3ϋg+hʹU{ Ն`sbd~ۊguhylTڳ DaA-{o31 6DAYRHhOD_ߐ?Vsl +kv)A TLfv^Ys8BUEs2$\'vkMfx~&}ΗI/,\UN{RY>ŭe8JJ ۋMc+m*=aM3[ɁY8q%ȸcc"J#3V p(Do<ÙZ ̣uX p692u_mI#0LC"MW5](" j#4 ܖ3boU]%"2H_O 꺻N1]!U]B/p8QKΐ\ș1G9GbSփ.@ra>2o\Ho);ARcP4[P@=xZ =Hh+f>ζd2Qdejz>/W 2n$tRNak[!0x9C]X?W(EI3轻G-evEq( 1G:z'(G .5DZ<Ӻm=K(cy?0JcE)BJ߀@_!>ƘB)Y' Ge8RGT) d- jy,0KRL")PJ/,gT '4ݶ~ݸ@ez`q0vD4.Pܐϻ%szUm{"|<Q?Y}Y&i05+W]8Sj p : Lvǥ 4$Poo_7-dgҤ5Z ŖbLri3i NMY俿&/;Bx-"`>1tEY˅~n 0'ezggn\*Nųw0(RY׻8or@P*g&L\A T^m m:NvSj_Ò1vN 9:a'$\!MeA-PұQj?9\Ƹ/ú"IQx)h aAة",$c{K\w*&;qcօS}V!B(~mw=yoYPTQC }㘁Gis;"׶dA:F<_zsXN.NS5 c؎ZB{epbCo;~H. h PZ떑A7x*a 7y ;=i$GZVb@<7<HAYw,?{h1<&*}pum`1f1 K&sE sۉƻB7&_2mII6ns z-!>p"-ѧF#:` )j[-Wunj `+2yv#͒7j oв)iR0Ĕ ^7Qށ֩lM\o;BJkkRI!L/Xc^Cjty|X6%)$pGŨMrHW^ ֿ9W̅VҶ y'%_II܋l7;B^3xx$_C]:/'k~1Z5,rQ_T &OE}{1$ť<amαA zA2aa^eݭJ/[)M-M)jĞD1&16<2Siuu _mIָVb~ڭ¡Cy#XB6a:s |.6 ;է[#iZ% DZUbh}'8gzC2foP̚JCYԇ;zVuiHpLGNJ7tT&O3bmZA^AT#Mlsv(ԾZxS}}=_̀&q̶M24l4oborZ/oF]]t'&PrMݎi rukj(mE^͠gvkҁL(k1|PA9/KJtV:Ьͬ-Pnqe@Wq1+ۂS} zoŜw6ןtRƜU}rLq ]ގrϫ[szrⷝlv}M0Jqm)2Ǫ&0#_갘N {!vGQ9Bm &YG TH$C<oW)۴,QX2jɸN^j@o؄v6Օᤲqf z+?Z2G-Uze:-3hH&Y"@KW1oY1NjDEh @핉/ZG&IZXCUc.4H[F(5s' 6}#}9~dE û%ߨ$zb egt&$3 # >Zjof݈K?j\Z8>Bf\ ȓ.nL.]9\`z[J18 dF{#Yc$o50gIWۢn#:C<&RJI'kJr%q/oԓ1uʜ#ogSK|BiH?gr^0'b9-|^4bτ(y61P{?e[HkNScw˅t_#d=PkP"BI*Uױ&$;bbNJRO *^#%ѷq)9jYǯAwI ECV- ج-02M8,/u 'HOK}c ?dr?Zn \>f!  ].ŸuQgq ɐR?;lo 5NN[7q6v L/ůSC>$5 ΨRRl; #]a糢6Us4 oů_Kr9|xeAb+ WE"6W*Mz#gp9d!~gB2h@YZlQej2e ԾPa)`a/?guhK\KcOMJK %G 9M 뗿PweL!/;޼WBJ:yR 9gF#8Z5?K&mkь .=Ϻ %EQ5+KAEY]9̲|(ט<~m:C/~m(Nu zMG(Sa~i)T \a(q`v*09tLpUFWCgNd=mKj{u@&tꠣeQyDB8eqˆ<6yyDoEthBN`|Kagc(x$Y38\ܺL9x2sa0nMpѼ/zt9dSo062ohC+PƍQtlEߦ4s)mbE0P=V]< ?~?ɩ@×LnutOJ_wc6gM5 $s J/oXIHr7/r@Urd C,7OCěcwJuٱ+ b,vUX&3UTb8h{ʤg魣阘i)s.q !ePtVX<g8M xF6Z{Oр;6LIprAO1xI ?"1FG ̨֨>%0-"X 󓇾K[cTJ$!?x]}<`] &V-o{U\d!yA(-Vfʭ&nƭ(r\ݿ'Oo|km;ڶe{{=lnFZF n{'B֞f>|Wv"uwĹ~H_Eꩼ!!е}/ j !P:Mt&վ_y}Ph?&4Fr~WJEs Q4`eL#FЪ!qx:R6 (Tmy36^:X\0 |5uATʻ{we+ uءcv7jQG-^Ցą9l!eoO1+=]0Dq( ☧iڕ0aM$z7뀓zDgΓ,ziBaBa ӦvFT$ N"|.y/ ;bLyfӲ!mU:gArQ@u$bK)4fLVb{s" _cgג/7~ >P_Xkz9:,Peִhy׷3+3BK\KTS?j1Z;<7J{is gِyI(-e>yYw&e#,- [Q2~MeK#0xAX1gs_Z-T!uz>!.гQq1|)μI 4K?GK1IޅUj0: 66اӡ}vNR a S_yUE60918-PjYn0¥XwP}뺧~{1&*AN[SC;eˉ>6X(G R53%瓐w":lkPG A!4wr>Ll/_uL4%~mэoa|z8ԵC4"'Hx+-ۓ"LXCOm$ !D,dۂXgȖE~|:ͤF`A7W1c"P?l7o{`m<ʂlݶpC%ϒJ_J0 |7z= ϦM^ɔ 'pkrXO%٧x_fxDIvJDRoB2~4_MmT+Uֳ ;UL![cj% 3 n^Q*A4ۥݐZ?WO[$Q9Xޫ_&WdSk3Z]|8lZDKeAPs O&j['V8:;Q/wXQ*m6r {k%eBwk{ Ms]}cw 7 k4QŚ')6🮕׳uxiok5@6,2yu`\[闸"'=Pm{*̧~a%\S[FQAac{ ݅ =بa\L e&fڙ"-9%uG]Iz$(A! ׷"Sj1Q󤭙懖2;ɮ Yksma5(sIp3%.K@2I{q^qhNu7=bld"ĤD$TxHRbձCӹ.N ОI<G Jmf3$Axo qAHydwIiGfN(~8m<ދ8zR/ro(T}@2#3F!c{N4S)F\0g0Y0 ꇽ]%K4,wYy?~+"%2w y\6K}D.W%ժ*#Cxf8'T.dĶDŽtva#-AdIΏO vC$Y ωY_6tWc Aߤv2̇IR<!cGpljdz@{|f{|/zNi#şG%?!Pc;%رNxr+2i0mitaϖm8DR<2\sŊʉQsp.E@4>m-1b6 >UC LRBč$StĿsL>QjOx۰Q?i:yR~Z6n,4$+?`[xwܱ JT6-"nY[:,ՍaeBg)3'1nC*8X$ڂ<Bk@a/tU N=wS%[B1J I$8O0[%Gb~G?G%1#n;b8]w}w[F "Z8'(z :p ;$iTq 9EZFEX{3vv߄R[:#* W6eF*oYOi\)2}V*jѥ5/I9wHE lfG-1ӷrcL;9`Jp BDn)3v tSOL nNx-BuL;;J3iF;LhF Gdt=<tʩ&i1~&?MiBЈ3^̩FXؿ j&xiDaRDP#ʙw b 3u= 9z, ÖV.[#D@ saX|fT8B|0T-}U02l|eS7@@xPˍ. (@)\H^T‰׍"R)Ȧ&V4m.2zSգn߹n5x@w1ڟ4V8aOև 5"ާ1Ɖ~뚲ZPy>5.oՖ魕B: AWG&|zl&&ܯL %KJ=F!_8[l\w'UuP\&G7_>oYVJd7 .ȵtr4aFo*=$h 鋙hHwAA/hxqO{# "iL44;ܨ _":T:Yɽg/XXV&1!ro)5@K6HP4.z[,hkW|]DdCٙXXYPh :Pܫ'Η(F>ϞLž naL=tʋ _S[wi.{zt3smȏ H01lu:Jཱུ=FJ[-`fAaj*{H#bpVf9 S4M+x>8MTO\6Nq;eR ,[HD+F 1k(rfhf^,U|#dqlBS[C|'.~uӂ G:ӏ3(]iJڠNӿ|պO*@(J׹ݻSI&/g8)6囟aZmWT!٦߀tpӱD{S+޺!{=rdx~fF%ESA̚8nx8l!oyH>5F ;빣@6ݵeBv/ed#Uw%")+>Vt0SnohUrkʇxM |AM~c??rdE!:"J{;Βul|)8,Z˼SxxmDE=ڮAK4\O&!w#8_~ ~^|r{p|תy$;}O,V^7B;IuwwnFamL>Wl/pm~]YZXbvT5oQ`0v>!@n06}F֔qX= 9 6("P/#3Ŀ %"%4Yj>D*FYf]B4_nsn0ahNX(V w3-ݜ|fP}'-hӋug8Qd-biՌ6diSFAFSIBTvA tuHaDDzpmU.?#~(m׈M,] k3i.+b2U\%%섛WNJL wJLFO޷DZPi2$ 2b&q]u[*9".-9:{}_<貵j*:"fl? }z67w*2\Cb * 5mT7rY=E= N"멺KGúY5s;6:*+[+IW096ްˮj 1V[SrR^N; ΃4ͰaK._MDcК~nĞSK ўJɣYadv!Ic_Yr?Z}:rI`b 2"[MKe4^+GbbÒuJM\'xSVWg98|ן?$ǮzwT>G[Lh9Y ԇ <ʤ?ɔ+vę"w3YXS}s+tԭFQ"EM[&Lv)͔KrR2-[nX#gMOЃK@}$;s/tOV6ē%;hHTB Bw R܂Tx ܿ??',mV;[OX3ƊqՎg@/)$FٙFl^ bL ZV#fs=4,J`~ӥpw=FLj  Mp'ʵLyWLGD>2}:At5: -\@h>,RwWJK$)qR.@=ʆ^hFʰl_$6R}ISwE -N =0e[[ ^ytq1l?**o+8OLCijo`F?.eOcv?ʤ'"$<֯AcS\pn⎻0ć͈FdYܦ.`C7a=piV^-inCxaV@kUGدIhIa]q<&OWF&t?Ƿ7kY`<]%A̛ZrV9|rnёxGZu k?n~-Ϳ%;4rK`Z2颤L_L An3!uUJ/JKc5|znjFEbgXF-W5#Hr > Ƞ2 [kż񹶐tcqq(SՍY8oNaGoAg򱁪ap9-핝MaGmoرW%af+CŵvHJ&"ɯC4}G??=U>iwD+ޒ,WtUxs9 [Ffƽ2&^ *\|(:| )Sq_Q>, & 6k6iJF3i Zax946 E|"ܪV0KkOlC0l& Mrj^Xi!y$4w(M\tA+>i^S,9*[?NwDz\]F5.R>S?e6b^vg?z4ӏ~gáÌtXy 7GrD9Vxn$>Oq=q_b읎fȆAD"1Rk%V"Zl?bCj:˻rq£K 28cD#Yzjvb]3%F?qhl6jx}QON_[7HY[z<v3p=Rf-~ǰxu:5-f,B ̣Z h*eAϯ`G.vȳLlՅf7Γ&"}t +)o#ND]-!\Y5ҷBC0 ͽvz*(yH;+K19S*ZJ"-զ \_|/ #e!r-z$Zx22U˕F6^/@bHg3eǁj%cʿ6!5mRʢ{Z3]@lJ>4U!xK8|*SAh?9 (=5@hGycͼwX2B+׉ίd1ch*VWn\g{\~%72%-@)P44G)_Y/ ZGУŎ͏M<Q^kz\:8c"Kw{ITs?A3blSc FGieJ+WWwKA<樦nwPI8Pѻ%.W 6i q2a۽pZF=:_GNt~TͶoU~1Oho0'ߚ!4 *`L[cSK嚷IY1 <ʏ!N#| t?D!\Z.W!Ny"zM41f"˦ dcp(' E"h3\}/%YOJIݚqWr DapZ KbHmڒ'%%X *qd*E/!h=EWj}8qɼ@,u_ *@?o(UV ^/:5peR.iQO3.NG0 1:ʂe"06xQeI 2/*MXUok^q}kҿc$=`'] s%Ql]LJHjq^o Vb-`aaEqr?aZzGnwmlWe)TU F+q%StJ/d "^Szk&0ɞ HQ>2 +^`ͦZqjlKNMW4,_YvZf70J.`=N(=c`|eFVFgQD=;uM .m9-i3]dMЖ}{{WN#L㹵\sJ?Š}N\/h{{ buy $z;uobfj @0mǢ,Hݤ IJfV9f\-Lza|U:?Tv[iJnq$0g'{]ܓ46`_^ռtQJd(Zsv9z +<~CFQBU 6aX_ W#k*kPH>!FH3z}wC0KD]#fyi. Y(1wJԗ`2X;  1,EkbɫLU`zOɊ $Fp2id0J7N (j<j!^lZڨ#S{|~ Ə+})XQr~1Uj}OW*sk49 *1{X4jQcZnx5pRB5n}pVӥ9sq`>]$'8hyc2Sz\gB< U (Qty췽| Y~?r ㅠ!e)|6aeF1婆A"8R[mWj!X&EMϝ%4lWf(x;fQԥHƠrFcX5Gm %XF#DH?*걥9(@sCUӢ2d`IQ\4Ҧ[b =p/n2LM/w;$PWi'aߜ}0 W9phd:*hB߄fiS8OnFjj^'6N$f wUI2!&ݩ":Ls #јw{@}AKmCj@agoȩ~gs?^&.)%3ϞeJRã3l!QH6kя@ o> /4af|Βfo?|=H 6唷( /;NjӔp>VKN۸<Hf0,%Jf#<{Pzs-f@!_/V!at v8DLi)KքRΨӺ5%_ޮnb ׊n6J Z6jè!ӇeW0YfCZt9 avlK{"Iuī+&ܯ'W|{^t>a͕o,Axt`~V=͝> ۿd&h`!U&1 cJۿ`n8U4%ƃ sIԠ;=QD7 b8i HDPp7WwCeǘcv.٩b!YRܝb!ػg~b=*A$7lK~^Md?4W )*,/wt{CX%mnJpLBWH{_X w@|%Tn [۰~D"MJqɢC!ٺ㶱I:s>y&¦{E t' xeBlݬ+_qW0'2W("(@J8L_7:!c@Fjw|d\^($N O v4 祖,7Neԗ`]gvDBeقhȬ`#nI6 T2rNkL?dM4ui$V $_gAxq04&K.)b7n;=1R8^9qs}`I4nnKH֣mn0 ::+no*[_H-d܉dIhH4wrXǬXureQ(r_DYQKθpb*I%Eƕ+r%)rGeV2:c#K,{a*Dp/P/^k 5FngInq@("'0/7!hǘC95 kcneM04?Ӆ$*ChjśjS8zؐ柚o7'"m`?|"pY?{NZ3_3]lId y{o'/ůЪa/m&:LOu LG54fKY.-QG.*`h #w|o> GT =VP4 =9!%c3uѹoa^] Ȁ}3z=~㥚e$tx!{ a*gǢ*(F7gi˩{F\sؒ:|ADh{ҺsU |!6kI#|[l#?)$JrML^CZluOB7t=b0fqt|9Z6M4Thq޲fրI/1Rl`D;f2t yeZ#pMd&Hb9,PAw!r"/)^Y;*NJ4_{{~Jj%*ā=J QEWp tY(tq?%z2W-P;3YC<&Sk;"lbA$L:&0> X~_ d-)SHͱ[;ݎBU|y[=SsjPѻ jj! ?{xUgt2r#9$70F켹|x@ H N„{4Lv؛PpZ00I+5TooO+*9#|%j_f1,NxPa$ܫsFC zU_q]YΒLZ2 Xi(?P&<9HP?OYi7׈xɴa٤H+d&r0$u+_/lt<˪M~B/Բz'ǰ| [TŜ}tHkwX,%5c˛'{Ի@A$OF- L8됑L0T,+ #ՙ86f) SP#-s/[wdw;*_2@l?bD~~v5cϰ= +FM g ~05%.o{ 羊|AKx! \?o=&PV[rЍ5/| K?7O3pR:ǰ$oP6#:DQi/>`SAL|[> Urٙb\.KD86ePk/qQ2b; ,7d]i8PSc I^֑O6$yƢP_rr$/QL"⢨|tdDёEbbjp(-_IEoh椗K/ă]F[~+1CdYɽ9AKu)ɉDŽ(ѪcL<+H6~]gnW 0KS$xI(LX dܹ;y٬omxݠq(]Ϥ^=CdI.eԋ Jcν&d^%ͯב̩gBҤhv8oL~C.`vh"qX$_n:-ιf(4/N: :5[~2ʌ@%;na|>ZX{o*gg=-HBpׅ4-d{*%)??M粽z*M^L57=_=sQE7VtJj6hұ2*u.9-cE]O(;8jzU%[Io0 (]3&:/Zk"jblUDʥ>+gTbU&ۈ('j;Ԋ|%Dca-0j<M$=3\>F 9?8$.BZ>[@9倻K3 ˆvy1(qEj1PxtPnhB^"#p>']? ]QՃl'qEk6b7pCXt1t슇6%P]#`߿ C=0Ps./R'(_?ɾt {Bzi[*Kz- 5Z"a ruTk$(9j9J^@q0;jrрɉxZNՂp.XsU-I{)㟣DgxLFnY#DŽٞJȇ1G:qE/b>qOeIgݠ#15LrqyhhI~v6wx G3i k,}'p VA.det3L|U`$J/@A"rRY? >9̍&a+|JM8[. ⛘+"*.ij&OcȺq*\fLxQ㉀)8w '=Da^8tT 9Zg{wJͿ?-:^&ox`9%8Y#_~`1$u1 ƒ&K,l$% ww G@svoZգ O0"Uy} wb1E<0i& *\,Wժ<k S }o{`2[AYDDs{jh |j$fЎŰzltxy ᙮\ CvЕ%ݼ+x$:P*AG{7SM b6sqtpǠs:chGU ݈hնbS 7%dz%TRW<< T&)A=hݻk' }u­'a1 -gڔ4q;2ɐB K2u)i$dZa=q.yqm'"D$O7z'P|,`JA;X߿gtRz:Be´SR g2=)c$\Y&59 n^]q|,u^i T` dwv2o9!FWK#{VS2߅-+.ta\|>v֡l:MH//8k XKe!_zʅ)sCU[{mh\_6Dg{{ߙ8Wy@ v@2Ȧ_nmj!G.73Sឦ|0XM!%r㭉㮕KQb2"Rpj:z.'!v S܁Z 56EK]OJu1]Au͆зѬ"a?@a$M̱!B:{fՍL]Ё2LҀ d&ʂ$!Bkb]—~Bj-# ؟mE4K@`$Tޜ9gPV:cZ+ZunEPH7耊T`Q c%"@oȝCܹF4]V U 㟽&'ߕf:e&$*Ͳq;ZpLwDP$9'nșnߴYTkȹrv#eµ?7X7R1}&ج-s-F3-8$#M ?,4hd:]R c5D99\ZcA1UHUUT{/8\dX'>Z63GxF3@4WiXWH'(XKuױ ژtja]U2-l%[IsQӔ$R!<ɱ2^1=*H3#HoM!s3eZs(W0cq@X/(IlQڟIRѡl퇹ȃh(}9 Q ؗB: ̓hOT# 7ҧB>~>nnժ8ApoBKͲn<7LAL5.֙\! ËY#UK7gTLpwf|PgњTj$k4!AE;㯡fen9%V~)#Yg:O7 ^?b%S:]+q/`2IɷKH[H.ީ9u75@-1k2nM.]ս'qoL. DHŜM_MQ;[nS;e2s!"%ڱJ43y;}=[o_zHot9x Wq^Y<y 2V0O1?yw2G⚦܏oQk%qF'x\b*{d%'*ImTǰ_48d9aJ\]@A186!!(Khrm9ߚX:~`QN퉄% X*Ayi"қG10z@,.[\"16|]*L} a}b޲~,,]$mL?f`1cӼU2ev,莊#t?;F5&]͟$x'Oy$*\:,~&!XkP@.'y0VϕB|7a!0kvnp{gC%KHMmz\A(蠸 H$ZB]tդ̰NBKGr ]M7)zXGlKY"ɀnDйsY9N{SIljȢ50E_@Q 1鬻†U>*2g@5"I1KAJqZD4,KPb\ gJBӺjn*3Y &d̮ -kjQO*;.x{l15rCq; $y Qd` 'ݎ Dl <BJPv5!|HK| ~_[Pn0UJXz/+[^o1TcZҩi*qn/e#Bݥ;\xҲ ݶ O= _uܼ> )9WHZ@ pTi#6\TFlQNٙe@ .ǸF&W˼./Q 0nY>fqqP!iU!30R~n9}|6*4r*>],x_Sػ;˥UXImFo۞VײVK4vdL )TqBwYQcյH"sdwq͎e/aB֋O߿bms68>i1S_wߢ4fDB6z\KmΉT8!n V /}ϳ;-;-_dwOp1YA3sRňuӪ#tƿ(B(:DM;LPvG 9G|W4VjL04 :X&Gx~Rj1Kn /hs}W(;3aKRn|[ǮA#)os~9jUݹpnk|s$_ Yp [ P;Sseyv$K(+4+w@zS2:jOZVC]AO[3ޡNО@zL7[[=q) dG}Av7 5N}0yM0)y*r^zB`qQSrs!C\Kdp(.??/?C'Io,$d&,nM}>D$f2֜^|R}Ќ&bma_S&&#+)F:#Ϫ.vMX xBH `UxVC؁nٴg_2]CeM9"&AmŜY.R_~E[MU!@A\fKSMߌdUDQGHϔGm*g^ ᕓ~:r9UYPlOfN9T0KL/m;,Ew| N粅 EkwY~fMz/%SwZ ;v KQXi*7 T{xyc@\[ qJn:GkTr8{!  竢o/ nW5|NW_ѭ׮զ)3! `ޒrNP+LPRP)ʽ SVr8Qcd) ֛FW|/^+I ~god#IttUڙpZT.q߶yyɻoP(BgX2(&twA#4KhGqhU;&}W;Y':: DXXl)[UE7**+b,Wh@tAemQa9ywrzp#U5Kwq ة?N 7FDJfƲf7b8-WcwɽN_.UǕ4a5/hXϞ\2R` \Tj4Wɓ1>'!qTz)1Fyy̖<",Bew2bb26arla`?Uh۶~;k ]ϧ4LPت3S L- ! X? m/J]˹{U>R%&nc"64{ ^;[  8ps3sce MͽPQo,mk0#>=];U쥼vwz/{u+1NT=HTz32ayP70:F_JW ʻOQ׸a/O(W(FZ^zՐ{GBDE qa>@yGsEymcźR#.,WVdG4U0ՎUgQq[,ց>4x QR7d7)kp|C9{Cz/J&&_J+{-Xa O+W%]tff>`O$fa5tRu\XFp1cn̘)䍧=z`eF2 L1v]C0n u8 L~ UxL锎=6up+H~ \WK]? ̯!ʻc6Ls ix|8?͓EPh\ !H{wϾ&}B4hPY[g|, -i S]Qܬ6e6xEZIK_N8ԶlQVU{V'R{1V-?J\VJ >&.rX'w%[d>/OJM>og)2_&0j,(dtK>+\BmC4L&0Pһ8KB~|Hx{ũeW gRpp:`{{r{+@i"ۛ7p&VjLI1h/i%B{?Iw YJ^z-\ XWxk[ -,j8H):g˓eŰv 8jJ(&^FҋCE@W{hw FCAYÅnep֗T= JA!?.sUӨ1ǥihiDl71ώ咚e<l:PLTZEzlhS:8.6INAvQ3~k7]5~}r4Eqc|l0 A3pN/Qq]EG&b;ψ 'jrܵ gF[p sA\(:X!fJC}&F} GJ w▒H? (f/QZ@$J̌^p/b+KДD58sVe?^A:%׮z,y,B*j5 APe /AJ1Ttd6#m310^>:OܠCLJB%KjiĊi';[ӂh. [?0˿\a Gc1G)HM X6h&&Љ|qXդvmeʗ $V?1G!Ci:KYAeWsU8ohTf훌{?b)1Mf6R::\g7)G}l0xΫdFu@){x&뛵 Ϛ8'֔Xͥ*4,7 :СH(Y_KE%>¥ *'}: Ьra.u#J,!At,h._y;ZDHSV8Ag09Ԁu(I?X߅ƽf.~d ss ;ƌ+!EFG]OWaKۣ.wW&g#'YDۧ_*'\y4.B]D_ꐻ!ᖩsAjiQ/<>Q.=h]?O;/zqh5r%TZ$]Y4_5S9itJ.Ž8B EtOC%S1B,.lO3D-J0hά+l@@1S`,;k@?_uRqeϴ"Yj{5ŗo,ɂJ º0Um@E}rng;nM)s| et9V(zQ2He8na%l3F;>N4a̗ݍ4$scI8nwSuE(s(ftH_ Af$gG@gH&KoE3mn9F8k|6@UPAL2Ԫ8ー(va]bHp*ōQCėjGF?hP7G2]ϝ7-RY/-?P[Gd%ZYOlu071pƘ%U(9rg)w-p{i &T n;A%L1D'[U| (74Gb#W%@Y4Mͥ2ľ;;Y'rd\5(3M_?@UԗjJ=6d_p,ͻ[T TYOD2yP-((-W1y@Ću$T$rܴivoYc8+[,I?xL-w梗aL!56z%~C$נTY Pr&x!jG=O¤!xQ]͟v\-> tw'QtN%qG_M W#&rU~ϲ^6p.?/EA.5i1EpA9wZ%b2@7gDfmEk%`1EwgCn%3% u@ LԡB P[S stH6 XuHV\kC^@Ux e2?Pv`~vq[?;>ޞ,S]d!O}v]U]gϰ UݕĎ-Gџtta85OTVѤu0*%62 pEz?Q&`5tA±1W8TdJw"yC^K>CmDe>$ T ѦUQLj>?a# oz.-NiLK=ln4*uyK^ȚҡfuVΜzk2ns!}ۉ~0藋0Li"4kM[VIc| *R\GmVV|H€@8 ͓:2!Fb6K)ՅЙ=7\i˜!iphٲ6&`lG*1GNu|x\/*+qqs%y4Is\7Bf>+Hh#ޱ:B&,1p:6Whk+,'S2%Q]j,?g Ӡ44),nX0KQ^OhSm]GݘF = e,fn5n_4}-p]; % NY鵯tNFm~&U5">&|)Vvcim.*WQ?#0QdJQ|VKg{;0!swVI9ܙd1FcBB&:s,%P𬻰=rt=^a " DMX>K{sAWeOq XDH}{:* g3"3v[ ?_Ed4d\ c">@zqH`2g^ J'ALstwnQ~5ףG}>W~O_ƪSY"φdQPfd t-^qmľ5OMk$[Uf''h. Qw:-p]( _.=`$ 8)vT71s\#}N0 KV:m?b"Q06C ,C:2x7W~Wm_!,Zx1}z$bNvzSOSޖrK^M5|jշZa ᔦ'2PFysX4s6KBf++4FA mq}g.s 5W6q,# t͠:+3dmˊ7(yP롘T6f "]Rmk9g5ժw/DUqo8fsEaK@McSl-]`'xB9<3gGg۫Ѿ$exV {cREƒxc"G{ ֖{cblPq+fHDUfΉ~U9`M:1 $}~ gϕ`cVW)r_ZtF\h L 񷅠Yi9SSҥ N@%$) j5'I TLg&0tr(> KԖ0IM8jҵkV?JY 7:X C?~ۓ:i<(g5 U41V·'NJ+B]vupՒ qMҴ0QDWK㏚'97e s(`TLPqɼ힀8qv$AYe)TJ`G S1W~{{h+ISO>KuX#4T/ 01[`ߣzNh0U&iSUY׹%F7>&۔jt2Z J,A|lL-p{e͘!hOH,v(ĬT=GpZlu@;V\A$f?J߾qS_TWwX'QYTcB*fL-v40LVq ,fZmsU@&'4kQy˾ޏBׯZs s>.{bl$RZg, `Ӌ R>R+ݿo 7=IW!Q7 ۑ(3\3|ApX˱ (LhQ6OmLl#/ 1U_4v=nm8*S`,Ό\_q DԦ%c=i E亏Epc::;kVtJ5HzW ieeGfzo"R):L~YjȢ%9e"C7R-l7Qr_)©Pjl2#] {/.~jsh=mzG>)<3]Qp-TD3B;nNYYDl $xUKk ]YGM7;A?DJ=AT/ \(w^d[T7{c'JI:S5D넵bvk:KDa|AU33>ſ爠Cf%ETN԰!7{xUL3%pz0YKj]<@JF zd*"!F j xizw(0[+9xUZ\ n"P@V! ؛jA4kH]0}JS Y x Ƥ%e$d|gKHJ=Տl"[z'ˎ錿MAt[ze=*(,cWܲCZM:|&zŌephJP#vbܕCi+(w@H 0ؑ*j9n\Nstd’m,p`sZ*6`F\t,eBj  >g< CeKLSYP bH(ܝYہvDmR3N\$ˌtJΫ7F/Ps~M5VVpi&rm9 o;f74;8ᢼ^=" )!2nݞwH d4Ub@Ѭq}ĥJ-@}mL9K)lSOOs06 6 ;9L u/7/})yM+#piQh)LE?P/wFCH77(wh~1= r`I$xvg̗DK ȚN 0˥kAf$Ηg8="%`Di>Ep^C ^쬢QiSaAm2Z'bzqH{n_2wcpb޺lunpQɟNы]n1݌;%j_Vl\|MHa'ncHaCR= 0Ŷ@A^Ep'wZ(k¼zMvE]Ll6Rcx" <=EeC^ Yzq(sazͅM+<ԅH -@K{Iƙ}S=9Y v3r|[411@?MY2OQ#54nR3M)&L=};Rj8suh|Is:Ժ,6H7ب(C>9<;^qV:\Z6BOA z"̽\RGi Y;yeJn>$ C8|ܮCwH5&Q%^%a' (k f=[B'tO"ls'>-4%9[S 'Z Տ#q=\%p rg=@ mۊh3yU #;)^fҮG'~{zK4FDG1*2 Hp{4Uw0V lԞd ¤l \rD 'wbLLC!x\^Ic=Ly<06uTLv4]9:?DDŽ*'uu&"qLg/Srz :_%L3_qӃ*#^K56gYsmIYF)ٮAmDoc441nҍh^,"| _Țvva"W'-vfl. 1M,HIs<m[ٝz^ ݾaL/<@PfV$xrbY-sQ&q}u06k +;W;+{᥮} bi״Qs2o?H,d_O++[vqr?8A0 .HxLzj uS]]Xξ[lOh!F*;Ep1.U( nTC')f7!m,_)v]S`;H=qM<0{V\ G{ Zvw_A_ oujm%˸Ij%۠4+BK]:wzAKGro7M1@6Pb˘GϚJzv -K1ģ~׼# 7fmM)w5Dp:Ӣ++ˮ %yGXo*<\${+0W1!j쫕9epu}TeƧk.%tSHl$4w|mg]/}+F0gwDk+~#' l6U=XdPJMfrb>R9P!#:f/tL-] |by1,DEgwɮ׳f,ydW5Z: >y*nǛ$ uè5;bSnO{lM~ڈ6q2֥tZyg&~< dD@ն."kZ}H򘡫Ӑlo Md iˎnH= ih eԪ3wTIea߷Tx[1a𷏛'p$Hxj'ӣSYkEP^t"lOecEZ篖EAXIl l6 ' Lwo KI1i&< 7~KO"oT\ڞפy*ce 3۫ݼPژMES Ԛk,%]e|M$v+-\sGp+i|Q[⻬>9$уA|y9s>3728ZP~ҊbualJWeC.}Hݹd\+C Spۃ|Dh_׎(r9xʕ+P~C'A=K>g \Hw ,)yabdz "orj"=.YEK Ԩ[9|( xzb^VɄ6/8Fb#A6*Giijx Ġ/Omʠ<6J(d9R&pW6do=F/ur4鵿ɰB. %S Rc3L%-d&!`={A_C~1 C ͕E9l4/yl7w?ozs-8_{F{mX XE5C'oLp3B~{zB)sCg|) n Heshr3z\7Tn+ KJ݁,ΖNԱt8лISng`@/P1aB=|'.p8$ Xh52]5>G.W;0mTz^ BEGo^ τ8z(=7 ?/w<ʃx樑cTP( kT(YpEبxw[3o곏UZI,+5%gʁC\X7Ћ9$`wҾ>vy, #Z<ʹ&Y{ҹSIƠTXS"L]V0qG4۱3775?y >d-& 1x?h:?zݖe +.(rӫoqsJپ d7c/sAdAVŮB2tXG[i`Qb% '($xE l347L%,7e R0RT9:Xf-}jUzdFt[B$VS$s1D\C9)2&4)ZI.^ҍ)4Յ=:{R Ge!o ˼'O5ĚG\mL \t]>_\ ;R+GR"2nNr.L쏦Zy54.w].Ѣve,K륃m}-eݶ 9 %`=eP =̑6wIthO!}(/:Ck[,_{/Xڻr̔x'sĩnzV iZ󿏾E}W1g ǡe 5a :ϰnWd˳cr^v1 o7 E+dѿ;9Ya>6,%wwe_(ـ^pM+5XQ_+ԤCli0݂ )O:$?넞.;LD@vtV`#H\={Gvvz7,ľBSI)(dגm"/x/L$s%fc#, BoYEc6 *iQT0y򯹅Ӗ{iw *m;ך "9NO8+|IkxN=W,z"ǪPrZP[ f{ˇhpV G29 }t?!6X>`@Q l\pկj3z!kYbvxd֬m ]ڰŌ$v  MO?Mղ'`0uuv%|sa خ=fO~^0" %@N ߉}XdeWTR I$6yv-fq% p7v6lM\#,T `WP+~ ybxzk|]?Rb5WB=M(Q{O^ *,xlG0E8|36_rG"2ؼը' aLvH?2X1JB&מhY[Ѵyw'{vBHĠ:-vAT)<҆zVc}{1s etc sǜrul=Kn-bӲO$W4$lOBIcR,,x.ODD_E>W8=0S/h踭T˄Nܷ{P~`"BH 7@bKPڜD3${K1&^ИNhh@L5L@Ͻ$KTGʿQMMPbMX ZY|:wD~}.}jeAbk/ nF;f9V m `px8 .3 XVO%]dl“6M!2xbk8tr;ZUY 0(%jݛ`ԇ>|-@+9]P \;KGz|-YܳH'ѷIG>SCGP gEe@\1U$~ȩ[T[_dkWQFL"Lv4] 6C,_8ɇ<@smVzFw6sGdRǔw/=QHcu+ X DT12}RFiA^NBww[?\1?ix>mHD6ux.M`2 V׹| 9 oO6&b>aky<<s:ry*q{<ͬ]zuEP]m+̑.z?(p0t6;< $A vS3䰢A$<:/Ǩ؟^D8e'B&ȩ 9pz%'Y%TnҚ+x~Şݤ5R>`rs,뢯 *ӳV&~An˱C&r>6\18zljC@bJO|O쫪J1v'=aQxzL <.~OZMŬ+k=Oؒo *!贎 &0qzSZA@XU]{YaIto;gqP@1-<}D|wַ{XH8o}|Ώohsbb98.aWn13(E6i2ʂ oq7%]7fxZ[=xZҩ[{G9fЖ~ڈ>7zu9*|C=N7[G/yEhsɃNO2qě_u_}L৶ߥ%s#EylrH Nns i/uTbvs_G3ȅAKqafG8WSƜ*cN79HSJA(LXy.Lq@D'3r(m5-ri^UѾ} ,#B!<>'R,Z~O)+\Z D`jQnW2;z*rWPQ!/Iaƃ jƅc rvLmxˢbQ<+M=섘Hm%"ȱEfJL  7Tr4 ow&5$"Нz=zk:Ͻ(cEpkn3'D% xn.jEbn^[r;6LL;n3j;x倂k5c m `P(u&b)[ѵK(c82Ȕدr(⇯nX3nx ^g,FXB3,<_R9NEJX#"!5l-nI^WA_RÜ=,6|M0:}ʶho e2|B# Zfr( 6¢> qX8_8yiQ~ x}о>j βnU0 O%Ի:1F ==K .cv^<ۨyV_OTR᫪_ޅy5OdFE"0e>DHWc+I*'5QзC6^ZzO=rЋ*!$Uu KFN[-#g-J\KH´Qgnԍ80VMS=a:6Ies0M|Kd&=6*dC"7c,N"O) ڀ\QH`' 4\p O&!%pgsR)Ka:"2@ uFUYq4J9DZ%7Bʕ1 @8 |\0U^HL4XpOP3u$ CONG/Lyj1>nC [WDET>h| 9H#o]]@z,TM`SfC?7ch4)nC݈b#G}]PU?gk T?*IzT`x:wfh+!(`*qp s @ҩS)J +*nZ&,䣘IMJ>/Yǀa%їYc9mr\i>o ).4Dfؗ$S)3Ģ6ʺY/a?6o5I&:Ucz^Mw{SA(}ȬÑNUHm"`Pؕ{q8 m:2_s Pqj ^]\-cW)rI%Fc+&# Ljq^< >=ƹa]oZ nyy͎rr|@*EǨ%t9մส@M#kafvIU>$%Oz@XYl4ZaƐ?@ӝOM?%w۸XVCEZ/TsKD!e%؛`?I%>bj`;^,X3E? ܌:h aJ" PrNU5[j| p\ crDAl+jzh!C3hXl!tۨh9A੥ӭ]R{8rLi|'[n~u`5/N9Mԟ颽E+-46 WHՊʍ|zJ>sEZK@\50ucO񷽵8BτKqն0c5)B%̨qd~:y~"ݱgu-3*ti=l|;1ʊ%ݏuoQ$2AZaY+2*Kd<#i.[XjUh%ImX;TlC&utf>P0k  \󗣥:^_q mUA`1Z}͹+ͦ<\}i":FPsȈZ'_֤#fCni O߭䜭+pCDJA!nЩ`nqMœm9( 2=YDF/$uR;p?0ZgKdߌȃ3(Yn=s| ƴ2ug#>A96r-wsnz!e:q2ee`)ֱ;K:l@y7^bց \:@9 ^ߵ%Q}%U#o] KeZJ~d nstΩ )ea+**'U"?]7J8\48'|$tm'JTS{ml~$ԖPﶔ^{v'>B3u379(`ŝϩ$>چLکniZWoZ5bʵ:N|صvov鋟uS/mb@ڿʨ^8fk7# &XfO?8MjYN15k \1%HGg&RH씚C䴨\K-E3u6Frb#34"l\1l2 @AonQjy=175Q [!cUQ&T{redpsfy5:&/m'iYBnhm&6Pʾ;Vi+u$];DEy'a5=7"2PFZ*RXb\ SG?BEH'za!E d%-::ȝ5g̚O&߅xaT+]3E^wɣ,PZN(ZuB=}Hq ٴ}DFk8MzUiFM\I7c.ξnl4!|oY#Mro[XL;]sjy-7D`e,L>,^Dva\I=#< 65Ҩ}ZߋAB&&nw(Y(bfdOn~eDKzW_ $WX&/x3+N]`;S=@3"G=7CiQˡdЛB-.`ms=)[c,/Clh#1vE/Xj~26sAU,4OZRY{ KF\\"ny_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT +_? nRlN9-y4gJ=Q.*D(ik\ų~| ixr`|ѩ8Zdmi> M< NluF:ąbE'c"b+A%QF}A)#) xD!\W^,|_"~y \KkuP+fiޢb;:Unq=d\hgB;z { GZUT2-)dxZs5f ΍-nEG:3I7 tF0*nU#[C KZGF/9G@Oz`eSŠi_8BR,bQ{pH]hL5X)J8ѻ" ABz)SW ;1匴^mې\'~~Bى(TY140WZ2gZRdY._YB4>";nnG3 ӋA 2G2Y۝"TMxCzWC轛*nF zG!Wݘ8 A9pF)B^7Kƻu~Ϋ!CqW{z5F$>aw~w.2ltFTtWǸZsI0C##FbgփKaImLfEd񩘩jR837.K'giv}_-:Ÿ"K%%|ʰrGq,o05ApʋQ46pXq< 6YB  zQ*dQ\R7S#QIv:a{”+X 8]@WQb5&?ORtY'G*l1D Eʶ}L-fŁ?AQucՑd:կ|,cٷgUWD%܃>͎- LGŸg~9opr) {w!\P|X<7/M s,@ յ 9c ?&[FH;5W<'@]V!h}p*6EGpރBx,jEbvK׸Xkӂr1q*8lŗH\o nd#ޣm|]r6]/ 13{H1uZ:! R@e2PHSA`{Nh?Bm }+_L\>위0_ؠ&' 9 ʹj'@X $:thk~D=9qnB)4½[k*PHzjK?0Q&iN3_40vxoq'رyuJNw4׭TB5ѹ{rw7ܯwzvMM2P#Xf8.i9MR15Q<]@VjuzdZCϚ͈ J꣩j#I^+^~0~N(3|?k- %8SkxBz{G3ѳ\F<{al; u?DopV.0$Sƞjeɓr΋AeaM"`#hDL\džBVku BWr$A8e&3}?&fڊj5 N5ix٧0(wmZʕc?̈.QֲmdA۱=KNxO+7n讃vXd,9W#e‚8OX2.MDJAsle}opR"Lz6ꝕP,ĈS~9혁D$?v| _ ^7m=w9Vds:5yfeAdu.91n[!v%)"G~<`krݼgkz Ugk\},ԏe q 潙 Щ"4?vL.јgHHMP0)p eKɛ@n=ޝ@RPyO7;X(г0KؔU)r]sC9}ªþQL:QάĮ;{99-ӄutzH|Z)ξ3!qI,M;W09l[;Ӭ/"C ߞM?R(G5Ō:lAr뜼]0]v)RI7_[{9>q&t: ˳?FO,S};uSRRm͙A$y:t=7l T2umȎ`I*"?cUX6$mDrH!X) ɮ]0HGqI1hĮNAR|ѷդ84muwu6<8m6jlmʃ@z?WZ :f|0Zls6+ynJrWYg5BP̭TbP`8ͫijy5k`5r?gm7<|Oܽ'$9G]9(脪C }ݽxM{Vay-_/oP)h (~"%-ȞL<-;=ߎ)̈"`MLl/ZuѲ{3G;dXANMu힬O~ax?o3}?G1rDg}F*\feav_=$ ճh[#(@ 2DD<{J)%8B"D~!ېBR[*h͠">*<9]}k+s:>z4( CgThm 6>UAou.^2Z;Ф4Ѳ"7<xVҊo1iܹN9VCr`ea-zEes=sg/sȜcQ(pjmjwy}oP:Mɶ1)(onރ0\(PML6+hsH椁g<YT 550RSHn=v7mBi\߬8M\gGV%䡉 hN_=:ѯB (P^*UjOPmvbZ%w/`B##c${OKJ,ތA d!޿5j]p݄&HX4+!_|JO޽eǔ3˂!c(㨄433'e(]T{ 3S±+'aص|U(RN6a5h"9?A3D^3)ˉX 8ޮ~ƑC)/@y"i$\,omw DZ+{H9*iA1=Kl!7 L?jU'͇l|hF>#L.6NEPP%Z285C/ -kT̉40#[pu_UC]_iLo2\8'ҜXkJ+p3z "DUSRӜq598_%|Ӗ 2fOW3T+vko1VF\>.^<)k >VkLf{[};P̖ {)r[M;WK0sWVn(=5DĄ.g'Y}` ǁ$k-7K/x5p^p2OIjt] 6._S6!nbEw^ج8vNop*&u묀>7pS1*hFɞ7\b!5a!z7k3'3ME>.;_чy*>*gR}bPx~Nc KcE uZ&S-<7PTR8 XsP [%qjIsэ.f#H鲌>|Sy&t5%BqA^m pƐiMNDm6|Zo)" տN'#!VZLmG*Z0)reu.5/CCLu$.DE2ۀ(`oߵaG hE\]Cl]H ~fV=b3_B_(R!$WwnFq&xbճg$VÛsW[9K3pQSUߗRsry^M7Ǧ Ơu_RdB+ d ϧFØ`x4xj*(-(/-db ]O$xL<#$slx2PҴLJފyX#;LŮJf (V|~_g-ۧj¿C к k(х'AacBoWfd遰@ .jWђ!|=:s5ZJȴ@8LGgUEaVm/ݐ' 7Ő;CL&"[-DXn59} UBzGRyv{Eb53{Swq LjK/Uɷw,¶Jٙ,pžΔCn| C\sBE3Ge@JVeVcV`%/7G3tCB:Wt. cnKtԪbhCZw|/ѧчc!b*>{{9 ̡x^V?NTWR^BG[d6c[kHpdv˯z/`Ae[;^@4,M[s6/9Wxui}!Q;lŒ XM>ڴ"xFE{qџ%UGZBM1CLǧAp6)xy'h1R+ʲԋ3Ȟ+>Ӑ H%km /M2"1?6x)ԥJ/yd2Ij޹{ ?!$ܬ}]cgu2둱]]Xc#'>+P}e6zyWKBŘ4Gu Iש%S`ط &H}:="9X=ծ,KwOXԇ2yqu_ξ8(x58\M5MUt|H&RF&툋jh+ 1{azw}git4pj*\"804[nN2#b9&wLz KDv}\,FFhPcmA:z=I>"dbK'V)Yнⱁ}\(YL:{ h?qO̕ xƦ5 emKtNd=突1qd~Ac1Fa*8i= u:ʃM'(-Do 8~Z iϡ⪝:hmp!`̉Mv2Ή.3I#gSS*4J#p\#h SŔunGN6{bFxCh5eAI&tOWL))1wh4XZ3Oe*~\qԄ/;wVuvdc"JKҩT n3$]q*`5g=cԃ%&-m:G2 Kb,1;jpMBp8Tv*GY*j՚|tPl k@-:@?oTmtM8 Iyl00\anH}^>ΩN-h؈B2Qj>d[.9|xUi?ZC'KEJ0#'[c(~"eS7>XfUT',mÂSo;B4:6.Q.U[P`aӣp[FDF&*g>Ĭd`2)e#l6s5߈RPzB;p@GVE7,mw's6:Ih:2>ag?;5pe,f5KlVi>SV#&w؜zFOVtb6"*{cMqXoYP*(Fܮ.LH~ p SbmwLţLoOLWG|u; rHx1k?X'4ezs0̍ Tn<u^%1T"QUIEC/p_7*~c 狯 SUl>-&_ߌ?ZރCW*#Mv?G!ǍKHkq-ulz솤s@8W)59 ϼBu/z3ꬃ^n'3*"E9?\›to8fD4Az?@x)^Uʥ` 1l~mWf]4n94O͎SΗ[nOQs,~Nh*muP| r( U}&j|by ,ZJAqaኡ]\ԩͷ/ޯ.@樯jX$N2c} ~^i4#B9wlQy9''ֱuħհ)}{7)(s/B/C`N;Q/{'T(qcHmp\@ b HdF_D*Ku͉]o}X=w{&f1EV؊+>Am O["^=ޮY||yV9\$!(ʉe@M82o;}'7ynjE ]d \y}KqV+,V_9\kwB%j89Z 6퀖~NG},Hg_gm 4+*JݳAKq1]^XoqqCGi+k"%~?2F<dkOUjPjȡmgAt^wdzAa51?kڵ{JWYOh@x«ZT \f& $n9[kHLootaSK֘,aX|Qއܥͬg_}LTj\Qʱ>RrAI@v* W(O `)ͥiM噒!xnH3Dl[-dH#mUV0\h:Ep-=%gCiw['j a=ped%(W$n\)N{ŗWEif2R4ZRÀщ@(GS>S-^Z.yP->uMAyFaCOieBrTyZylwcƬH!ű0Og᥇bEřUϵ/dz~ʧ+*).9=u1LeH["a"gT`k}\,m43W#9yY1H2ʣhr"Į%5djI(xJ?ʲh4pTfHИ?]~H%olg'ykуXw--Kՠ!_ZC2uĭ,ZzkG8[l)]e/.B>Xfp" ޓo7sR+4`FULCڸ`i]=uE&#_j3/FE7*s=,U{'5GoNm8 4hNF\9 |ovܩV}Nq#T.BXG|AЍXo%mM)RrʭzzKXd:?!): mъ _T;( @ajlqܓfݾ057r NUzNN.΃0t@6dldSFq0 {Mr|ਲW3Ld" 2M>~(POl˰)nh5Ԕauͣy۝[e'Q)ltJN;T%<]3,l؝ 2XliXi83dhӔqwW9L ˉr2JPf߾,ގvQTknI>ZKk ;.mhDVIyrj#Q8⃇ _0 B"+\_D)MPq|W>3l[I!.ȘD_؞ #xNF}!Te--BC:^~N޺_F94"<Yw#Ag; d'ɹ, R|u1 ~>d:?q~5qBaF{ܨQ/|p}wItL}w=;Y89Rq謸:táNlPQP*D()]% O'Wk+Tx {fU=lq{s3RaXX7cgx󞧥<&`=xo :Te7 i^'D>w 2H]%uK*Cb(Z/^Е ^0.`J28E^RA){94ZWX,_`ijc-s]QΜ7v[g@B6vێ#ɏl7Z'jq4>lY-Gpʦڦw:8/X|u͎ЅlQ@^B@Hy vm,;9s'snhTWcPbHZ`KЫk c:mXT22.g_ 5 &.xdftnϹd5f7wW@;\f<@ldaH#UGw"H⤺bRƦV' a&S|}&CoH`texaaȇѕEYB-Dy%2̄׼6jyls@xrb5iTv)ei;NZs~hq&\XIL8 &y<*QU *Oh-aTXw2sfjH)uD 6^0j9?9#p[g0;"C3o{e!zCyJ'UXyނY`[NVG9= G-]xW-:Xh _%']} ~1ȗX].?a!>ApѱTM;u ٰ\.Ur1J =f2oWFkdX(a+y:KZH)|Ag2jzSjB-%Q7YKns5.4a_/nWx K|./2~خ#53>iJ$WH~-܁ *6W&EӭrEmWtȈ3@ r^>sX=!u"}¸ǁ2F|\6 F+(a2Hq֦o8*Ċyq{R@_q{KE$'i-_W #.~o6婏HB?N?[ԝz@^R?f &78fsk!/#٫n."+zVp%8%y5+UgE3;L9"TKZ2 "1 foѡ[=X՜@xl_ޫ ysh>\k~ya;6v;W>PS=a?;5 f[Sڨ[Bvm5lv|zC^Fkps 9̟$+AӵiɮjEƷqقJAp %8ZH# `7C ] D|,'TW0D;ҕS354z5rf%$C.ӜnY4pNU{i[meJVKڇ1> ?&V4M{ZAݥ- (Rf]V4U0MLI/dՠ " \i kh(ZF~.̞TՒH_܇uB)>cWY,AU. $ryra\xnWn5mGvѓTϮ/ K۔f"̭e)[bp_ 8de&,>ї"SUY}3םAb9_?a}tC6B]S&DH76䟖̤8E0K[#DFAT 2%kB$ =70fVb׶ Tt8< ҨshFxX"!̙iYX)Yd.;P+䷫B͞ 0$Г7bw /1mLo[X@ߪ' 78~2YΔR |Ҷ3/&>Kg@ucHCG\ @vBQ55;d}7VfR,KxDM%5˿Rԁ)GpwNfaOSo6 FLmD&qq=WĢer'2EЄ('P63x u;(,zs_ת5>::Mw?ԨDc1JX2T֏CO!oZQ|Z_ QGc| ,rΚLcj,Z^|A:lNkkW7%!VgMB 㪊f}"Hn= 8cAt-ob)A 9:S1n@#O„dyCJLAf{zJzY'Gvlmʤ~p\JBLZ: l~o9(?ێE\]ks5W6{`^R6'|qVG{/@Z)Yp3޴N`$]X9)_V,zos7bwe/@~(tT>䜂+k, SP7sr$8a$NeT#|Œ/)nw-.Y.S휓v!' 5s|*0(Cܸ5}@fJtn/.|G)T3,a '[if}"?%`',ILrׯ=vצ=Gn$@Rh1Z-JK4|oam(K(7\kblgh&̋=̫#\"J?j],vs19n*V8#̮`[)YgL7NsV2 v'qX\:~Qg 6Iη=,'h4mQXR^Xae$tW3Nʠ_098y8Wxdƌ‘];Ýe*ɠ_ Qqo8=d":n$IñQshZs&;mccsX0t3J$+2&Еü^cD1?' 2mgַH%E:%sD/=9l'?d2PbdIL1 gɑ_~WvdhS2EN`k-c-YAn޷UqdrkPV|`TֳEE]9X(kr>J3!PVAh}`L-,o0l[bGbs>St G'ym^~HR?n"u2f[lq&׍ƨffcwKW:ԁ:$cwNev] ћhkXEE`٠_뉬,B~Mi9[x_^%ESښ`6\ \7T?C`x:Fˁhc,N8 ,I~L[#B$;FQ(y'G]9EQoL.jm,EuTYHԣJdK!xx>~[kn_<ܼLH&G 6*ׄz+O"$=f8:HF zzT]ȻFrs |yK:#~{6G",>g5'_׏g聸1^9mX.UiNR&ip.A\Jx jJ5N[OX5׉J"09H۬`5%37MP}O ayЛ7`4)(Ӳ&ⱞl4ެKsٍ AZʺl|}yz)Wz9u/ƨxjP,x{(<4‰|sS:>.,N!'.*~WkPfyAqhmX+t~4;;LleYY(#Pg>J$y uo6T\/i#x囗F l&JcШ>{sbzrj>oLr$R_v:sEbʌL{:&_*3 [k*tpnqNR,RŚMsNὬ =2S>fZmxjP^Gp7}G*=[>uX{<5nd:׵v1W?;HJ(}K@}yY1Lr yW9/6^<(M\%ls'Oc Qz@-mu ꣄0 IhX@fbdp ФVx+wo:^=+"gl ݟ-&ds)_ TT9 L}fctD@E +yG+Sv!!hQs `SM+)f!ePgCHkDRg7iX:9_:> &WҬt2-,wlg1Dݿڊ;,2* sEKsLU{&+9{\'yKKӯv)1~.8:`v|CNa.%΁?9XL#M Go&J+M׷D}Za Hc8YN =vԫEA/K0<τQmtAO0mcW{½1?,G= +GlCK$EjoP"RW_׵Z׉gŅ})n/NQE"kU$X >~PIѕ jcvd A-LOrQ>,ZQ5@ )cvĊx\zz8Pjk5_ '--rwlCx.HZ`d,Nt@<ݚF7~"G'xb# IrH~>V#psOllnJ!o1<zQh7d$ɔ{D1QXj|26ޮ/_@^i#U>jaq;HTU6ZY}~'Rl_t`s+Ji~@91iέ(52Xu N`NA+`p*\!ЈQ3]0YX} 73qID)ϓ."d\0ڴ@#kSG*LB-kMJq3;[M'<=!&o30@5iV<*̻l:|Jt7СR pRgˀ#iVȾ=wtyG<\dL@~W,t#`+8Niin"uƀo&3@M?#b%bmyoW2[f}PJqoS) /LhF 9K6=)ӵ|+;ԅ 1AώU(SXaعiulCS3@a1A3֨Կ.}OH '0 7El>˧ty4㥴:4'UHqZ8''FCa ~Xo}Ak;Eۼ7h zg =KkLqa7ʅ|TZLSX.iK!#8HqzlKX){F#&\ȈoM)T0vdĢAo)߈ G8p=P(xG04#wEx.qB!TjwƐ[px@o@k6&akej\+wqB\٢KX8 . urM͛NJ԰25dGٔR!–5,7/ˎ[0|QcG]NDGu[^IMyD&žbu=-,S[a;Hojh&b8 jV5#8Q2gEZ Ƥs+֠7oRyقY*qQ>ϽZ9tuq ;dmJm] IYB2߃u 'WY{ ֵxkp+)e¿ǔ/\6/@Ha( Z708.^^FL~B=wzUP@ɭcC BhA/6sQPiS9f7K(.x5! \DC\WWCa,,\g},?3n&;s2M unS_ @B']Db,7+W }z_!s$fn;25?D*\1aÈRr4!{?b}&9O&!H3LٓIGAc4nsBN|9$W[䩓) ӹh&|HỐ@#cQ)7-kv(|-#Hވ9B]$idh,zktg=֒Nfh/I}< ]l^RuE1FoD["Jgo(VpR^9) O+AhԇYHx}_gZEYB2)\x@cmzg4ȕ )8&cxs 뭓鐹R 7ލ d˧Xvau-CY^H?Rў6xS|X,"@.@Nʰc۾֜Նf!ǔJ(3 lֈE>';A'QOZToۢnH`ُ.A!H5i$CQI(ߎ-+%tB Rx'%=.\7@F3o0kgmJ1Nhlg ;R{it}EkEg[Ȃ+GѤH:ĸPw[RwQUth(} Ӄ<}GkiMÔ-g3[+YVm(֧sv-G,Mpw;C&uA(YD0Xn _:rxߦ+aɑ|!ϔӫ&Z_mܖ 1AFg+$~s[I 1F< V-^&zQVϺqӚҺ٭[m@8džn2p gzgdž!VC Sq! VQ;wvaExWxEquB n"{dvm2I^ 5tuj(a>[81GV0nMNo)jAL.vmn["9qHiV/g)u6S@q\ܹc;{f%eA`%)z@dֶw94B0R5,WdN5"ۻ`S@ \0\YrydkDMϺ}vud' s1e ?bu"!lnG &Js>g/=NPŦhfϙ=cp۳ `l,eB@ypTImN>o`Wbm\F!>νW fML0UqP;I2L.Jd)b=QI?{81/ܺKz4ZZXԐ#^fkk֭pz|ՓA9 ؉7p K&g|2%m"Dc:l 80HkJp6-<eFq)6!E8PSnjO0 -;YuM?iH+pNNyc-QMM\rKa8.8n¶55wilǣ2vKPq)B/T1)Ny3!._}5GhZNrz $ c frjY[}X9zG𻟃YMSZ_"O#Z#)M~ᮏ@֏ܧ֔#u_0~ˮB~3+5 Ϯ0#5qq~Y퉄d&lF9(vGnG'Rx^z,r_8 :2쉜oU]Lq|NNoM4#h]A=: ((ѯKP]W¢ؗhs5ЖF.T,2*U2^wa7RFMQ#͖"pw#r``qG#:r>kqHk).Ȭ>L{潤X%!,]VG02x)LP æyObw%|yY48 E3 PCj $<ηy5=en9櫵ي!ϵ^̻lUVg9='2춦 ߋNj[dU Wʫ,,m@q%IDYb`n9y @X#a]S(*{W.A$iϋ~gX WmŬ%&VwoQYBx+<ЀAfd<x@2Js@kE.uY-<.˗gI00qg$EK/ ` #MտS-1[N/9O>X(ήׂBt&hz{ӛEA'V*JB|?Vbs  WJeq#GE*Q7uXhx\/[mnN2$3!X.U5`[L4ِ5\Q m= km_M)%CGF(\F)V?6k1@9r?( &aљIy(I[W/z++J܋ynd^G8]νSi t{:M1?hƭZJ! B?Ҳ_w vQR? '{NbtLD.M4@4@/78Zx8<T59$ zA}ucg+9}=yu^{Pچz\,c:lQHli}*:莌UR;)Y[t`S95˗˓6bdDy_G~r7g'SnU{ {6ƙJ 1I}u.-v]  jaeב{Bhy.՚߶.zv=^LiҼH\ *t[۷:t4X\VloNѭ`7sؔ{@s/|oOv34 5oG%#NJZoG^5*$Fi c1b=gs;sb[vRɟH] 6tf%Ŷosn.^`*t}*.~ixaA8-)6[/YR[5c21,r{<%Sl;0sn-BμvcPNo,c*C7wʊ;HKB؉CtDSz0%AKӌxexzZڬbR암K!y7 ԤToOedjHLonS,G)= /f,?8\̘NCꋯ,}/K^LX(xN8ng}& x᠑11d,VgbwjVqXC5v9J]$&"fxE)GNJ۱$ttNd)Yhjvڍ K%Z45//PCũDQJfJb54?L]ab=7FTr9R'yqH!4ߐʫ é} :6ԨC0!wlsCΤ'ɇ5ԥ2ةmPrB…?Imod ƧLBU^y'347Ŵ9:σs:=CjWnYWoЭܐg⑅^}bg'μFqte_9 7hOo̪j$WA;8b3I4V`Ia!ZӼEMqn["o\oi?TbH-p[b9VTE9PC$҅y)6!\F!R_y#Jo;d8䨯+7b?!L=D830YU0˿ BM x؀bЬs8D#g8bahjulx&e 15B6Ʌg=@ȮD}$&ޚC\I1SeZ G I`]@Plz!7)T9iӧ pIL*H[7[GY◨Z/ht~jD^ݣ_I+˥z4MrwYmzrN<Ȧ$h83io>u/<,Mz k1< cE\̞ĥbR8%?y;-:ovmS-3Zu r"\o2tx13WC[..t*/Ԙίy= :a|%0NH^d4"DD=5LD*P{(]N/X2MUgQR~oa ZBDdh5@Gbn Zɠ*P!"~~J2Ifv~[j9%~t~){٘ɩaQ%>̳%4J}W;$ᕅe9\]X"sy>8=-;VQ1Dң:M6¯l#p _#Sz&_Utt (u\'v`BA{ımǟ?VMC~vRR3}+!}gfTJ(}#P2y˭=5yWUVSf~G$1Dp}+Lj l(.,PںZ7 |H.ا[ANդuw#;OkqXH\!Gbē̍*P-jdBv^W'9ba NFZ9l?jIj'̕q;{Ft jzx[(KTpo|FPn\ d)Ib?SŸP\Ų@g*Z&ĵre VU~C n#-R\-T"efW:z<:v׹bЎ1czp`iu"UvEo39Lׁ=ч y_h51mu/m$>6y#eRȝrUVvvZRJzYP/(oEP k,vYV.2<:.^A4Yr{E,m*Y^K;8y' Ӎ*(߮kϥ{S_(MVd"׿yĿaGxae(I۰$+cux1kA"F$G Kx>'([}ߌ00/V%R9baA3bc(VQUU,O=<6dlOAH65+8bه6dn?nw]2C>Vd䵃26q~b9 qqXξscGV1oܿKADry^\"KaL8fnmYR?z/?/z:տ9Ѣ,w7,?{xy=7 ԒV&BZ( nXʃYJ(c%\J n$Ui=w5zb]X\Y>7O:1BxR2b>5LZ:y7 8/\VW<،\ߚU9 4b̬h?G"Ng/i֬q 7HbAp7=xv9@?c;8N0rL-z#G+OWp {svNH2mO]yª(@-LD5IHE2.k./S5X,|m7*݅} [O茉I5[%}$&bৱoݨvn<'1یD— $2ׅEW<袤_2q?}oX =ܛ[K% V*6iblHjca]>e`K[1Oq;duh څXM SmAdS}xE 3i}FA+pj⫗_g;yuO 6R9֗W[T*|u%C`@h66uc?B2䓑ϣ,!F YɩSC DǪ'qرu$dlIP?y?7㝱UjJN+*JyC3P g+&R vHDeqt2$x1u߻ _d} nFg(&TlLÀJ02udeC4jiat/SX&4(V]vٴg%dkh-r.F*E^FK&QLlMݘ%6ӓ8>y 8d5ݗa+Fe;b w6s~X^8~/ect@wλH~翷M^m͋Esk挺<9'+HveZPb݄k7!݅Q9ZjxgLA6+H;V<fҷW`u|^ U|ԙKڑԛ)bM 6\.mD6fPЈfNߞRBv?ӑCG.wɒ>#n)?3$%laeH&:VI ڟ\Cf9w$芀*u&sKoJ Uٖ葋!V$4_ Aܗ`0w){.Qh;'@LfEfY2ೇnۚhT\ET_ -ǾT9Hu.x9uopbUL __P#MgS;OQ`u,*hSCg &+eKOkaEA-m}.o~'}y "bTEzGXHcڸ.kVlRԸ^e> l>_.3{9Pz9vi&[E\\VScEvc`K_@rcs0రص@+g^Mюf8vNQH1Mɸ[ՀR6KGTlDץJyWJ0pG;/${|t>G(E1 u`ފ;o=x!>2аa$V;#dT$K~sf&sq(8ga'f [u?vWGף*b],bP6A|aY*D5󥺌絿< .ʱKpfJߨTċ]=v3 |&pMP9ڇW?<]Q!bA{PCH|iAYSy$#O/C#2!WE<˻=Bɟ#2)z'"hdQ,%O頍AYm} w0U3 JեM^!]5SvN*{뵾b4t6(k~4WEddu"j1G%}ζzuaajCwDn^H7h,m$6QAq)H\~~XQL'%~mS?$;]i̛79zD 4i+[S;I nn(}vj(jTsZ"=br)Uc*U6M e:㑬nc [ hUrҧUCɾ L]Nҹ\@O["yc|hN -9zDܲB15`Jq$.+6+#؏ߦ+eGg#(^&@iLAF^_sQWV @Ы3 >&D*dȮjA\94K? 0kXZtjN+1ݏ(%Y᥍('Țz^,~Ͱ c J"15P9mN|BFM]u!G+h7P~}kW ,%E3SދwV"TqtN-xzH%4Ur*oG55bD{@_6h2Pf+#pePFӖ+j,H=P~vpE:>!b3q;/:Jgq7XUWP5m sH y(Nx~ݓsL&V_vp\ldO}zw8PX O􇒁մ1rc0n@wMRTeיqC{WDfXv&_OY,$'XPGw{ `lI+λᒪPPg}Crt{16:rC_gV(Ξ8!d0jsY2AIzJ*2/L*C&fUR:=6 .s璒[pԳ#{{&UU=,s ^$nHw)M(xhɥ]:t=X<#_zƾ"ˉraκ9CeԌNّ &P7ض/M#b8xLE1zr{+˛M謄+qy^] ZZN~q^eMsD6‚B]FF\fcN.ܷrwX+Hwd{PP[i- y{et ,7B?$g51;B': "BE*]M>PɴiX0&}jϺInOiV,oֱ^dzuzɋഅlnk}~]%8r`S: 8/&/z'!p&?6=C;Ѹy7AqhRϦ|@ךcFT9!u@ UXYDqY<GJqUIpI9 C\~Sy8\0esTPQ/׊d>9Fyr*0?W$pjPk1?(BthcϗJѠw yLp w9 FϛڿaU&MHJ^n W* HlۥPgHz+>50=/n[Hf(`#i4錴HNx󀶅[7:hr\Bern*H_V{MslLC/Պ5[NExqxDT1Az߭78Drzԟ37ϸ]%INz{fpds3`cV_tl?8G,8<8HzQ OgPr?7Q KP(WYDB|,F"rbj hOIA1Yr˄zJzN[ޏU%y_ -Rm)OBNB~+_DǻΝ={'41(;xQLJyuTSuZ8rg0D Gng/B(ͦ*ҍd3v)P_S%,*!*CUcJX)úJ*8t&[q@^6feW`h> G򄥲%tvB Vr\>t8iDĺjk\nwѽpÒȑBTzރ%\[I48F7 o5#];u\Y @C~XQn&zM;y1!`%oS8yv?.8 lzj| sJJP(x@EѿךP簋tf'Vԑѯ5:?U*Z]?ýv̮[V(dp i􈲣Q %U*RgB"uAX>;sţ\Iz삦X>faI3"ەRkKDۚ.FRLa]S0s&<\1D~cbBq؂5}uwb[pv{aa,:YhR[Xt`pTRfJ5HJJ,HYpn%i̽32-Ԕ9CΞ5!K ӘI6`>#3RAYܬO&뾙bǵ8)VϻX$b(Y%[^>6s^}v ڎt}]a;eT2jf*bC6uD+UH(e#8|ϡԤZ-Sɭۊ܏pD)eTXzi\ҷ' 7qH4LaWꖶޏF\6.2\NJyZ p~2^=MaʻJ](4Oa)u>^zu=@7DtOv[)b8-6vı\e#ؕ~Mp_q96uSx,dq/ iwq}b=򓺁xǻcl~߹NMџcMqx6tDB߀1|L=Oɍ@*@SKZz~Q`q5w(;Vc SXy,$-zT%DrK❄hdu7c\a8vpyB2D=Qp+ِ,@ BDC=WGժ .TXoטXJa+HЭAHnIdHMHVu~{3y3? |^URP܊q@2aVaw55U%WM#{0DUx> %LsYt:-ZUIau Z~Ha>5b&a.2`t!ely@Y^%q[лsRo'@T%.hW#4h=.Am %rE-{ )zvPzvk^^^ =w)*'pA-(TQQ zbWŰ678BeYx߁w }7?8vo>?m1UzADNg^ chPD?l֝c:<3#~RHeD1hCt&|BI/:4.kD" N^;Sۧ܏X:go7fe9P=%/"- aĊue. X$ ˱b/Wi7AޡGl<'AKN6j8L-py\0 Hy)l)=z]0b&]@_lb`{p/'8KMj^Y'-K6/L<?7BGʣwnp=D6Z}A r}W|jU?d~4z-bJHSAMx^eRXJ‰Z a >7fm۲Yc@2X> /Ua=6A"n]/tMMk}/)4E^#aΪPg貥gc ?d霤Z0rPAX7}Y75@WQ'ev[D9}zg_/_(Blu̷#K¾sMl;}UbW m> O$UqDTu;u4µ-J9KdHD]\6I$N;-h{t>PVDV:wWP_1bLP!HID5bnoT4{|XdǓa&mNr[" N uGg;psjV8GoXr:(^7T2IB1<^~% DV J*@d2FmY]9C0}%QŹm#}Qm{l1}WUA_zUtr fd buJl6EjT+=Ef*0o͞eo (Z.tYW>By$dkET*oIddxmmA s7'%g51ȝ\ :6K+]2:O\[u4yyUގٰn?NJrjO1_pEa-H3=M$ F|3MRmayri~do}Ͽ[n!@=!~.Fq3<ðCuEsetx:Hٙ~Śpatt+wvdn?b]<%R q}h|y1Ei5P`̴8r%k{rM vi+pD=bĥm=Cmܨ,0y4#RM_ ^YJ 3O_ʣ(L/ddnP5G`yٺJ? D\$uD^#%3URdT@cNc-5 g3 -OZk*7@,9yk\>Hz2땓G ϯE&͐ygb>$ͥ<^:ɮ:dg;uZְ|2i،l2[LKC.^jě2P\?@>7NfXoQø㢸OCV7<*j;['8Ů]G0CW[J*ȹæW9ؙ,hͫ{zІW&l)ʯߕ/+FS-Ur gΊ2" ҒFk6;UajM =IBW5yYEQF\m3EQX5Ve_e7^gHI~xHc8-tOF!6oZTok\{G>9W WHRb-9$  $TfclGC3}QcOC `_IұD.-p?A΅K azod~jq!hԋGBZTq^0 f9Ad1KHӤXV@vY7KT0&LJ΋VSvЛ31Gy~ySb& l/锅҂=+|'鯔/fy$u*vjM꘥KX͠|[%A d|m4a ]7LC nOO9x$nuq'gCo~9d1r8\Y?'h^%x†dN•J(A6(1{E6{.X9至^ʹ3{ݽХȎ/) y;ãHKe+U:^pԯ=5ܗx+$`:H> FwcqOSH7W.??0_U2Q6rir:at]D"b?׿mS*oigl G4A]Z:3=끶"S;uX:څ\VHXQݢz:@h犐qrږ*J5ڛz7V1nçrP>NH! O<kH\!!oP9y}0֩迕~x&;B,^-h.V rFQbCTzsq;_ Ċ2k%o'3/sЎTVc>AzYW)"IR?Qe0LfV&Ɍy%dy[kūޖ>&UӤѤx!;FQ(W ͸?c}r(]]T#S#  y zPd~-bg Fh2O5U4@bf|`Q;]lNįJӛ t%'}IP/zxM;}xx @FJ|RƊkOmCɵ̡ _Jj}a>y8HMm{N>8AjrH\$!*{`C)qB82Fh,E4@&AI]}=Lۛ5INw8"cK4 .CA?;ѣZg*0 {QQ{ً̮{`ONwx)=6Om'c`xPF{WQUee4oi~ ,BGQ׹MJr׉dV1(+oOin{Lt}..o?dEgۓo D?d g >q,Ew=ĩefVpRr"O|fig@4ӕ%Z|D){R΢量u>7%Kה-GpNk zh:nĨR@tjh#O^AoPDTlpԍ|`ʷIxݦ:f!s>G8śi!WǎSd, }ippR֔4@-ӼOkU<Tѹ 3ߖR)!,a1~kA7YfLaa5O*GhE4(Q圲rCb'HR-⓺Nߜ|6| V3!ndnR mYs_;PfMa=D(*(ḂzD:n@ vʞݥm';Sf[oQ@5D{Yz@M]뱖m' !p`qcáCF!3PJP'XpwWV};p[HG8:z3'zhLS`dKx8I%#N"ߺET Q\K=%zlnPӦaZ_d n8j?_|8Aށ` ǦcLQ_нNp; '%$pi"YͯNeUBEQ2`av>hK=݊sl|o4j̽OIFSATMf+Z1 W"*kvffnS/n;O 6ܞn}K}xߡ| rNE%kẾIoD`%DBC+,wN /!Qc~ iƸ/ sȘ2QsYj.M|ⲩ6 F*p! \=pXB=/Ejcݢ'U,ԆB7֯+6YR#w&O!A>E/=&G`mx%mkKE#FTsA-s-bK?]O)e QܫYyzR ,{ J9LA§REʈRGҤݪp!yzyU9ǽAIlRE9eY`sc_uC7^ǑW̤)7Ľg6.(kL|QB4'GQ4e"O_z̯J+=)W ڎ:&7[ ʿl69p֓O["wk= )Q?Pmݣ*igIV[#ʱbh;Qųtc_JݫRa\g`)b/u  ϺU*c[$ ?4ߎjх5N;\գOuM:;ē>^"7[{6?{DGM<Iģupu?tG :Ly妭,q\dlH}D{?W"Xg I5ҎU}U w# RϿ53p50H$ũt j~z|" Q"|* _CbajbEx"%2 r9RBeVWߵcq*';/#;mѪZ{F 9zEm[0M1Ҥ [2IVNpW6ܼCipJe˟4B14yJ OvV :ވl/#+} &eMtw-goIjMmnCV5#Y\kytJodwf`S:>{:У%J3ڙXB h&p*K6~S͌CjFiLBD'eY[OU.7i%p (B䝍6lV!|)s3FeW No [geܮP`mBo5^ iOӍwZFv + jScg\ƚRR`@p,)Yn︫n+’z>9.(9E` /BWO}Cq[,1{Q*D#ĭ0Z3K4D( ~aAeHy@DO0g/Q徭Fb3\\`£R:ܦ7l.#O`3گ3tA{`6)kIkƴBu8D+?J:D#jkM,6G:4qW=(?$4K{:0b~Н|ı~֫/Zz{p!wXT+ o#Hv{ʤ{؃tB˿ߩ\*/{/P}ZK‡4RN%bQ b"]aiFKUƊOb._/2^Hc `Gѝz-,&u-ySʒãWT;rNu,0fd6 j<~IY_o\17,\x G)Q:~ t%%tԻ9J)[1[IU!˥ϼ̒n zK^Ta)`'0{i (Cr3;n ǚTv@ uB*!kTx[wFf{h4~kKͽšJ*.ԕ%Js7ǟ+U%0qq3?+bWq4P'=M9&qk?]ATW%w )z!=>\!J|ApB;fN~O"xwʂU[4 V.K 0s$" O& 3heUv͒|i%_gt>JP7Q]UQ]=f&4 zEpRk2x{Ko^'w k]5hO.q@:-ug6&hЮf"@#2cN=q^PNXGP ]A|/[w P?/Q\WB2e@11 (Αܼ9$0y%[<ڹ5tBO&zN%&Յ+r= iqj3t,?زԯ=UZN5NX}w Mav'l0Rֿ$7|ׅ6檻DU^X*,(r a.ȏsRթɆRx9~f>@MeҶbWԄK)ma,tR—7`ʖ&M`tZJQz߫lz~pk0t OzX0l&,mӱƿiEbAk?;Eէcia‚ZM|H^W"2.9֎!-A{Ĥ#˞Jx˾dgMkQIz]ĸ 8UJn|cw`nG,FD|h-^ ]K7HB$_\GAt 4 ΚpKXS QkcB~^m.Y  IL|HeBi{k'G'kCjK1tW%ӵ{)cu b孬8ܓ9;ɤh}~Cs#Ӈo@<|A-0ހ/uhPS8]Ʀ…0k)XݦNoLL{_?jF\A|v0M8ݻKT܆$T} ڜuca*e@wOO2Ð %-Ux9L%/FSX.f>)*V ⇎4s>Wͨc9,ËHX~*x^tB;2_ Rh)ʚyӑQ\פA>WsFDxH}^t|,fちJY#THAt@Lotou5@wUO@OJ*_xl:-;>/&aU&u=yp1JlMNψ5ԊzBC$z^F[r䖬Ǵ̦%;-]j #( #Mf^܌V' B F+3na &3ri@Tq6sXy.a$us-IoHɢȭ^:$6Q[zw/odݥz0)q*% 9L]/O3:)=ZZBQ\ٜa eC*OseaD@>suf-I^:?䌉k6= RŎ9S}))UJ$O^Պ ;Ըkv),eb&jS)Bžͣ5& IZB-)96i"3c/AI|I@e/c*P(Hae!|kc, A"LoC$nT8T=d5`wU^+ZPgH|eƧeb0yh;1${j)>\į햕 VWbPڇ~JXbrJw1)3o`ց7,ڼ$ڸ@ Tn9`4Hb[[__D&R n;:~wP{ؿ| 1/O~M^ ^oUmfF|ߢJ7_4h(ͲO; B,`TBmQ5??P91"-3Z*/Зί;SIܘ@݉]C P|Z}ygW_M&!D')Sv&i ŏRѨ ԀՖ~+spx!$"5kH@cS 뙋cӀReQ>[e{`D(\֏>1@~+(s&}Wa>)*J#V֑4g~BVݏW$7 d!˖%ցXHGW럫pgu [!ߣUp>04"BTBP3:XӱD%X Ka.%>I T#Re#TfS {gb()) Qs©l۟tne@a0~ލU:$[n~% 5 E86en2h)VVٺRy/O"(.OТE޻Ov fLZr+97G|6枋B%@0٥u-}5{qdM{][܉84nTSyZsxUVĻ3yj{!U0NߣDokJUW|b{ @D}:8=$vW)& +?R*KP U, N]#5mL}!V#w~űN#$Vj`cFgSy=tVKw$UDWZ̓}Ibf]u~wU3Frsa@ZȺl_xK|G(y7{5SWt8GӰ'm+9g< yc3㘾8 Y؀+!XuuKMf5C3^*a}Z.#'#-뺲x*rGNs BurRl#lFgK:_Ҿ엪y Q|fp$zwcWLKgpVy?OFZMOZ/X}nWVvg53:_="Ī#as$@~S>߂-ݚ ^š,wy#!9owM~WɂhKnM\V#T(oyxwB47[_0yى ?ۂwBP` nY¤#d{O4vx#\7U*u֘]KuUš>87m,8 Ff\ XZNL4xM6wq"xj6=/胢rG~gФ!PjGJ7׏-q/ B7ؤ2܋k#j$ML3ko:[4\ژ3&wO)^@;_EQ2?\1hF.?D*?˘s25+74$PS#,{@@I|b2ź(`JwQ>Ttc([%'j^>faGj9܀mLp"'r }ne[:jP?vO+v1qi4'L7(xHD;D";TbWmݏwܱN)삉~(/o *)^i-UjB]{fyPu|!XsBV@ɼ`{<2)ZйgcZH`}.f~2 Vc(8 pt#vGnn"S|>VWGbHUD"R:rqKBqB^][þΗ<ǿZiJ2Ϳ"P=׷OQN{vI<‡nbk$ Lo8sT 4':A{Kmlut`9tY5' IC-,"6\C8lʾ3V߀Pi `  q{I uk_&N%ZQ4tn8K]U> O:'BwP@׷QL1J16$yXWb P}GWKn6 {5̆ӐCkY\谯tc)> nOp#߾CgXAeAn=cwu,&/v]o% Z)U2p~'Xg5f4%l֢ #FFpZ5SvuP c䦤1Qj#qfSm!ֈ@ZcL՛9 rfiڿ}>Q¾))8._BZ=x4/u?dkPۂhOF­Wj&"eXitW:hFvq\mVM' I<2M8 C`ʝrJ\UC@dn Sp:|VyCТX.t6ab.4,L <'l~sT5KTJAr@t 8 3= H/ ۓ׷7m W9 Ԁ5JA*H]5z9Ez_wMox7YmRhe_8}@9^m-3KG\l3u21 ǟ@eܾ'Z\#=?TBoSx hgV O!$+=dX1 pNɻ#_&XPga5^fM!r RkT@8@ S/TDJugAAYNDsj9AoVX&ndB` 7jIh/p mUkE2-iu"_M j2<zSdmҊkn^NdYp`(=x\8v?8I^#õF;T"N)1+(ڂchs_ $+8=tV;ۄX~HΪ xב-GL282nF]z}?9@~2~kU%OշjGTzgUbFjVCR0QZCA8tſ dIj)QH,AykQ"@bm34b>L/ҡ[i/o|>tLs>F}/S Ŗֺ~ʲgoʼv/<ݷ%H,r-}(w;ΞV ѕ6G+L-[^)JSN, 3*T;cL@Y+jӈYܶx)69|i9Оp@Vh +dIeOu~c:xAԚPvb `Gb\atI#7׏Z^qvn"vSߢۋ@+RǓz}7DD*U}n7BSܔcH}Q$8RZ3Ʃ¹%$3/(ǣtBm%[mRyf\':HDQ-!񮏂~p1QʻYs}xvWOE(!l|n d #ۺ6qwQ&߀$d@&*qrw7wk猙^^)4h^ސ<Z,G3hhsaiy{@ .\IA&ncZSFdT~ \` hdôZ" Q7$@,4pNUfk}j?F@ T*\R]AIu-J983.&:fn< 0pۿwWlꍫjG0PA??F!B<)xL\Rz%fi{Ɣf>̷#sQ)!hADΉ`}=4B8ifkf [0~N!Ɍ=q~B|.<J*dyRRdmzL"@4M][%,S3c-{7԰!MgZ震lGPk :}POL8w#")pLdIlvH6W^нi[tDQWID. 4,{7h^U?a4ƧoW+JCDx'"_zO]z!T;W}x&xʄ44IY޳d\ɫ\t@m Ԇɻ7h{Gy5SiE;|ʸhhJ8FtVC{q^kGiZ}¨}lU ̿پ^cv|W̿h {X%7У=AMIC;v2y†/2-J8?Ϲ*GuLuZ{kFv[e}A$KNdkA-u,ϬS7cEiS<᦭ϟT+1=^j%S=$#郰8AϽRCz_0^8GjVȕXĖ( xhSu#oʵP 1z]R:R5~I_ =?uϖQԾqӃ/DusMJW*?=!Bil?ui(P6ߠ+ rk`BLˇ`)"3>VӑQ]Id|l:XFl T#102Z Qq8%2,.G\K <|I>CNѺ(,K ]} iH56%f)[cм %ǴX/tpvÖmPƜRN4~ޘoL vdx+ [oV "{l?&XpU6CQ9H01 a;ΣǐԐɜB6hvȓG$c 7$8VD;ەzxo<̲YAH?#]Cw!ɯwMՅPl$0V0b(F{ Y?uhDVZr0ui&'M^biŽs"bҭ}v K[ UlzdS?^j}_[12mUYZejWQIu1gG^ |ũBZ0^E{_3J uaCIqJ"߭Yb/#ҁpAO%l}8ݪSc|;)v:0s*),SI+MG(thg})߬'ѵoD>\-KQ:]|}3;ϳIKJ*AK;0ՙ2:K-!1wGaPܑ[!]ܰ*9g$i 5@`|dSJ 8^!iTw-~ݳ3OC~U!N)ʝ.:趀_}mwvHm@Y9ː^bąF Rr`^ >fH`GIKJ?BoөȾ0";vߤ큠| ,-(;]4v'#*0PԦ8We>uc?`Gdϓ_0d)钛 !)sB38|s^k@h:?tLs%iT ]4PE%NjJ}M.=0>t&b-=Ҽ}@ Hu`Ѡ[OF̨ UT#ZpcV t}poVEt[=4wS%}eP"濘\Jlw}>%md49z :ۮ=xn 4b!OE jc.W6_ QH+Y5XjxCB4$$Vi]*@]:Ҿر5E>J#,0n=[+"`"Ua.W ([l R']-ʘ'B57VFi V)(SM3A5cT_M؝МP8!:&;26z^ a&ca9#/dzD^(/g22#LUR F5 #F{YNdyShf7XqNs87{i܃y1j (LUy+V{xI2%ǻڲfСFDFnҳWnL7t(B, aX1W~Ut겎ƮږN2< Wb8KRhmIbIG<v(0Wr,}_pLaW D?Cyev䬢5z01nqlT53S l-{9WqRt˔>TW8fi)Aɖ-7g4ڱ~L&Ω$JP, A ulޘy⮷Ӿ~b=ie3 z35luNZQhw°|̴94di`Im!+_mݮJ$^GL&A(|`u͂aj3]]\!x@ۃJ5Ng=ulWg0B5ppipKh7Cdokcg޻A$E [sd}P2| 9QJ4{=o{,iς7+ጅz§Q5c-(lڥD=XՠRTĢ 3]4XltjC:@8v{a@r惠B eikKPhkwj\L4)~:H؄4 M}ݳo&X=t4 }# 2]^zKLU0[$}j8+q:5WkLAb܃F_iesYqWfIjFz}{#t7el`WN<1P9ᣇN6/!&ls+`eeH\U/NyʎG=j7LΌE /T {U X(޼DDbv o<&-1@Ln\=ʱ5>W s5$UH^7 0D{ޝe}ʘ۩i[GxC u15۝ԭ8*:NpFLc杏nC9WXcO+,&'b3NbK1y1k:Iշ mՁRb !z)]s#\X–lhѺo ߵYY?K44K oif\SKS!mX?(vSfgwTp8/:+̘9Y㊲M )Ebv+v8YW3[Gw1ۻŗQB*Φb/~nịgD-q2~pkw6LOAK2uR_tN{qj~(?ePR 'ͯ$EiH&188j5nR "b1tZRp͡k_a\:oWXc.l{B4"W[Ƴ Z5Kofq!8`l'$72A HDHf5'4 )$NQMpU E@u{!~p-6[et:aIP<`mSP ﬤ1&ў i-DAmKAWF\%V7-fu\ZkyăYW=Գ7GBh8. u=ԁ7pJ= =}yH* ֞8s޹S")*YC!1x6&3nqZWA}: "./2O^JHa| Ź IHsxKKeuoWzp07]ʐ;BlJ~'~"#}1tQڒ ]>aQm9]-k^ qn:إEJ/%(|0pM| ̿0rYFX.bI^ZXwbl;z1f2(.t@꾣.Ŝ ]!I¢gi. *Uzw Իa3+И;_ O/a +^i@׋E(ӷqvJbxJ*kA!h5Tbe]QÑn8HuMD3`=mVP96Cuca7҂5C\:znNu"Iݽɉ\* <-PtZ>҉rSzulp*ρE"rˇǤ$~3yD-H4eԵ s_\@+aӆMjAv'歔lvkзH1 Aek.˺Յ3Jb0\yRE;&,4hD'',T5aè^^R1܆cMpRN2Pw|Ywdv"T~¦x?^=gZ͊N+ؑz{;B KWcr5{p($>Җ))~r1{Є՝:k.kk LW-iQ %q1,ϊyX.;ag8V\͉ˈ:ؑű q[Rf#9q'h*Zc)0yI 397Lӕg;yBn/oOuNy•2O}:5Rn(Q%lpv8am`7u]Ŕ_ZǢ-d`,(4p_!7P]QٯXrȝ.b*tiS|z-/C?EMP檬LxxSlͨ/m\mU!@ڗU0ƈZa6C".jaGL<(ؔU1I!)*[R_.n˹ʰ0 ]CkV=e/sIU'Yy(#Hg$WZ8x`NQ9ŽL+MDW`I-n3x`ݳV3V|r@fY0ܰZua=fJ^)ӚZV\F'óE"e{z),'N%j(\H߷Xԁ]q9+dLTΊGnx<*joHa@#yc>#7XTrni/'4aafR)ۡQLB>nɥme,Y+ ȥa~l>y> ;'6,Z^H/!N"A,[Yy c϶qc5Z\&་lKʥ+] Ԣ&۱|0#]+.)DPYԛ*:ZAaM`sݚ3<(~Q ?`hKf|C,m.!)h ts2T돡{&G^iNdk_2<ǙZQJz񡨜yH3]1){NawZIRsa$S?[0sca'ۑ+1i<qm8:ɫt(]+&VF^[Z796}遚ME/ꢫk t͕^D-o(6ƷqѢ r|I9O ḯҬ(|RعK"?AE+ t$*'#0ˍ}qû<"*N$OvRLpƆ\#xЁ<Ņt@]Bxn^Nsu!t~۲tg"4l.eqw3=, ]ӹ^HkcP=" Rsg^XYYL/[v:@ ^/ XϰS^wbd(2QC|Ye\Z* r-niSn{y;yʵ N¿۬ЃBtތ48OH*KN-M9 oxknInx`,5fO=?T 菻K9oPx`oLј}_Rhk1 FHdӣwp,[T+9Y,%[qQ?xu5+L_cJ_%HHp)cPhd}N¯DƐ^7*vc+8(br[8VO *]m<.2`$єH6þo }Oj"Oc;H3:؃)ФSRGؖOrRaF:WN?Rݺ9w,q)EJ4ӫ4m[^j)1lrݨ8  )ƥ/C10H#(@0ݖQi(SBONK[3ed9jXΜU+Hc$21jːp+ı< ޸e0Vlvsgqgnü^^]s:21RCc!Жmo+)8dQu1({" EJOf0LĖX'Op?dk-V*$豚gpvSSՌ!diӤN6l~s(.d~~Zx#gbvHܫ˪U^9YR&zP^|8Udry4ְhq "FqAcԏbp$xc ON5/~&VwP׭LKЇxVB=̲Mt)u(܇pQ/[]6!|nw 7:n!*L_@% Gxc($jf \aoPF!{RAI6*~4`vpXI\T:RJa!HԤ|}&PBR323=_Us Sʟ kml=Jgޗ.8УG/ܺJߋs-id,ūƽ` JXwg@j6| }su֯$|G̒x%5.J 2/7Zx劼( kxWƇ")+]<,(9 J͛^F•owj!% 23gR蜏zk3FN,EpW=t9R =?_­7!ky2gn5iIKR[sk b>:laҀrܸ" +K(._E+1wRmնZrsu\!mO϶ PJ*>BnK9*,S$]N 9EȐEvON ju#/6+ .I9Cc-CP05dzk?Љ;$xWTH2,sj{\pR˘jV]^ˇ._^ bVCBVAX,7 7O,%RM0u|ʣ6!8O&yvI'epTW6t)]Fz 8,G^9gݴ4#W1":BV'?875$]n㸹ZuMF5Xo  ' Y#B_;5tN.[)-zH/7k:h:6x/H6W㳊UZWAmF kl[cRU+͋X$ZzUͤ!wSWXyI] ЂB@j_!| *t4e1@*@%Sy1Vm(JYN MNHYeߵgϭR@ެ$wsh6&Pg$^D MW( Vs44 (3"ntZ6"A3J3R7x˂Vnu)2oEd"397>r_d~ĐNwi=a3VHLbH"?٣E/n0Q$lH*h?S`ci~?nu90!u1Qsw >A@h,)nN ڣiѭcQ4&~_*o5]ȱ΢C)EIۙ/$ŏז TYmwxH,!JMR3&Lb\َOd.m!)a/TS2' Wڼޗey`ϛ4M!( 0JA`%bbH_^Hj0:r];/RPH!{a$8E Ϛ.(q̜ma,<)3@ BOOTC}l-Z},H+DT"Ri9&4Dnm3ZG8'=,Z!AЬ-y5_5cYuh;RqBPB]8C7ص-\Js#$kq]ZÜ|Uȵ`E'90%XG͇fb0V$93T@Y,k7f6j[k;tqq*ydw}>[mZqFB;"S!A6Ntj9eI_f;04]wGV36&xo|Y*D g$@غ(~>p4=+k~)`a[48|p&K#%‘:ϡ#:{>f*? kB7ct<pH``pK%"v`3h$ld1RB=*xknI9Y2A2O?J)ygCP>J=@pD,smPطIsb;Ӊ&+¬pH&Of}U4e,/;h'zL@Eȡ=  >ʕ뾹a/EHR}ShZ 1Mm{`1g=f59.9;ͺb/E`QB@u, |M&fƁ9Ch_(j^%P<);}W -Jm-|<:ݪ>'R4kRR7P7ӌTevq=Oԭ&~gRAiVLΛIj ijyB5Vj+VW(Or!imnw$f;~ 'E'qY=I->1vQ j?\_u@r\%|DlM;soI^à3S˹Ar؛48Tz}B+QĿ}BvHFpIrR298oh,R^!*o&j3u#VմH>BtAj-fT엠l;"%x*rQA\0ʜ7i4(@I0L( ~ʭrpz @qH^96';80$3?4*4fbBs+'Z9)>HʖVk /PPm85-c~Pmb%P REs.{w8FDeP"$eۓ9Sz};*f6>t~(I}J1ܻhuWd13< 'F3I@0ƁᄂCk8'+%ycBWմgqm4cPD6 ,Zyͽ9y%be1q-.*'@u;5 ۰?]X6J#Kxnq0'{16ahs1t]{AdK_}B4D!)h%I$"}c1kZLbYQY. ċ›$V&̝f`I]Ֆ+r1d*6=:_bTO?#*bPPJҌp*_<7E4Wu6 (ÞVaUAD٦Lw@Ƞ`Xw*1#=ʉu] qpQ8ָ" K%N-*mO'NDP¿+7>^\r>ս8\ o-::Kw'Y-3sa+9 .sS8߿*C1:KTP 4U7r݋=E-e%s#`SJ@0vzS^\ͺGWqǓOkqV 5<&U{R>+zFZ/ٮ߷e@6炼K )S|nSu a{"2ϟR!Nt1ƲCdE5=f2j{ D'mw0ZRDQ\{i%BA b?ke8Jw,]|~镚Ud_*&ںo=zǂ].+Mr#^+q1Ky՗"GU 0\no*a _cy}NyR[yUTq]Y-e7?%)BJ62+wXk/~ŭ(Z*^Np_W@@c…ĕ_6DJځu8+JѪ-zK/$UWxe6ABUp{"DDESuxGq}zk׌c4;zmQ$}QJ^ â``@Ǡ8ظ8ߙ0M ~_cr`i4λBdI j>QdO*A||e&m-m8!1o%zRXo4~0Ԅ=l,$DVpkÃVa\@7[)}$yHe礆HI`%9>GYyO8bNE>F%5Ҷ$"Sf~p=w5̉\y >;wcUk?]`$oNXtnVP7[wm@+\ɰ'?/%FVgG=fawZ]wօx>N4aoM}?q]Ff붇]3@fv'.-J>tr}N?ݓR[eo%3;xi1H%-M{0 xG=Obp<#r|g^.3'o~cQA,+ד]_1MsV*5uV aXkբpzSq=Ei*GN{d(|C'l#/\ܹy@Ho)SWJq1sORmVZC1VQ233)Н"z}|]2}p8j ƒы`'0w% 6"E9[hڗ=$Y qZaŦeZ|Z|;67${nS!3*C% h)Hȃ2N7̓bϝlTUvlN LyWÉ6ABtHJ,WU6a$r#q*#N RdH]iw-;O(^{cr/I&L@X;ъ*P k]yY0WOY.\ †pX]6i,X28/%QNtmiNp•(=d6Ff'I[L &}9kni l̊ ;0psCJxOvQ9׸$;=l"P+AqlQw4ӲqҰ(J\):qŚS޹8ǜeVP9%tUSSyƨ?NʍHGJcH&Iv;M;ڪܮ"xɎ&f̭0V5YߦlpLE_xS {$$+B,C .\߲s1 GPW]#Sԓ_|5ڳ]n'(^ 2 xGFY{IKii՜} *0m ɔ#AOm:;;zy_rc򧠙-/FE"nWOЉ_*yC˦T7jٯbqiBLG0҃*XB!M\aM Ezs1M& 4 R9SVr˧W5^8Po޴;R<IUi1Tؼ)I`#@ʰadƨt:dRz_Ź^N?sgolb0y/]NE=Vʄ<{)RDCȮ!m$јce j.[G n^ҧGI}U+/ W` 3fjX{P%a@ΠuvZsB-Ccj, 6f]!=xXA`[\=I1\FW@WMĤ~]W`.o~H!4Os)IN^p*20`ESjȑ'rʾnԾV*yEEuČo3378xs$A3lGϟղVr4 9[ dZqP LފK![nļ%Z@61YNMƄ=Og f|]yBU9K?ĸj;yչ@}W|[D%Ve_4q?-  J6}2)Lc9~HGYteG?ؽp7V/쯂CݫU[S@`klZµ#B/5e)`vh"$QS@6M<$ky:k Ȥ̩+21ۤ3Wg5x12{D%>h+ Lvu5S(W_+lXan`@"y~-"z渢gk+jȍ1vRYТd7%mOU sA;+^mmIR3];ܿ'GFT7a V,k/'BԚm'{R䀰a 1G86 Xĕp xÛ9OΟj"nUVRwdLOk)ZM;T,ş2oU=GuZB{zn @~Jj8?(emi;NU'rcÛ[͇R]tUlyϱL(9==z2')M8I,IT{՗)hL$pO$*7A6 e@@M4b?˴t.ծHgKGFFp<Wb} ZYW`II . ⫦IvhD{X(uvxf[fKzAiPcz&^hf#1={bJ?Y$) PZhh@XLF[1P2k)Dwbk}4z؊,]Ku 1?ߜ qggt'~?]Tsd` F=}"KnOJh;9A9Ëst"Eyv%@DM爰K0EQbJUhgk>Ѽ@ưhVHo0Bc!GZ\?=WPEu6n1-0&^G%&\ʦ|;yq& 8VJ>7nG_XbBk:U=(薌&/| 5jnFuw:7fب*>-Lp}(RF=eO@Mnj7V9-'l:%'`vtXpdd]J|47آX~[QS(Qd4ď} (Rs q0n xQ,庛AtXd{Բ?0Yn(Gô$@sI3jSr՘9m?d E`Wt5&_:sܭjale @muU<_Nh;@w(|ۗ=l"M!CGz&F/eA?8']n{U b;GZ{YAenuB?_9X&*oůaɡ8yWE/g/Igl0ȵ3TBO!™H;C;Թ8{)n$!T1b* i=Mr?SܞQAA鏕.mշd|#mY(Jl7bf% -S|2uZS*u-+4V^xFYw @CAkND5hʻ}t0Fr d]Sjϥۺp8C?ݍ1jA5=.H"g).Z%ڵnR2jR'a?@/^"gZ (J+lRWPz| mjڇm[^;{(>>XK e耵=LU.E;.h}K3-1Q]8$-Sfi@`榧$2idTGm?h^ѢrXT9YNS:x@ FأU*j4vAרƇxEeՇV[Sg-!kތwth@`G0K}ls{?1 ع1X|QS4}ɥ8L9Xm.MCvŖ.yJ7ɷ_ei׀kb;~P"\=)t)V?*ڄIø+ߚ@]qDsf4%Z*xXZtboD=UKwS( dzbƯYWAT{0#l6L\"уPR޳xY"JjУx59NHʜ0'wÃUܵVK,tو`;MI ~{,5b7~=EdchOb@tM!ul7`,_.0'GR"AӋ,o(" ~g1_Xacħzumaقb9'͹HRc,kHJ5v  k 6AkpETw5"ٳ/řz0u?8ѷn~{S$"P|>Nb:Qoθp$H㈮zm_?$cL#/r[7Ә {͍0 ,S7 k, uێxNAHaZɕI /yGM>tEFΌ1Ȏ,YeUנ5_NgA c;rsVBm/*ٚꥈ)Tm79`^׭reLx.]`|sjGg~vN.$rj%goAf`1Dv1!b\b.6U|AW"~6`NnA'ul+6$spռx<(b^$rZ&J0u(V^"IM&f)7Yf*@&Jc[Afu ]=P?Y q=5@ע d #--AX]EszxyLBA+)Ih( _+9!@Ͳ?;@0cCN93sdԿ`CO eB4d^# ޵cQ4d$ _MuIe3KJaΌRfɮc>l*l;re}%`HȴF59{ah/4=uϫ:au2WذK`kPWݖ/;I&/6fLD8$G䢺Kf,]Mе'Y&xWͿۢ?`uouS*X;D0*(x%dRrq_zuYbֆCP!,W訨Z׿"vBƜiQ(wRX}gmSi~E0@2{:nKhS&:.3^`zEQy HƟ?t"#줁3 @)9 j_ f`hb=Gnw%2`.!G$B/=G@ܐo/ 硠D>B?>㪈9-t fGO)ۓCr]}k3|*XQ\7 a )cG%GS CIF%wXt(KΌ-qJ97kT*2Fsɀ( pUiYZd<9 7_+-$hV&Zc>sZ\o|v+cJrMU2a0b\-If^)OOkSlZRʦ~i%vH/jCUlb]҉z,*׉yn~k3Zq/>eHN2=#{=9qBm)%wHH廦ea~! __ŤKb&6I]6+〯 6 W1x6W"`_}|}] VȿVOsC**wP4#Ai+UDmw#Nok` q Ւ#8 Ė,Q$7B箓|\f"l-6۸o f }%on}Q8K{J)T$w ^hz)!Z0enm[b^[1`+&ingV*COG!}q'v~*SKolߛC7iiq3xs˶XKKGMr|@[UJNu)Et>~GL1UpԔ,R|dk+RۓGƩp]xagv(K E0Zд+b=\߷Xӌ默J ~X(Nx,˨T~T CE̔R#{PoB!Fhplr٭/8]$*]6v3Tw{.ȁpEK9z*bw윕Lc/G~FW_pIYMM"8f i(GlQ"铥b #ui1-א) qpz- hr{Ux.HZ+v!̱faermB2\,0֍N{iׇc{i5E`sGgQ;f˸!4GuVAk#AdTϜ1hmV*G4_o/t:?+^ɺ0+bo4s65"kMB]ԘzJ)IՁp#|d&?c .́.bGTl'^FBESy֗#;ZHo(;ƥʶ jӠSnN4%ZExȾ?ů|w>,QPh51ebOreyrne>&>B&SB 7ϲ>B@(O*S ap%u1L4{ڷáK?nęgrqOfnyY kb~gBn,xEovxc-k*;=eÅֺ7&g~xsl0W?Y5r]N2d4@2BE2ۖ;7i{~˷՛~]Ÿk"qCeRCSP%Gt+ [7@"4n/0nξIˣ<)@a9e@6ŀf!~wo"O[-jf#sxwx@j&5Žx yIzL)-9G#Ek5Ѯgն,y!(3,!΀JSR.h2u#u1 pd#G@k8s1J[#DZi{^Hy/;>}%]^HN7t>:#Rf-fwaC / vcěnHd>ZtNL^CIAk X@ͤ\4Wz~zE ʵUYư$}zssV/7(#xQPg%&RKWj1ꑓW>:<2bL!)tJq/V]Yw/P<g9@q ._Ӳd0Lml(TGU0NTZhkL1_A]MPP<ȿ^'}$a!gwt6´bjmzAGkJ{n2$Kʋ{ \1dA)Yv`x."' /꓁w^ H%UeE@=@z%3MkUH8gɞ#w !F%8"Α؁4nΩ8H,MP&E=~bZ`L]򕏭 )0h_ -La᎗0[ȴ +婔8eft1:R38~W7Ȧ4*@>9ի[T3k!* rn΄ qf0dR_/=ɿ 7wk5Uth՝qK `ckZf@3p(6b<}'j+C-ɻ4{X 0oM]㑧:JCI0BV~|Ccos<>*f)Knk+daᩬҀW]IJr.peMŬSǝT !x..#R**ێOkzS^:C{F\۳xɇ)*]42h 6d'۶' ɘ*s?{ Bjk/qlyncs겨!KalZQp+ɝznB{ Qp[rڇgcM~C73x{xFtNk~ K=qn^&UH0Å閹&@zX$訾IxEn#z1cTF`=NE_$=Sl9Ĝr,.P3؄UV2;̚H!cvi1u3K^zS?# oFB$J mowlŇ?|hwf# |dw ;0n_L,􅩐H+j׺ehh# [,$1Am(ʂûaf5mrl!1³IqMn)!fOKXkD'gug]>FPk@f3GUVi~Fft*( B*Z]`v7&@6@@D03S3,,/2,7:laE% ;hy pSU>}] gBA-ۂ{/x 9FLJ!n,c6[MKSN@*0c" hPq8Ns3ln" zAƣ6)P Wi9I0OeKX<[a6~`¡[X >/ؒс zmϹ~?ږcI/ OPՒʸV+uC&S\j"e"eRZv~ c=* "%)c“![pT΀:CBy$:v^f9dKʫ Hs3rtLb0qQTF !,]zuURVE~i}RF]0%aTb C٢0ko8EeKтm݅-v7t?vf{bom 2VS'jl&{ը#Kt.oWsׯCteLEUET@T3"4>M^"95!fe7v Su\h6+ll"w22Jw Q(:.';} 0ɀi'ktQ7cWr+j - ǠzNA2˂G;C:pk!8gO/P|]w{!ZyߑMnQ--8́}mұ?*yfXWiSڝ3Z4Άy'*xAL%sѤw{Xn.B@X1^%Uy 3d&#cWnt7M6|)Q<9{|+W,G앀Q~+t?I 5$i^+AU> O9\&fz|^(v{S))ViΑ/";FA!3pYF|kf^$55u8"^ԂTHV3%|/rВK)^]JPw1o3*CM,;FY,3 oDҗUF QV5dbtKI(>;5q7>+\:VaΧ>h^[b8R{xX*H!?,ʇ_$ .ftp2߉{B/?S|!yį2^껳j^!"ypawjv?ֿXm(Jr(c%Ͳd!|4@I0̟1ze1"%}TUBR 'jBo /{ӷc3dB6t%t1/.NMeŦ,Fy3280϶]WVYV7]mo{r1[)ؕv.#q $}:R fn\,_ ],T}x p} 2cKJy+>_/t^KrFGAP@%w4jcUs)[׽.z})qd[AKmqO3ɉ=Ii;eXNQ׀Ddp k9i>g&O* \=JO6vzYg+"}Ȩ- 4{D0QnI_5zHK@ ÷iJr}?5 2X r!m-1;]IEu_y}2ql{E_PowF5yC~}Zc5:i'Ϲի5DP&,VJEC)s_ÝS\[t$\3:IX~$?٨(L%V_#G,‰egW-w9yr㰴16|1KiG^נMdˆgLY103`tt $RA5[@j7dVqf~Lal$Umh0б8qHcJ)Y i*=_Ď)Uq]db[>fo`ۃ!]cm+>AWt8Yc8.gh^ ~lt> 6<S5w7??WLQK@̶הt'lZ)6P~*h}tt`n?PS8]eoremסn(q@c#I )VQc ̮͊Džtԍ\%e$a(C+oKiEht)K&HN<[=gX$RkMK;`3 ԙu,~p6mP'APMgh0#GcsE.aXr){Q$X796=`VI̯x~>sł$ړ Qk؅/_$ІQ=G# QaZa6=5ӎ+ILj mYX@l&*؃CՈf _TT J%ZE͙sQT%l5xVv Ai7.RExu˘t`)gC5Xn#8oW!kjmT*l9ɾצbmiW7\̥F|!=y]~ce{%]Û8grs{X=:_7gG=;K{o߳.X.`|v(т?r`"[sM92ڹ0nl/?;(xe-3g  tfϰ'_IC75T3(e/QlGfAy1MMJ,:$^9X'Fvb%z.HYC)Zi0y_UքBڽYcR!653LJ1D).nzujsڞ`tѲ}"yz!cӥX2n`?Ζ$y}&\LmӶWn){b0mIC r Q_3h\yGhBN5C;X$(0+(6(E$F; u$6䠝[-ib e#y׋BBgA7pr!e4C*\II`qSzv,8/Qn_M ~s@&-ڨv%XNfV;n0G0<Yw26Obo0eZJQ\І!ت/,c[Ot*ٙnȉ2om_Es4O]ƻf%2Ɇ>eZ |`1<;*4=ωߜţWa)iAX{Nj9.j6!9quÍV[O1w$t~m!dNlX2KA;:(OҳhYIXa~PM{!#ល l%fhІ`Ao*E3!!J7v hlmVc'ӛF}K#kzVaƱhclբ{JN7@D sXI۪)3nrm1/quKxr0Θ=1صH$+>>bgޡ R%Z]@U-|PV0\Y:E|#s^Z@fWOxF_l1dKD72hQﯬ^oJ m9ǴL!OU0-G{U#ryG!hK WئefQtXghż'b2E*+PE\ SF'W)¿9=5K CZ*nykIb6Fz׻S.t82CPwD6֓ھ88aR\ <”]thޕ+ȷk?\q --ՍpѣC DPM v\US3#a]OGjEHW U`L k˂w^;GP^=C`25L]piv\=l3l3}CefWtbFG;I=,&^YIdYUv'Q$g4 5EgpnYF1gnXS >ӄ7GĐ"A:φQ&VD|^Dƹ +N>5{wm}T $!Vjƕ3̸yXzQ _apAPj#isϒD LdjPnb&;\\zvLG#g$?H\xU0RhnEj lL!24K @,c^oor %e8Nl*@D Ө''!9O[MͪV7IN8{r@$聇iz|'<& ˣ IF 4ХѨ+}HeN[/(rRz@2ii/`)crBݫO_vpw e@Oޛ\_Cs^(QWL/, 3),qit;GK ? nMCw"\::=vfƜHtOry `[Y!ý:J3,A_b#`Q4rLE !X7,~M}&Wu3R-elC KUA>7 3XB㞸tx5Z?a"N\|7nw6 j&BtO N! gJ/T|[{.YZ*^-CT| %u+dN21 Ds(:-]CӱEkK51ЎPvTvR^by}$QVPǟ]{;i"dCMސX_6N|C]kc,ڢ;Q@YG`ˤ6wfڧHުL}SX{铃2ݧNm]oOUa~q-MT@ 5hw >PD)cNH,]`LŽe"-iL'5< ֪Ĝ,e 6lE'[!.I'gx2$*OO$`c$&GAt-ϏQJ4}}R n[FrVsb(>1 K/JV"x[!iuUuG-:Z#z$`͞tѢu@I{Fp'SRe56SObA$q̱+%&ЍPHO'93oNyKn 4<+tUGMhB/?'7WNP9h#JoMThapX=;[rg KwMEJR=ۮKz>VZN&>Gt`q|5'4cv* Dsf]0#{| JL4Zd&9kfB(n5{}`#8MG\2s])WMݭ !ƍ.wißTa1@1bbY<"b%)2Ń4`HgS=I9p4HyI<'iA)D+2o*[=bW vbE2M[l(6Is鷵Y.*XrB"uES6`+AlvRHVHsq$Օ J#O8녏s ׈׮I<fK6>οxm \nI5$QHv AS־]Ik2x\0Ϥ_lwjMZlThP\ iFKe2| j >_{tkT00|VPhH"̊[QSwh hۜsjic[@;=!CĚ.+pn8'%@:b M\X'bQKhzBZ|s+m2",t7O {f~3ש8=tr@,y׾R)p#;h}faجKb0KV!ݲZ6MX&C^FZicRq\Xr(A\=Fe_j,hmL#C؁2Eސ)@B20"KM b˚J?>yI8˯-Y7IzqօjmsgyS`l2+1"`IX<4b6ÃsrTQ$uH⳩}mG(w˸`}w}8;z%I 0]Z+S^ҍT"w5ڄA_Gϡl~&+*NjaBhzV#GcayƊ(3F{HUtҰM. kc%VO NJpHYUEeS~6gq10+|-Y-tta^YRzg,4*l$݉D{>R =a(E`uAWUO6,*z`Z(/[eݎc@>QZ+4f~R_SR#AxOHXvI Jѡl|U+-1̥{VfPvLdCIzj[1hEiwэb<髫t%zoa'jRcLBaz \;3H 6a+9ܩ9(Qr)/9 voՓ y0绐*D LvH$5 e )+ً@01j%E,+ Ö,5Qi{8_br[66gWU!mJqp[>5S\MO^Z_©H: .PJ}C$fV>%:~H2(eUȄP(VDfUB&- ou:`xV:/m -bh-{Q'KSn =LN=6!`VEeL%tL5:ȅF[xACm ѮkU"E r!ȡ Mgl&,t骁Uova $5^a<ڒ6yNBw$Y;5?VQB8Zk4ZʙېUBwQ([T'{o=V+D'gd3E^ʮlasޭm=>M@%Emmb΁} MrmUd=Q<ҋU $]HN"z[+vVn@ӛ&]ŋ «s\>FǔpS>lO}%^~e0ˎO dɺXV3و#&Ǻx_r`l~>=tKXA8AE7x3أǡ}B |&% [f\0[VC.PVsh(㉵Av"I/w>G)MOusOيBcr).(5 =+q֯l) eSQ&`t,P2v@,E!/ G (raЉqWaڄ$#8[ODs9Ե&F,\&ĶM@,h ĜiІј=ёڋkm7A)P[|3II] ] 6L y⤇_WfvZMsݒYo?aVBIːʉY͇{sqvCboA0OEi~@%$%O_DA/|J*B;1I1XdS/]~#^"a^b9v[mi_!HWMz٨߾Bm&wb#m]9T@uiM@?"7Y,'FІi8X׺%5\룻 LeHnch0 ߷<}2f(VVN T(m:ABٻb#za_a4Dt|(YqKU1"췗z6IF2+R0Cš!|睰ę]~;8?@H<ʙdn;zDδj9ؑ T _u9]m87: r`˚LLnE0?4Slm9ߊHS f&WϓdhZ0NX: M[/U UryרꦸRLkBxܾwVr`80>J+#i.' ų!*4sʙ7p 7:^U{v ,Ic9;*.y΁81#07ZM8mx !>G ֢h0^ɷnK |o8b4x5J SsԄmL^2R/qb iGOZgM-(5nR:Hcy+lg]- IxRɤ8,JiqKu#ڭB_>V#\c Fz 5[)%S+v9ol 8H2]ʹGГG^⮓Zu+)l:7NYR6 #NqtCj{؞%$eRRfmsxQښu IlLߒd.zW54R 2nqWDx7L!@Oe~ߘl౗YdEEZ>(#HƤYJ A)YKRja. 4U7;y6qt]*lc"QD=9߈s1w28h!=~ǩ$Pq,gL$ Tj)+.<džIJ<yD+ks R=@!-LعC4WJߖ3ͅ;r #nKm|A:JaE}4"0Y+EM0 li ֡"[ѠtZjO}k)mF;n +%>f}g(= .|c}c;5t3FAAv9XOCipm~qH.>v%p kXoMd|Q˸p'hMh3`v%ӜǴHWo\9, 2eAV]Sֻ~ `pV1O,Oʲd;kiMsu*D\3Ed{T*?E}*@(i6S;!WKܙ24ktctn|0(Kޛn6Dx4hCnQ{!)q堾8[D Sa; :lF#c\*`-lz>MTDFz!C?r_'Fԉe`S;0!;AjN0V 6)O}R.HgfC2[pJwʬbx hoe=ۏ=q/d/N^5a, ). ^~IH9Lgw[=ǑyzݘL>Qd_ +&^zuˉ5RR)1&NNo,N Y@钥F`[b&zS3Xv?sEK:A$0%-ҳ^ IߝT`r,P4b\W猨ܚhuJ"r(VXT io FBR ͞Ll&̧N*{3Z(ͻ !XqKy[hn%`2EifGH*0Op 5g ͞Eѹ&OoѸQlֻ7&6R];oC -=sqk']REG urJ-VI̹T Z@` G[ @EHc KMa)?lRˠ0"yR*yoן QNKˍ058ݘ ϠCt*we:e崪Y :;^vO .pVf:dX ʰ q`4 uغj =R-h&%ɬkTIl^#ei09|!5QڡƑ'ten 03[t;Sq"_ߏod4ϸvr8MqO>4N7]^6gDx헁S^%rTł{;r壍՝bBgO-6lV˶olrL@C+zaזxJ>cW(-\xLY`D>RFsGXaC6G\Ch`!JhO*o4@iyy +ВJ)6{-B{;k,eΏb5΅U pr8R>y̜JF4**}V#vi@䩩u[ˮz#IV=#NALF=sIE mhe_i5 DXAK(&|Sj k|a@#ԿHI}$~tDoo7uLeDvsmOLď;Y QZtv | Ujf D Mʑ(6Jn];l8oD!!kCI:%f' C;S.r /oIFIJߧlUı9UUMpHP({!eʉlI#y:@逸M̙}]۠|nɒ1=TWw~$FiM 8=Gc0u@An c2戴8QFfoًU+c&\Ifl½žӍgewܤFX]@݄lo;*^>S7/ 2&djs15V],| ,km"R8U4X'lv*$ө/q(u/[Ei=QXxxhKGc5}Pл/Pu]IHt<FtDh\lf+.[R#u$Qg"XiW6sg_Fʚ;8W&QL@*!$2={º4mtNls_~ôRjJaQxҙsh:cd<$c$ L ^9UW!ta"/A- jڿ(VSkE 1/>5!vpQP.%duu#naзc{O-pC/14#@rb 4bf;TWwj-E!#؝- JFn)].=F8paݪ3ƵuE]QblƩ^]iyY^; o*B"i!sQە.Uvo"dɅR0E^Ajɽ]E9knTeCl~B}Ci2 M^; ŧK| S1Y"s}yoC^y{Th}A\)О\fR|`I(6xdԈ0$zTsxpLJT{Cѳ HnY0<^/yd;4=9[Z6@=(,!cC^>`ObMӅN$duq}saWG*#n\!Ljό}lA;"a n/`tJp&`Oc)jm9?H``L0ẁ=T#vi(80bj֋ EU2aH U*oEv#mN&mF =| XY*d 6S\Dp lMZ׶{m}XMizZu [ƚ ZvU.Su=ٵɋ#c  ͅ 0"c.N׎kh.k<ohJ׎pILe)r *ߙLޤBChFTv\E`k<vD_6ւ |3 J O -& ld\Cl`"[K 0˿zv!nBr UZnq(7GfqY]VHT$x?a=-;6Iqy$C6$mfT o%cRRŠWFJ"3JǏXZ+\$*SS[mSR;4Ɏѽ{c5cr1 B-  cKR0"RO-JmkB>9,=ٱj8 aHN#gH٤338b`AH5(#8#?'Z7.\aby0 s}SØM1O[수ߚ?]JL1uLg5-jSQғ'MwccNM?hٴ/4۶icAtVGnm$ 6&B{&m m=b.9&MԖ1]"}$QA 8~vdt{UdA|G`cI};4¶k0LCym~HRD0(+}F<#~}*+s~(\or Sk\_Ba"fC[$Oe>h?~?R @vyՙNY籁2`)8(>1_\G!(Dbg>;3#9 k I7*t %?ctl* fDe >$$pʚGbc?kJAȌMZAqp(۟0mBV w*g/ YS@"za~P1JzZm0zqhmHTXAzDgnI? QSdy)qӐ˰Mٯ-}¿n??;BlZԉf24QƀN@KW(CeftV2`KE2MZckyek`@҂/N:Gݏ=#|m:a(:ljˀ8O?0/3lf4ԅ*u`-R6AaP`sjD2 8PFrHc/=r`h\C5E_e*`5\1ŗAcp/C­0}F_?;^G+\7t QܭSFs=j[&5j\nbULd%H󜆿HˆzD<0KƬx6=؅_Z`u1oFu-IvX<_뾣b֙)YR͵%l|.>|pi Daj^'z^[ZqR☻mͼH: %n\k_ҘWcm+P׼hl85l^OIIJR:dLQfیsv{qoOž.,(Wq{k?碌Iާyvӆj*(l 3bl7@V'/U=Q#`v{#,/_]$cncf2-Dd ,=ӞzVg Nx${Q1&h4&?ڒ; K\y4>\A N޳PdҐ4nD栎QK?K8S?W9&ʪsK^,է¦"I[E7NJU+ @mяYV`\=-+ta~؊9D  1C3|q*Gv۳.EIV qkf2mi"|Z*2Ďhޛ?Jw q[ghynPdRxyb7.|Rpp¬ZCboOG*IFS^euW^NrMf_=x h/T-)X!|9/[Zz,EOp\j>xIg|{*_ b}~(?9RFs S0Xs#D>wU݉`L EYJ^L9Y~ޤDv Hlo#)5݂?%}$L7jʱ07ktpgKcyBѽ) tn{{&O;dO(í'v*/&HL"tevݸ:B1!,"CsH\DyA?b(G^o%h1x&m!=]F58?O ~q*yf:vUe5tNba^_*w?A %V,e-zg UX iU . 9{_&t.{ќY<L & ׂp|+)OKeLTR~e"N9L`[fjfޓy85%M(HF.PX ۭBg`^hgWn" DL?cASMI=391nq-CC{hed>:{5͘Lrrު?=}Fp7fpv@I7 zIbر9_Xʯm >v2 &>˼4~4U,;#랔 ?SUkMtuӑC|PK b8M5^VH#R<@9в+ܹ<;5$sl^x:vJ,k4?[NmP} ]( 6\T8?D C%n-b&DKשY4wrcžV] U'T i3 aNPetCUMb]5lnӫ]#9d)n|C ;ߩ d_kEԬlz~tCM5 eVv5Q?@ wE%\dōLQVՃƴ=T! m~ۮ?5Ԯ:7,4wzfAz1'{cRS0*$( tU@Nw(tg01RYCkݝGhitqīP GP*vJ|7#Uܥ[WZ1k][\twsz5C xMk_/VCJ!8ɤx":vTjޗxK"D#N2Oû6]]wty3agO%ee.k+FB,믢{kTttkvCt0q"Zh{V}hc F1 Hjut =X/q9*?󥥜TwUf+:OU}pɩ .^w ݁ۺEo&Y~oYu m1/Pjϻ0(/. klF.! /4윇[v q4y=<^dsc9t'!gɔm{=`]bUc^Hڧx?v=փle%YFDLjC^b^ kCA ZŴ1b8+&MvfYI'zL:]p֖Uw0!waGwB}AcC_?P \@[*y궭/+'Mw2V289:GXz0"Ndzξ^o{9I܋AAI!!)#ʋ31k qa|F)1H5N{KnXlKl?97ܳT׫;m頙L%9-ԘߣM?tgU߯#.&j7G`bؘb?exᾦ]@"ԱpWB ۂ#]ѮXG& Mձz~xWya^a!0vLϹZiXgWKbҐ=3yv%}X5&K?Atmmhn̜dLinW3R& cQqN 7ܔܟ-QV EQ_;Oɉ†Jd]>%Az6NKhb0?x.i3Q5I~;npe4];8^eS/NUY')*UWf?˘shK*k͙r}&Yj$b; :S-:%H`P nEkYյ}ɤ ~!.R0 Xp䊏GbVCK.=oEb pkZq)įB;\-4P ǦՃu4< UK`Ik,{twI©C@\MsCd?U|ZŬ0{?RQ(Iy06igkd}ХpZ̦ìT5"CscN0A%WgJ_朳IdKZ6оP >D˙Ks^>M%w_Zqs }"Ek'HH$X@, 8=틏Z3JZ ^D*d O9e:vA@s(7rxL@BVK |Y[ױӘ[$CwsPtWO$z87qc03naV?.@:?BJvJ*M¿ e8iThFmvzRq|iX辝|zː8BT:۰7z4aoNj}} !DL-醔ڝ)u!GWwF>pU!l ,Qz3܅(^[т&\ v]e#G ,C< D((*17Vp${"tצM+.At1$r%\zg]:sn./Pוlnphk舴D45y^BDG"@{@ž^Qd1EڡIH Z'3帮?IZll$Hnh'-umt+_GWRG#)h |g>$10<[wУ&.4&0hWƟ. Ι9;|%S!`(xX [<~4I愣98rՃ"Xꋖ^ L]=ZW|RB6FA|8g4u55:8}_r9iˡU#9Unjgt(i4{׀b aN"O򹣕 ڿp=oKK6h;;){Wt/#1MU*011C[t |D߃7Txϑ:cgGn,bزB[ȱUP˴,h>sNC7Nx-B{ɧgC|>:.5U$Bw[3Xmr7Ypu ^U:Ԁ>.4AX<N#DiLIym=jGHks~'JI{'&'Z9\3 me^x"\Nv`?Mݩtz&قGȅɼ.hdy {zhNbٞ5DA1kK T-7g\d+(ȞXXJ_fyLJv9䍀Ib;̎0i-WT(H:'8aEMV<ZH= ml[ 2 3Z>-}ۜ"Ac  1py!/v@sk^zne$i 1#Voӿʚ29^ȾՌ;+fX J<~16.My̦SxNy˫ژ^`л wǫETb H(L˸P4SWJ`&H {h0e`XN-U7=BVP~.:<.|vZP<;Qt]NHvc೮څhE<jm4J[102&ND8K W.T*cKoBo7M,Rjrur4LF j:fR3nG>ml+.r}p? 7?4s6FӀ\措pY"j ._懹аh?[ݘ c>ʏ޲!֕Mr#j9wvʁ̾YJ%kGz9mUB5|I qüԬ畗^=Ҿ9b7' fhEUö0l1T#d o8_TY&ke[e9"m3(kkeǀIv]= a,[]2Q*b U`JxAcKwo:8rBTG"a6s%S]:QQB%C=Br[ey"6c'φv.Ty3, |7 $S-u*~*_*񍘊'HwLoF2aj7n2эѿkHfɉT:EAYę }^$#5M1R8BQFwe<%=됐䏱\G]GmN(*aDi=_9  cӣm3ϖBՠ]$s{i3[rNaFIӲyߕvm{Jlޭ|#A%.tu0 <AM̀(}-B[2y8_;\D?ض(e&'_ l ]1i#zBOIL@3¦QO<1w- ( GRހ100k.bin  ^y(}GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2343295 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/c2bfeeb1-a0b6-47d2-be35-50328927c1ae0000644000000000000000000000252614625637207026124 0ustar00runnerstaffRar!= ( ( ܀120k.bin ^Ӿu0;F-F(879k|!bQ'h)AjgZbaćdǝ7\ &bܪ5*_N$@~ - Nb}Ԝ}ᮇ$?qY6\W?`7o: op+?B(u `[8aDC+J\K5Yh/V|:ыw=޳iJ s慃Z|ۜҌC g6 *_Upڙn7;w?\\N>*k9As yUDQ*Q"l2DG!~Z"rCԣ\!LSε_H=vx@=$iQ1XAxѥD;j}{p l qX z:2(9Iʿ4K0ޓ'؀Í6o8+q+},r%2!]Q"AVZv4=$iB=ioJS!=g᱔+ ֗yV"l\ydD0XPmb}ʰt [Pi"M@JfaB|vf1AK+d Ćd Tkˈh12~hKaOMylu#eQ9Y :nj܀g4zsYzŸ)=p&p0пCt8SC]"PԪCd^G8p{Ex.2A#f誌[вh3qɉSp77 ,'o6xQXg=2u6p}ytv8]~'Esj(Zc]A_\i3Gm憨#TQzWZ @q6C}Avj2"<Ӥ|7{hXf?02b-&V6=z*( K5wVQ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2340395 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/79e1de93-f1ed-4ec8-ad69-484038a8d6260000644000000000000000000003600014625637207026026 0ustar00runnerstaffRar!iaE  ( hӺ120k.bin ^Ӿu0 }^(VbnOM9 YooY@Rnɯcr^L)-<\>uKV0WZ4Vy^TN5 !q\عqDov޿ye?c'sg_)%mq_Lv?L'D)sbS>k[-}oiyr`g>.lY=SwE\xkUs}%K5H4d2a܃`OAѰjYI V@d)F v{V~DՕ wx uͲNT5-v7g[|ꦪ8p"(GrVΜ/|S6`m<̀)NzzoH )9LS^̤NN@x!@$8]4f rCfRcȈm̡I "&s!\iγV)̑gY +I%Q6 U('{#zNe%Rc5!>+=DWYSdR3HsP$$2ַyŢ->bxںI/HPt೨y玥RE7D-7{bCeKl>  Yy NO U9>R5FEMO6S`ڗ=?hf|e^h"ڽ>νe[PO` Ӥ1.|PLS%oE )HV[%yHcK q{ֶ5n: cbx-rI}.INΡ/Tu+cƺ,'̴uXB-C,cj6J2(kl-7%};iR]Mk@X7יbQ{cߒU$[ ]+-1ʕtR-8uUD/WNyWz{1(@.l G٫ Ud { YJم}ՠ,9}p7!q EPF6&Gh=;=7 1XFV%CBMr7́t;\t$wGmw@~?@]GPA!) A7 9[7~F남XpȰAY0Z/a.vهĉ餠{t *0䗗·֪b#)Q PlH$F;R6:%~Zb' 7h>af1h`iI-h3pQKkzxPmL%6cWđOV羳&:BvtfTYCw0R),M`r `m~2*tBr&d޵JR3o cUS$}&jEG\Klsc 9,?܋< 7Kt^CQQ%.c}}"uKhjꝼ-w?P38 z/.ɢC^"d<=LF2|zckh#_vIW="_=ecP5f@KvzfKTԔK|d =N L yidQ(ṉ̀LWO!T$uH P:#߿FT:2Y~0/tBQ=A1!'h[bMI^uJp.s3ZhܵIRN;B@^YdKIg)s{}A f:zʽ%fU%byAw_'thfvvGe-t!+@|ݲ᭷7pwd ϻ*PߧI?owD l&] MǨװPyN5"LD9=*DƮ ĩy}Ll[NdD8`Y+䅊~T(nk^:IMy* 3DxC4HOߤCr Q{knr?.ӝSbQhlE}  Aڻd;jTM^0jnvjEf;fY -VDc٥6^LXqSvT7C=M@fb! HTײwy`FY nB" L)4Tt(lhʕ"`,CY#B,QW:O,&9hi>׮zɢBKG7x=UdDwAף;߫ahJHIF*n'{d@lZ=wcq&Oqj?85b 0g2p)I٭@poAPIzHGt1@EsE]JQ|YJ1S3ܬd*׸֣˲7p, |nr#"<6Xtb{xzqZH3ܓA?;جkŴ`]bKnsʭJslgx8=dyuuD2 .G?9 }@zj !R<\>t+\ vմ(aD*͇}K`h9rghfF˓MY"^TC;8ȦKh<%I6Wxc5ȹ J `zAY䦠F@OkN6zQڞ =y( G}D`hz vt;?=¾H*-!=  II ߮y۠ئr:ta"z1?@p{X9 R⤨Lw/^WޗP敮{qϼ4!Pat|V8@*aWN$3>?v@/6 C #v'xxR_դKnȖ3݇a7֊zKG_}^ifdgfM(3i/*"~^'^B[,w{:km:Vv7kIp>ƪ u~g@>(ڈOd\O3.S}?)u8XC1KFjtuo(An=:KAg۷a&h>BtX-ц^(qjelF#<(B5J!OX~7m+,|jtF&;1lId{h:E 4{Wlsc_!66 L|*߽F4*M$xb1uA$pb{א]4p! ?կKʪ4M#n^,_)L!m,gzmu6Q rrG$$sLlEkk\ؒ5Z=i%6@gȸ<sIpEWvr,FJ@2'[1։2m&Y(uD(,TfcpTBӫ4zO-ŽI<0:C28H(Цw(شLe'o6y+ $otޓZ5')f/)ىlH3w@J. `Jg</^PhILk}J9nOS &FeG 0ё,{]G^#0(bn-)!B&U'fiR3bAVxn$DםcfĢI9ȓWr$h;b.ݪB9WPm*AθZj׌h; ##DG'FiN aۮGBs@ 6/0 J@N٩I_b}d;t)dV"e9K nwGI?屧 FCq=SQăl5>i& _n)(gc{%>N*-z 0{ ݄ЭT~n'O S/3aRs%&-K robK gV|i4ciOoxޒ9kM|NǾ4FfW 1ӊI 27Qg"2p+/,cu#M -W+sڝs4X8 l?uѶ$-饩e#OqVaXOgՋLpSa<ԧ>T["y|/BJˮ(k(d7"ʊre6j#C/5!է( RaT~ZۈZT`5]9Tf6 ]\[X \ fv9]j`T-hTNSbЎjs'SQƞ)Fuגu (l }NQxsC|'CCHMӗA)BMY0fBΫ~ %aٔ4O`JG;<\EG;vHJT '6-37E U0KU#ûIbH+ύԖS NK]+^YsDͪ}dq O/GsM)yV?f×G &d Iձ.U vҫ_F#tѫ \%WUP_Z IKx0G-ѸO~@ xVi(v[EQc AFIqUh2X_fSstܲ86>'8 \hvq%1DdSy(*}vզכdzv!69`%S/RB;_cm`}9~}M2LiK 'KqJQC(s6n'y/m֩%3,}  Rb =}AɅy8_&?w+S%DxG:Vɕ捴 Ҕ|Og _]S^+4dgZ6T`|ͨYZ<:U$ʊhbM댱0~q +ı*%ptU%#L{B.2XU,)Jr-Ur(^5(!)3L,rzO?k[wzb+L[{Coh4 NDq4ZHAOW( DYu0%T)W-IE~شޤ a mH_h7"Gr8PoYGvLeȬa1=У?plW UBjzRu(`*cnP|LQ}7 ,FLroƇևbe|Ny:+lFST}0hSV92)<oP)21^wB9*E^eT>#7_ɒpdkn>J%R-rS]ELMa:@OO C(ԄɘP^Xj]ta5(hbO$B@Iߧ[6[›1shf_2Aκ6FnX\h^Țں?Eة DX1ܓf&%ZB8cS!)ї;{ ggnWu@ _0Rz$!KGqfE~ݳ-ϚďqZ1s ;pC,W3]=*gkT3)=)}lTdl׀iӎ{pG79A ̻XO `]}qn%V;l,1Qx6)P0NhZ,f7ϒV#ڇv>1L#CAwM#`N E"kr @)idtD{':tBQR9W| ۃ.(V> -E݁ V{:*'6s%an-=LM2ma.j(TlcmzAz+KX%Hlox/%T "Nr~i]9a f%+:Np(«Ѝb>\L& )Џ]A +~;LKv 0z/βP?ĆP=P5tHVߎw$x:)j!jd1OH Z]pQtV^r-6>Mz VW+$6MKhaN^*p_CčKۀ'1{Ӌt97\՞²yBD08 J++ܰQ9' Å!jJ}gOXX&cbT(0R5ƻsH3jNWk+m{!sӚS1'4$BwEF"0;(Vo,!Θ ٽ xwY[w?_Fo zd%Jϲ bU;J ,mLBk`d-i[e0:'eۑu/4V=⾻cLsd!/<7+a.hX'YB acS \3Qk8@j⟧@;y,n30{M1GpFd4^Y,~E0f%#n:GϤo&b2nӻhꄠ.][=N Bm>f5;GLŢ,ԙvx#ԃ <݌߄`E1SuI 0} 2O PCUˉoi싧-X)6^3fr2Yb5z!;>I}kV\Fy.P̓{NЮOrHw03$L&K2/cN%w `#Sð6rh^-:։N`Gv6?0wIG&{'ȉV5S6WӪ]y";v_{\p^ŇGj ZX{I <zQߋRcv稚4Fl w#]JLD{$c3SW[KlL";$%*_z%i900a~@8O 53)n_7?z_|מdm)jXѭh#+`zDi>w[*)߄]f;qhH4mw=f` 8YӘV`&UvII,=炒e2c9^jvy]B-k+&X}0r,y.}mipGo׫"8ka8#ں{ h֪K2OYVN [GCfSxg(O4˥bF>4/Z{rJ3 XքgKY܄un?z\y1Ni0^ ~&dtƢ}ʆȨw|Y٭1kҰ.gC&/( ?:zyQB1!Fds)) "Ѽ`;|fwlÌ)CyaI0Co[S(rN( 14p^}_=ZO8%iq8*vR@^rɑ1!BC9S*BFr^A^AJqJrL][aJgVDB* ld)x!K, $I )ZiXUgn5CLkx5Vq(/%$Fk=7WMӼ H:"?xgvzU( ún81 Y7 :B ݹKJUdUL'~- >vrލRsr\[gfz:Q4NUQ"G~fP,XakB|n0CVZ*th;dEY4톖 ǚs$ '8r$#_e?foAY ֡7ѧIӃ>KinkG1頂hIv}Ql祍Rn'kΔ$2`i[l Ij 9`6㷔E l01y =0lz=OՉ,uy84VIF"[GlRvp] - L_?w"Gr?|n%zX5[$&d7P AѻFbeiIaI $__̻$k7r1×#e%6&gխ4۸X#lb89_,cM\te>j j5:5Rzhqky=LxS$q:9Wo{=3(/bi&X7PݏՍS*fRL^2ogݲ{m0c1 x 0" FL,9n% z"E5WeqWz-ڼQ0_r⩁R_5 k~![4'mƳ2p HͨJ$zs-J0`8KP7;Л{Ej+P%6ϻfLlx0߬R&-=qw5iЦ! VIF$3GTmP@>(AJKIN3v,u"To1`j 2lӞa-XIAK~WdcYy,|XS3~D!316ޝeTv0/Ab&̈FK ƮЄ!"'*QcÜegٶjշ\.- fL]xuKP0"̾+#u->Yyp1gί/ T\=SHXE=yey ,A.LZ€2.nWI[= ޿hݮ_EHyK.-[ T"jsMEX؄:yqm㯲Nę+T҅{9ţWuk:HeɃ-> TN'.73cGv•o XǞr(qvˠ%é3.mrGI(;26鎈U!8DPK 7e98FNߚP>V6*''ټ40^0ZK7XnQ5%_c&c'_[B*\Sr^JF;(rkTpbϱc҉uwUȨwHN6pE(3ǿYsi]y]Wp"7>.4PI'hkNcU-W=$PgOﺲ_ԉN15*ڳn[+atM1 R< {\10\ Er|7:0Gց< KgnjiE/,ryQzO]⵮ $ߓֱzʞr#fn.F9njƎ lWm|%EATӥ Wd >|<(rVRHV='_e|SrX ^2hrևO7 Sb']:N\? 򭱝OeJH@ u jHP& p Z@ȓK+/& ! !^FޖuZbt=ǺƹDng8'Hh:Ye~(iE!-<S@T `(mՎ#GQa¯˰YN` `xov*WN9-72o<f*%^u` +A7Wګ ~=nG:[+?Eaa@-<&ͤV כ]ǐ4yג&ojc~nѰ:ĺ.;CO&'S|_zIތ9>$.GK"@ʌo-vJ1q2 `Ca>6\ Tѯkȓ 0I5#4SCJ9V>/O$Qw4%<`Km!oikM9AO1ϏErV}TÛ]ž7JJQ Q@uႜPLhBG}dz(sހ6V8 Ӊ/J(. ˷|)DS HډH2E ̀Ϥ0b -5(rQts"*L[$˴iHjH?B|=s$9$5#%S(&X7$ 9k6~U2'Ɩ@CPǤ}1̠Wk)q&`K ԰⎱8F@JvXh 9LhЬҎ;nvBfN2Vɏ\>D&>:dLUE+|A Qa H4?$ %o/##6ܦ7j:M<*NVÊr-u.bj_af"dj؉Yڶ~'3ɤH2ޤrª aRPz3 Җ-xt 9_YA??hL}zk9^}Fįl^mʂ*>bY/+ʩ۰%DM?&3?Jk^ OFmuUq@t8;֟1'>BHɬt.8 Z[ٱ||.ދ$SrOU OsVgՉ lw{X8KgpITx2m"gH7 #4PSEB?n<k_|'fŃdu'8wP3®2=_r'T<>@3¦QOsm\1w- ( hӺ120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.233735 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/6bc6ba71-f563-4b85-af93-1f04e36671e70000644000000000000000000003600014625637207025726 0ustar00runnerstaffRar!*u> !( 1:120k.bin ^Ӿu0$o/>Ԃ Аmↅ?(IR '2:27m7dwPIXvᝉT]}UUH~duJwph0t[@j2K҆ (*47(LU?V3~T6T"_'(,CalQWӷɲDgc' 2bk~6_;2NNSQXj6] E+y/$&k&9o.oDtY(:jHh(k gSZ)S|sr~j.cJFKe6^qq[]t^3JbrѡwQCdc$>ቋzo|#{6zV^ 6Pb[;ۤ!ř# HUSk$1BԀr'߃?+^w#r#i$`Y\146WNӚQ6b'H{^rqD&8!#5ޔJ.cׂ md~;յʥk,(%( iȕhNq7ě⒒%\@n(ljS~lbe@r+~Ӯ.܊-n?ىHV[dz8xOК2Ȩ@=H!8j_55^6Pl,jԽfS \ ̆xێWsUrxrwO[.NSIےx)F5.V5sd$W"h. j($?72ᎾK l@Oˑ[-qfn|7 ў\h@1`uϷʀ(n#䩣 r`5d$_Պ8v́? KG"3߾f7b I'0O[`ُ^ Hz09 ;{&:))Ó= @vl=ηaM-2r۩Dl_ "Ϫ).vc/%%մ6?aj '9@c6raZ֊M )߱9k{ɷFDWIǣ?䋴u1! 3{NO]y gwUj>.^Y[MkFIj'nK䊮.̈́vvPlK=ZImq'n Yƌ6: > ~O$| =ʗ՗{,ZcE~.q7ZG &$(s`M@AwJ^q{#U*"qU5hFuעoc8,Py=0ovO"N!B~B&?]UDz'Ai0 ]\׺3 $sSz!4i ^DiP\h@D&8I(ђn_D9̊ʃ)."p,/a$l-u)YWVXOk@i:#a!g@Y.P~1%ݺ8H۲0IB~?ŮrL4W(w/ 9Mi[(jZP2E84Jq_ z?nWao7?XwJiQu6iz253ݡL'6/DWgk1҅jlZ]=9¸2>u Y! j? 1HU2GOWYmP Tu9PۮE|0X )uW/@7.GFnYŜ"=)dpSy;#HO*Y9#(B 65ה$H2k< R2_ }pRWFg vrbksP,)m.fc3ƪ-*)FhbH#[knF Y`PN1mnݥ=p$ɴg f{{ m]4 q* /-lzb}5 ntOҲԲofv 4}|Ïm~$ju {m1,t:Sz׈^Z#m_vQfv6+^Yf66!1Ʒ@ ̙(ToidIP .\tA<$rPCn'sj4%"g)ٛeI@U,nT8KĪ ƚ Y]&_s*\愪y.WwX>Y u+=c |'Uc;Q䥇  W6U=`#| "#UEY3'ߙ o@ߩ8Cܟ9RRε2prUv~V9j0Lld0( ӬgQ ?f?ҟH~pޏr&HqЕ5:4l賦!:@CވnXXyEp9V1As"4%RRPY\`jW/ şRwPqwBdYrh5hP?",E{6Vy(DIb2]=4K1ӽlK?vV ^4i-pqwL ~ňugu=*QˍZl 2Bod-rqn#~RhPNb f"< +as[S.!krn"C`f*T:h :V<|hy=jJd5^*azIpCvF~e>؋DU-Xv+(X5b71OebٹIO:NҌكH.TOgǿ'ZFRצ_IXHa&4 IAW}57ifqSk-]UPvXb|)Ezq|Ip9]Ѹ"z6f;x?EGgIHRvQxPy*`C04ef{: '-Zz!RY"j߷kF|)D8ИŘIՆy1 .ձq;_dܸxs  >LQ8[?U۩YiBUUoWܕu } #աn377n3R/ 3lL +Z|P`#yO,65c<,]=lWh)ĈlGsر?nLE. ako u,0ui_׻+h^iu|0:d= uƈ Snڦ`?X7v"5yv[ 7 &Bjء>H=PXcB|Р]Ks5N^[l:_9 a' !uTeX9lg0zQLV5[+`ܾh tk5qowǂ}koB\rPW0`㷊MZ=G}XQ$ Qo9lRKR/1$N+Ba+2>RP) 2J0jWUL!S WNup,Q Z0aQWW ,*ۻU^6iFaÃD!v3ZIݿaqS87FĢ;'EcE6֨g^/e p$Kw'9$M b"-%3)x RM$lA`/m?NЬBB-ZeV' 7Ϟm>>T[͝OY% !KV &\Ǥ.rCXX,!]TEPlʲogX3>VLZʘ~!_M>GZCj^ŒT2}k4cwsSRWng^FNZk>rWY?KC}b?>L1Yiw1f4+ XNԣW^7(O,^gz#)c⊃Z)+B)sT^ $?ϟ.x2.&SK{EOGIЀ$m5=3LsqqQ:(T@` HnK3o}FZwJ&1#Pl@TSݘbL_e'`S49[e͞ڋ zJ긁A" z l)"tfh,d3T!Jg`cdu\@nO/IIdj=EVq]?.Kjy˚`U`P7i 1Ktec| pDgb0Hf_5u4 = *䙼#4Mftgr6٫je31P/}M1Ћ[R"u7" ɼ e93C'0G9D,,3MAR1iMɭ* ꜔0hhEy!8 aJPt[FU( _0S%Jj9l=(k艇3 -73Н𡚙Ȭk@L乄ҤT  ^%3Cp;ljMR?I]LQ<^qm~/>:2mxx=?^ E;IYseI+ -5Y&Tt!"zP\0YPW=M\?cU6ZuY&$ Cr{8># w`WOdyaE#ڮ\d _bᒟƲԸ U:^h@&~́·y'xd/Ca~uG7@dG1MEtx{?䤩Dq(I&t|уw=$S "|ɃC+ ^@:I,y3cޠz!TvtT O!x Ojr#P_Y %29WfOZО[ւ8o1ago4#Ǔ4t!7AG$^D.@eP#:fON{*bEzDz>_mIV#-Gi*ԇ?ôO i Vn0=Se-a2eUO2';z?ڞɤ_jQo Ex2~}fe˜^j<SL'ѵ r$LF8J>MӜ|k6/ l} ܐtI9şj$}#iﮜigȠYj lSZx"ɶai Tv 5ԨҊ8P/.!>6nWQ1~53M+ϔP?DQ-Mw0.AȾMdHK|لQsuIb"$k.}A~`6foEDS+Wh\+#UUt{@9%$GGC.ޠfgm"XfYPkGbSj=3iooftLf}xnYNnpcO{8ag3IkzYP!)rB11:(QkL4/"k"/aA F9 l,QE4ƚ@޻50VCq8|ˆt"Ce Ģ{@`n uqfh|(TM ˽4YYjhn+Y*:`޻TN M+wd#(r"Rbu"Ǩw}7P^f[džv Ӱ${X.,^&װm^,Lh0ȭy dzL9GNJ_? PD`{!]r2dI\t|;Tc6Zq]4cdM4w%pn{r1G}jl&A;>Q-6y,~-hΛPOMn}h){t<Ԯ\8<,'U}hwC8>߬L26?ɮfQ~XCzc`F/d"O۬M6=0DMfPfYɴo÷arV8u۷gF\hCDY]KǜR!tR@uNߌO|#?su~ЖEYWfkyLa;(h爁#3lm8R=,ijѥY0e4;ꀉt{)iV>~}|x(=߅`f:L&8P;鴈:=d %5(Mqy+([!MpЋ&zVPU7 \ J/G=A^i0ϬOV^FN*9eqJ]ǁÐ %+WDvwJu~8\ex.چA'7&9Ǫǩ﯑&H+w:'(f(.JkbkNpatyXu3xgr/[xfp0j2\i|@V^q]ʡ_gn]J'y﷎BϨwsOZMarAsHPW#bq̇,ɗIIyW)BeX%|wKee$ bi\Ο ֔$`6jY9P2sM,6(k5L?܂7v>iJA`y3S1-恶>\ rMYL{w E?N&AP9|EMVM*)@ǿv;)g</)(_.@RVc+R"(*WէgZD+y,c{uP+ݺ(]#H+Y ԧ՞/{hA;AKK;TJuiU'b/^4FJ-~z"?BB\YgDuZ]J39jI8Η%Td}؋8< ߆lv&˗Kezɏ0hqF𯁾i#Q2n<&\ mH^G% s nTu_ڲY0Syx&EvOܐ4{oP)ǃ5|XҎ?mQJ~U,_J9iNL'apKCS2j5bs%;a"Eg0G$7iH13Ϊ1ʵ,/ѫy:fz'5g'cz/ ;:8<W2u'$ jcN.tH0'z'޶hZ)hS@91G9%M{/}z›q6;uZb)"͛98%yLT֭-N6vrżluc | kؒP-З|!4 MXEFf]y/_my_m765Ō+/ +)g#tia 0ew<8h,Ll˱.\`g{. MFMDp49$;yOIM`:#t ӑ63@M 0'7RcoXʇesz#}34- 6?`*ϫq8k"^i/p0gX3KK/HC/ph['Kb`Jg66ీB2J+գbV`ړh!b55ء8p{O͢-)Ђ:o~ثO's ʠ>#efŠ RFN( hs0GQ89z5\(7@U%^' n1jm)r_ǐ+9)ViLȁ :|3Ba\'z5a7{U7㗙,J|7Jx:R`@)m w:羳|Ȣ捔j$p-Dԇ?Px\vAhj~:\6S1ntVk1F_#A 4TѐG5tε{z4 b`N;b@!<ݣzX[򼒝hmD\.;0{En&$XpJ#.w&}z\1\Ӿdz7Jz)4c|!,eӛUXRf^pբl%Qd߭O8{4*Cjki5DŽ9RRJ\\Z?/1V 0ugR-Z7RG7|]r{]mS`@X֭ ~SO:]@.Q@'u%ljJ%? sPt51() _iWr$ꍚb?3|" RDk^8׭q`ӷl ٷ0ʨ _1&Q:YXƨl%WNh&m7XoGvrʿ7;73#o}A)νX9ufϗe#KGxRkS YeR}}J\Tܬ=f /(Aoɼ-^p]{\zhmi}c<y?A\ ]i@Q5!1W<ߪ#l)ǏG4T1B٥aIͭǸlψ՟!GAPpl=d}q b˖D_hirnDI!|{_xQ+HM@9s=g{_y=L:DCHCA/lN )2xKatipRQ'pFQwsKm8lGL6\@mےK=0ZS}KZQx@Q> S&&⩻ak_: Ih4OT5 OĚ{E&-m;!ց/Lz Lg#aϳaaj?V߆·H6S5xt L2v~bg-!]+p;Gqo !Z;s.c@Fp1+:|x "cR*"^y)Rx`GZTavw\ z @>-J uϒcP:;WͥʓwR:saB2d>8,^{iQіt"q(ץTP1'D#`MZS%_'VƠYg`3ޅUWr/uDEywt|OFF p\1nH]\ed_粖J\oW@JaR`br@҂‡ͲJkHxP^j((W= Tji&w06qRC醯kdƯaZp+L9,$6[B/L<̒h WMŠa֓d* :Rۨ8PT*[Fʏ%2ɇhTb9:{(hh`WsN*$fꢦ\ *|)!vۈttOX2LH$Q|852 o>oēT:BMF;Nv!ei67BORd3*Mh*/kUJŚyDe(ӘjzP_FW,.(R ɕ.V|"MuDƙL^Rok6ݏR/6dmԱ5vd*i }~V>ejUq+Y<(FL@b*AbxԞPձdK>ľυ9 VfYD nMc4:*6FOZR7e{ ^nZՋӒޚwv}qOI^ S:cnO=Ք!uo;z\R+ס{ =_V cU@( ~qI-"/z'*P7ټJ,|vCrYvU%s.Gre,<)K Աqat#9k^:>sؚ>BD{SIIݯy#Z1vf,րz!伝!%{FLNKSsT"AaˣKOu{#ԇGŨc#x3|H {pt"jVLWt lWG!+XNb@o]uX^[('Vcg#%qAJ T[yϻ1ˤ/8?Vڣ;trTݬu$vr#^L S 5)ɬާ3D1pZwNv˨43eR+kabJ"-TQÞV N X;_eSP9SX3o,N;hv~H_.r7c 'Kx :_\4_H34'{JT)7v+N{k } bֈpm61(϶ϖ ް|ͳZʓ/f8֠(4P)%d[v|`-@Kdʲ[K>jOfBk?VJzs?qo1'hZ@ /dcK̀x=#$A@ 8To<3l VwQ9.&I(QfmǬCӥն&<^/@s Y>hS&K;5ayՎjXddſB.BNHə: Mwy)# Ő4Vu+]s١&rB4w7@[yEG#}4i< A%Ф^k`ÚEkS8d>X0ӳ 9ǝXZmF*EΧeGrZa=o^aOġf2j! 1,#T3nFE/&u\p0_#G(g%1btXdL$/@S.WQaԏBDsP۲+ܠM-RX]D%͍Vq{e9%w(6$rkxj 2E RZR`$`KOoaU[hu9s4FC)ZFV.g:SΗ1k*(ڵY{w%hg$g!YX<-#^>~M"L ]F]M6Br˿CPdj=>mOIJ[ԺHz{cxjnSݶyS0h4Z1J?z!ܴpG_ѧl-{We<+ DKM<IW a[,˧{wNFT_UdK)K%& a/T+Џ഼,+X}nq45Q\N3vbL j&esuwXt7<%V'%QNف> /G>Z`]OriHoRz&sPj2x?&>Yh=g~8)>l:U*5ETU|~.WۂY]p5^3OI^ Jv(Fr$ҔBv#7]+?PYgDB@< Az25gh;J:سE Ր*Yl-SYsIʏTs#`!=/oIt囸}קrX4NSGX੬g#:B^i3 7kV/Mޑ u~1_' "ـ͍lF\iTUD? >\Kzhy1)V,8^ܱIn?r 3QHL%G} g/C-о@, }cÌ q 3K8,tZex 'y/ൾ; >9jZwE/y?/"RAo~{O,w'&MdߧLmMȭm`Cp'@@3¦QO1w-!( 1:120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2335143 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/3d2d4cc9-529c-4a7b-91a0-67e3e0ddb2b80000644000000000000000000003600014625637207026131 0ustar00runnerstaffRar!I Ba(  Z120k.bin ^Ӿu0 A)*UrngBηr9|j΃0aa&FEѢ0c7.PdWR2kbFw*9'mDV dk AFѢDU GM}]8qFXƼɼL"O%Ox~h86R|i]R(̇` 3=%T] 4La~׏lRy*24]b|4xS7qR"*Q[)Sp<GNrqid*Q X`/ 1H#ddZC&9/YV3F{e7(gRc5eEz=!Ɣ9oi"'j_}֪V!oQ5CFV恅q:i DEF"WD#<>9P9\p֏Hbcگ/$ڵ'ېXx~X yMG}1!Ak"otzRL10!pʸbP!aM3!yNOCƠdp8%`i5y(_Uv֏c '>~Yu"|~μo3y n\Tڵ?pf%|p 43~eD엯`IԱe(}^׸My>cq+g8r"5F*dǢ髙4/mS,vF\x 7)h:h0wM)9d# т`z"'KfKq%-@:!c4DmırxGui0@fkzTz(wS=@xi/nU#32 P<6URRc$ ꀖ y/dؔ^1r5G Sȿ.Ä&tそM86@$# +a,N<1yb-bAn =4PY9@ [c`pU)GPKaxW(1OvA46e2oܷ[y5(s6$=bjL둥 |䘈 ۿ v; 0ܨ!j)I|~ S(ʊ>v3ʠƤU_Tkt-tGO#6B_3% $_2 R8LtMv2+w"ƠY3˘X4e q b5&pLhw=%N_PΗkmL3u{>Txϲt,|Y?>iX8o-iE4U/A0g^)&#ΏүFxyޤ:.GDs:L08Y _Df,k6}]ާa~@Bl^fo`H # |u*T/% uu9@gHTFɴ e2##(+1=A9r/&4YI6~v-'ǦlV\jڹge[R]?r+9nG*USaMX{5i"dJrP43}g>GiAqsug%oˆ10&vDo|@)y2:'Q=й ;9ܬELP`ħ RDeNP{ҲӚoL+b;v=OMƷSUחH nJ%īdugjBNos5] x:&3)O#PE i%K|ES}(@;~+ވ6KgEQ}d`( ŇSyǙZ{ ԳcT@/^5?D^2(YO_; Yq=F;k͹|UEjNGq.y3p^[4/hJ/_nFo@mylϠAeX(c]^b909@0rg!+:XoXW@v<>\nxíӘWT8Ўxg2zfA&vd(^?h,a k<#K톙KsK#hJ8]/A0 ^!08#.\bbڭJAw=Ž=kLyivx 8HNVy2[ LʠDBazhqE,_-a"cK)cknK|hpC Opei =0SS(F&f\`I=vX50>tF*xlfYYbq`u_$t ^T?,DEd٫e*(IVFSRlPy}hguŸiTPDIUvx Ȅu_N:Yg:%t{:Pl:]x"ܟHͨ$L>uDB}/+N%&'C"NG.elhlۅe;+ij,^ Ӆ̃v1'%Gހ;(Cv}p^/KC1N0u߾sYs酄k[ 6N;pXea&$lgf TWXpWxR^n}+i 6jdW0H@ JU'N%?yf{)!+Y=qA! F+M#f|3B~.3hK"LHv;>8=Q>!Jwrʰn/݇Mc. ΋C:sGp* HL,RnXru)G>'r%8surE@qDjbޙ%ũp2d</Ptl833`a|5jls]rش=$BC2WI tz[^(94=s~ x}}QmZJ}-ቃ7[egŽ[и\H指=IKcSkE9  m< 7YvKͽx~IR;B*rJ@5 d[P.#g @xyXTNP[QZ^б=}",}"HII0`?6%i٫R^ہp&*b~)zʪXv[s]+Dm/ө6_JodziOA~vd̷W&YУdݫlpI%\Z&saY;4y9̱J8' ǦJqsizVWk|LK8<@b[&`B>vkmcL4? sp(1z/$e;Zt~h@b* r\T&hr,BӖ#@4땻Xug}-)Qy;jl$[RJ: iM^oagxI0b0ۂ! =mIw<,*\iԨ6- )΄JzV{{Bi&vĩmusq頋*_xc0v~=EA}a5ױFٺ:)b¦]6=p4oqu1w'z=tUYseqb:!3=843Vi)O)Ҝ"q2A#@(û,G+-TH##?5\ =ŎOY5R%"NΕj ?/?˜|I2 G2m>BESV jM/(~fz;NjH`TTKܼnf֔_LTo*iH0hloU;˪-oVp蕭R~ K:I#W G'@v`._-%Vh-qެa?ڷzGMK:o e;C4q㗟m?H> 5Dؚpk:i l.5- EwR3 O'U \wz8uYOE}Lv ̛Ns\1tˌԊ.&& \KiXsߏ+i!Qe >cØ~9R &͂{FdY%[T4\2aie}4.}XHR84͉UQ8 ؠrԵ5,'"/>2=$HJLUՅT-W!y ,IyG N ٚ@*<[AӬ)*cc`Qw6=آ1gag^fv u{hpos7ãbޯiq}a3*kJW1~I0Gn$\lklA~S.%d$#]@t=ڕ1s O&4mb1[R >Nh:oEC9 K7Rpp*DW_g1$ !CSF'(7ZJxR{S<)JAˈoT"3Zc08WdteNj V>" yD| %mj1ypݺ%5x9|u5@bא 3Kp .EY^ ]":zeprfyd-|BJ@Bx S]rt!TS^&:Fa&j6:D"<+`J=Hp|%qc{k0I)M*`t1/B9;>vF[km=R( ->1 GޒQ& iLOp|5Cyu|8eei(%4m93c}kUdN J h}aG ;L|gD r"Ԓ]E6 vۓ.MMmr5?,CFaah\FJu;MaV9FUUMTrm=do%뾋r8n}V%KlXwj.#,K&y5!~0N31X]F}j:>>gDE|>SW0ǰtYfK )O؍@be59<Lq#♣)S>gz2-VVJBPVƧ l0qRJ/b$0kΰFLun|^Svűث(&aTx$ @<8;yI6 igy>iԈ?xSF=GuZ4{ԩ:٫&V29Vc9F}!넁[ cף!}BD?}I(ƖfՒ%b0O: YUleTŪ*KLGdQ fѱ~ZZv6ޅGVeI>Lo/ԗd{VkY^ix3iRM61x 9Ldx·v'qk A7n.y7{cQO< Mԩwrd¦]F۪"M]@i^vHr5YZxY jK5ÜJŧk8{m?/y@RS_@rlrn9qZt \A$'wNSp0/EODjh0>'5ן{hD\ҫH8/k砸HOk_W>,2s$7V*cz Y 2|zUKx.Uv5(?%~.@]e@*V% /)/56 P{s!Xi]6RS #Wh8zI0W|)"EhNiod-L&96apvګ xPdpTBqp~HW%i~"E@ӧK]:ٿtX5>۷X]=;ne*[rVhTJnPMMS;a/'P^'4XfJtߙuD> $.tEaUK |7by{gȤl\^r|{5MUgo ؾ_]C:< u CbP~~: >y2k]8D7s؇JJx~}ZtzL^ # t )'Am.Rf6ѱHr(n#ߐ'>mP;F'G*J hnPs.dqs5yL*5TJ4s*|>=:L: 73ąxW<,avX^Jo8œgbwv-o|!+Q nتUD3kStR{( l|khw\bα/]M9拖gtJ[}ַO̬ΛrcMcbƆ g歬xptYlֽE -8nWR vEWKE1 HGΌO(iqB48FJkT3x{/CXgqxedn:1+$ݍ=,&c$GTN$h 6$k+DDў-Ź][Gy E} f>#y a˪ߎnviki҇εϊ?ZȍNaj39>^5XJ!ʤ8u4^>^q%>)+5ȳ wV ZYRgڎ'-fRTy%;v*4M''r?1-8"O^֍ /V2ٯ(%M'AG !>wF`pjVWF}".nwZpT5E'NzYH}0̦٘X>ǽ*xWU &AYM>zw RlrFnjYz(]a&1|6օAa*8smxFpȩ`g4f UQv޿`~Kk)Q$djͫP(Jd#w _w vr cZk~^G9{M;܆ӬyEgGlOlyߢ_jL3)@$/Q-g.<GLz[V[v7Zu# 6#+_P&I:W2Ic 1ɤ"-@NszOCFuAt0| `" /so$}@ЫoŃxʘxMS$kFl. ;3;C^&q,2TGQZ*#TrMo?z,} 1Px+?\φ*GƮ7i^TV8Wß)4fLH.FT{oRt?Ex`VCR&*cė( 6"O>w44qbO6C7鑍#:^D*/!Oc7|-ah ƽiz&k9zl^+>/(\GwN 2.Riwj~oԐ'  XV59`e8/h>*H`%%*q.Z-#Q}~g<.-PF<Ӫγ2!:BIl;`[ U[CɌR ^NEib)-ոܷР+ UmI͕qf#FtavޒӬLlXr{i@Y=ǑGb}.-ʁ3aT2K!F{*E'LY= 0iQ'iYRq -E*ȭnqO xtuzqFL>+Cc"Y, s cHR¤[qGev+G"Yb ٚ>BϘ#«Z5R8HN,]VxH>?Zꎔb<9ZNk[FX6T J5wRQl5hZr;÷zV)6n85OOl\/.HY_Ǽ#Kk[COC"Jwa|n,b"lf&>8hPWUxT\j$op5f"_ >zx9Jv=mq yG {KK[^@Bp{RBCvPYL=rbYJFU$ '[MyN^Cg@Z,;t:+[8wl ֮_/~ڤd(9Y0|qTJ79IYq(oD 34۲g#jDp7' # * i>|KJ+ǺZs)(lsǘ;9Hoegޖ=z8Am#M9*3۱6}ROB5D5T X‡0ZVE]5iM\GyhƲM,s$}]2CݗTLƺOFaܜ+oW#kd_1 흀N0z[.y]B9@! *ӴmjD$Ƿ4=Zi. :v<5)Rt9x蟅 <7P52CiTDْܺY4kUsXIY8W3 B`uJwJ|P"$qο8I\:4@‹/9njEŖ25~f6!4/|TpJƼMjfG{F]<cZ~tkr[%P*Sx:k>IB;cASQ9ʈ/1U 9ުUU%Y<S`Rk4zy59υlUWX7Im1]4<;3yXzȢDW/z/g͌fMDf4 bF)UoN:X_ +OMFFAL8 ( Nb vjzO58ƅ沰cQXHQe'7@FPS$lŘlQ>(iIil]{%]|Υphb9'lU+1m%ϯ-[plrnJxݕO5WK+8a-"hBkcv;K!߰fUP`)MSٶ4}]F<9u&iuDئJSq($ruִKv l@qGrZˉg ix &Ս\}݇̕n֮|,j/|>@#Ӥг(K;* ;`˧Os|Qg,㦉"/S7niK({1¼kv va=ED ۅ@lG'|a4kύ*5+ :neY@AG*X78Cvj(fX#8BRs테\7шupWOŽsU>:w)HCn{*YȒ3*wMekArwfa*ULBsp8_#YШ)^e9'F"JtR[[XMրZ]ꯠY]?(cv0 \$ ]&pIAb_//s]#`DA$q_*je㛒Z=L:/ݢѪ44Lg/a( #A^۵'{q]<`Y%{d`d8!SynJ;, /vv}* >Dz19>hdŤ"O17Jy<DR?u ǭ0Vbf |lX<2Lj>,u(eCAS>sxvrr3ǖZ=m Pb:H-{/3-4: ^\)P_v!q$ [I맊ӟ! 3kԁN7W_kvfOHx 3zJdR.]9o[Q<5~tfI9 PtLJJ]bkZ{CD ))JQ{M8K}1jYN.(VRj!iz~yɺN4k=-?hͲN4+{6>UC%e% 9es5v޻)Z\WemvA+>¬H69s's\$hf}]0lp=\엖w鉴KgyhrK=,@3¦QOҚZ1w-Ba(  Z120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.234652 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/e819d66d-ccb1-409d-8794-51205742fb1d0000644000000000000000000003600014625637207025645 0ustar00runnerstaffRar! $  ~( K100k.bin  ^y(}nPx VM]Zu9~"o9 C5\#Ani2V6p0]d8'yaRa2X#҉\9;'oߠІBS+1˹bEysB~^u : i`tCk3!s$x( O8qI2|uWQN7O>ghlڤОBK)޿L;I>nE7ȇ0[wl|Hx鮥?qL|8*] r]rK9HUuUj00}Ű vQ]\aho/C6 uS](c^"W5؄\ut8R˞7#jRgJw kDHe(8SI1#Moz)fe]w 2Gxʹ&2\iAcO[}a>$AqJi )̥MIڒ1SbW ioen~IcQ9Mp'KLESJ^IL+ʥHށZ jGpهFYE wiS`& ,;7F4X\- QZ)nB `ݏ;Uhtt7cWZ]yi07Gx0>͑ql0Y9p^_KU&L`%DpQ"&"mƥYQ϶c9!T=N'h[!,G^xMXzD{J#'ojM(0Ĭ5m$sP嶹8;{7i5Gv+nɭ&|0diOstlpэsAcie%"Vx8ka'I'e1007Lݹd id\TzV'Ba6yى!,CpȤ+|TtivxbIʚָYTztҶR2B ޷Lsrcԋ( _q%Y(u. l+Or>pT#h3.d0^@: w'gA63.>1u!KWZ\Xͨ"`93r:;NT9*biY߭; 5h~^u'GR]M7Ucԃ٢u`<"]݁δUwgH,=UZ9#ϔ1o/΍$%7'nmd r* u0sb"ESg-!ML៰ ;@^E8>~鳕O!]YM] (M?=3YN#0UmlْXc}G8;k^dp[ 31qWҨL") MR;7`8 662kHƲ2+i@W.q(#bx܃;}sqs a4UI#CU~ֺAqcF.[]H뮚C!Z/Wy<0听v0g;ܵ'hsz|9['s)mS? ow xRj SQ1zmi"\5s^cY1#&\.Fǔ寯z0D˜jB$WS« 6E/8_T} ~Ma<^':X 3Vt,^w{,I&l#DFIY,2fa0zGJBPVD$ao-23zDrdNӭoT-֥@}Y- %j"=jx#LߩGN(w=  jRɱKcǧU=S{i=婨"!r0GѲX Vw1Z2.FbB_Vx Fy3l]U(mxY 7v,uN`3?:5-5yL8)_<;3?}]j?RtɢZExj?k<{G:T[TL6Z> #U q=(a ,%k DIߥ2R% `oj8x֤%}NC6s8`)nq.VNeFnH$,F?-Yt&C9+~xo 39dURam f[KY:aQokpذ0p ,sf3"U:rL(8Ah.N0#y#p%ay5H r1aHq'Ux_WO# Gbk^hg{/Yn?{' >N:|b KaTUuB`8:BCӬqei˔̿ ߻yk&{i̦@ㄎ $kS<7_b 择SmEE(m[} vɔq4NIV Z+sUE)4kwN0f/5DuǗt0<(^&[zx }mY˜hRp@eEBK0\t~$5](S2+$wK>Tb]||B,.1 u4]usMljr&τG e8yBpNJnDb(TGغ۲C & r r Fadžk`.RȲsw i.'Q UԘX&<r#iyk^CΆU߭e!{ ^ y39U(:LJ{ݲ7_xliߣ>`n0ާ҅C@{<U~U_l7*f-mM)JC<~Ī%ԸV05nYxj|.3cp("z^}@8:da4tRR*|OQA.LP0/?)ecoZ -aTSM)aPї]RUG#U4(#] +I7,NdCP\E?MMfO1J!^9/^gYo0*%]?ۯ)\:f?-sA M&w#"}HfHk=F&B&=mgCusi3Bh$rZn-|͌M$5x gBKzuI6Bڕ+-qI Cցc/ }|lV$.[0ͺ{[Cfpivڙ]SQ̏[W~}hdzDLVP5lO>4.I!w/h>ҴbTF:yV9mKnH iM1ӽyg6&żsŏl. 3lwUO9T2F^#)1+J45YR! -q!f( ]lϢn:&7uq#~8_exa0Yn[&\V =<>%>ˈt(>$9gf̀Bң18#|NfЧP _]8[W[C |<v/61 cyB((Aaޭ^ڃ, |zKg#$8Y.?%|L-')xS'LhȖxN9O→PպxZnGv"F+@X */fk"JvZSH{ƓϢuvΧu2cz̯ћuq<*.\ NWY9lf3 d )djl.C@MNx_v.\YE~"W&a#0-ۜ$ 2PV0ϝ07ɸ%SE EO)@7y׈p6W0_aOOcZ+ZUv2Q-5GKlX Q^ Fv:"]nP%/dA+A 15VРmuRh$>̣Zu zQu =S( َRg 5.6@d){fa͜z֏](C̭Ɲd l#U`W2 ܖݠm8MqSv_9،)7iUh;`߀̩j1G?.B2 4BvOtXE,E@p&pAUUOfK=F9 !|&% e.Xȼ&/㻞vDNI.!8q gi*+..@/OJ @o/SPvM2MY7 ]o0wsf5޶Ub6{~<.yEIƪ^K2pEYR;Oԅ,u d{_:uP1dp!9TElտBkzfNcW%Zw&͠@R('V,kw,d܎yv|zQL{ь~u%+жTou"!J;+Ӡeѓ[ o<քSG J%օ Ws,sx Z?I) 6~kfE)oo#+8^?XỈ a1o܄fOź`Cϸ,I %.`|~)-SaVz~)FЪ3n1M'{x1{LR1e)[c+ }8Ƕ-/#B 0v٧eeYКʫaE+=_B1- 2=I>Remxm} Q)dX;) "b~Iju(рi&Y؞IIT}79`H8fËʄ/=E[4Tה9G۱?ތ%۝)NĨ o٭śyHvz#/6$@C5?&^G£ x$7dVw-^cOJ42 OR=&YL?=J1s92/%yoҤHUb8^kbO6.K_2Rn;nC"2Bí23XH*_^*m# A{ltzڕ$y )zib{o:=qK9K2NFݝ.(%p$=O$z{Iz":Dž[e.h@^3~L a_~o׾kcH5?\\7i8$[`P۶#Jmc!L>Ei7!oikzVH7H۞e{'}i']ܱa,76PӾC0&U\ ฆ>cQA˅LFe̫3C QtC4m$fbN:wW' xX!b +Dp3k=-_fփ|+ vȧb$[%՚_ y>iOgp;)ēxS<%QxOvK[Habv(ҟ{$&/qWNLe9HW ܆V>Sȁ#jMIozZ:B-"e>,'ક?i; YT3͜? d X=hcKh:/'x?Prcp:rn^zm@(ro5k>y8dLlBV'BwGOE )#ڀ^Nvװ]}{SL;- 1 1'M|s!L8>FQE:`W.7X*^ }8Ԭtj5"E֫c|IkqCvKWΕRjԒ2=,W>  5C~L,пp|{,&=S`ƴw))tu (ٴY|vToF1Lc˘pr76AR$QFU/DK)u T>U>cwNyqHt/҂hPc: ޱ(+@#G.ԟ }?QNѐy9tJ.g,{.^,EdpVا .vƩ84҃wzo??N(h rԺpX펎' zzX4_!**Qddھ{ [Z.Of`v5%c~aiMG8&oej3@"dZ(.Limb'^(GYM_!(eGق72[f;,JiNL /0B+v4f<%uxH-xc6:~Fؚ!8l!gi6/œk_Y|JYb+qm]_L= b(&qw$DE4dK]G;[1I[j.^0ݶsdu QVsWX9cU8]ݹDM9X A̛8Ƈ"WЃJɒw<(]2Qq?߭hti6d{"kA~7jlѾȇ-!rEdG#yfGi oy\vi4E{#D 'h:I=&˳An!=3-J'6bB5^$*9VF<7m&iyPAc#  vDҢr}iy?F8Cswnwɮ (FP>~ 2c`Zws MT/)cj AX;ĂOc;ĸE۟ >e /\7fؑi`'^.n,9WFq)i[~j]ixB!x2Z0YXW2mGG'Ε~+¢5cȴWeks((4Oҹln>TH@ VCJ E n3r{< ɪ)Cʬ|qzU+CvD3)]' 5d}ձt[.6ѲhO}.e u2A/lIdwژ^S[+Wܗt/X{s@`ȾB,ms[bR_QdžA<6/`$[nƋW fO[H-fVbUoθVpd1N3!铭)JLTg,Mwv@N/P~m'F:7Z..(a^}{4ʨ{zdHG"iQڣJؐ T~R6Mp}.0T_o|~"sAMɇbFO Pf]|9I9\5랝Abf""gs]]Ô)wgg7f7wHf7 yW"䚻~]Pe/\^K㎬?~Z7kdoho Z[_dR ‰Q3[[Sv 5s#y*AE;WʿP'w򜰹Bdmd&4f0d?{rF/ GW!S`_p(ix%­Ovxv~Vg*lu@MABW]xn-A^ʧ986f/4  N ptؽosÓѐ}JZm8MR6wR_q43_: HKAaPl2Ns1܆J5K'3c!PI2N?Y :@흱Bj_rd:HvA dȹ KĨ^PN !л 'QJOns(a$ұ;e '~4d.g0ABlvE;\ L{yR>S.̻oOcld;g f:UXɘ)de}gz5K^&H[~ZY`\XآVD]zDr>Eι%N1{5yѵ 9$jC - *bezaCi&ҮsMC1؋0y!J{j}?,@87m) 'gſ?@.zH;WJ(k4f';P̬r j<5W* *~Ys]h :611=Sio<퓴N ":ʟAYN/: "ߟu5 A@3¦QO}K,y1w- ~( K100k.bin  ^y(}GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2345555 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/d266818f-83f9-45af-a6dd-44e7194a66dc0000644000000000000000000003600014625637207026025 0ustar00runnerstaffRar!e0 ] (  Ӹ1120k.bin ^Ӿu02zTNBuLH]gDxzi|LӴwNeYYZ7[=!k+Wc\mDZ9\ y2}{')_^} 7f6,d`;BOp=2=p\bĝEK)}Ԥ y۫)4B"C.oBbQoWp7IǓ}d؟)n?6ؙXl6m>q{Mׄ2?"D+؂4+ʠ%w{Kx'$`y}bSOilPŠ8`5$灊#jD0߼[% Gq\V3&bɧy/8d`B8 0<ڼb𶋒T;| KX:Ne\Mb*}6JKcBA=;KhW7h*LTpO_B`z(K.Yb ̌IOS !%Ց>Fiq| Ri*/vBJ8tBXj!\߫Gf8g(txGJ[` h2)bJ[)q#o)/胱K$a+JzClP(S`qO%ܠƁ,WGã0W[ʀP)KZ!C)swSbP"26qihXaҞ6ޒt Q[VLʎ3~9r*LOKU@QQ! jÏd9exnd"I; >r= ߝM4-'{~3<άϽ!%_GK^*HI<kik0 W`GV@yB` `cY rR$ +vǶ9F\};?Բ sop^#J DX=͌\ڨk hL(i]X;qv^ΒzţQw Mפ!~7`q9yTBp)٫H cT\>M:)V(YqTQDLn?~'Tfrzk!FW_܀rt4>(KZɥ@}joMJ&.h$ftXkXcfoS)U e =\c,Wvܮ=/7#yO f`֋io>x-/P_NN#{K:~;"] =oеd'no0{m)i0/ hv/'̮ELtaކ*S =ZvM^#nMoPlO{ε97KfZtmm6_ks瑂p 1 75}Odwj9ʿ]Z:^K&_ ఇv&VWʘ9-Ok+P4s] y8ȴA!a?V6(Y7λ3l |> ř5a[ k1;w}yI=Wڄ*1wZz,M1iq"AQ?+:-%G@muD.NM=Ь$&fD<~>#vd6mkӸpOS@iv|O_h'輹-OŧRs÷v `(- K!3>=gAœ@nim t:+-!x|FkQL=C`9^͡3MF5B]\)Fug?t>e4#O> iep4K[]Lan1>[t2Z.itvEK>)5'}U^pJHIL7d=XhҊZ՘l7nqDZiEXH:Pu7 1IM>SHgqU}57T>^vugƥ"L®8qGB"[Я'RwZuwұE-s zP9Ʃ6 r 05q/<'R\ˑys^ W Sw>r@Qiq˒-( inSx^װ4G Iw$175"~vBڑT~ܩŞjjFSÝF3fFQBبTW9WV TЙs-&3:elY^%T?;K"bߢ- f,gpXy <#YRDRp ȸ{5/vƻ#x;[^/gguy}Ɠ"۽m9`Dc\r7tS޻ȱ闖$#?yp#Uԑ%&2|F7bMDLBOӹ#Lٵ?c2[7g H"K"rL]mʜ!5䅒aP4$xKv.ZR&Km P%I%4>|8qΰƶ[_s:uiߝ=bvDƏ!試 4`|0{~`=Cj0ۧ/d<&$ՊPbRQTA-:?;:0:OB+G#[A.R-c~۪( a1nf4*SچֽẲ3خ?C$'[tk˚G^xddOʺ٢W%(§乔l"_5\ŖV%@Z= m2e ܷG^qAP묷D@̑KÒ,,LҞp,ձ CR*g rփ?vQԡ1jg-7Fѡ!o6;XT\M~5zۑ<8|v6dёVO5}k_Rw`5\<å [Kr~a ǖ˥!56\ G;] N'O@C"0N~5PD)s/TU%̈́SnGС)ܩw mzIOp_𣮕(:(2XrswS+WB1Q҂J|E+lyg7hG,-'|f&i  qxÊ7; $jeUCin[76| S3CMp5^9b +vMBY]H6闦3g'+dg{N z]h Z9f²zbp/~54N:tsOu΃2]2Ŵ ȳ0аU6ۃ+딭J [㴊K'~|y)sC=B3N G n]]B߉s"Y )}KHvS!"S9q*!46bm VKL b+ )F ##p `.)GS RV Hao;d'r=m@Y}~0q]o dX)ftH\_ ^#4~0"<$A n9h` ?+nI5ԔyT͛3o]%Qi)Mڪ>!lA@E/q;aɲP,du8:Ǧf\$ Lzź{Xq^l.7җ܉=8GqISV]FNԀrfD~itkKvX=h4}wJMaZ g@ z. 2X5]^5)`S({30 e TI-|`|~!X#Hk~&[Px h!,JU?fP_xta<"KLHՁ5_C X\hh ^VaQAK >zOA\G~/$5=_AB{t$Sz9ȣ sใOX[w;нZg;|ݣuL效`}k1ؿ M{u*{a}MԔdLj dJrRowSQFt֔BS L۪[ n SW $!p \VGIJzH0#ZRq>Qʄ{:7uU7v9Y(;W_Qu獻 PFx5>+A%R{mBI|@- ?:d\ 9n xE5Z\ 0`{RdLli/ oӤ+ 9PsG4vJ&1E+c%nq oc"7ܑ($J񂤬tF=DNf:6` x +sȒȆ ru\iӚ6igGK"GG+()f., K Ґ[uNyy+bdW|y]7}{DNE' H{5~yeiNhOYqLm1fdI^(v"|rQyj.K~I )@·}(1й:r0E̎|鬖B5.TP<!b~ Zx2}@ν=Aj&qC=]Nի,B@Ҕ_w#mSuMf+s ǯٍjZʕ/)\;6:hz{`Dk.cV૲27 d%먑 MaMXSUg/$}lIAdهFX2o}b"nV[ Ls!Ett>@2dsܔ!<5U%~ids?h U.%%!Ys&)d}mqB_3C$똪 9,?&작}e z?llixfaQ}fQH%X{?v(ٰI [:N^\OX20qD?Άߍ5͓Dhy`|V6%D :8FS5\S zuO쎎&eJ%8tEO'z]XFGvlf?Tx*;+H@b@~'vUx\VېnS]f1풷-qJPA)X_hv޿- kmL(IxHr2TZ|*TPB>ẑz n3u\d*es].Όuqqmzj13Tcu,~D'd>m`eJ&:WxHYR-@IzNHS@dpB >[Ӥ~EiX%KQ="{c5KJN*WLj 2!M4(uhpنdVWKK!; zU˻t6f<1ȑEŃd3~Z :\:fqx fQeDqэhV+m!5HJp:F%ݮdfW% kYi+ЮTz5K紦'A(!-W¾-q|KP<./+e3\YY?N6I锿pzQ8K"1}N@UsNH(*; Dԙ1´ ۠],|:xljx+xixړA7!a.e._3!C];4meǂSWh ݕTC ePϼN@[\*}x+A* sOk8*M]He\~+ 1ZpgLb'ZJE Ϟ]avVp ˌuLPu=i^? 䖛r{؃2$9P4X@.W[nd5*7UXM/?_ZX~̦=RAch%cBB~ЙE?ؾ8^\VJ 9^T5DA2K-(noCUMt$Ɔjw2*֣.BFx{M?Ⱥu}*]JLAӒl 鑙_n!8epw:G4m]?.XuxLO :L_=VSEGKs\ӛ3 諐BޛkhW*/LoP_@VU.y"`Iz?g<K7dZilN[,w&[2آ: 5*pCGcy%"6-%x`r޽i~tJ_aN^[=okPDq[4/YjMZ1{gk{^T|2q|( +)/Uxi?D»]5Bꟲ~A}W"-̙ΦA:(i$ie,MS-.%&0'st`sgEeET_bOdL/C.7(eEWٻ,A==y I^wS~.8}WMG yqSnw c j!r$EIPe ~Wblˇ{a ӵpjEUPX4[gbY^(8 @'oݟ;+-1h8)梙pw&=xU0V{RxRn-,e,5Q \| ݊zl(]NłAZ/#>=HuC|pR8ƼhrC nuV`O?۠: [:h`[ SԧHAUwo#y+r8uIV<5t҄'}qCx.DuR=4$HHFeߙ/0)¢I_>IGkͰ%_hgOӁD$AzQM(qLc ;%RmLVPY1˚v)t 7홆>QInSs36XFq#*O0 8PR,A_[Qf=Lx~ qvȯM2M#t@`Bi\!y,~ۡ ڐ/$a.|9`ny7Ѧa;-WDeC5v@OdW7CJO}hP|G&y;B=t l?F󥚘áԝѲ77x=kgsrzRV%㔯ըҮ9h[. ^GE3Oaz_⫛&daCۙ UB BnPy8KVC~GV-52E\C´rTp;MUfX3cÙ~|Kơݬ nR:*bp_UlǧzZ0\wJq7JM[!"V|Myԑ=\Ihۮ1 gQ )nH۞R4%Yچְ=ɤWyt|!TkIhw:pՁE( $;>$wKn;KhF)X9¢2lqX󹂓 pà;WYrmjEgT`7?SHl O:dUYΗtm:뎫hPc 1 X<,͡CDRN{|t@UgtM9cT?ACӴG TqYINo&@ʈ9X)jō`lB11^gJ4 7]ی c4&k X6ldtew}VFBySԥ(n*ȊB8mq֋tQ"%?!3}S10fۚr*٦ lG&;o=EJ-a?/a!A}6sjaΑTta w7-oxJN~&qiS–dO^i*S׺cзW*-H@'2] IGY7Mg5lUfyN\};(Q(_, 4O7J*;WJfxB &_ Nɜjm}3*D7F4&UL,}b*#BNBE}Cˠي Bg\#`0/'L@򴽞~Jđ$lI6׿ vN!t'5 K@ɚxjhzfQhrީrsfFjeNnN2Yqv{t2&53œwJLX +`Dyx>PHLkq<үX PUQ;Mq` 茢@~[WSb6/gxr563z*I";\JU)ő'V |1m]7&ێ''Bl3SgfW qD--du+f"應yp?0{sxZ6M!wMQ~N`+v[_<8s`8BA1-W+yg A.ʽ*s N?KΒ?XG\HBћ8!-@Z j8H\?Dz!4iX*MgH# Y4?BH# |a=jO)hZ͘͘Dzn,AZ2Cm~?JT|QƖ gG&@~Asz"ZtOS(Ou) l-4xJ.g:FZ6\Tj+vHҾwZ[Y)I=rsA%#h3ljRB^w[",Pb΄ȇ- 6Z%4D?3 ᎥQZ|a!^W0F]haRsk* čYA4p2k6D4c aETuM^d󍹑fq/"HpƵŵ(}rHK7Y٩ ,үε.,{f .) }ƿT$K&zEyyJF؃'|$&-ړug 3IKnMղf/UX~d˥-\qDJPxE7PP/z3\|o)W{zug2|Yx :x*M[fbqQIO?[CL9}淲P?"tjBR$f.M[ `ȋd׏(2*Í_3!ZISނ:JjDژFAr`&f.'q7@wp$ &3˒h,oyT4A2ܣ<:!! 8K2#ݩc$LzgT2ً˭{k#$Ŗ@iX?%VψC/M],_}"L{y'g|0U$&e ~p\fT]xȉ}7uBv@g o`{˛D/Ĕ1iB垨U/i%HܺvN^sG)pJOhšc_S(XS\_hjoRN#"zNrg'BE4$㒭үv|h LM=SxXJ4LR|7G5 m;`V44vƯh`膆&.L,@{~Gi[x@/)AO7dzO!G)|&weS ]+KTڷ:!oL7 D$ y9Ht͵ژp ^C]Jg _=l+Cf KXXxv < (."yɐ)' YM~[j aR;>=%1]=L4Q-U+r+HrUMW%QU~qt7xщ" dPoGfa-KURZ'>|Lq)ADӋ{JB~~j]xl:+U!Ċ5s̞e.r=.tjFe &ZLBB$Y9㳎i٬JaU[B۷K#}\v? պ)"V\KfC77s#(e3*+{n4Pq'kGOTN"F c6Ǭ9d3?プz=H1N [GR<#2BTwEJۮż;4a86c~6O.cRH6>0IŻjCDA|U/2J˟n$<uy<9 >!iNߦ}i~,f+ ѓſK64^ล١QGsz7":l8F._o_I0p[ g y:A_osB-SjD;dzSbخ-+ws^1rp_:J>6/9w~#EO~DL=n<'lum,mx("L9\]+@3¦QON1w-] (  Ӹ1120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.234837 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/f62c18e6-56fb-4758-b499-edac3988fc6a0000644000000000000000000002613514625637207026126 0ustar00runnerstaffRar!"QD ؀{( 諀100k.bin  ^y(}ubV;y,$XG8 r^νl0iv4y[ qsPiC@Q# .QO ?v!USа;Pp/,ٺ,0s̠tHd?lsZ%}tN仑B?mD"sn.%>*4|8>2ShsgLaF?}RBT}GV ܑje6d]^k9T0Qaٯ\F'oQ-Q!B"X>ΞBhy,PWB a~Jo:ǼAS)FӰd8,&)ҷpū;5F֘zި;ts4 'minŞA&j sF S`)]S n.#6rf|¹\9{Y 9/?k~/ ;yFD 3p=- >* XF _ TuLWLu^߸—pK̎_l<0m|;Z .!FXsqs(W+ŢP`hv\ Y܅{_>r^١Lqc̪~.k!/ U"X!ke~yVW߶r'hGdȾrBsx5#?F@/!OygJ,X&F "7ARǧy>Xږv*W|~NJ }q咉tп~"uoMJW/WyPjvmXE LB^>Rx_]״Wp<]Z4QD Z]ɯ@a:Y'OA;څyH#Fmo7)uA`23 j#;( ;?RWLZtwF.YCHG;NGw:ں}םD7szfwS9YqSYrE70cd?;)ϜԞ Dzu)fBwAk8(=HKXdAi;}ؓqV:CB[cͶ6R@`M Lw\ԕafiFm{k[n+rx9䝼jwܜy95YûWpbzGQT]/ \N@HR%tDנSK8wތM栻?F6ŽҮ+1:.rV#x8.M/!dB29?eɩWO/GIxShV~ W 6V@͆} Z_ܡ( ;:{ԑ1e.D~z U)`% Q: [[WPrqk!UgU-N!K]g A Q X-'o_1Γ? mSx(KS+cB4 yZà^._hls*=:m8ɣA教S,.?XeB cS3抾Dh r֦ȴMr/M]B)^A*K4"F"o"ө1$}=q@̈́ ^c.T? :c%0=5ED> H3ie=z0A %9]sEz$H?{8T*C bxHN ^Jl 9a?@@^%1sJweFL}N?ȥ{Ԙμ9C9[C}%.9^Bg 'r<7;e"Evf5!]ͺy`-$ZݫgNi9F[g RʗCӆfVu1צ/NG O4X.`稅QPcԓ'\Wޯmˬ`^ެC,v: P["w k ge:~ciT'X!LiE\-f[#0j2UX)ǝDq&~93u"Sl"1*Rq* YtMA;SɍVhœd̂2 Jw~S=8P'$Nt /BL )*! T%#r Y=.2)UmnkəR2n" /7l'|{Zi šLeQK}b,w42n&TU m\t+eCs?%j`X'TR鳥{N2%k jnGCRCH4IT1^.t6]%Ũěj&9nhK4y"m% &YzS';au6C~IeW@ l1mH=ojmf&.15&׊ZM"+3ʋ3*25{HƢvQ[Ἓ#g^?Вzy;邁!}B'uxqdx¡[*N6 L1SИ'n'o;VP5HP&H(Dd =oX+JM%T,RiU_0B}C%z+dd܃(h/P%V`T>@jnWw I䧤Q"TED! }&{87zurw% vk@ŲoOCE&u ,,IےѰP&L[$s%g۰4kD4+ =DaPAj,\1$TuDw9bF6n'#ۡ p4zOL"X5`$ ,7/C=X~ Rݪ 8ʔe[Y}IIu lD>Yb\-;&Y YXiej"?EzDDo!du`ƒD6Ac4uuDޢ s8}oCCĹRჺ0Wm8ɴy6>AwɇTn;h_Y6MLg.:'_4۳>mg;4[EЀRCq[0UX{mo#\㏼8X[_@O!pҏ4ӎ2G5Ajj).Ժ6 MFM;4oGA &=Y hE=ׇI)DP<*~}&KBά8(a(fyEH4syy{(,EC_cT^rvh\UC{STՅ~ɗrүx@w`˦0".k Ͳ0νP̧ܧ%M+FqB]SPU X7{B_:vY,>0KR*мө@nc W %pfJNW?A5½]À. 1APm-?Rä?bm/@&\6ǔQeL;lx&ISo YB U?/7AxW2% ,4da.JlXyf"K@+ y1n1| f+BY>#ӻr͐aD"S6iWTRf$'<?ڻUOFwLD2H+D)4@%x8x츅#OG#/*"}M~0/x @޼n:VbZ; 7 ]8Ω}w܆&O"23#@[ݺuɾ/^^Ne-xk.Do=4 $x?3}rF2 eX. Mp@i*K] VD˺ \a;m2T?]ȩp< T| C'WI M<};|ze3F6KX9k<-wTHwJ{‚ivciM=k(tmyRFm(xx(c}QN<>9=и)Qv$PGQ[BksK 4{Y n#3Aoh0PƙR[{ G) URyvOڦN3]*HرLo}^n- 5:ƹ IJ8Uj2oEK=<+bW27Z$e`24Oq/wg[ut ;Уϔ3O: I~gePMlJ4fM{xv,@7soTD mGR ssD3 K ;̙Xa|L2`|tS+ES@Aṅjkw|QZFpaI2|:>sGGI84Ѧ2Wa2[tp#N?ހF4DFM`οaA٭,b<3tSl^ H#Ri}hn5R@5vd39VLIFm1C̖̿,T0*V0l,NW8Y\*.Fo87+ =B9+KAF Sd h}9Z& ԥD$qq0Ϳٵ.B"NB`@Wh~ 5ߣ*@ZC*,Gd`vZF^'Ȃ݁{;*J" r! @9[n edɆ/ƻ"?am3,kz[M's,Phqi (iiRO=5&cZ"MİiҏPj}D5dL XA6?9:[[f:˿u-?9y(BM&Jn4!92F.'IHu5v$⒊_=v?a Qt&M,L*z(Lh ,~a@O{ ͇'SIRPCaɱ-0jukc9cpc݈! ?(%lWLx>.|#md!+Rٚ AIPrZ%)8]9Ǎ2ؓ"sgmhXm,ֱN)2?Ak(cG~/U˛ւV3)ؾ(t3uTpCN#Q1s v $Z&5 1)txwod̵8CY]VyP$m#BHi~,[ny4#v+j!6 M4‰P ȠBPEWh4^-t3Y ^HWFEY# sGCd{ཌྷyVO.?mb:(^c6=} LYZl5zB/5mPO-C>ofpu?ɗgd~O\a G?Q ("qc/2=8;Tn;i@G н̍ 6 v|2yZh32|@{f%T{9m'%Lpm<!u&xpdL C]y:]pN۰XS"@M!I$vRxwD, KnNbi?y3`̅:ܚt)PZ]|YqC݆|+񷗰}i'g-p\{ l>h4v&𿗤fZ+Kf?qS :Rrz49<J9>|r @tL$<\52qtBh@$4BL RD~eIc*,<_J7zVb,X|)%"~7NB#s o3\ģSlZABGXF6S?yO\"D c  xY5fXaI񄴫n2}\=?{Ȕ*O ^<2H !s{|bʸ&_ҳAe@"};DJ8C+읡o;]eDKf`qR唬H>lGzzYm2~QRu8JD&wXdJH4De*E1R^O \v .ՠ06QX~NjeD`]! d/Y^Tu5Uis'OV ﯮ6~o*G8*/T#Y7"Ug&]| oTj'l~Ӷrmu.U_ψy1)Kq G~jb[,>Xz D{ .GB?\~sя4rVj~Gk-+~U8 B-Շɿ=rňݑx].—C0cG V  >7d9WG|Ϣ!ワg(du{N͌(cs ̜7vkx$3]h/ÆK[SN9WQĿ AyR! :<.)nD"dmTXKXn'y7Ks '*mYxs 2Uh5R궹̒@m8+͋y)* 0ŰPW0˅Ug'_wdqa)I߯yp'C 6nzu;=2pÙ=~vaBZ1#=ojL~*' N_UaɘϨb  0 cWRIٯT/|=L NQT Ir|̘ce7Z|d^w G/)\X&ԓ7$_ZNYk n/X#<6>$/%4t{=o1y~Hu#0h0<9W0 oT'Kt|Þ׊Qe^|vCw&-y,wf=J;`f7{ZXPO9@! ʸe%4I=7b5F?9E0*7 JC]V`BET @d`X#c߆`ہީ|F9P ~T%!jn=I2d9 Vlx(-n@W>r"MA>^p]g3W{͎I/{CӫTFy`̎b])BΥV1 wov 03FbA435LE:`ee3TN;f% Rar|b**xv7XgDS_o\YK}+ '`wJ ݽc; dH/LSȽ_: @8m|,ys$&f]4L vEY:$4 !1tG0^^9)3ix_eQ>t Ǘ+;v2< yp{KV޺|VWCxaL$b@7E*홿љ}N(;d9'.=o/۪[} MA)C̝5'+znew^@|gk4/:R~cO38Y!M"4R pP JBH&qe@3¦QO1W-{( 諀100k.bin  ^y(}wVQ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.233628 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/686e730b-87c6-42ff-af52-3d6a32d449fc0000644000000000000000000003600014625637207026013 0ustar00runnerstaffRar!e0  F( Ы100k.bin  ^y(} |WA 1&0pM+)RQ fyZ)iL\df&`v7F|WQ}^6ccsgJS6I`>`=2*^?MsCnh2_^a&s<ܥYքYZ"6{^&-7iZAΐ^N [:*RfǸ@.ti VD C *jGZߐRZ#Yݗ%l\ m³ TC[g 乩7waGrڍJcWvorr>I7ayOu)Va)HCtb06)N=90qD7gS3Crbwt>o o4v&?; Oӗ 9v3mjb &Da/ñYZ&DK0`@;AyQrj _rـJSws4'u@͂ƈbӨwdeFI=ꘁ/V5H|UX{3^ySӾ`}6(JLH 2{`0booR|}jZj#ݵ(B|3EzlƒN=~{m$d.d5 H^?9PLەD{uGTYe)KStIcE_R/fl.cNE W2[Ssс{&{OEHԏ)|dģߢkT i+%]0Yvm /+W%VU%R?k\#nQޘȠ3[;U9J_ƚQc`"4IFW^;]8å#yh{!$' N(|wE$mB[:̜kk6sz2msX0VŸ`xIE_!4VT<HxyR/ ԑ<ˌL;Vaydg)?W!k7u%%e`.$Z$蕻uvx7ONhitqP'V(ge4Y ',_.G'\trU >1ZآpEiVf2+E`]w4U<SQPpAZ%Sŗw>M])4:Y:yYJV_Z .HD$_x 1OCte4\(  3/ē qSyUb6Cjp6p$-:ME҅ЛmŹ2?33cʥh4X1wZb Ϊ(2\zATa2@'&rTSOe[>fm8Atd/~jW br5hRp'&S FĐʤ-c[ "cSٔ6PHFPy|އ?]Q/@Alya"RN!H='c vSBi8•W;|Fw=}7vX:H@ZLOIgxaApbE I2m4{3ߋ5TC$_~xwԭ xcD`g-_͙B#i5"k+ 먒+EX_5y&REme2ECUе 9O\𫔏)X ^amGa95]֊*tFtMKk@ 62xE%PH:V ]ʹ igWM@(mh y9{ JE^xrGk\o;`s֋ ݹbqTtxAaΑ}%cK'OH*v`& @ (7BR'sthT$.fC"Rt4ٷF3Yz=kVBy;n󬯣JM-UmTR'e ⅾDVQY26ZeBQ G-3).tw.9jz%PCmp]ϧ2ZhdsEpONy;jl)$^PCC#ap*+ i ZU|IVKJ]K.xx7uD؆37z\Pkߐ-3|s,AUpjQ'{>e-iPctxw%.4ʜ;nun8W5D~, 8磣1n(͇+Os!}xx 8KB-@T Uai b537;W7q|["Y&|8Ɛ{>!cXӾ%׾= W%CGUfcw!WqTbJr_eИ SG* N+=}h=…uGpڝSV)7љZÈ5l CdF }Șfҵ2R=YE@ muk?íyMiE_E^$bz^Bp^tM/^y VFD.|hd4hXeN 8".m(^pSl_$,n #U%J'wgq69ЍW ?*2&XKǽPCGY_3A)H8‘lۺ\Jʟ)B jd0iLڦآf.ŐޝdD+)?t#CGgQpɤo,C@'6|K rv;ZQW["QI7ϝ58S`T =R>UURiژ>zELZT #$,kZ]A:^Ojאb\B7ԛR CpQ8(9qE]9 T-]B#mfnj͘mD|֐A|7 t̚o_Ҕ<A~(E@P7}ōKsx|&9^OKI房q t: h7Oy'Ywz gJO_=䠌+c5퉷}`5`= nĩ䞼Sj` 3(, ~fo#% ԼѪU-=[C~Oqn O^1c}-to+]Syݞ \Qd\\ ¶%=Iԅ&}4duf h'&C/QֽZݝkn"nvE]_2>Ͻ̨3ٌpkCO,i~_X%ˎRΰ5lrsٙγROcsùJ!5V?T3a?nM?C  W gbW6L@ΐp?(U{'ֆwwӒު1;SØ;= &NM}ogy/TLO4`6Dqn$oH#բ~h VDDiW^迂/y&-׮N3csfb Ǵ`>aK09mz!705{oņfs+q[Ӗ*}bDaq2Ωk~y>`CF⇗렠YrIaw~Bx~ߨֲ3o΄ Cw"lɡ#0 lPlAyɕ5<жzH_Dʏr'K^/T`Bn/e $&*z.6XD*;LU HYı,R>≬.̟xi9ZJlî3Hp HR}wD%ǍpU/K㊳1*8iu yīQQLol^Q'niKsh]Dyqi# ݑy1cOɞ8K#X?MiW<7#bQ&sEFB&ϡҬQeqLc([k pս肢MѺy}!786 WM9ׄǎؽ dtk̀% p:~=δoB5*\I,n͐Qm9f\Ћ JZ/Z3q觳s1KX/]ZYdW=.L[͍{W{PQ[ݴ]_,9`JT.;hU5Hv2?=U "'01Uҟю_W.3v̇%9n 7c#q9b!5sL.ȽeeUjWq,(k-yDdgi> B#Bg**Pk9(qJ2+V3y[SjwDUyRvس"uxn~w9GAy֞7yڱS=L74" pќc=h)FPɡܔ =z@TW0ڿt$4SNUdDPR{6 `5PS&0l2v%p"(ze%}d6}o!"1yIE?=ΔCBf|xm$k0W⽕udE!&4!7 M҄udq'Vn谻݌hRM6u-&XiNd٪c,Y/;ܘwgFJ($hX.5=DF^ھyVP8%U|mjT(6, hts{E.W]W"1$E1ؘIDHظ  _*%zSj|wIU)1 e]fBdD`S.]g33t]`Co8SR``ߍۊW(lam>ka0{6Ll7sΟWvꄙ/ -:@`B}F\ث[ V51XsyW?:a_ɅK .k8hbrAFryTu`5#m5B/Jisu:FZΛMCM{HjgD/%N>Q[5-ߢX+'V-p "P4* ˖O &Gq!"yް@ t_ svHTJSC]$bJ!fߡ?:'l\*^ EhkZOm1zDҨnHJRtKQKң.0ߟ4 +(C뤡ِ ,yEϙ8! L'AΙ[. ͗^kKLC, Q品u&u7=pBɈ f?عRUR[luSnlZ%I mjiV-mD~,$<e$UoX%xzb"hD!ߕ}Ϥ"ͭe}뒠ߪEb8q>Vד\St$=R3n#%fF˻xM>  t~tTE=򇑵UuJuR`?!F>rh#QF`1~")c,5~~ܣ#1p*\%Zt(2՞~֛(,uU]·2Pָios`JxkJsQXnBf&[?NbL?(OEf}xu̱k~nQK(«?% k`kNN4[dB5뎽u;ua4Jah*.zU jPdF~@X.'ÉV6sW';#p *?t F^ Sp2J\Fm^ ]_$Q'S"-ۣ2u5j}ػmٻ 'j{F` ZN(b@ПaشWbJ{EQbabl]\:˴Mℶ я!~$yRTjAo#ȭ?D9Dx@\b{䎃Vr5{Mpi[ +`|;h5܄uiwHM.-: A*{mF  }y=4nqFgd" <@+F3G=$ψ!hc?b(G9Ǣ çCڱҢ9Xd.;(lg!8j^&LWC .$q7[$iC@EƅAf&""aZ"7V‰JTl}M2Ϝ/b+V+y7э( [CLH13p|}-ikiW|@)rY&'Fєk"e:Y^CQlC1;{)6q{SI³. KlT0ďD5ǐc{R=c99:f#nRr߭{ <&*(o)6p'?`qg 0(F # F'X%"0JOy{(M~QwD\ʓmډ>St ׮upU" Z!T7pʼZ孫`Z{'yCA?D+ ChD ,C _*w h ;id[r&WpJr³4,&J"ꐙ"ƾ_ua͊38Cz!uV|TW͠:0y '9MϜ]k:zNHfaB$wc'JnθFd2fxf] ?VoA6{#0~֞q P&"bK܀<,oLmȋ}\;3f )rn5ayny.BO v$Dq_]AlVK%<9 +B]uցn*_zD?F4*ځϟsPjVg>Z c +#-zN@cf`=۰s4 /0&K;I5|SpzGN"_2R"Z=Mт,4ȇUU)[ufҵsL1s M:66 8QZ\llZT/m.]ߙL@Kyu;:=L@FxwV2ezu#ԫ˱  S*SgOi,J("Gь,C2ɗ:+X%ם(֬Z[~o95ϯ\K_4MF^+,$\V ̧0xNO#7:9*ph=uޢ3>߅KTLhr(f6vPY[;˥ 0NFq[)+K⡬% LE$ǿ(,c`<\|B1(mv,As 9:O}c-Ġxr>Yx"GTl{xd%E'vw%FvCUv;u٤FI FBC5SQC1 3.$[ѯrH3U[Y^K..ꁈ@}Hz$cAw欑 Ep̽BTkrnE[7kD(@n.ڕAZ|[akX&"{K,eIBAXya"Lè` Hx25t4Fb]yAFR9 uG+ArUAyj2}#(ɞ U9nz1dgO@Ig2X$$~cZno;x5Ճ{bo"r3n! S"Km#c&sL^Ϩaa*bYA 7N(FHjft̖{/J{$h^ڑ_4!z0l/9oh= [mAWQL&MEZh^>̛+]SfqsA 8V,]ڻ6MSHUUD`Sx ް{FƤKs5wkD{]1)H|u;5GtH,OSUZs>X5iIe4Vy3"oW9i8_ҿ}є&[[T@K?ַWz[7%(\Иh%ɵ"·I);~_E_NpYƷ g7^(V/kr 8޸0`5`&=USVO1XCgЎn h4T97~Gr>GbyEcXpRnng)6:C_ݭV=u0uQ=`jz rnP%# BgaXdq W/ ⷂD5'yѠ;LjǗKە)fRi yt+#euBGj cĜm$##C,F-f˷41߱ro V] '31kR@iM#g ެБ=K`i1ʉ''Iz$0&p8S~bM=h}+3FЛPieʹ =5;;=^=NN[1[^w|EiHx26j,@SH$ΡK')Ϯ>^tޚ[-e7 K=n넭‘NI!Uh̛$ E )Z8fh\z@w"%idiu]J@ܴ -futAD $f:4`nq8fͳHƙuu%K)~@co0Yp!d)Zyk Ŕ["J( =A#ayߍox% @ёTp:GV r5y=OTx]@QSZIzEwTlkzΈFK{9]50לKvr/F^K(Z: vZ -׍zd`9@M9ֺ4c}ǫ&5Z: qāeBC ]?/YIvyɆl-g38-R?!lr@3¦QO6Jc1w- F( Ы100k.bin  ^y(}GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2334118 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/3b7d77bc-b95d-45b9-bb25-22b156d4ffef0000644000000000000000000003600014625637207026224 0ustar00runnerstaffRar!OO `V ( o2i3100k.bin  ^y(}B{w0+_LX%*e:{@hO6XK }\b1F;VY6+ֲ=zKBR`d-a9|[Irj'}{?JY{yq *Qhl΄DHEi9Q" 8ܕ\$_+j^\`. ) R/dӝ~IgyaB5BN)ܘ9,X{πI䥽`1P8|O\IJF\S BU{a#~VafVBG^՜:kGwH"ґEHN'/lQRJ悮M,75iAw< ~):0 ,Wd5DFkDx) /2N$?#S |1"3bD@~kgtZl+XUrr{O-[ğaTw]0rp?th9w+ V$*\>st:SX酯#hx.5qP~-hki^qI86o<. uz7brxLU352 Lb|6C޳y3LUr7G [!:$WzB^§3y)Vfx:<,RD6[K!ATQ%cF.:Yp( $tEP#Hk ӧ1E݋+W;}Ržc]%' @7KiaYaOS &H DL!0oj%c;t޲PGx.2jh-滁FDn|t6M `P`sԟLN[|ƜRTI vU9)~%GlJŨMɒu] h`zw.C"@[m|飠*4 -'ZwЕ#Dp/67#WSyڥݕO */ԭȺt(yin|%;+यEʶ we95׹Ҥnϟ̒k|ᵗ4笄m]^0x xXbD ل D$ǎMI]ƚȯDk7{wRx6ky q1S?a7vt?C18N1̂򢺽h vszL! qj&6Ֆ4`͘ !2xIRN=W:r1 A*M%ž3XO-MGCso<ڮ'9O5z;@CLZK}jL2$bsG,gy;h y~&z)@3wEp;ZL0|6k,?^G0vY_mdw%kEW#bGh&oŜ̓X1։|딼ܮkױDɑ:9ςwHƨ3`z7z)u'Ne8~)k<0=Y Unc>z|j[kop)(-fXs9,:k}-A@>E6S_+f^N: ?f(0|w΋us+OSQYK*Ǻ*0+bWQm`hT[`jvUka.#ŇLMW^JW7SX*\|O!aq̇B@ h*S. kW 5v Qly#-暡 (" DD={$b"FJ$ {sn&ҁ:=(Q̞QW7f:dBɉ07;#z2{]^X)tlʣɉ]r]wv(Q9jtom \X%WNK&2jZqVw!A"{S 8x>Fg<'@gjjڄݝ`tC6;_|֎3_]ʧZ8q\(VIs_㸴| V/h`*1ƶ!.#(_B]bدs$j]H#~jWܑϣBϴuk(XPߵk=? 4 i{ *jkUgu(,N"jMbצr09E>&EJkFZ9=A Sc9r{9: -t`c98p< M ݴ6V9oq./FuH_| tY/\H|l0]a>$L{bR5%тEdY _TU`ƌÒw6u1?sg+Zeh=E3 9ugዩ[rwȟagl $N5+>}d'M162A5ZwX*cʋmg<[Àr܃1ߊo4RVm<~Cdz{eӵ5Jv;  yy; %tVOx=/~Jڠ@t?ow-_%6dA"p 򉳱t3}Dec̃B&~fnm*b"#cX8á*PDs5b*kQ}ߎP#|<,GLkK&:Pwؖ[2ӣu͋q BCo} =4I^X03Ɂ~ؘM).nmJXgEyl6l-`?,+u8R*&iHt|3/oC9S.QG#ZL2|ɇ3̌!ۯ83Q Bw׵HϽ#,%>q ߐ_oy3Ĕ%d5NryN9lgCg`Ksf'AuDKk9gl¤].@8T|@$=={^(y8T:][ܟX{Fy&aQ,GQg4=?QBb_;M>~o3CɕԞ>-P WUϷPLhb7 {GW@E鵾"]q , z[8]@xrb$sVc%ov1=͕s8v4: ûxK.TW孤{d 9ȧY&;BV222 S@ SJYm+rt :c݅[rgrfh 雽 \-}JER?q*Yv1to$kL$#nr{X{ϨFc3*鶂o;U̱ChpD( rYI~5{Pnq 򪡸xuS2x*xIpoMMęh%͔85^3H!ut:`]/\YЭDe/<5$z-+)gI߫Dpx}HqT-&djaEyf_L!'\_i0c'=XnSQ\8^a4 .PNxvGV▔{Zĩz5<1w>opuZd%= ч [O;ɓR[8xn"fԥC!Oy#z|nb?"P ڻi63E׺q$EiT|b!V؟hZ.-Lq}~CkFP @39Γ!b~O,882dYJէF(4kL Q|TEr3<ۯs2ůrvʷ@`weT0p;E G1_w&&gJΈ> XJIS% Z2Y׿A''bIѐ#($Yz˜KWe&mgpBHY&Ha#MSy6.4&I_%eM'-Αv1 ߶C79lN^B$X euh!7;kI z㎺ܹ)*!Hoi8XG޸LUB pRgT<}ۜn=wz.sGxQKɳ#)Yd[p P4y +{͵k}ۣ {&%ߦ63G7ܺG |OS8RAVm=9E6zGy ('f4-2(YQr$FtTi2Ґ&n;s x?lytرK悎7ef`KCAC3fD8&+>dvT駒#,cqejmMO!_,*i`*c h0\'= !# :/ @Aa-sSuYM%Z:_L X8=qu2Dᓫٷ=Mxs 8?IW m Ynm8#S+^* ^vSۨ;}.i7psb 8g甞N"IX ^Dܚ?9 _0W,)<؅AD˜,s~d@u#6mIPt` 5H.]]Q> ܃Zc=u#`Hy5o4e YO/OuiƷj+@E?:Q樱7_Bt25|fb/_ ||ƳrIBPKyW^ $cqZN޽c)j= e)? 7!j)-I& .#s)EC3伸ޕ)zzᘬ= :´9y$%WqDWѣx JU #@e}:5FNsݠ8Զ/ənF.osɯn-Rù.fZ$pW᎚|sdTiq9tCئJ"'NCz -@o9O0ЬdH Ybdݻ*؉+C ++S3úZ;# =nox^}Id,Yѳ&}=Ewu#{O=Yس,ܯ7[zC-Sx[ڸQqm%+Uoi{ڂ"uEImʛ`GfOE =zC yf!mB S 4l= 6-&lZm&@uTA8@ wT=ܟȄ}Ha0zדm }ci>މdyؓ-FKu-Yz*O910v+hҚg02{s$~ckAY~V1+T^|+Gfc~ ¹Qo5  VHvs<)֨3s+x!Ra1oEC/./Z8X6`ºVG&r;\ġbWŧi@ꛖ 5"?${"p#iZ)T4L"o:ktb1I"|U,*01f"10M/A^>[RQ۞ww4nY^ af;>RK?s)!F؎傤n  ~5ۨWRPZJ~]wG( eU1~Yu?$l`A#p lvY_ʪrVLYfŌ>zjeoo |D[1\`؄ Sl}+D786E~]./S' /n/ɜ630GFJmXG^q咁w+ǰL)>XZcJ#vPV;~3|8;1ģEJSW͖]6|e'BdlcfHf>KH(r1JR$ q:IܨimXhHo0|Ĉ7>P\<$L6.QQ`Y~Wl y*D|~dgSF=gw&\Gr Ӿ.ef2tjljX +8+HAU*qڒK3Tf)H*ts)o+UD۪2 1VQc:(v|]ow7ԁlaϲ·fϽ)w ?~ T(G0-M^T1b! dJ CRP;8綹]۴Zc|Cb$jOѵ{ RλՑq)5954f.s5le!)!R4ϖlssD_5knKqDIًqi=M,֎ŵ )DJЬ8ES|?WtLcG _%A`JÆ2u'NH5Pdb~`'>7'U .0$yN,1]VɬūgNy+KUKEϯ}?^e41"; sgU`X{ƝaO73j:;\7im_kLGN(nu%(cG&9 a>K`4J;ܟoLT8DNLB$VPt>gU@w"/6)6IňN)w]}wȇ'Tn4t!>M&::zy"+~:wW|+EueTpdj(T/ 7ز w酶'4}~%MjxxHa &^aG 3G/@GEkAKz}>jas@miTXj؎k> 02@=J͇ nkN*U pL%~>EQFc>Vώ~}VE=x9 3$ ,D! h_<}G YeblSDOӱavۆaX%wͩ]uS`ܤ-}9F?fTat MFa [Si{Y{ hT`/S);Wd$ |s-Ľ sp̢`:.*?)#X3w~^ssY='+_\]ӍMrAKh 4X4idgw{հIa$"5cY*4YsW;Qq31 '3'S<ӇNrA+S=D_÷„Y_wqf$HSr<+k#ISα:ꠓV-cΰ1w*VOf5?ELO=uoF'h S]n\ *Le١<`:H t!ߥ|yWT?3qkB'# Jkj4aN,x;+4d&Grs$OG ՎgM !JGȬAJW\czS3l (%I(e6@32ĞUT)dٓ\~{L=@ 63*s/~h9z $ HvdHn7 ::ꞗKnA[\zZbtʭ U=#6Dru`IΪ 2Qwwm(lMed)qУu<|Rzpp@9`?Z  Q:]'J}xQju2BW- FykȪ\ܔh75PZa<ƛBX|A|MtH\e% S߼6F ٸZЈddxd)d!/f?5,()ǂV$pf?CIɲ6ӥ,C(iWKDUn$Yׯdzv|chZc<]y˸1rӞ4zZsaN- __"+bYZnZR06g abKY}̗Eo^Q 0ᶄXF,ās{0NaͿP_֟B*JƆNa1X*bۅx[Enp(L?[S~b"7g3}9ʦq!}ũN bVom+LY8 3й؃BBFsP>V'>tɪ0MYB$@~rKR)uTKmkLW etEY|#Fѵ1/\_Vt&˗fxbvH_9{M&V4rc5 ݲ]![F VsR j~9 XڳS,X\}L",?Z_SSy/Q>.fÃDĢnq_Df1I6| VH/ׁdߟbY` 5r@zR e*pݟpg]Wp](\Q#VAQ J 4E=b]Ε˶'K|VKA13mDߧ mt1VZB~DکGf-cMՀnUw;cqu*+W.)7^oBU K7@z;5c |n:THt>=eJ {~i6;S99QP o ]Oe8pGY-^eQ%V<]ubߍ-5r&g=D;ܦ^fd~!řMvԾLITpK)~/ۦTjQ'sG`g3OwF SC2h2Z|B>PlMYE|h,Ir&/IѢF}XE@ MSyػˬVB$WMx]`җrߧeP.P7I1oa ث^~i9 "(;y$Z+ѻMK;ShliE/i؋Rx\Xq @+8kmM5D5^UfT]5᷄f낈Yw(k9';{D4> TU/^ h%dPLl+ZŸpnkC`LIí8| Am(.clrؾ͛;Yjv]&^K,`,JuAw|7 VZ nZdWZVbl o0&e߈_WЦ >w=~ J u @7C`eF0T,N Ob7489:JD{6@f6v,Cbcn%ePnunwarFX7, I: L7 Ne8U2G E^ʤ>½Đ]Pr&b_0t'lMk ĶRBw]G>ƀ_؝"Gcn<9Kq֥ze)C?_ #`iB3[";TWݣ2ѱi9|w71yR =) iTw@z8!?.!N:GQGHLt/߈xesk%9#~J~B(*,|եߢe0:V>i?"޵?OR^AWp+/bG}o"(JpXo+{<0ݙ< 5 luF遼1:Y?KJi<_GݱOA ߐȆl!s=OεgyNފch(ĝ!N91fK'+vD;ς.EgWC`i?"R?bSӨgu0 6K ^blO!jD</(9W|\rbG+2Δtp6o+2qUpLt Fۻ_n.TVgu&S[,wCn4nolC0S٘# f!kW8Mi~?m](Uqz U]UdJ&1{ ߵ%BY\ q+"eZ,*0yL4f?՜tE!_gxXÿbEE],u,\O<.]B d}`C\޹gg &Vq_(v^6bF?^|Ҿؙ󂽕|.mKFL|\Yv6Hprto&KB |9's]!L/-)‘ W7=ȏߚ֛W\Cƈ/y0c1)!^>؄lȁ = X}:q&GQ`@X'EaRJ,-ob(EAJ~,Q 2j7"uZHU1SPGYkT$UR+BNPwU<1K(ljW]^.+?ߗk@*ZX(ӝ|tTqR764&`yUHՐ-3 !W>`㵄bs&=uځbNn<2^a޼beQ,q> G'NRw;wW0%yWXads!F *, LAfwIR56]3RmO-7 tus#=*/f,2;|h:!/Lzm& kqy#4])I5R~DR)k>푻(0+}֕b8uHm~C;5 CM\fތ7TWw@($Nu z ,.U3@Gh"[/ϡ% 6Pɳ$ܻU7!\G#ͱJ? xנ^]m48OPe--/G8)̷Z=}8 T4f4 (yׁF@`˖le?DF b%ezؤ;w{kggV*o45u;vuI`$8p`R`WEtv F-~+pߪ)c윜-%uJ~|= y9(F.J {/B 9z+ެgB9M Ř2q݂![sO샐5a1-(E{&^Oy>l"kcbt ڟMR_1DaJ #{k@;*|x0k߼N"V=s•)M=Y\5D5^˚ƿJYdK,&je%,n@3ۿ[7ACqߔ! 1C-S.,8pػoi0D= 5%(kkdfQf ܷV _4'9&1f2tt ӑ40b Z^AT.͆\8RcAoOVJ*Ҟ2$2+7s^ ўޭ SbI`ӔQEڜVG#$r -7ZbNUr< ,Iur"WTGRsC׳cDtb;>Fd?bԔ߱(PJÎ͑b╼[yHңXKsK$tiSc0qmX ~g潠H{>wz]0DK 4atl5ryy8| ؽncq(SQ+-6t33GӼeTp"u1H8+8vD_Y6okIAU`.sB`4| qINWX?&Q 4 pvRZ;K+Fq3}J>s;ΠZ.QW"W1N8P>ecsrmQ$2qr|۾sՄ/c$v#eI2C0}!x * vwd @ EsE>! XOF*Zj9?>B7 >eJԝ~m ?ܠmc$"Wv:^gzMo+Ŋ3QDV蚟Elovi( ѳ!ՠAc}[A Y%J17vl1&ڔeaHxȎ&-Ҽķ2Ui})'/ e}QTnM|+tDYpkn;2\[KD֨tiuFNV.#7ká]6ZȂT$3Agn (>opRˠ7,t!Ib*)XUGu{~w/o;ZWj>!+*j죇sqXf^韸I#žu}Ҳrx?WB]RӇxhb|EJ_<6׾,lm-U"~wC3wQCYA<ŵ)wՑʣGjeb\q U&cϮ:{9uSuvDJLtK!s#өqW)e*rqm-|d~j,*ixk? GZU^* F*| ocU. % h{SPF ZKeK*σٜ}&AtZ:!?T s=^A:8px&E db;r6mAλ$((u`xm%qL5Ѕe<}{w$(,!;h*ofEܙ"x"n '`kF?tmbXXF`r5tl^lRf #%{";8=y1x =5̡v($],ru+&n83|3s׵Z**nCagݼ+zbn"C%9ܾ h>Vifd"U1q jfOXDX* < 6,s)k;Ea Bؗks}E 3'~& E %d͚ P=_՜C}ouŁb@cӿ4!(fK ބfdmk [|‡|v~ 2s‘j֋= K7`p"*FwJjNOK&=0A'TGl{@-jJ[ŒQMzuBQ#V"DU?GShFETo. l7'Dpms;5cB$0ojUQ RJ X_ bt7Jv(2e|$:/[E4&F_gI~\>tAq{v7@e O} ͹6#7v#۴~< ~=Q"]83xdTObOjN>9DvD|hpiq"&I6Λ~]`gGP%q;H[7B)EvsLyz#<d/Ygc?KQMA%JKm,QvG~3A@搭Wrէ 0YTBl!o3,N\S m\.'ʱ<.0 cr8}]UҰ$}7L(Xv%ݮELW y2׉ǃ݋u#Heucn>H%yЃC+@>#P- mz^-6hgnE3BU"X R DLx{ Eh\0$c58Sbys [tÞPwjԍٚyN)}Sڹ4E,)HUH[ F|B.<Gf@9ܙY[ \} JZM*Bؚs/؇BTG- kYf^Y-[P#V0HUS@j{JE5| qAtkM4 ۏT( ?L^◘%OlCL=\] Ux\s;ր Zسč9Ml,A2$[`֨{m DÕEl+QH@} )B<e 5+xuˆ'&9!on#/fZJiQO 1GN35:,pa@E}Z^τ1:*̤"Xz\gY&dSR\a8"UWוH7IrVN ?jt93s&XK?*Ӫz/ʆ?7{@d%hHmZRYfM#Bڧ\ | IY~\ŗݺO4.9ŕp)cb&8l|^Igݔ-_fH>f>菧a\0 [.9^8V3Xl,o!S3Q8JS8~#s@ vbpAs뒰yt=C $~6=sbx{$daK}iA"l7H]Cn1FtA +!UE HfWPډ>EA$z5\Nȵ:ClhyrD( 6CX"WOf{ :t."ܲ(eA G*SCu 7an R =imhm3H,s-WL~+FkZn‡c5-7>lđGr)O&BKhhaX0gC]?Gb+H.{=Y&t44Jasb5)aΕ$%A奂BN`D*qW-5^Mwc_2Rv~}::95dYPNLsjƟLZ|og%]M2f/J6/^7A%g 羁$HQmyeէ]s܆[Mb_F ss {_? j/ǟȖ7-0Йͦsd?~i3"B$ vQ[f9(`) bRHI:4 k[X@wN04|FOX x8PApVPD5 ţeU_N Ö_XKh~-{&](,{+\ U^b;*s)MH+v}p=8U-@-}P Fd/6K :}lܱ+wHh}/{d 3d,G80QPB>M2FJd8I*Gxn8p.LA$nAj#ņѮa֋VXw$3*R{b0)Yz0\ vl.ݚ̕Ul{gF-T(aRj+΄F|Lht[R$kv%!^wH٢XGK hFᄶЭ숨S؇M nċ8 r\yR[Y:;@5|( \cT-7/+ubI\ siS>cڋY @ADcpa>񐣅tB\oԾ{o5,hWB8IҾ:ݞtݹB=@ *ͪg|v=pȧ !#(IXƼ%-b, ۪n3+ɭgGmɴU}jIa߲bp) > FWdÐ6K _䷢̝e0W}2~8 2q |N;FX[9wJpNtFJ%R8aVJfŕu~Hng_ܠWV s:ݫ؜ߑTp"V8;6_L0HQQ,0#VG-q{XQ J2Vw JѕA*^1jFECK &ʖt+E ]oݹE(s_S\ZX ~dJc.MTL>syRH\YMZLϥ4G6Hx3CÒWbe-7MBSmc hRo華[W[]+z?>,Rʋ 62,T! 8>Q2b$No&)22O'J=%#0vTj=G׻ l#.-2D%Ӆq9b:GQH2'2xGgS*~>XATC k.es8HbkSˮ]x=en ކ%x^8գL+i3DL\Eia6U Z$-CCXɸ%okS6\3|">pxRqӇ8oj!;ARt<_0M%v ȩ#N?{~٤r7%"sxZƤ#SY\Y)G?R5eOO%#RYL8vbZH?~9 L`Kw/=l-JW}W׷_S2ȣnߺ)C ^mrOR"/Un4€ s_VgEpUX}>j m:Qby&bk#=:m (Eqv[*m?>|l5/CC 0e){.)YtR-N!1~n <ᒜLެGWbk,YI1#']OAhJC~!Cdx{2b 0% R=\Z7;1ANکq, p>>ajLI#-]0lZQTYI](B$@$ ]زX_ȉB?`7J6F/,p;j/nԧegkGO%T;|2da"]lb) =q=!IԜĬL!R2j{Cq㦙`st>C /ʲgܠ} ~ ~T#S*1![r9_A6Nj>]X^!Fd+#(9lGbK  .: ;[z)S<:DLĬ`HQ,L)F mojXcxn+G'#%lQxjT6v?|d_0B.ӻ'8 ).:{4E[ cJN-*qѾGGtl` +jCWͭ{XO^}vA1ũBq-Qoo0n IPLX; -T,3?9wr4>jjWS-FEuI#JmB3bIL˼E&\RLw05N&t n; *4.,E !@U4IA0ʛWo(-#?#9i]zK/"2'*&@sʆ{jU&">y[WSrkGo$[o/F jvzWKG` 梦C7A詻Yx4*iQaX!`)+0C6EGT&BJ,g2OSnヘuPa afpl;jI%w /\&0t%N`z2&Eojbqu.ZguS"@$o7brXMthjdOPEitey*fOnއX>OYGঽnSfy+&{:ݵ5nL /Ka<{o톅)yl@]nJpVV5STxvgpJ[Wܜۤ=6P9#!턃ڕa!kBŭl@/ d# j @u]'witL^I9d ŢJ53hqQ'X]0m\Z)Nb Qi̼ 洓fSUMs'sL} L3E\}}zpMpD~!|aj3+&31J)hĕ#9,jC6"ji"ȨqRz?^:"RH8gy@ )7b #з@ûqD02MrbN]0<(2l$GN[(8S d܆*rgϪa=Mh AM)&j;.?C/gsF5V܍ #-;z@/kxҽnv17}O5O"xHehGefD̈3XBQ=}:1;+)IbI,| ,,H9MǹLu]T5W `a,,ҭ U+q"P]%2WgRϩ!݌I5&k<0SNW k' !(kF@ j/+}M)#諈5UA!a0fxGY^/BǿVްN3#G)"䇂?}CX1f;wcR]cXB#}Z`4aǫEq}[8 iû$x>U}4Sm 4Iy, A?zn;]FXz:WR *Ϭ)~Avvs#ωIߚA[E (Yꇻ5/a % /:攅@\H8 ;?UemC7> 1-#M_ap/@6vJܝWLJFAmbݔ> hxn0V }v:ODڎ9#.>C|(هX&\_-ά]U5oPD9tڡ!^O;$|Iwc.)I1k=^y*{ uO9"O_v&KMȺI"ht%&ܩd}@/BK$ 1MMPH oc%n#DH&$iᥝ;ȕ2 3xlpZCn\ᓾsi1an_oy"Sf5RlMcjC?&b".}ڊ?a]b?;d|.LQQ*ЙFѯ^à*ҺءBL!m0:/aǨ]4xϡUhɓm4B߈q뿊pš>brImύoTޗK+ #'}ڟ$V}nĐ zlj(T_Ӹ p˼Anc[RxV<:\{Pxu8G V}p^Ҫ=Ls\ b~zȞA j_!9AJ\ uwUo.DwwZ'^T=GtUuẔ>2_)Eii36<,# bpӞЉsH &wiޔyuhNΎ?Y5[q~t0VUWrCYxu:gj2um=k*8)e)V1X@6;Q#! 5H7|{*Gs/ovx*!|ݏ+!wqvݸ~(cZ}!&<}fT?W,`HT].yk 5l-LݽX-[R>GRkKuQ=Aɧ]:j⮜wpO3KOtuZRPwa =`ėlҰѬ+nJ9|N?~| Z mU"TT?"jـb˛O>{n$NˋB)izFL[K k0g3k*HUHpL nֽT;=aۡbΩsjXxu^;cj7 ֞v^K :+}Mvq5KgW(5 vU˴1H\Ci(9gl`})X%1T1*C#J5lg׀s@3¦QOk0;1w-( 120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.234148 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/8aab6897-3810-47fb-aa69-8bf36ee700810000644000000000000000000003600014625637207025732 0ustar00runnerstaffRar!] ( x,100k.bin  ^y(}[ 55V G1pҬUNȶ ,YؖuQ }K^yT?B0GoHL+"p\!@jEi߻. O41hmWFF~*E4uBx Geg;gCLg5pkDY(6nF:?.ob<d(Z4ŻC2B9c;.7X*u^4Gj.އ+#kpdyEҎٷ"Q p]Ӯ۷,﬏֥~%x\w8KW+@o͊6{n2LG2apz8o< /(:b0%G\iϘ4Te82Z,oJSQ\4%"`XAN^/ݟ1jfm<4n,@J:;6!˴""Et=ݢw)y%y!ƔXglky*bPsNXںLd;ȏܲ:D k>oŖ a#"gî @=.ۿN Zζad|j\z -_ nW|nOO0鮒=p'h|)) <زo-q*j9mҤh#I%.]dE2dyN^{o5׶6g-'cnvzxǂeAUXR4Lڠ3!p `ɕ2(ъ{,A;9.bhErI((uxɯD#!5[M_%PxE6yYY3%`1}iZ;Jo`ɐv:+;*>i q[2}"}\&6J .Q#a9lu7w9sԒta0tMyA}1P4[ Cdw3Qt 0~=B9oT+B\/=_;JχN?<*^(@~FOO߁}Uvf憼ߥ# F>Ip?jFGm.mA[d'kde#3څ$ٜ5z:U\g G@FT0fbg)m9ѳ<qTΙ)?GRP-eu V|2L_,pdRc>^7^k]U އGxyd*Gٹ3ů4i z3D^S#sV,tX]ZuiiZCC0twj?" >F&-Ǿŗ$%_V(>2K]WHN!d&HAbǁtDl&[%fGIz_!*)!<]X O vJ MÚY%j^<DEwWY" iDeEJ,5I՝YQۺG,*/PBZVUF35 ׶ΣP92~8N"Vt?ER7NEV[3(I- ́ \ȧ2Uahߦkle]ɗ^#FF6Cf5, +cRGEr9\\}_xn<,{${78NV(]P O 鼟@/f'1uejD-hٰܷr 'BjU); }S,XWvQDΓn(zszМЬ2M e K^+CۮͨQt0JRgĢ㘌G)~@kC!}װfEM)Jk3l+K`Y{\8qw%H{yrb {Zp׎Y{EY2#i#K#Cm&Ora}VYm;ے(9h<6~qC&M,BJ" z Beh(GN\kyz´EL؍0>BKD(~ 7&pyFi"<:dl= 2IxF'k̊OwH$?"<kV'p_GH^J~@V[?lߖ+-30krr~K嗢FUw'a`˩Ub ?Q?ˠ ŷ6wLR18NWu ⡋x`9qCK/8 J*;4~צd~s-Usk+od#xRb DO\Ҹ#V ?nCEjncg!;u#y"3`Z1*v,%T ~# ާ-;hD` 03fF]`>T'5r 1j7I:PhB0QGm>`:beG=I"-N1h `_Iqm68Dx`ǹBFtiF|K',wllP_io8'-c4t&csS)Gh˕ȼ /KrDZМz7'q,EDf@D$\6҉d]bطKnK;@H4@bF]F + h]nգլKSpp|3/>''AsF|_s7/^ASS9g2Xh"8L_L ,4f$%9YbOjtݪԕսozF:Ff/AUD٩iķk#xc!1~^㎸-' aq'BgqZ 7__驆1n&߅p-i߻qf;V }V'ϯ!pJ|NsLMS3Yr%uE3 ,S Eo | #,†"x[Wk a 7RLI*|֋jyIAӗmx(&nM:XOK_iÉfG6D!h؛$B5ꗝXf3 IAGghQnl{5^Jb^3x'WjG̪e+W]9MtF.|lCqGgTZNSJ+Ou@'e/?v,yb@cHokt`a!Vp5unL;΍-=:lm^1x4 p2K~;_3{oltYF(aFdzYuoSTS+78$ Z3ڦ' =OGFj{σQo@>j˜-eZӋ;KGLd\FR te SIV)&C.&`|=y|])p$Kb揪J('#?xџj8^TM۲={-BǝDg4dOTc)V.q;C(&bHZ.Nu+$g1OyeYԝ4B9bjg'gs@8/rj TT;/A$*2J4TG1ksQ!X 1԰^S^FH;u>1o hȉԦ׫N@Z Cȇځ>D\6gZ 􊿯onsPOy -\UUTt2uZ*H0|!3M]wy ڱɩ -tcoϹTIt/>)N"\^rl|evNᏸ~ٳx WBڗNsLpFl9koߢ蠎sEnr*.~^y-|ں (oCuSdl5wOFjCtQvPE/1VϰonHڋlsH^ :-O`23U=`V&yӬ`z0s C,Yv15+ YMȌ(uO+;Uנ _&cHM\py!&/&=:<}hS')^ɋ܆Vn̜= TNr,rUڬpSpSɶE"6{ 3IJNkt."[ gNr 8!t)cr_\5% z`t rmwBXF:"4׈˙I nS7"/@zgZyznxe#,5?,jmZ ?׋=@:BΧ|6ߐ{ؼ#Map+\7aiT™9C`Sb)x";O6~Hm0e[N鈶@NMB#pd3Kh_(ܳ} tcz+ɭ`gxL"_Sfq/]5 G 6QRϩ9]OL`(dgN;@5Gkg3*8ey+u>\|Q{sξ'qKa1kr^pEq3>segXF%h%lxzX`.1(Yd (ʼ0>o Pd#m0BeۚdeDQ!Tܦ$rrsX?đ+i=`rwDY(c:DR5yAs$ED-R!;5f=>垢'\6D@|ZsY4Bp nD!RO;% FUٍlIoɰ,՘J2na' T=s@eyeQ/ZbA1LP"7- frS1Y%LX$-:`Wr8Ѱc9s[?,̨-n FD(hZ ;V:8Cd.2Ey]E´0 =kӷc$y#LJqc7o<E Rj~I"$* ~'fbUezϜHtMy6>[O" sYPٝ酠 @Lu KMΡIv5gblu#RyQźϑ ⸅PpynŢy:AQ@b3\*[c)Mde #̣մ)\?݌r2j Ιcb~;Ycl9i=Ɋf6_,ѓmmFp~R0'"tDW?RCO n-v~05Ɯĭj{FD !3Z¯,h3 De3KnaԃPk?u׈ i8=Tݽ;$]w3&i=1O;\3>A](s~55d`_>U%EzYIuK'ddPS?¨(,:1qd牘m;xEDFv/UQ۬ pTSgBG'tw)?cR_-в hJAWgp"bpS|Osv99(qsd< G#FFc+W8I3No c3[)=XK(} .1?^QQ>43peuFeuFV֔O$: !{՚(pHJHcm̍M{em$?Y2)GI㛖 DPTP8%eeH&$ պ9ۭ#!2>S=P EDrV(CA!\y08_v+D : Dq<\0pdzO!='Id& VCYtaUoFн@p`#MBH]>)6fmވ)1b)ZzZaı?8w"I7 B6.H&lv7q,o~Ƭx?Q C@%k}{J p-4,< ھyX6Z],~.9|25Bp;\+;٨عN.f'rFc)zٔ&<}( Z坉ϩ/-)PQ^Ö0"wVW6Qg كy{E+?1d)cg3[&vEWayĸ?=e rwRu6>@BzQE7̋2Ώ8ISܓbڣ>`6sN԰,DjHlN\jOCZu#;8GY߹.iX"r[ G^X<뉨R,((hl=OXR9X+"SWy"Չ r Xa&Me7|I?^zŭ:Q ;N7Ǖ`k(*P?9/ц77E|hdYY`7}(Fv<U&4+ܷpǝ#H]r,(Bίa2t CmEWj}*T 5E K{ TO c)]uY}p^=ݕFdlj|RUm5Q6}Z<_d 㝆w98rW]eW+f)kIVi(`"i?ν Y4i}}t>",8ןw4j+96gnRmB]QPX\^]<,u8W&J2S84!+%*#"v/#8j{!ɉにx@A𑵪}\e6$&̚<>CF0€ae}swJG1 gQ&q݇WCxo|&)`i L'0eI;k18SHnt0h0>^˾ѩ 5A|/Y"D`jځdGZZDiiԩD}67loFUk+*BVVF:B6xz" y9!E$D =o*mՅ ~NL=x]^) XZ Lk)L+>Xlf+JOOT̽,qJ!:A?N!4c~VI#PEFҳ1`@y$9?Fiq+rѓ{ޫ7"qDI]d"eBD=u |VbA|Ndu7}w `8mpVJkE}G8 =m⽷ b֊ =/b.2O[HN1OE-c )lϯ"(1ݎ)E( )i益@>.8Y%9 H8zNZʵp3ԑh;1/&=>!fB$OfO-4*vwAܬwpgJ))3NlxlR5Btfv? pk΁i JPBp%t7Oh\OQ~ g-i'\"ggU\~NW{I_樋~Pg;ci|[,M@'3$-ǛݑΤ7`}&(uBɎ5%qKh;jϕjv9Af-nz.t+YJ&mwoUE7CI.[gΤףC!ID5d6)kccT `^K8K6KXil!೸ky ʕ^{&pX ž 6xK7u|(~qsl*^H&Qڊ\ dBp+_ɫzI/аQPʢ/靌v#v-~Β;a?n-]נ,MWam7`W|X) ~Qlcm~/*u\)D@E5|4Vks*jৌAı:A)NWo+<4p k2-]t`lidQDfy!X"#ixog{5BaAggd]X|"ac-Q DDsBEn4T9-\sۍ,?iO`\X 00)g5]=pwv{zVM.OVAZաN N}B4r2Dpb2P,Ytw?# 7ރ".79dduJ PDD}88.T%kT53A@9տ$5k..L.nPH8W2C[y`_Z?k%8_տ~Vsu7%:u |ȷRujz_[^}WFbc$CL#xvf5@|2r9Fpwo`@a$J#`sMo΍2acHf>Ohm JNew1fݏLW:΢c.b!J=zC7~5Yd]ț-xk 8Of*Uҵ教lp; .!XmܔIAȽ3XOoDمM횟!Nc$t2L_1Rc^X Ӛ›SMQhGt5Q~]H<W,r%PɅ)|%B&yqY zx%[G\gt-\Uj#0,#C4r:ѱm,}HOjRp $&'8:(T"iqD=UDtv]B^*hO KϡNLxw=hX ~F%VL>8t'+RXw|$w֏uF)`ەL]lz uԹzQW0bPp&+Ek/ Ez+{:]=Dcchk9;R1c5On*9BTdjAQ/Tfuc6@ʐ@M=A5wh 2sSFhFmnjz+ڣ`;Ky8FF"QuxI kS%).a oCcO~;xO{MY{|Q-P8c+h\ BG <b &\h0:x%.W)鐛6jb3ZLW(^)˝"%QTߕ()xm3+\mCʐ_qdrx`+)O{ݺAgfE l_f=WrPjv D `6Lɏ߉` TIf%9+(–Sb!f7]֫ļdb@+d+ V`X^m{uOpD=‘+|j#.08t-'NLv:M{oPx{X1qD+x&Z6EtYE+`NR lc;N%`ZaOFtS*lʼof4@|,ӗ'}2eW/.SA%v$}D>"Lr_e?BLfaddY,>Ff 3v6k /agMSp-\_JPl 4#.kF}# ͍W)IϯxVéeE4;Y!e۲NӔ7AFX' $.:nrejߎqBqP%P#!l_~*!ՙj Ƅ9 RyzvQNM/O(HU>Ҩtn.5M60jҹ\ǒYBmg$^iP/$X^6!YHA@Ӫ^LȫV{JkDOO}s6v0\L9/RQѬx.!2yZ\GjԢRo_az\֖MLԐ9P'VWBpuYW ?f(t+9sȬjkeXMJ} U}ȍKqH|&'wzJef* D 'O &IM2'i^~!B0 k:G|`TzYA6v=xf/N dr7H"}tz\R8AVEŽa:0 Yѓ@LEơS dRJp8b`0ղOї {zk{%+Iy_>32r#mmXu'(dzE:@x*OOD9!ش%ryJxNT"ZkD R2;PpEt8O݂6^GPNKcSntar1:-bRMi eI./];8 ?C,~(hqOJ$ O sM"e,gb]Tf.ql)Q@֚Jd^md:!˧|W8b<0Ck,u ڬqe^&v=W&ˣa6Jj村Thjv`LBC|fW$E&50n2IPLeg4DUx, oFH m÷6ư>7fEF8 rOu0'yj2]e=CED-o &iXz^/NETD>[]UGsm#>h5ָR)'|Hw6i.i}^[>u9;ehV]T" gzsW$ Wo!ldW^MrFJC +^`QwOG7*Hu=.ϷX%`.ѤD Xo\|@SA6˲-,ͣ_ 16tE>wEr!Tnx? 5Nm,Ʋ=sW|p4+uSB5bƙ%^$(!n,EMQZzz⺙kbs?э:: %"}w +T//;&n8/dOT:. 7,W;F9Gu21Lz9Qe@-ɦ kŽIc(жŚG|;c<\'ED(Qu#*e =ߌ3 `|w&~W!R~澕1ɛ-jB/FgIafEU3?r.T6v ;E|bdDd0#Qxs*clNY[l,_"TԷlXH `tU|a*ˢg"318+laEShG{wІMK:O)'_ppI6֗4؆327$9^L X-Ԗ%@Ag԰`O-2*#gA +su_C~RHVf4[g/gF i@& =2X{Y#ϮqgXAze7%{L,^ki8q!fl]M22`i% ; M<2D+rly#`GwX,3jxW q:h'vycCFw(vS?B AQcdO@_pN_qј0e.xc|ݮaS÷ c2uo3٠Cؒ֩0pvoKù^q[? 򴈡 G%9AYk vtY5UPK^~!tY<3~#52~4etUǠ3#h<ن.`GV>Q0 p q 8h~91Y`4̴@`jNxjS^cEAkt Yh>E7=3B‰[Qwޜ3Ϗj+k@`\?Udcu?<һ>H5J?CLછiLA-=ق%cQo7F@o{=dXga•b , 2eI,]9gIl9[w|/x8@e,V߬>r>jv-7JB! KɦrR g g~:L3["6 Gs--Q\+9zנFcWn|yS'gFG>I cx>|]N~~ͼI5KWri> 0 yQ[.?߇])Et^#;igX_|EA|Q[&{HF$ȍ=RA{:.~w5cGȖ(W:߁("Ta|0T9ڃĭ{Rѥt ĉB.^+߇7j(fS_lWdޞ }!wTATCbBVZ!EL SpY~w9hD3a Y.W}_;; +A7|ehuȶ߾k=q9Yno[XeٝNbȷsf =+(%<p_c]$[*dGZO!)[R2&'”WG=jw ٯnPi(P F4+eӏ; 7d}G6l x3?e)fв;u9KZۑV +ZXu >@/3Jܹxi t.5[F*a N| Lre/O~Ȝ.de_5TwupmQK/xP)KNra^'\ yDXe+Q7ucr~oL}0Y' O੮:64R3NccIb  yyhȐ9=J!g6ѝdMwZ;l7po}I9xxg+t?gO8Ĵ*ɺr+HUU(`r8(T~Ttm⯟aS9wVx/]8rFI9X0@aI}5ǔ#RH~,cuWٕtj • ^L  eL[NbC6Ɂk' wd|[%pTr&g49^w|LU࿥{ l,./HV<ܝ2RԙrI ߝ£Y5bb&^I' );JXLP歓#V58 d]FtcRj8f1KW^ok0㯹g1 =OF=kU=tnb 2)H\ẽk\M3RXS5΍5Bޘ1'8QcX_NW+6ѓw?>bw7f(n[AJBJ3䵦T;c0oX-\\Z-7CyO"@L{̓ .YsH7k#9E`s<~uCq6R@(rNcwCYg1`{b* bWXN DhK2Z<cs}7+6!GK EFz4^ϱx t>m\cL4&kϵ&!,i@ "B8zYag)\ĉtuDbܝQD( lȼO>k8 9v^~黖0V9B2DKcJ J+.±GMDc C~ 禎<:]"YLHWYA (t~~v7]19ٟLme]Ͽ Xΐ*fJhq8[8//׈Yu$e:0ɐ*(F)Yd0H"OXg3{V,Bi5=}I<|RBLrF旆%&@ H`Jc$&&%V"4Zd )&{UBT;+׈Ȣ F1SUChw֙ #®=>D'lO9NCtNr*s.%#;+{D+?`/Uhhvϥ 4K { x?&^QBa. & aēk Pc"; mH?jjE&wxWf}>~9& 5KyA،ZwJy:$%1/$ߏf0Ad#+s!%Ta™acG!"Qt iL4sc 8ﶄʮGYȍ-+X>@04GYFc[9lg5J8`+!}qAFAc#69ێ6T .˦[5XOtsTi ꥙&nk SLl! Wf[j8Kj/^="JrFg,.3 dɸ<|A1"]:ɇ{÷2'x4%NceRBpC>5x -͜SSGao̷9d8趚]MCK_grXxvpR߈2ۃ=} 伦@e$^P Gjyߐ|ql_ksۙIH#)`U[ق3ޔg9mlQm*F9'PB}$ ~z0[[7s3ܘ[nGJjH3ŷ?61r?S0Xm@D0SեI]Xsal+Z$ebp_%lY\[+tbLAsɛ2B΃c"HIŦ|[[1RO;j})(&JDlS0ޤ]B^@vĂZ}0K yYg ujgxH%ulvT CHtnTG<(FjdiNʕ8`W/[/8)c 1g}lHhj]5ϙr< "z"]iW:(+6дk M7\Ԇ]%=-uw8C?-ؽȊiE@.U^)%Z9tF־ ilZ$|F ޤ8ɁHVS.>/tEtAX]^pyLv*Ļ*xH~7謐qC}VX+\hts^hӎsY6 %@+99ka7bs17o9gAHO"(XL~[:‡Bld[-nMLnU}Fa! QLGY3Ŗ" _Z5up *EA?-d[`TiWm#_UcwͦL;VC!o~2g|@x޹vpH4OYU@5reaXZi4FؾtŒTbεkn&ߜ)Ā8xЯ@: .brcJ`~Б&j5W$ 5.AA(jZRڡ Pu H+Wv\SY6g"ՈNhDnMQOVpp&{&IbT/Lu>{iUNO6_K[\W@/i܃+؋uLwPm^_Dƨ~$][;qV|0E||:]U|{+Bpr8jE] ~yq,< BkEgQSf7D |^b3#_~Vp߆=av9FR|B1 b-+F^İ,|]7|p?|U!_:nK5 +Ȅy1uyJ# 3hĘd/bƚN&ħ <>: l%-wZ. ADXILA.LM[cHcgЭ %)LYcʜ\-Gr2k,>w r.=rXYrCrUUmNEz=⵮]*F7-ʖ#uU0zRQqޘZm*tR6V+Q}Uw1))߻A?}36Z8NsD5z[.gΖͅgl_\t(gFe_ZV/U7Osf%7texGĤ%a+؍ Pg@.a! f۽Wqi}iF;a0Zm?lӆvo*z|}\6UjBkJYZ{> mSL!^I622Kn**T]' +f}P o t4@=2)߁zW%K9:lep0NE'Y4EilK\fE,dC#s$@: jPQj"ra0_ٵ莍C1֨4ƠW]v`gߧ&rkZcԆ)^`*"EO!|,:]1_i'߾2TGN83w.cdԄ3NI]KV=ĮNmA.:.Yi4S*\`QfZWkqD(1LAKhӨx)3x⏤`V`ae۱! [q=5ZlFHRU=,Ex:˟׺h}0sZdEG53 P cIMhS˚UBGɈڿGev V(ˊ NDT޶|7Z$igMY( apL&W6/H3O92z jlh[O }qęO{i]3Mޫ Uvεd꣞,(+B"V(; mIV qea0 gvДF WGuҼ $CDݝo`i`#˴x1cqQ+`Ժ} nCC{^Kx/D&w:1Qmib¡,н~!,<⭻>K(o]'Z d! NY L*$%C mB(Q$[a.- d埱G4%}u1:d~00d\!ʣNQ<}xK^ `ʗԼi)Et{}%22w&]HjQ[\JUF g<&^$0,ngWm +ܐ>9c/ K$#!7H$u2 i+kk 3tlpA:ȩ<xX$f!,B NEP }rK%j)c8އSЗIvle ŠjT@s;V]-b(+P]+ f6Z0ɃSz.}p3d9軓N(g^Pwg_Ϧ)nU}[ҵc@hk, >IXNQM,9|hpG~eR\%C9 fml~*Sb̈T7W7Ơ?б =2֐@/+a&*a3Ni]%=w-T(< ,D@ӰVe[J 5&tMnmjӴ0WVlq*R#u~"FQ>bA`h*NvF@~y|+{#'ǔ, #OGt%(<^C\{@ǰ$RFP(n#Y_i%d+.$#Ywk7ܳw3D֩R;T0ю0{سDrLMfb伖4~gIXf0&{(m= }4CcimϓSɎ^1 cqcРnۥ <Pwy]7fY!P[DLJrʠ(tҜA>n-k@N?Ć諉VsQ%Il*y-ԼbV@wbo;ufTwܛ&Y ܕPNUCqoxկ#Ӊ0R&(PpԶAD(X v-N?^Ouya;8c(;Hd}OҦnWuln97"FgJ9$Y:Dg8z2/6""6?J&oB4ri))^֊ #,EU^=A~Ǐ;p850q]Fܴe%uUPNΥ=u#TV~cM  '3hsMX~ی  w@b#ĹRw;UI`z*lA$6: [.brI塍\Q4̛{{A-^Rn!ȫ 1bmeS!/l1d75S~Ukgo~`@ `.M;˺++.+ es`Jb#KNaP4a(m`@ \W-טB8zM6jcuSJ_~@dU?\z$hܤ^=$<2Ka!"-L^FIEI(ۺv⚕NBlz9y5Tw+!cBH~QHf7/>l!DZd:͝Ov ^/rձ&ap06$n8D%Y6K$u.r[mTM|u h_Q*;_7UoDm<Tdӳe\8{tl=I uI ikn>R9n(`셩qpQ2 勻]a$T.?<8F HH\@M`ĦY=VmHXҋ `v9r+a3C9/U7_s){l3bJ?,Cz=Cs}5 $!Y`SB_z#TNPsC]@8=-")HE%#f3dbJ=|#(0vX1RA} }_4EU){j0|(;Q%x5 jVMTYm_z>$yvol="@.>>n^j+X}?`]w\LBzzQY2/(#GLπ:dZ+͐}]oۋYlΩ'%)@O: m6Q%+n:3$J WaX$qo"P#!,5 ?Or@DJKɨSew(-b& dg[KvQ+Ty:9rqP~@C:f * _,hm*2ro1[\jNy:BɭiΥ_W#N]h|;79)qaa̿H219rx׽އ(͒S@lBD/uM*!^/l }Clm_r͒ iC MiRූ!Kђ>俇HhiAfpe\WA2Ea] DKɈIYnw s##.1Jk.Z+tMHSkhU.aO)Nj-_oI7Q2AfH!3I;d?]ʯWscGK_"J@ e[p}Y+2Ioh={MH^2Ǖy_kōλ$h[U׭Gc?%߭?Ѻ] ⍇,%qY-Y>+±q9:yAVxpy$k?:c!-BF*"7CjqI~mwѾj}850X7-Oj! ?~䕸(:,#V}5,I%Yhjڡ+{`sju!WW("ވ. f_F 9 s #ܕҹA&6e`6׎]!Ձ-@?lZ+<Bso94'@Ocs$@k~p;bos8V  ڟC ͕Evjr(Bh-!QOoi!G6m.Lu֩]>t:eYwF8:NU<ܟĤ;^,CލJ0 ^MCe]L ↓)>UU`ln&yP̃;sO{u5O EYfr@?E+++dt]U0O{S_ފgΗ\g&[]qGHlrJ umARW.5uK7uz<7L6sÎ[tvl.'>r6+$M$ ߋ~K1Xۭ jyFkK)q.̙h[6;n(T;;﷟l ➫ϊc:{|-}}3p缍'ښYhG-_=]NITY)w.Q 8EebwwOf\BeȮ"N \K)ER#@Ez34‹)  ҁAuX*z}K$!4Z;?39u}`$N%Cq.GէTgB^Ӹ~-E9Њ JBWd)Fo $j)0ZᾌJ VhC`P囄 DxQɣJ<>I) Ő*65#;:%RR-< Ƀ5ɥ8~ lOx[`Ljqs@列ko$,V7(/殪jn/_[/JZ?oxvYzN7qCxtvIȮ[@E\QiXr~t`S[^vM-tL[s(iu qbQ@5cZc异!VECk; `<3|YPɠ=*AIV2 #n`80YIl#Oܻ(]+]({_j@[[c/TrMv$^HsɶMU].b0gրtcPUr;)*cMNWh&4\k/EpSi;"i۳p#^}t+lpCjo6i /x_;v- dpDfʎ&ߖ{\p@JQb'r 8LzƢw<}vx56Uw7]8Nh쿕<1٥^7m|8h^ެTg^уU?9IBU+Gj!tJg(ŽLH ə+D|~xO:LΤD a3r;J(-~p?~|L 4+= ݭZJz|%ʳwomHԜ!5q G3x;`my"dsP͉%I$t'>o6don*퀰Okwg;ťC3@Cڲ'cc"Uب,e^[Vv`H&=5JO/!pqComZoܾ64cTUv<)TjZ!*M#~Lb Dٰ_ Pָ秂ި[73*%K<*;+tكI**9{l>,hC5E]{T]ϢUN b,Ki럚0f.МqT,؜/ѱ%֒i0n/Ђ.=8;'0sI(-q~|jWpǮ$Y(7dRNz{_b#]kU[;B:vYWIU^q{ $2;n+^ˀϨ.$g?SFYPWZFSvTeO甸SEeGCnؿUUY?\p4ZԷC$ÌxmBfZ[:3h5"X93nl~H#1 œ>ʶPԮ ]j@vA1+ E]rv`$UgWV2rxaQXHfUdn"=" FCAX&8H?kʣM.+#hYMZpyk#K,ZMB*hexIsIT 诜_{Hqs16 1ɻ!y;MGabZ`ރЊ rmo(x׀^e=wok;@w 6XQ?Ƹܠx=g;E:~&7yx&/"yѻ tcc=%/p]yml%ߊ~nA ;W&DpnEg>|$XjVZ 9Cځ4Õ72Y'К-^H+bsAc{Z(j}U[!R>ZKT}x15erc{p/Iߒu>goJx bIS\ʚX.m%ݏ@n^ݘfL('+Y[\63=Šj!W1=bϦ9`_EOv(u(LuZ/U]=ucB%Sk!9Fρݮr- ڨIJ& z¬CC0 5fgFpɾԫN̿9tqtՈ]>Jt=US9ξ[:l ;.-rܞ-Sdpȫ  4qY/t? B6r"?~)@i'S* զ ƱRJ1*9xIyOQ޶gۧwHF1 hzaǜ}m K~OzmF!5.N+LW)xKF;>cQ;{9ϜeŬP>qt[a5yѥW PDɨ4:B2Q&ĵ(nJGjnޘHMg^B*rxJ{Jާ.[z`eXޖn_ ؒgMJk 1)Qo@Z  ejG<r ]ܓ{e!$x T檲JVb\Zebi*"~Al~m^ԍ[6jı`p=SOVǕzRjeFxYȆ(1md9.9)Xu&3xI0/j% TY|z9TL՜wu2]M泪~`9]; "MmS~EJRwOP<@`< SQo/A3*U*>I#>Q⒪}TiwȢ4`GI&ǡ,ѧF ⓓґ%qf?U& akmp 2mo:q-2Ps)Y?'<_9|~Эj!ɨ[hS9`i OlBQݜk6plNbqSkHVЉD;cPf;@3¦QO"1w-+S( _120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2338398 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/70629f48-11bd-4b1e-b1ee-2b1c902d60690000644000000000000000000003600014625637207025704 0ustar00runnerstaffRar!&$҃ ]( 5QW120k.bin ^Ӿu0Gi05=zH|A3:CPZYX6n[Ƿ'dmy)L;ʹz2 щX^S4T"Q-0]|G9@6^Dg '`џ9;'T%Y; ⣦C d:Q}k."?̜QIe=''hȲ"Yb`!-9g|ճ_`^bj2V5ZogV@~\&՛93|Vw\aБuG_-5[_0 =0ǀ 17~ - y^:Q#jxoaU(y; i@c a`~σ'~u TI7v`XiEfoGE\]A: VҚ)E/V F )mTXjg;Quf@kѡwk7(U"Z!s]Z$bҶJe$rҋ %z=H?SmKXU ԻHm0p'kK#ƙB<_}he0lR\SͭW|'8ϞUЖmSE'yRl+ hW7qWQ(kaoW&; 7 ഔQ-Qiq ӱ9SUs),2V.AӢ]FQsWnO԰Y+UVv蜊.5z۪Dםt!D_^s2Pt{$آ:[$CQhFwH!eV)F3?Wq@h$կ(-X:SwԫefFeFz܇|xk7yOMEXrMǠXCX2,yŦ?2[⍊)҇U±Aצּ%Bv2^x9>KF"-0}*cC6CٿFE{ucAU !Al;Ua ɹ{mp-ڳMWo,Ar6L $`\rV) tNG;ݒUNO_&#T\9~-p .B_VǿCPCĄ+PD WVEen:FYN"E5#=df@oƿR#0Q8,{ ѡ.6"7*jyF/[B 4\8IDxZnήn=Ky>wl(-w'hm{2V])~?w #E2d0?Qd!+! P00#bO pNр=/F'E'.BNAKEx^(K%Rr7nt$C97u`%Tk!z4yl~<:mCdu4$DJsjd ,;StIf ITߤ;z6A>![n /u6mCM :-F݀MA"I/İ3VO@B`wk`L6̞ݻĚ~O8q'M'Es3og2 `Q'|ڝ z!9ދczU :̌'4TJx!8x=㷍AZO++&I- 22jΏ1w4rBm5b UJډB'_ɨZͿ ށv5?^'Xd xiEu7KJ=ͪ(?SnHƙU2UQ$%{=Z .(lK8 mMDABhMoYbkCUa!KhUhfW^Eĥέ}zzu#Q{19}]i,kӱ랊2>C,\Fg!WltqݙL1)Tk}8`o @uz%e$% ahvàZVm2X iqpXlɡT}SpTVF{|6{uEo[a+'Psrx^~G 1=Z'X@\ɝ-T_~p1hc)3+%@ 36}(ӊrf}).xX.̂30O{;Gp wYvw43>?#љ' P%$Н>Y;G5$ZdјD6*m-qn[~=}UQYKX,$k5 7ٗ*I凒V>IDX- пōU(oTD)` 愞M?RA\Q:%jtkhŀ-5r[^4h}ME[#.U۸;t"g\ZnL4@=!H9JAroƩ~]x/mj\p̃ տŗ('z&^,7z(Tb"LْKKRt!Lb~67crƑioꆜ>͎DC޸`5ZRW krڌ|r-Ce;WBߎ> Q~ _k^ۋ,Ϻ]j/m+uDP^E՗rmI*L`WѤ-ë}8ZjxRxwuAn wf,[YA7QlV0,@mޏUZl Yս̀ |F^x!ٍN`[?mB.RvS0h}[ɰ?[Dpjۤߑ>-vE)L 0+ޙ* %2B;m-S4XIkjoosHmOdA4 Qi]$U }ǷIndBB۽vU*1X_4Ųq 6+6uYI2D=Ei~b:q譳m3µBN;q;^&*FiNeC6OYTFo@ӵL#j|j%75E v ~'xDP&d˙c(#ս+(0נa)brxUQmuȚ||`n?l{gM)Dn*XM< oWBFR0PL1PA LY΋c=FXn|]ϲKcHЋi`?n c``#Y:G]g+7Q5,)C`k 'q#+6h(2(K$+HĎk=U3U>}νp)rT_0\_9vt3_'&9J2Xo)y~IB3-N%הjÅW(?Eќ{2EͭCGyI'FZ;2!Cfw%ǑWFP'>xGE)L$SVҹ7(qȶ8C?te6@[1; hH ZdKp~tNLWJ)2xE {\kCNt+=?@;` f#r|63-h&ǯG!H%yH}}г)6GP<.`!`v9M3xL#+Z9q|f"EÞı%~c#B>{ZSPx_F5PP7Ä́kN1n#voTa<ZlVyu4JmI)U,YNdN'MNlc T۸ZuyۃI[^, :%BI:dŘ^+e ZW"vXcFXgBK.o` 5ITFaN)ȜT?Nw p.WB͐s$IJNTˏwbu;q(]Kl>m-CurԜBcV7rdG.崲oۘƈ)gǚa*aS(Xh^fMk7s6-sO0bzZKb45/gnMnV:t7 +IKLV a18Wˆb..GGe%]ckYTL34\3\,maz^Eh#cYlX☜%"7s,ӅAD(JZeOcNSEq36mּDC?R$ZY 7,]6]PjmBæ!q^jVk`Ӻ\ҽ< }l L5+2.B86;t`b!sc/{7I䠑.XS-íJ m&s͟EJ? =mTX=&_PmpyϢF6 7YuHH4It70@j!&:(i.ёr@n῭Q؊YU( )[eP刂tW6-8#^$of"v4GG4: 34g-Iz4U ӾWRD(M^gg8hd]} w^:e2W(y6t^䠙P N bh-eu*P, E.PS 0?+ߨ#0!j(wB`DH$R l.ʘjp ]&YD'g"y9mHB b1|eXW2ΰkV?MuM1@\|"~TB:L/}Okz驰!^pH.!O}@j,l*}w0_À4lj`[ݴo?jJ<|T>=rˣ$?˚Ė iR륺U{Agϊ:|IkH+M~ɑ v, }^ m̎/So[VH젗R>qkƥ<;&Ui{#w CVi s_Vf%+Cźm\ARaZIe>_Xx~AЀ6rulIM,NEI7 Bݘ;G5'ꖃKq>K*l˽hTĔwMt⧮Nj ܼZV[Gr*砳M~ / $#a2c Eˢ l 4 my ԆN A^hxLy2\sC=g> %j=Dimʩ>+>]0;r=Xߞ1gGU 3#TP$xԖGM{KpIGFW$=w5V'Mz]}*=. ON#Wvq\:=!˾ȫϑ-#Ǐg'Xo)4Qdu~% Y+b+G=+Wf0aOp@"|(ny8֡!^7;@*sP'-b8HnOj[Oq*esރcg (+;SCɖn3-ibWWLq0)jI\S'ZEh~}Ps O͂Ï -xRMxw%4'/ JZ Ķ"}|ldlfb",W}:W#^xI/[zp)0SZXAholFIkSk5Gf:B;ʟaA]AnV N,A~0lcV!,ny107^58x3yoQxd}*NW.we Ba@!^2y\^ŎD:Ϡ<'Ē@[]m^ wvJ 2 ]SrЩIeigYJ__T֪f*Ipף&P>o/{'bam Jratܴ#PQ1|.&Vuv6֒Շا7a҆@@'eTZ޴Wk1ז %9T֫z\0zca#eNʄ.L2N7mI= b]&ΛYY,{/s3KR͉NU n/[A/%FS׃$No(BM>p&aG ne:_FEb w)E3 (j("fl2A5Z $ O,%.qƹq7݋5 $C3 pBtU, 8j̯]l?~DHGujgvn+%Kfmpǒ=obǥ ;S tF rlS CO1OUW߳V`MRgh&شؿ?tpQ8H Zyj 0!@$3~ܯܙDVf ʔ6e.4#YI ^]o<&[PfavN;&WJ#rI_O]P`AS7)!oq1kގ2Ye(ޢ-F;<6qmC*bF߮` 1Ղ*ւXI^CwGޠl@2fƚiعָ%v_d RLK²km 7[vIGrf 2P}M18~f] CՀO_}20O4~-nt)fbʮTJ-Fq̘u= omDQ)i% epeVAMMH&@uwD#N+suc™Uqr͋&*6eQhH+-;|G8Okr (iMN .dsi&踎LD*Y.$ >d"f؟9]mFV5!foa暶(!> >=#BQ/-X#6t7fz]o1ka؁,FWYDцtW h_8clfB PV\S V:/ؼjM.ֹF [:X{b' %厮-Un*&:FUqcmXQbЯۑy jrҷAo !8dO5iϙ(ySQc'`CFTtq G*qL~Gx {0c ØX qY&׉.h @ T?ͬ;JhhG$1oPlU𙾪6VwGj8gDmo/}79VI{#h"4Apn9,֑_"Н(ɔDf3U|]Sƭ#BYUL϶ s89YbY1 "qnI- g~j؞9nL+j Eb ^wGp ZU|3z5|ˇS8Ng}WY`JFIž<s˰s٫5 !wDsYJ[OEc/PjOg$KO!*CBwu%IÚ9Yt{8۟)"077\s } M4Km]7W|v[V6TL QGZN@byj*Vja_3cxR_ctjҎXeۍꪸ*'QsQ0c6lz=tQ|ۃl=t %B fgu9g׋[Fbs Lݿ[mMgs(F.˴/bP߉Z~Gnmvkt^m+hrf"&kd[ط.`5L# LDLΛ?gBGNp7? o\얲W/rqM6$ImDT- A߽RڇPܪ݉H5m%{8AF1V !0Xُg:P^>/=Lh(dF9=)AHު#nHyy!r}˫ig>]ŐjU "ES.gDrc+Tp}e3y5Hc(%N~k.wZN|36Lء"6A#].E`| nG;4ۨhԷp#zу߬C{!E4RYA..-!`-XPvgh\Kl(O*9uja VC?[ g^$[7O>}F&U!+ 5 EQ H (B{Edw罇EbmXT,m1ApsWo@gzHʓ=~Ϗ.kTQ{z͌Ve\t ՘T`n ?e UuX1&( E437 吔}K+W+ 8zx w_P6픵S3rDUދߚދ(ـ ۭ0 VMT7иH;6&)d4)4rM<ƅ\[C2N(ƳXv&ԦȆ5A[DVrs*N.Q@+bҀ7⊵,JJ֘(,T+|zP'D[6;L+*LY ݾ6E2~p(X5a阙}\|+nA'K~VS &UWhbI&J$i&~(҉-=$$.,XӕGg.k8h/ClEXr{ ӷHZG~Ӡ΁ HX|&6!2y{UZj1M;%噓jkSoxΧ4'SܠàvsvGQWTP\TPݜgδktQ3bn0!4{ph5*5V,S/Dka侊/Ce 1AJWܼ@f!`-XBX*=t JI6Kc[Sg0ˁKW3lŇ J.m.%$@3¦QOu1w-]( 5QW120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2339344 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/790f7aa9-0e93-43f9-ad05-81394f02072b0000644000000000000000000003600014625637207025562 0ustar00runnerstaffRar! $ UM]-( c120k.bin ^Ӿu0,C$uڄ{a|m;5NX *mpñ/JUk`g{l!9BanBN_m{?E^Pq"F^D;-z,jp- oZ?,A2u4R3lb#20ri9gթqQ<`T'WPqP**/#*\uys5n9Dra` `J3 &v$"d31gp!Uk|mq-Vu¯c\SH˛~XLeaTYw QĘZ{j/Glo1%k#iV&31 V^{H{״DTsV6'z|Lm{Fto4 Dȟtwwg"#GFE9,R@NK)R9VK*힤TTZ+ 4ǧoIBM4ҕZ( :)`., >Jd&aRBwuE:  4ٕeu]PP7YV]^wy*7B]HX0=1Yqq.gMֈYKF G}AH7u*`Ob)e<x@.g/7KƵ0R\M;(|YA5c鵸x:EY<h-쏻~ymʣ.~om{: T]lONCTYHK%;W7aoG?Mŏ/v4t΍!X^( d2GscƦ"LDXXm4jىʁ|zem |eҮDFJe+.LNl-JJ6>+X' N Rؿ{? .jo\}L}ȖLSC_@ۨIg7^[* yAb tx.jӜ{D<>s-MvM\.yȭ( XN5:fȬex9&"ƦB'qXJhZCB&xP7{v)@sdu b3eܐ=rkkڢ؟2#Џg !&Lp%e<f]ódN0,1 $b|rBTỳߎc[gnnخO9ǃNw3I|a8TXX7ťu|fs)XM|F8{3+&M;`Z|J=4E-( N3F(/ Bk&Z)ʢBvbxVGekpck!)bv[ToM\we`"%6-Ц.䑅΢sdqp [󙨱x,"ć.Y'>Cns/WLV($>. +]dߞ6TaGPN!C?og+ gRv`Q`o|krIdp7ס!)|P,c!~K'?q7;&U1?!j*dO"' $5h,aHW6{ې)QKgq~{~?cy q6fRNעDx6o W_" :.`YxUz_||hFrxgtm @ O /;SƏӹбɱXDz 7-nӝ百THygƜEè's\u ,SޯfMc=Zۢ0)(*ê3tn[tVT[oRLe??cfQKGɍdv/2k@.^u8Iؙ[+ſI$,i=;wC4M]CnBǗHI.?BKyRbA?c05( u_|s,z_kUDI"m>nc`~vuuC ~'l<,bdf&6Pa8lLqa&T5{rMS{uwǍ߫|/5hxF|1ܚU VQ̿§Y5gu3*\n߹J&QK5r|p`I3x N7/紬;5˃) /|^u Iek_Un>[a \=,Tnr<ԟC32qͫ_t,J뙎" *y c/q5A@j@eRGc3rĩ1N١R /r&UnOaBuލ#,0%>,i͝ݛs؀ E.,_XGE4 NMr-h7ZG#d2y:׀@@ԍ_h#sT8.W@D) n'yPA^JV{LįBI9fCneXP]gW.VC%L2v'mwH3yk0Ri`6\dPE{Q|@ cP pqp9Gk.N|( @ȡ#7z/|y`-C i"ժ1+G2`D p\)DKJ=m!D>V(~AUHC8YnӔ@Pb e.L,.>(b`@a_1[Va50\J,>o I5ٻO5XߣOqSըNpHZVQT%4?!m bĐ|: I`a:bK1Kzkk;|qucjs#e폨.iL,VP-6t\Wǥ$uĢ$hJRꏝ1<15]~D'abo dB !KӫKh;Đaqc):~O[A|(/8G9ѽzf[>y'?GGDZk#)Uf?NHۑ b"n a5"iO:GS@a  f)qTqP;G.<.!&oI?OEiP;謒k >Wv~z6V(fKHrPw]+! cN$>*Β t:ûT f<Re 3a`DWs y4_FKGmBo1V ϓ, ؔCF<܋lwsB . ;J9D[XFʃHSWVs ͗4ǔGtQ ''`jWᒍI^f`(5!^ Hr۱,c5Wl:C9_KWi Y+9,iJXH?qy11ƃ+2 K:L6 N VQX͓HF)|e xDVFŠۏ cP I* A(N3o~u&xrsc%RBLn?2;CQ7ckfX-tݮػP'>@}fR=V}Kp8#+|&5,uH(yRM@=@xœYrՁO[ylYYL%}=5=#|=@8v5.|g; Vk߷v)R7ˤhdK<_xӹtMO`5ezsq+~gnWs$6'CϤ >O6 XP Zx<`a'&'ue,>i ? 9ҝ6/@^l-[WC$!ڎ8@ i8(G64芻KO<Rfд,^b$xFdKmvAS_6:MĖCIK:D[e9餝hoXy`d!|iUp;IuVHm }h5Ru>(+1@!<߿O\] 5W>K vi7\ {[y0.a4}˝nEa_0~(? CKv 5" fŒg Dh3eru8i1禅p[1 #k4TP3- ( Ů#jFG,EOse{I Q9V~~ ˲ z0@@^D1Dm_kpʍЧ#&NcrK/v)qR&Md{M%TyR!Jm+R0&~!JݸgG{u=nwYNB2wk!l~acOX V״熦" ' H7$9rIjǙ\T$#k?o,] ۵%d&#m\e, \a=!'ve'AA%Z|a">=>(Dc85 x,{U.-E(ufY݋l7bK%87lYڑ}W8YnHBg+6(H{*`S:hjYRٿT.)M]&Gt=n4,^9X96b/sk{. S Jv;j6zKrh%[!K^y`O+r۷^g1^'gHЩ6f]ɵrEms+8)rN6SL8Iu%Ff@\znӿN~4c0Zh2/AO'.m&k,jK4SoglƋqzZ-J!}F̻LtচXZ"jEd*c}J_XB2TW݀~^t Dvqa +><Yx-Dd=﯃i0l"gjC$yYN*99jKJT!T;q.cQIS(84j*m4hIdԷJz)RrEC/@&CZ|c;_uG῕}i6¡ZLo _ʈw?&YC8I^`\MXKEFeN kB}&q6i),vՔ'rQx 953_6s?L.aor@ފC `rTތG~|N$&cjP[jW:5qx2;6XZ8 ,S=~4ԙڛ.@AXzn :u~(J*NHFa)֓9Fr@8!klI2T]bIK Mc̉ɸ0}۱/XL&OAP{bī<|k] ȇWW 10Cn&0 m*:ͲXk%nFPT5/..iT 0$έ'z-1ᢄNc(yK/3Kp8A'c/e~r\R3mlQ5`ø#5$j+%s&@fVlTKyj]K}JQ3K8 nPP GfQQ$CaID8W ;D3 0~z?{Fn\Dan&{*'6£- $hS& leUA5]ϫ,>x,> 220>4{>!pFa{ NSF(R1P&|-|}{ (BR  rU͗_E RܩqGD =wwh2/Ixai% )/ˎґN(TIr![ɫ}P0A\ 8&+,pI(kL[OEZND u\lTO&'1WQ-#wBJUx"kLMc ͇!`Z3GF} j\@΢CSbzsΐF^Gtq-#@A,2ݦ* kx $(6D s$@d?÷䱥!#! {yp<} я @?aR)HkA۠D505G%vxrM[ݙa,._pjN)) ڄ$ SU=^TLf.y "d^587^gO$݌\ܵCOkS܌Ⳓ|i~eLsE' ᄏ~w/oJ25Om SJqV+nܥq!O=.ٶ6==1 zea8,@BL SXOp7KJuΫJTQtq˹7+-5H,#צkUR O7o] 2%̊ϻO8B*dv^ @mpx.xC!3-%A4jzlQgV D<;/.TXUrٓ3ש~94] >t~Lhem:6ƘpKw4 Bִ2dn!$ WBiS8,}䑭VضzwU-e?CdECsNR%֗wIB?DѹijnX} +BbVk=E` ~=.>>v?<)᫥ _D[V`־}9DQ9a1<MVSg>UchRCÌP6E#-~WKzH蚯q<%BgaZ^Gz 4`7DO)}/İ2e ~y]*af{ ȧ2ijEIytܞJqXu2~0ӸxC1'M 7Ljbp=_T;T>&܂l<,i2ib'3@tG̿ 'O>sʫypWh+8J<TA8=^q vkbpEQ 8j&a,CS[#"˱rY~^Tx[2pHC@Gn@e DuCp/zٝ]CH~pWH R=9W̨V]~c Ru(ծvhܯul4~]aQ3{\i*@GܽYܕFJ`IK4TxDW1̓h$ezoǽ6 q1ڰRޒ Az70s#ܫc-8*x?ߏfI'6r@1!c}N"bj?\\5{Ʈ.ϙp|q=[h[THԢ*@"6ՠ&/ᭁɶG3۔*k˜wM 5xAR2>ML@\jdP\/dt4i\R%Ȣih 硋::pKTw1wWMoZȫA>Eԥ|xl.15sP(g9f_Gm r>.ay0wDXzn_;.UO*Wr{:ꓵQ3*fvh^9ŁG@ [='Ih?2Si К;wQ5YQS 4w4j<3.'1;bz.8#ze!PQEA1|rN6VN1NΎhø1x$ͦc P쾠ta|wݢ $7KvxegAJVPO#Gjj(k 5M:KQMngvЏ ayؖ^x`'IsP"ʱhl4 5a7~ZK&&pw-jso%rF\DZIj򑣘1D6En<^Xz [QQ&>rx8 *^?6\_܋Sz eEƘTZ-u*uܼF5أeC?_n[,kտ?3?Αpk`k0/t8i-'O%QqAb`PB ^h?2"C\g9ڢ?n @V%DZP\\ye:@ǑMUKoWPkoJџƾBv@jJ)ús_;WJEH7~Sp^Eb\8_U~FymEkb v[˫ Zwy;=RUz36C>/pӵDXἠ3P܈u>/S닸h:a:MH rJKC) 䞗 nHž缔æ3&QX݀*K)SgKHu(D`d & nJ` p Vp=#ت7_FC@f\;s8כlҴ>r 1E7M#Q&x\]o4s#lGie4e:0?zٻIR <,Y@9+cş;=xAҗmK&YtIWS\ =(>VZ&Ɓ%p!'5-fv. M˃Ĝ;gZ89]-&0 q:\ Z/HcD,8YNT r|]B1'|@%yB!)$5'rOaR$剎i)i%'L*NCS+>TS"W}4x.2Z~r:C+RhˆVvhneJ`@niH gf>rV`&\Rkq ;1g"F>*Gs!7پJ++Li-$Hi4ͯfU,F]&)+rq%ឭ»'ډ+5QRJoPZ\i(KL;aiLA 62Ԓ2kkv`JiNcJggvO̎EE%w=+W;!֖X_Ar=O,n֪k?q^fF;uRi$՟Hf_|ll (^GSJVx7؇R*|NכQaSlw:cby%#"nZGt](y"tG;d#{]g;A`tr( >j:]'#=*-mF \xdhU E![OƝjݕ}wWK]:A}qrusB53yg _8*0xǖSy̷i;Ϯ)- tj+<B׆_U^ =qbm',+&jInq=Y#R=fE^HK" 'D2=Z Ig]h>iNF"d凞lRdZtF)Lp~j]5[ neO*VSR,7qX[#[ p<{k r˂oI"./BVg ի>t-+-|srQY5V BP" ƞ --УEN}_#,~\"OJmތ}g,h W@\{o[h< 7 R6\AiNћ^{;*7^O噗{R"@~;}L` ?+MfDZ_iS*Ёk> İuv 4 r8^2Xh<#DM=\3= =E]@O/O;T8I/vwF Z#}/G u6% &fAhJANJYߕ#Sl _{z a;F24Dl6\vaПMI I-YzZ#pU$;0 ٧* 0ay@R[x3/TӮOu3/;!kQxj.}V(X\]? 1~)ӝ뉀HҾnr#oXܣT*[Q݈$gnLP/Ց62P#QϚxTp3Zr%|J3.v7\j(́e߳]atZ=GQwT 2,4$+k/v5,6,U^b-+E"(@Aоfm0m[xa>ha$Bd9UΓx0A騵t Xo1лCc˘'W#j?EjM&5іdm'-51jK۞7sc!a\·(ǥc$P5@]Q%]q| 퐜 "CQؓ ÿ%Nq VJf^7nWiϹA+BB? HRO6 x)̚%޳:ݖ%cZAU*W/} ~ѫzw]&?/BKMN]O>@ajEUޓ46^|GyiLpLe!1;SA Iy䉈dq5g0ՇVu&D25?XWL8p~o9}|ꯂQ_{zfk@=t-SVkkS/qQ`)U[lF@jj>Nr]w6Ny41_yugǭ4'1ͩVzry _Wzy-7["$!G4-L8ӈdJmAZuهQa"RBo-rS:]>ztEy-܊EE~nۭ&Ƅa3 75zK̦AM8qSG15mNx3ԩ.khҊz9I%yCg Z)_>ыl~͟}{12\:T,uWA#n/_}5-VrocAI'.t F4HY΅g[^EgGi(V῀@oQTA/n@|I2I!*N%UTd|qJ% X b>޶e0LsJxv}C?k.f^PGk'!_ :_YMRkʨ^CI<ƀ6 ŇD ְO]V'NL{@?k7s ѓn$p3c$7]TM'_a9>.DW3Xp1^p{s_+I$^係zJ`^FثLׯNAHl9!,UY~jTԡIG^,WR~+kmp&R\E ,U.͗)OcPaʈ:N?BSUS#_ \eu~ԏq zT _,T_8iq׆6*A>$/zzJ$}6v{tvOAxBR֔zZi8{J2ciItHK?ل;/՛15(&[8_ iP*K'J I ZI?7fZL^V2V$!ԨÉlY I7< n32u_ H`H[ݕlࣻ!Ȫ8q~p\bD}c[ a?]qYw |Lc%/i]Y+șbX6Ԓši -&B"5E04T}8N?t>x<~e3 dYWD p`zH.@A#T$VkA&ifTḺ‹`=L h't|Ul&K 8Ձ:\tk=`4h mdyD|ކV )O HJ"Kgs :`ⷍE\z: 8s#U$?yA4YWx˒ԤB?l+r>Cvw[eg ע`'XWDLtgn&|0XpI1f}2e@3¦QO\1w-UM]-( c120k.bin ^Ӿu0GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2333117 SABnzbd-4.3.2/tests/data/obfuscated_two_rar_sets/1f34e542-0a5a-4a7e-81d3-9726c24bb3fd0000644000000000000000000003600014625637207025765 0ustar00runnerstaffRar!I )p0( a100k.bin  ^y(}KIEZ@&i ou\~u(SHReY$mbq67Z}. <xz8u4. 23`-gEոvTsV"Ǧ&33l;λShaW:pf}F&DtQ0bbX>}Y9Z(-iXDRG%,gpB6!j $)"(wbf_YO[Ci@mv%m AE:u[;CKĝ3 Xz.x.K<?G\^UJ{ FY@Rh<.[eN4lL3./q9KyTe ׏_cm`},D:- |MUSs*ShdrAA8۰n - +c1VQnObv$} | RuMC$V}W)x$@ńU:D%(š>TǙ~5(37$8 I}j` |gm=[t$҇&&A5:db"aԑAIt] tugtORn irxs jTI]ׇPhZsUP!2 .3@m#Hdjľ|):^5Lb]O`C0t#AoLْķ'OY;S͘!6ъ7ժ/xbGʉ쨊"S:SJvxA8=)eS)bIMaGx cFK(ՉBO@-?I|߃twwߥ p;|,@.n8-6+Lٗ(5D0n=+;VzMtMԢ M1ecPGgD=/O&Hd^NCr9jL p ~vk[2rx(\+OmU^@qc2()),Qu9m˴oNyuJm^Xi#^t.8"B|e={HbӢ 8E<2j\?N$%{LuydrΈietng>cLز s:yƥ,Y4[$? 8ar5w#qFpT68\a#*|P̓{XXBk~F!uu?~#6|כj{pA@emlNt~ ڻU`1? 5 _jnɳuOA#K@xi 9f_'6s,qF l5\e7l-U@WJFa]D^ro/CM ômOVM[yNCꝖ7#T48 fӤ8BwՂu qh|Dr-p**q?D3'q]uť\<3*~PNE0dm*iL{x{Xu?ˠrb:)Fl @t2ٽDѲ?Ck g TZϷ&Q(`fڈHkx`' x2]$w|䉛ةQpFO}cDixӊ .BhȌ,9 e/>Pcu-#GU@^E :˴U7^l:J %^v5]A# V`% 6ꀍ'gh A,I tmTHW "KB؀ '82fiS vGR/t!0~90 O5X :/[iMANr!qme7cAf#oni[x)DCyyW a"&3`N|sޗ*{9c8; i*R2b:u淛2I).\y^Z1mdE|BOK=aOCi.*!L<[m>] w{U஘\39w77kFO&O{U(lr\cp [gLa'f< !G< `v^ (]#`hzul"Z53f;5^)F/Sl\E+j^MyғB{p_-U~-=w2|oȄqDter;ljպ?_qWOMS~!9#~z]F@'r 7|Ⱥ1)x0 jYPL103"H)p<\\#?2\GYSJ!*z NBGXb 'q~$&Vwo1:g4x{x^,l7\N`kWM)ls6#mt0yI=( / 4(#O2Rv#HWgeT+CjPs^HtP:f(G'䠑RŸHZ[ieڎhUVW*@Кe" ,s`BcFf Q(cj* wgרk 4( }# fYV0_(KS$xh d3pj3nʱ#l {܊M14'Moq1.߂{7ShHw8+Kán+Ф(Ga,3򟗧DdUF+[bYf}Zy@Ϊ(%ZrY%I4Y$]7(z\jTSG9\K\*"7h pVdrHN(*ܫ^TI/#}:"O\S۰ v8:d\r !HcxMYs! q0`T@Je,NAb'q54=q\i%vT?T 3v=MBxPhc<2Ϩ|UY{% W18Υb|?eн(9(N+ߪ 8%QYCT3_hӄfwK>t!(!KT2FcV . A8z4Aah(l5*bBv̬$5* *`TW5=4? qvܗ(zٛNʀѠVt$[fQ=fKNjlzϘWA vkn9>P+!>j~>76h!\R꯻Lߦ|d~8yV~|^RA{ed%MF&qPI)灛*~WB-Z0{/N\Q[T8*_:שZ.N(6X?/ҸrXHJEo#\L-V"_1v*`ɝ<SvPJjl0Q ّzHF/KŝNyD}3F BP#̠IWatM6)\O H.2cW($JTO$C[H7 |#@;0t_B50DsN.J Lͤ=hЎ}>@ W[z? N;wzyܨ#Ƽk G(zH$-=w*c~@R@Gq6cSq-rRzѵ x%_.)ֽy8!i{=5=sD*+Ce%= py>mߥv,KȪ?ՙes!y m:9 ;Y5T>~D{X#'DMuY,FQ# 6G u.`TlnjO݄\f "S&aPp{,k]IE04WX\_ g4"̪ᙨ6 AyUBPF')z Ubg!}Ĝi ^P'&MdАmYP5P8T㩋BM|N߯!wíև6ؠozhJ@EmNz̦b]8x N\P3O,ztϥY8!SkEL( [ tԖk(D~ǾZ~Ip !M^P Pű0`fvPsoڬSـΖoJ^{x*= S0w/;8 y@{DW`0U4ke8i"#n <]lN[*36ze }H]n\"Z eߡ]Lj됗Zۧ} +\ *@vI, [BsA6С;T&\1q`#ilp-wz[ 2B-h!m(GrBwqGUsSA 刅w knHGV5c3vIc!X2Oi~GQ=Ѹ3>A+쯏r&k۵H\D*(ߥt# x)CntE4AT&[&ήh~+-7h輫 fBT#? <ٻ1D{#GLvڳ D5Kh--ʛ;]-w[x<eS2)ى5>+4(>qoV> 4u-& ;#x:EE W'ƌgӉxFȫ~cv@4vq ;ۍ- dyDkjQg7حQdaީɏp1:{䓉9}Ief=dnZԾY@qX6vmn:մ^fI@D8 葌;'* FGaӺ`KPfZ9yvv #j3~Ko="huxF>t$dwEYpMkFx|K8>Qv}wo`PPt`bS#T=|wk{}\S#- );b(7{/d(M/ c8ÊFE]c.<7Χ?XҌӨS).;D 2Kq'_8wláɒ,Zs.-u(:Zj.&Y|I*G3ˑt S3f"p(9s^?W$gʴ{8'^|{F{PYLV |$]ӴRk;LB.Kh/)Iry? &o4fΎzPqGТU?Bk!ZzAg3vLq7+.Ƴk5,~o:dGhÊqe50~/uV쉶փH>f0OR7oTVLs0#u]x?zK *J:AWlzR";{( CO ڿ0k8C{ݳVrYa1]nTUTTy[0ɃҼM#wldq.eF /b_]os:G37yҠxZ 8i0W@YORɷ+lJL "r4BYpCV|0i)'%~h)}h7XOl13ڑJN ˘6(KO'ViWZLU=ꁹk_MtmA V3rs@R̲6G|\@n\_3 0#KxW\Bb90sq!5)8/t+JBnpM=Md3:M+!;ȼ{г ^ ك"9>/Rc U\ ~dȾ0K닍;KxezgJzF+R +Ęk]?*UԁsmM"e%;9CgdBjrFWPNv9`a! Sa~y{񈫊Lb”FpS[ Aɐ4mG.!*oceKYvz#b@k2YgAUE3ϛeVT/,WnT։qv=Ԓ:lBT+Vxn3T$p_e=:)T[+E[NZ L u"WNq@v%_зA֣sY[)O({PGJ~'v$\HoEwqW"-m\IaGl8(zg3I]]C c柳 ޑ?# _<ɭ5tiJW^(}hD}k3pofk뾁tҨ;,hkaeJ_+תuυ4 Cqh9o|98'7@VҐ}_eKh'bu!Q,x[(lʎڃR{"'2;w2I X 8{u7x/9gmC>tCϩ;X!ϯb,w< -Y*4#^E;_ǫ&ƺWh(08'QxRhOE3ZJD[`٣t'iUo"hP\[Wڳ!RVc;O0bL×qLaizcqlxX!13G wow 0tjʛjMSwh-_c3ǥfX5ۅY3HJS06*;gzXښ,u>SЩe5eԉi"b(I&Z^+FNጽxfxm8@s"1Yek*-hjxCa ݻTy᠅B]~HȈŐ4:CH 0zūAfG]b`8kY{I@d 8K<^[J,ZQKl0 cV_{Ipf!@)lUE&ցkzS7OC5}+Z/ cF=z" . eN`- C**]8c%08(zLtH򓳰ȓyziBy"X苡Bs@>.J}`Կ!z!@WD; V| 7:)z자̃N,Ƶ-eRmc49GT[6' X9KzLmh<j#Hz[30Y3_/ASDׇ8985=1EZ;y5_CFu8lm myql_Sv1-dfIQL@65:d'<'3b R5 )i_fBC GYXV5BGЅ.\q7ӌ~N^&ife SUhSgь\+glĭlRR7MPhI'i/:"6ޏ[8Fu)9;)dvZ!mCV8ʖk6{syn̷|_YvEkFڶ83RYaP"}IVEd^I޿^PϯމiJ /P#Ҷk&ز{?qu@dGq]~8LرʹZhwAܾm9F&+CBJ4 f$Z>3qEK އ|6+6}, $4%bô4Ak(̛pKU}y,v1 }5}^,o*|^ՈCaƛ9dc%39v=PNh5%xLz)1ZTGIIЖNC{b[8pTh)`u&`b,>A ߀ֶLiN~ @". p?G*dl2"{7[+jk+pX$tHͶ;YD(!S>xE^xK7(籌yە[wC_P (++ҳ9u 9w˵Tڼ҆X*$M[6Y9w L|ԓCA6:!@~%>~Q%wJIAW_37շ0a~+w<-saj?RR 1;+O;2!2/qHOP6$'G`PGDT\U{2GYȻGJm#)KHJ^rjzn3/CCGp<n{Ӳ bH-Qq^5mt+}7Cɝo˼ Υ[u¡V54`@JPUqL.X4\'+^"ǝC?9^eu ժBו1>aoP6=0@K%Č$N,_:< m[}+Hպg>~>Ϩf>DӗY9lV?pVv;f" I' K֎ ip2|p8k%q&>KױrZNSyzߞ: 5 =b : So9̈́t./d8W 5u Ptrib,GB9΍ Xq=^w(IIA8 ]A) E\b$N; Ɏ mXoXv ֬;d9sJͷ5ߏb%u/zR ՝x;Km'uP9׻T$wyÉkfҝ=IvkX-ϱ'fn0)߹vX;RP߂7 @I~Z(2 -#>䔒(HB4PHa +P{R*ȣrE~`0%.bPM,#t͉w"<,v4!!e(6vwi#G]Ngn2Xj-b* |iIL DzC34{_oc~O^X.@-T1r ujPs 5mj@i1V1M-<,А])r{) qJMbKV7>ݑk2ćJRbEC)M"oVQ֎`쨋'OK\˽<.U"YSUl3SЏ$3c5?;u\%pgS ՝'44U9*3^9I*IK`. zm H/liŦT*!)\$LaT q2[]ٖL_R[u^ȉɼO8l ?C}~ʟ|>HcYJ%3X;WzGrdS84 @Յ(-s'!."C-b SBa@q^P>`&탨2nZP=+9ݗL)gFC3{p(FTKXz6W[[Y> PcuC9X) l8='$-z$3EqR_55~Di-N @55qоSME,H@vZg4ެ`W)Ŝ&6*9N| eLociD>"$'!8oVG;psS~n¥") ؉T~^C3ޕHn#Vg:nCpdl3"I!IڬZt!eJ#ލo BlL;>/O2䩿:Zfx`?8%ZWoN74yN(χ+\.$2Is0~3zUϤFC,5/h*2+g6~ NDG̾'Z,ơh$2 3[rO$ޜ^ْ\VחCJ9@&9o9.ɋU/ff>ޙڣ^F^PJT]ֲF=mnVKdOf#лρ_},:{*UqǾgdh:e[jfxWKA9.C_8jԎP߼]8yr5վaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaijTZ|H4k^~RtRb[!k JjXZv=t1_oo[-mo{[g>>}x<]tgZ1v,CMKh_Ȋgp̶NOϤ' ̍i|z6?PKpR4w8O@ aaaaaaaaaaaUTd`ux PKKRu Orename.par2UT^h`ux PK"R././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2421513 SABnzbd-4.3.2/tests/data/tavern/api_version.yaml0000644000000000000000000000174614625637207021007 0ustar00runnerstaff--- test_name: Check version strict: - json:on stages: - name: version (json output) request: url: http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api method: GET params: mode: version apikey: "{SAB_APIKEY}" response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" json: version: "{SAB_VERSION}" - name: version (xml output) request: url: http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api method: GET params: mode: version apikey: "{SAB_APIKEY}" output: xml response: status_code: 200 headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" verify_response_with: function: tavern.helpers:validate_regex extra_kwargs: expression: '<\?xml version="1.0" encoding="UTF-8" \?>\r?\n?{SAB_VERSION}' ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2418823 SABnzbd-4.3.2/tests/data/tavern/api_history_format.yaml0000644000000000000000000001167314625637207022373 0ustar00runnerstaff--- test_name: Check general history format (json output) strict: - json:on stages: - name: history format single entry request: url: http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api method: GET params: mode: history apikey: "{SAB_APIKEY}" limit: 1 response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" json: history: # all four sizes may have a single digit value, so anything beyond that is optional total_size: !re_match "[0-9][0-9.]*(\ [A-Z])?" month_size: !re_match "[0-9][0-9.]*(\ [A-Z])?" week_size: !re_match "[0-9][0-9.]*(\ [A-Z])?" day_size: !re_match "[0-9][0-9.]*(\ [A-Z])?" slots: - completed: !anyint name: !anystr nzb_name: !anystr category: !anystr pp: !re_match "[URD]?" script: !anystr report: !anything url: !anystr status: !anystr nzo_id: !anystr storage: !anystr path: !anystr script_line: !anystr download_time: !anyint postproc_time: !anyint stage_log: !anylist downloaded: !anyint completeness: null fail_message: !anystr url_info: !anystr bytes: !anyint meta: null series: !anything duplicate_key: !anything md5sum: !re_match "[0-9a-fA-F]+" password: !anystr action_line: !anything size: !re_match "[0-9][0-9.]*\ [A-Z]" loaded: !anybool retry: !anyint archive: !anybool noofslots: !anyint ppslots: !anyint last_history_update: !anyint version: !anystr --- test_name: Check general history format (xml output) stages: - name: history format single entry request: url: http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api method: GET params: mode: history apikey: "{SAB_APIKEY}" output: xml limit: 1 response: status_code: 200 headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" content-length: !re_match "[0-9]+" verify_response_with: function: tavalidate:assert_xml extra_kwargs: strict: True # don't accept extra tags in the response expected: | !anystr !anystr !anystr !anystr !anyint !anystr !anystr !anystr !anystr !anystr !anystr !anystr !anystr !anystr !anystr !anyint !anyint !anystr !anyint !anything !anystr !anystr !anyint !anystr !anystr !anystr !anystr !anystr !anystr !anystr !anybool !anyint !anybool !anyint !anyint !anyint !anystr --- test_name: Verify value of history slot count strict: - json:off stages: - name: history slot count request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: history apikey: "{SAB_APIKEY}" response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" json: history: noofslots: !int "{daemon_history_size}" version: "{SAB_VERSION}" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2417746 SABnzbd-4.3.2/tests/data/tavern/api_get_files_format.yaml0000644000000000000000000000353414625637207022630 0ustar00runnerstaff--- test_name: Check get_files format (json output) strict: - json:on stages: - name: get_files format (json) request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: get_files apikey: "{SAB_APIKEY}" value: "{nzo_id}" response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" json: files: !anylist filename: !anystr mbleft: !anyfloat mb: !anyfloat bytes: !anyfloat age: !anystr nzf_id: !re_match "SABnzbd_nzf_.*" status: !re_match "(finished|active|queued)" --- test_name: Check get_files format (xml output) strict: - json:on stages: - name: get_files format (xml) request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: get_files apikey: "{SAB_APIKEY}" output: xml value: "{nzo_id}" response: status_code: 200 headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" content-length: !re_match "[0-9]+" verify_response_with: function: tavalidate:assert_xml extra_kwargs: strict: True expected: | !anystr !anyfloat !anyfloat !anyfloat !anystr !anystr !anystr ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2420135 SABnzbd-4.3.2/tests/data/tavern/api_queue_format.yaml0000644000000000000000000001310614625637207022007 0ustar00runnerstaff--- test_name: Check general queue format (json output) strict: - json:on stages: - name: queue format single entry request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: queue apikey: "{SAB_APIKEY}" limit: 1 response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" json: queue: version: "{SAB_VERSION}" paused: !anybool pause_int: !re_match "[0-9]*" paused_all: !anybool diskspace1: !re_match "[0-9.]*" diskspace2: !re_match "[0-9.]*" diskspace1_norm: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" diskspace2_norm: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" diskspacetotal1: !re_match "[0-9.]*" diskspacetotal2: !re_match "[0-9.]*" speedlimit: !re_match "[0-9]*" speedlimit_abs: !re_match "[0-9.]*" # Value may be empty if unset so !anyint won't work have_warnings: !re_match "[0-9]*" finishaction: !anything quota: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" have_quota: !anybool left_quota: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" cache_art: !re_search "[0-9]*" cache_size: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" kbpersec: !re_match "[0-9.]*" speed: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" mbleft: !re_match "[0-9.]*" mb: !re_match "[0-9.]*" sizeleft: !re_search "[0-9][0-9.]*.?(\ [A-Z]+)?" size: !re_search "[0-9][0-9.]*.?(\ [A-Z]+)?" noofslots_total: !anyint status: "Paused" timeleft: "0:00:00" noofslots: !anyint start: !anyint limit: !anyint finish: !anyint slots: !anylist index: !re_match "[0-9]+" nzo_id: !re_match "SABnzbd_nzo_.*" unpackopts: !re_match "-?[0-9]+" priority: "!anystr" script: "!anystr" filename: "!anystr" labels: !anylist password: "!anystr" cat: "!anystr" mbleft: !re_match "[0-9.]*" mb: !re_match "[0-9.]*" size: !re_search "[0-9][0-9.]*.?(\ [A-Z]+)?" sizeleft: !re_search "[0-9][0-9.]*.?(\ [A-Z]+)?" percentage: "[0-9.]+" mbmissing: !re_search "[0-9][0-9.]*.?(\ [A-Z]+)?" direct_unpack: !re_match "[0-9]+" status: "Paused" timeleft: "0:00:00" avg_age: "!anystr" --- test_name: Check general queue format (xml output) stages: - name: queue format single entry request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: queue apikey: "{SAB_APIKEY}" output: xml limit: 1 response: status_code: 200 headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" content-length: !re_match "[0-9]+" verify_response_with: function: tavalidate:assert_xml extra_kwargs: strict: True expected: | !anystr !anybool !anyint !anybool !anyfloat !anyfloat !anystr !anystr !anyfloat !anyfloat !anyint !anystr !anyint !anything !anystr !anybool !anystr !anyint !anystr !anyfloat !anystr !anyfloat !anyfloat !anystr !anystr !anyint !anystr 0:00:00 !anyint !anyint !anyint !anyint !anyint !anystr !anyint !anystr !anystr !anything !anystr !anystr !anyfloat !anyfloat !anystr !anystr !anyint !anyfloat !anything !anystr 0:00:00 !anystr ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2420835 SABnzbd-4.3.2/tests/data/tavern/api_server_stats.yaml0000644000000000000000000000277514625637207022051 0ustar00runnerstaff--- test_name: Check server stats strict: - json:on stages: - name: server_stats (json output) request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: server_stats apikey: "{SAB_APIKEY}" response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" json: total: !anyint month: !anyint week: !anyint day: !anyint servers: !anydict - total: !anyint month: !anyint week: !anyint day: !anyint daily: !anydict - name: server_stats (xml output) request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: server_stats apikey: "{SAB_APIKEY}" output: xml response: headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" content-length: !re_match "[0-9]+" status_code: 200 verify_response_with: function: tavalidate:assert_xml extra_kwargs: expected: | !anyint !anyint !anyint !anyint !anything ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2419403 SABnzbd-4.3.2/tests/data/tavern/api_queue_empty.yaml0000644000000000000000000000757114625637207021666 0ustar00runnerstaff--- test_name: Check empty queue format (json output) strict: - json:on stages: - name: queue format empty request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: queue apikey: "{SAB_APIKEY}" response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" json: queue: version: "{SAB_VERSION}" paused: !anybool pause_int: !re_match "[0-9]*" paused_all: !anybool diskspace1: !re_match "[0-9.]*" diskspace2: !re_match "[0-9.]*" diskspace1_norm: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" diskspace2_norm: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" diskspacetotal1: !re_match "[0-9.]*" diskspacetotal2: !re_match "[0-9.]*" speedlimit: !re_match "[0-9]*" speedlimit_abs: !re_match "[0-9.]*" # Value may be empty if unset so !anyint won't work have_warnings: !re_match "[0-9]*" finishaction: null quota: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" have_quota: !anybool left_quota: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" cache_art: !re_search "[0-9]*" cache_size: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" kbpersec: !re_match "[0-9.]*" speed: !re_search "[0-9][0-9.]*.?(\ [A-Z])?" mbleft: !re_match "[0-9.]*" mb: !re_match "[0-9.]*" sizeleft: "0 B" size: "0 B" noofslots_total: 0 status: "Idle" timeleft: "0:00:00" noofslots: 0 start: 0 limit: 0 finish: 0 slots: [] --- test_name: Check empty queue format (xml output) stages: - name: queue format empty request: url: "http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api" method: GET params: mode: queue apikey: "{SAB_APIKEY}" output: xml response: status_code: 200 headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" content-length: !re_match "[0-9]+" verify_response_with: function: tavalidate:assert_xml extra_kwargs: strict: True # don't accept extra tags in the response expected: | !anystr !anybool !anyint !anybool !anyfloat !anyfloat !anystr !anystr !anyfloat !anyfloat !anyint !anystr !anyint !anything !anystr !anybool !anystr 0 0 B !anyfloat 0 0.00 0.00 0 B 0 B 0 Idle 0:00:00 0 0 0 0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2418332 SABnzbd-4.3.2/tests/data/tavern/api_history_empty.yaml0000644000000000000000000000416214625637207022234 0ustar00runnerstaff--- test_name: Check empty history format (json output) strict: - json:on stages: - name: history format empty request: url: http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api method: GET params: mode: history apikey: "{SAB_APIKEY}" response: status_code: 200 headers: content-type: !re_match "application/json" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" json: history: # all four sizes may have a single digit value, so anything beyond that is optional total_size: !re_match "[0-9][0-9.]*.?(\ [A-Z])?" month_size: !re_match "[0-9][0-9.]*.?(\ [A-Z])?" week_size: !re_match "[0-9][0-9.]*.?(\ [A-Z])?" day_size: !re_match "[0-9][0-9.]*.?(\ [A-Z])?" slots: [] noofslots: 0 ppslots: 0 last_history_update: !anyint version: "{SAB_VERSION}" --- test_name: Check empty history format (xml output) stages: - name: history format empty request: url: http://{SAB_HOST}:{SAB_PORT}/sabnzbd/api method: GET params: mode: history apikey: "{SAB_APIKEY}" output: xml response: status_code: 200 headers: content-type: !re_match "text/xml" content-type: !re_search "charset=(UTF|utf)-8" pragma: "no-cache" access-control-allow-origin: "*" content-length: !re_match "[0-9]+" verify_response_with: function: tavalidate:assert_xml extra_kwargs: strict: True # don't accept extra tags in the response expected: | !anystr !anystr !anystr !anystr 0 0 !anyint !anystr ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2325075 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/8fcf6c37-1903-4293-bbea-bc8fc56484db0000644000000000000000000003600014625637207026434 0ustar00runnerstaffRar!85 ݐJ4 My_Test_Download.bin  d*,QOZ=w9ݐJ4 My_Test_Download.bin  d*GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2321963 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/144c25d6-6e75-45d0-80d9-7e09e0c505cd0000644000000000000000000003600014625637207026126 0ustar00runnerstaffRar!C" ݐJ4 My_Test_Download.bin  d*,QOZ=w9ݐJ4 My_Test_Download.bin  d*GQ&././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.232649 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/a6768881-217e-47a9-bdbe-ebf81ce6773d0000644000000000000000000003600014625637207026371 0ustar00runnerstaffRar!dYQ ݐJ4 My_Test_Download.bin  d*,QOZ=w9ݐJ4 My_Test_Download.bin  d*GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2324276 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/8d1cc822-0a5d-4fe2-b9e1-62ae5c0f5a080000644000000000000000000003600014625637207026407 0ustar00runnerstaffRar!h ݐJ4 My_Test_Download.bin  d*,QOZ=w9ݐJ4 My_Test_Download.bin  d*GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2323313 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/3a63e6c4-c681-44d5-ba8f-d34bd5b026bc0000644000000000000000000003600014625637207026412 0ustar00runnerstaffRar!'"F ݐJ4 My_Test_Download.bin  d*,QOZ=w9ݐJ4 My_Test_Download.bin  d*GQ&././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2327108 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/d9fab0d8-9846-4bc5-bbff-a468847717790000644000000000000000000002640514625637207026332 0ustar00runnerstaffRar! ـ]4 aJMy_Test_Download.bin  d*,QOC\=Y9]4 aJMy_Test_Download.bin  d*wVQ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2325869 SABnzbd-4.3.2/tests/data/obfuscated_single_rar_set/a27aa04e-62a0-490f-9a06-5fbf98edd5280000644000000000000000000003600014625637207026343 0ustar00runnerstaffRar!NCv D4 HMy_Test_Download.bin  d*,QOo^=w9D4 HMy_Test_Download.bin  d*GQ&././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.244512 SABnzbd-4.3.2/tests/data/test_zip/testfile.zip0000644000000000000000000000046114625637207020503 0ustar00runnerstaffPK`kVaJsMy_Test_Download.binUT  d dux  nH@|PK`kVaJsMy_Test_Download.binUT dux PKZ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.229094 SABnzbd-4.3.2/tests/data/basic_rar5/testfile.rar0000644000000000000000000000043314625637207020635 0ustar00runnerstaffRar! X1 aJTestfile_1234.bin P\ dlńCAv#C/%|, aJ testfile.bin  d[2ńCAv#C/Nh4 aJMy_Test_Download.bin  dd@E&ńCAv#C/wVQ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2423816 SABnzbd-4.3.2/tests/data/test_file_extension/apeeengeee0000644000000000000000000002161614625637207022364 0ustar00runnerstaffPNG  IHDR5sBIT|d IDATx뒜Pz+ፍ1UELZ3vWqGzM_Y @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 "&n3^ދ@b@hL@hH Q ,TTT T7z0vP`$ Ѩ| !0*6Ӿ0"V\@ 027PHy?*)M@r% TH)|@U?0%?Є?Ȱ?&2$y C[{9m 08>>3l???$ 'c_?[nk_ zw;r=9 +} A{Cj@f nb8%} _ BbpBHG ^/oc7iC aD,m('Y ݀i-!@dh9Wq(dB H)˛FCG]w{lg }z.@4 l z8UE D%€ b{vk_s[@_lh@HL S𗋩` @HF*s- )`H@%@L e?$B0<@@{ ^w/xF)-B"-V'*}G*???*4! ގ8;-?S7zek5X ^ak3b )Hk{YR S@)Xa쎩2^iڱ,[b@K 9ro3iGlE0r5 ]O{|]V.AIL{*uw;rek.,Gd4E$+{2w{Q`;ww(Y6 Q vO;[|יψ'wy_pH8B[EhWgp.58O${Wi+=7@BhzV{ ~Lpd%Us|wyK8C@hIG2 s-AFOQ-ى. ȨmL,t;KG^w~iaF&Yږ곢{zR1adCRReT:,??Ӵ#^e9ֳ]EjՄnzTbDiaF"Hu`2ں#ڱF \^ft U Id蘶By}[qז1Q {l93 Y}D[ovˆ}W(B&*Ae:U"AM1;nhTHii:W :ثz~7in AQy L;Z hi~wn׌vc`8鉺Б `gYSGB|W?9߹B5*B$sbߚnm4ӡz[Amle~tOgy ] Y T:fX2BpW}~*}@r97!MS3֯'eo=&ʴo4J'not;]Ced `7M=g:jHuD&64ځ~G;הe{帀#D%62wW#]???SOd #pj x@_m?WR"DUV :,_hG^5);r%w18-jH 0**T-+SֵJ-_TӳYms:-8lՖ G5T90=cec:|^ٙWF O)Gvmy^~_Ͷ=3=~"Ipxk#Y8;]Wkھ-B`#U2~R3E^3.Zkޅe_\Ow_ Tzom冐ZoU߱{u}{[t܍u =տѷ;kٙ`o76zwnD-` W*Yѷ`w?\;i0, UX^NU# vGaȳu]WcwL8#8JL~GbUZ?'Hmg\!s6~=Ʌ=? 4$ۙAn{z_Ws8ݥZ= +tGAk­9TGxV!>aPaÿ Ac,ۣazvWq6vd=?XPxҰ@/gѫV̏s A;o{Ok?]NyʐPټ~1A0Dt@B`P-AdwI -,!P}a?}ia(CoOs,wx: \:: tE v6jվoq{]"k{/ ]l<30!-- i%eԨuvk}ƸYu+D׫Q wׅ,e⁣_Q\ k1yy]leY`2Oͩ ^hGkYDSlpA* upAF8M .Vn=׽zUSl#U +i=DXJS#w U} OĪ|&wlϓm5[.ϧωЎM2b[2%4 \P*\wn3uC]2{C hoalɔ0`Nhj7WQu:F9GR[3%\W8Mh**7{2,g^{%A^7S5 У*k/{M~4V]iˁdeFeJ0QĻ-+ +x3"]ְRV'g}Ǎ~i`9T G?+r'9mkg[L gjK˻=RU> zfs'XQ#|K;`@m-8{uk=ȾܺyD|*s*E T=:gOD4oq^)`P4oWΆ坭:('Scy%سUtDv$ׯOUߊRT+t%88w}[ n*Ӏ\;>-TAp\ zrښ2g9{=?W֩-p{ 9|mo7Yw!R#c[~b{'|8)gonHc۟_}ֶ͸~Ol=oָؘ]XKo5^!vq!o;ʊ|Fg;Cp<`g;(onb9 - F^q,붶{ 8㏭mZ4mgM^"C>ar/Ud=" [zmף_ Ⱦ2fG=ƉR62,Oi-OGE@A[Ƕخ T*Ti\e[?cQfj˙mlՇO.4坭~F~*rd9;~~"Z@ a;,Om0kF\h|M]ḛK5K-[;9"j`yHeq "(kqzYlwlKFY"\>Mg=nFJ(ӱ zwԟd[lw7o5$meXU8@MF;Ƒw \nb{ ~Q ToC0h<)kzY2T"@GIA3J:rWd(3 efgQT~IpNT D Q`w.-Dx7mYv F=eQ͌"R " U:݌ӽQ5vA+AUF3L~iPsuy3nKP4Ҳ!{X|RE}(BF3NFf{'zȊ|PHAtԎ۞k0\>myDc"!4ڠ5h\nrr.2gXF@JBhikF4GaЏxQk6:.іm#/kYU HFЙXzu$w޷vcJgaeȬ{jZn/On'#,lq #tZEM 7\ɞA@GնH}6 T{.`}eZx9ZEmFQ^ E_{[wa@ñRv4Y 4A(dZ z-9Hg |i@92:NVFZ^ZRٲjl9:RgZC%ô^/b5pBc#Fh=v gc3"T nĬ˝H:s6i8ۚ3se; O>xuu#N Vu aPuyGhg:;e,@DKgW*.`5Z-i"Fle!\@Q l>"M GYFQ;p?&zȢ9ȝuWLdO2! zPu.C'W '~;uqFK EuGVdw;720 9O{;Q;쑡 8N sx*^ |Di's`{6ۻ~]AU'aD`Pߪpm` GBf $Nx'"5xxQ]{wS ̺Np5jd!Us3SEcbp=B j9T.NGϑ+EmĪL )#uMF .îAMk;DA0=7H1[wF BTwMSGG@8o/~tT . 19l< j+D,N|?QAz5M <]| uUEǚC 8[n׽z T+7Aj"DCk`;w!%5΄|A*| gd]\1yd=u` :1S *{ 4M^xb:)9ldݼoɛbOc*ōv&T [VF]7 Hv#\F{eTq,Y ~^zܒ @Q1NN䷻:,e),Tm.添k#MuJr4C&;mޡ Cc)`61fLMKfޖW<UmWWfdȦ-F5jZoz[|~8֣s^ Zu ٭Ux!.= TF;6b a_{. \=uzg}m2:qG;G"#Ӯvz37rTV݆wɫl;1iwߑ9#jX*h{N?`&7P3ۧ=K8nJ& MHtl{ hkؖd!Ҝxzme{mA(Ts]@VB~_L#W+owr,#t%FT+gO}c`xđGT{Bu֛_,2my:)U.Cu$id9rƔ:iY>@B4pFZ>X 8N$wgyiISmB@[=+)W22{zX@R \[x v >- ,$tU'nХ; iZ\76@81a1|"ޑD"{wo^LӿMآPTadȱX2ad[mTL+9IDATρZ~^z BgN+H #t d"R HzЛHY EѶ;%R H6Q#"Š HDВoD w A^?. $WN[2@Ӓv> stream xm 0 EwB\B i[Сtc+4KrK1HW$7 D#35Io 80Vzp%,ǥFj*UCMbֹI,EgC^h9q _I QLQ֭( H pنJQxSM,a!'kl٥9Rr/I endstream endobj 3 0 obj 190 endobj 5 0 obj <> stream x9ktH-?$;eE3$N8q "?bcvƖ-R%!) Iaxѱl}6 f.{/eJO輆cԷiǼ {'Veb2/o"HNNffVmѮ=>MX$Du{]8+ilPr(n7KS$DK2 :Zׄ9zg<ÙUPݾ Ͱ%4Roh]YaVӭLʛT?)`D֌e$Қ@}T&) }{I M avp))Fi<b5*i`^LMUZ❭. 1*V\|_ɍ -eq97Vv>Z kK'|aMpi >[~򳶣 :kVZw6ꁤ̜ayEf3mP^-'A+&VjY˳R95wC'd) mjS}sƚdGU@lYwL,)bdS7se)kz٧5OgYOϹ^ؼdQM ’5U8'WY"vK-Od+̸EžN> ؆VhV|COLzfjj4웮mk=]w?'~SwRTP{-z WDgl.k>n?agx~]%{.抋r<9v/2ťW`?_S(]5]vMؤ,-F)yힾ>Kؼն7߉JHzlKN (6M6J'VJrIUkg%rUp Qq#Yx ާ*0hWѣ>wTsg <U-c3:USTKӟs7[,Ȉv>d+;yl`N!Tb+Hz;>͆vi˦^i692:oCV\h  M3o>)T.x6;E I ŋj5[Kַ%%<)Q cKX771氩T,9הm+f}o][ߙ^T3w㆓o}߷nEQԳ?w^Nw;>x7o86n_0|J`g KK |Ԟ,p'2 5Rʺ:ڔBYpݛWyGUWR۽^R_̛4K zvڳ `ɒEY*%TFKR?l5,*HT*G%҅2~Y8H!3Ke# )dE8qk[ϾXD黦o\^ߛvsxTO۞II'l,-1;M%.sQ?lucϷ]ta _]W}0= Ͻ b_==xOo[K e+P-GC.IyðU|=#f#X,R\XMIZc٠c}EzIsv ׁqxϨ՟ לeR%$]:nOixh]J3ڄݥ B8]|Yo53k"Z(d6[Mپ̅{\XB§]x S.tђ]X.|UMP pp6:΁la3FJ΅%3P-:ѢXl`/tQ f P"7a:lņ/ V,xgJp,1a)Osacp͑u8\67 H*r$T@'"#ᔼrhfu# D<"hb5rh*Pu[d0CȰ76ܞ E\%_̾P"(kWWIp*&0O+r*pDh$LDDj3 ESr {f;#C!N %RH2bޒճKT`HHBXH/'%+CPX>HP22%ayL%$Cp" G#r'&-[X( FGS5H:IX()]@t(aJ'byUɡD(%g``02Ip Q"CIJD$bEz厶9A 0dl yfP(Hdu8oVCU Qeɲx^26F史eni;┟& N*L{^4Fdu22ZKMm3EA> <@ !D{sV} j:eAR1⏒ 'H]n 4M͜筭!KkWBCd;߮ ݜi%(n$ɇ<忨ݜYC6,TZٔySâ{"ZّI.k$NcAn%n.5YvR[K\cy&!^׌#m9FpX~8ך$IY[<*nAs'3Q2J=~Ce:fo)qS\vwXscA}W{4xەxWxݢsYIͰޱ2׍䱊׆$#ePρAӱywxmCzS||R/9F%-387|לgט6=W<ʧUh[ܤt1QOVtzSS\7ʼn|c#;0mS_5fH3z߬ X(6}Ggw݁y7SnAm|^i3'_d횋j>="ݍS<$e5_;C%^0HtS0b @;C/nCw z^O8W0Nr}[&*ut9tMԐJwUǫ$tE~2jQ ›C7:B8Yk_A\.Ycukg{^8K9yvvxW) B X$JO05s3'vK0S:ySؿ11!Jv<:C^`{ww-ƿkYw~CP:y+!Ip ‰PO|?OA)?#qQ[ڛU+xPumәA<R?3=rm={=}ڇ7';'H}H+7%(uboOYWN2k?~[s"]C,iε45Q aI[^kW@*J-`[Z˪%h)<1]Q:5ժeu𘶼]=41 z&op8x]ښn6jA< ',?LU b_RPQLr : I%I'N0mf%͜V@)0efvYroir( endstream endobj 6 0 obj 5864 endobj 7 0 obj <> endobj 8 0 obj <> stream x]n0E /E+!!Ģ=PKX,㴕;_GU[J̼Ke^ (IR*$ |bDmU\$zwŚbDFjsuj(KcRT<3&еokKOp4$gf S#"KZ4MI@$ ~8iqJ)9 ||@>es4| )p8| ^ ȏqf4._1.| ħ!w ⋉ endstream endobj 9 0 obj <> endobj 10 0 obj <> stream x9ktgIpI*N!?8MlNrl)icɖl%ER5W%Ԕ-Rt6-hw-,r8{h)w>9M=oG~(`xǦ)OUc~ӕu<51?\.YG?6 h8'ƆZ8%aul*~;V'cQ{V»b*TN@H;fRL6T:kVDCȗ@sJVݥ>&Uo=s?U[2vk(rqxpp(׷D/?'aC> ]H.{>8 ̋6wU'ev_ / ܛ< s8ga<@4K#wM&] ŋQ;`;Lh%T!xr-F^Zkw᳄|&#;o /~ʰqV/5/˯^<--/$T#U꭪W>ʇ3)҆_/ܰQQ?NբEٿ/;߳{W=Nvc-WnnߴqC[Sn5իWJAHQxN0-ՂvwýuB5U_$!,HRq2;, !AZCp9$$9~$ l- NᾁǻAA: VaH!.ihnw86q-RK ֹSsn2[׽y2-;.!pw1t2S2B\g>uZ] _033wHZ%\F]Rlo.QRW>rJXh N \eQgf|n7 Zu ̜N7t?@&N->M}*(B1T'U H\OBn&˸$06PZ(9aKNÝD%DpFmπ J\H9a3,T۾qwS Kӣ]ʅq\r 2Y z % odCV{5rMfd;w8f%%6CI"@ +kF8DwbJwJt{+ 0EM 4hIn6PW.ٖ{ ,kl'[]lML 2.9Cͻq!`sIb*tA(C5gl9W}}MJ 9lNU}w3C (U I@Gۻn%Qnh4!.ENƗUٛQks]#8&"9y-S(e$9V酀;c$,+`9Wj5 +H \#r2%_0R×K;la78#w+"!&v+hJ =3'dmwDf܃-L֓l˾ʡuyxl`Nc\xl( \gsmT(#ȖRmωӌbB`< ar0G"pQ8b^ZEm5rX$:͡Lz(96GZ{N4I _t=/pRG=ɑW]1*6m+BDnPPl`JFero@4:JnL9FkEь>MK(wYRAZTf o,J~`7lѕ[r e*ob5 x5Rkc9Zڍ-򧩱RbM[놖fC`|Aަ咷r-^I0Cd m[*],֖+A0?jEɊVX)k!GjU"ۛxց-XinihZ'4rMю̓[+gGCn5l:cY|NAfx^Q] jXVÊgb V<׬8Ϣc'ZKr.&qt:h1ŃA&T:H7UZPew-8kA.e-8oAɂ'*X`A9F!BɂTR0’j^~l)o16׶NŒ/T kU7WWBU=hIğͼf(QWmU64c omvT];~ݎ1kLjk 7_vI@ˌT2+y:cWcv-pjLȝ;fvcʎ;(1 zHu)?x9j[*-W6.qvLV_~ _noSʂN>дڙWo0|x{z3k0)#bcԬf`[m,AKmmڶƭK(\ c?h\Ox/N{1ňV/bU^<׽8E~ ߺ\8' ^|׋o2ᗖ G>`PPo\LF"g`ny+(_cQJlHlH)/Ȅ/#/^xy?(X"޵8jiq5Ml͡؀mhhњy6\+0o`6k{}|4CGRA,--y5I0j;{ڷ?߸»'W~{㞅_uɱz_R`^ **:֪;VU?$y ox́o:%r`;!80Vvi I_sD/呃-ʚRxQ6LR6- J] 40=xu|w\W.!_(G6ʿOA Ѽ pXFVGw˄ t7rӛbN 籢+[<]م?-8o=/^8ۇ#uۻWolnޱ+<ʾXRhte:/6x/+\?3?w.k")$ӺcKBxϬM; YkJCq^= D лh{{#wrb>o\oU$F}Fif?ZH4RlW-ʼn$ysqS "c 2_5/*g*AazWRX}sI O "^+r*W)0*Aդ*P`5Tݡp>ZxW:I.U)p s6Pupuqy_+]x6~}4"Dٰ0LM'bYaX($Q3N%l3B$O$9zTX#7LcI$h=fbĄh X8+z*M“GdS)gcx*D{Sē P(7S!>J'3ch4A‘h|2%kp:_er)Fn|*9.k1ޔk2Nh#Kce[T idOOONO#?s4 ̟/7oq_p9O$zO8fF·=>|޵3;82]r$|z wӰt$wMyHIwaݶk;Vn}v~۸xkD3ѳYbֶrC|9BB5:8+Zʇ4` y'I.E^[p}ωbOψ>Yۙ9qlr{=H>J}/xW>˷6ln1 Q?lhsHna~Q#:6O`mm)>ȿ_cRIc CtkR"20M>go0ֲ kk >DO=TKP -Q@Gz<"zH2 ?dfmNI(r'Z endstream endobj 11 0 obj 6241 endobj 12 0 obj <> endobj 13 0 obj <> stream x]n E|tW#Y$Cu6S#L2LJ]U -#BHJ[#o+ W[ow{G4sOC>V"?Q>9Os@>S>Pn<6nG'%%cP7󋎃 endstream endobj 14 0 obj <> endobj 15 0 obj <> endobj 16 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 17 0 obj <> endobj 18 0 obj < /Producer /CreationDate(D:20210613180800+02'00')>> endobj xref 0 19 0000000000 65535 f 0000014271 00000 n 0000000019 00000 n 0000000280 00000 n 0000014440 00000 n 0000000300 00000 n 0000006249 00000 n 0000006270 00000 n 0000006472 00000 n 0000006823 00000 n 0000007040 00000 n 0000013368 00000 n 0000013390 00000 n 0000013587 00000 n 0000013950 00000 n 0000014174 00000 n 0000014216 00000 n 0000014539 00000 n 0000014636 00000 n trailer < <67AE91A23E9C0CCB1F80B410A575FDF7> ] /DocChecksum /B6D2303A4180982DEA5BCA1F7B86F20A >> startxref 14811 %%EOF ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2436626 SABnzbd-4.3.2/tests/data/test_file_extension/some_nzb_file0000644000000000000000000000744414625637207023117 0ustar00runnerstaff alt.binaries.test QoEbWuJpTnYmReOxUbFmBvLx-1623601671928@nyuu alt.binaries.test OfUzNpRoQlEkAkJwUoHxJlJj-1623601671929@nyuu alt.binaries.test TsNlKcDyMiCiNeHrMhFrQwPu-1623601671929@nyuu alt.binaries.test RvFtBzLeVzYhCiSjNkYqPkYv-1623601672004@nyuu alt.binaries.test CyBcLhFsErVvWhKaJbKySsLh-1623601672003@nyuu alt.binaries.test ZtFjLqEiBmQgZyHyRjIvLmDq-1623601671925@nyuu alt.binaries.test ZbBmMqCmJyRgOjAiSgMmFhUs-1623601672012@nyuu alt.binaries.test OmEhDrElGwEkYrHsTcFlYeYp-1623601672019@nyuu alt.binaries.test SkUsGaAkBjNpHoCsLtLiBcYn-1623601672044@nyuu alt.binaries.test PfYdNqVpPpLvOqTvYrXoRbQi-1623601672045@nyuu ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2437952 SABnzbd-4.3.2/tests/data/test_file_extension/sometxtfile0000644000000000000000000000004414625637207022634 0ustar00runnerstaffYes, this is a text file. The END ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2435803 SABnzbd-4.3.2/tests/data/test_file_extension/my_matroska0000644000000000000000000172747014625637207022643 0ustar00runnerstaffEߣBBBBBmatroskaBBSgMt¿+MSIfSMSTkS5MSTgSMSSkSIf˿G}*ױB@MLavf58.29.100WALavf58.29.100s\]u-_ij͟'D@8Tk@!C}ׁsŁ"undV_MPEG4/ISO/AVC#ツU'ຂPTUUUUUUUcB'B@5P (<0Tg@쿄TsscgEMAJOR_BRANDDmp4vgEMINOR_VERSIOND0g#ECOMPATIBLE_BRANDSDmp4vmp42isomgEENCODERDLavf58.29.100ss:ccŁg"EDURATIOND00:00:03.100000000Cu$p"΁GVJ\LC?LFw$K&]KY-;!9Jv4)W$`F1:k_qƲG@=,Jb&1aŽ%GÌƈVIH,naG*Ҁ 2ֳ/(%9DP|6 & A>EGi@R-}n'`1'M' RdmNحL?Q]1mLg@sd`WQ#A& ~slv3_4 \L ,ˍb)r 0lsHV |f!aD&hBh@7wewm\<>K0/hK,`Hb_E/M~h,dz2UYۃA@F7"⃔ ] Bm[؎xoc_8 mcƯ=P( 'pd:$e7L,{c5d~h*!!Ѵ Y4'-)Mil/'|fx˔P1~(":`>ͨ҉= AK@=qvwr-ts/~R4lhIs8S l|`UEECI/:'RP&x 5pC][v[?iFU"AKS'Q` oj\ay q R !X} L|#f&R"zؑ kmC(Yݧ<0Ri~(êbCe!d,kl½Igh8?Og7}d&o.B {,c8xK(ؿqd ~`NNdnRr 1P p \jzeBUÊA &dϴR뙤~ %PCgKar_&?1 97rY_fW7n΂)i`J^gG!c~Sp--.APn1xK֦176@վ_Vx!(ŮZDxb|qmZOvhd m=\0LV,Or2` $ H}A{QJ bܽi(3r_ P-ϛyTGt=r^NƱwL=Enj~2DxIqTCwix \ a*A8ee'0 ٤K#nۃK68.SEgQGGAC qj o/h p`%|!Cɠ}(p{ #>?6%T,S".[ H %87`AzJ=B$Zrr$oN7*n÷98ɫ$]Tu3Du.ؠ<9th:W@W&`q _ToBʌj+cNWKc" 5F\FyZ }unVzjGWWNS7kz[BuNBbUN$d >?|F"j+2*v$)Zҋ1fGTt^ ;>{ Wb%ni\#jʅ Ut9EK L؜! ՞p"$%Fjt2pA/r%E8p9NB 7 lwUe/ h؇% zy<& !->䎛<JĦ( jQG۟|ħ\!rHDs&nG0?bwOˆvZ+cJ0Egl{nW7SIY郚>m!I;;-%U@Z]dֶԝǁ$t:W Dnwϲ*ai,,+;~GcXވL#*]$BN{i&f7e9_։*PVknDKס !t4HŜ;JM}+%Vl {܌;xԬL!UӝҜk0W޷ɰy}(ȚPQ,ñf^3 g$hRti|ֱP%c"pa )F[ph6 g•;T <){w0!3ةPpYs`@֤Vov Ng[ ZX e݉H tv. %`-q~:tL$5$3p]MzR{0M%]A#w 5QT'y+gxg(!xsP_FO89j5V|;z UL&V Pl#X֕WZ CqHBۗVݷkEw3rmoͶzȑo  :˼ V#QbIVP 3L~|iDME@Amg)+<@q- ~2l@6>c>Nei@O](;1[A3cm;k ;}AَNÐ_;@oq,P8N'C M*m5эl"*Њ[=G\%>@d=>.GNv#x,{Ew:8l( "5Drolh/ef /݇W8D l@48'qY] l(lEX Μ!'-(FyYhFxi[΅ O4:椦\r_xpr{%.{ 6M6QHλ2"y&nNz4ÿNo%1wU'k8.t h>BDɂ0n(3jmAJ,!E"O !ORQ\XƒDY"M9oAS8[BpLBBZf{O"l(,42YVC|T88<*^x3I{sH@*ƳN϶B}K }W{Ij!]7_hws#,HɔK̸` 9"9%sOL8t"&ǗJ]ËYO(;AGD=oƚbs  Jzf렞2 Ԅた-E]]80͌bP·# 4mTC.f[+!`x=a/2Q[E^~ρA.ϩ|WTO {^=XBz0M1VRܗ(d\³0.~Z 5 j?I} \uIm(0[Xs;F1;x;y-fPW׷;$٭M##ֵ4d̓ӶA/8`׹SH+7SRDaeQ{lh @Ufb7Fo06Lt5$XLo,I%IJx"p77J/\ɏHL :U:9tp cjllmٰw}D] `"NUN0pj6q]`Ja2ɰ,8&tYG OC(}h_5L3b؍ mTh[N 8Q `s Tux ^][E!U:+}4^̳(&yf 2xXu vfוRd$$*ъ+oI;Q@5AAޔ X)= ]^|vYI-,I`NS0+:P>'`J=v35}0pCh]0[ }1Ǿ6֪;O Nd+TDz 6 7cn05?0ET79H6tM I{qc P:r'x]\k(sU'k=ؿZ S3 @|bA 1L7+˪` n^ЙvqjyW`ԅÁUxO`6O"ZC" +8ςdzBC~huplkfhaö9LL{^t0Տ>{ylLJI'ԯw.}@)0ϪlL|c97EI20 >:j* d.2;'mhVU>Qcd2rzI2/vdO_Kcj~q6W̦'Hxu,z8MĕQ9C-!gXHxM@j,v ->:ݏ1fkZ}*/zۦ b 8bc^Qz!|DZE26G› fAsь.ܠn$c<:J# dV;[qsf͑HTD7~i; փg'C+l *f*u28No)qvw/Ð&\?:90}˟?# 86zueߡ_qp?0?nBÏ@Ih( lJݕq.ֽ𢡄4g'ubَ}힁Kw+W4~FfèQ]BM.>UŜKZ_>zNq܎GƁL)8V`?'cmmSR?8ݺبU7 yJKJ/[{MkL롤t0pMiXؑޟPwX/KtL"z/ӢL\Ŕvg^}=uq-ƪځ!Ӗ7#iR.3^}wj}7T;Y;#ḯvIO=A[L$tP.)vm[jFw# IƱ|CcJ!I Ȋ֞XD]x9;pH)/_OudP^ړ΁19Q>F9AGڦt+0T,Ba7[甿{ >ߞq@{ QڪhlQ_HO@]D̃r}T5L%7 "iW |3T| ?I Tuћn9U'ž'\E 9s8:$JL<rt+x'$v6O:/wFiW?ke/49t pj)#~<c_WfL"ڋj5HςZ`ۭvi*ԇ{[L|?}J}9:࢝H5<Lֲ>5Hǎ7ۇ0;.rߌ>~~)n v^m(* MlpIۑՄCq*eEM+^NKڹ׾:O G(yFkf5Fv*@ 6]({V{C?/'ߔ! Sm_~Ʀsi?^av %Qd S9i[UW܉U" rn4[v!/Ź K)5{_(v w|T9*D}I A3|A=cKO.:b]dQg_JMc'aDiR4Օe-%~MQK5MTwj 0K6%5sj@gPaMUn U:}&筚5{e*i#-iaC~%O~x8(>Nu/TjBdH7q:,ֺG?";~ kjI,@ 1wYf9Q\Ig,`ټAeA*jU¸NwE3L ,uEq>×K?JyecSI6^X #G K!BU;B޶SS?]O㖘.?@29Ĝw$ ^B4]eJj%2nݼia E+Fj0,I/G R#!4$鋔g!^ VP֖7X811fx$5W< =Ȇ*1]AUQXQ.Gt>˜a0N*0_IdFƛTv:Wq}Tt,Fwb,FmJT})VDBEZm/VBdUH\)\ɀEE%MOv5֮_{.f@_dі`C`]Dw[CH+ynNt<&,͈L8zVmlr5A#uU].iG?Ok׍Fͽ2ҥGj5 Rnޟ@b*'dHdwE~װ8_vpi/}1RBsK?,(Em>!BujȜʻ?Xgz02Qn9Q?G/BH_GW"嬟lupNÛd@_i×(MaB0Ra/@"gP.˽l]6FfIKڥ}a%Q;×MT p3([,Z_ndO*ڇ[2 z2iĉO^N8 iRCt4@$K:Wjҍ+ѢN,Dk:6Q8ΐkSћǪhR[Ý|69M<';0\WJcZ0=oˮw!쒺tX; Xꭥ< =ȏ+YΪ .Կ]JytM]Cb[gc͋(a݂Y^75V[,upV nk1fGHR_My1SL?̦EቾFwd;L/)y#yꓵ<hZO=;7cR\K)SMM͵cI cw҈_b_sɸq;z?h zKF\jlt\X]\ቭRI_.CC34Kt1н0{1wWźt`.hm S#ttz< ;Δ[N7NClb%RNAs5D dy,Woˎg<];af85Gh>څܢMvL+^`u m1j̉!/O@$LW6`]&^n踣tSn5Th2תK'S3&!z]^>XuZ&qOql_52LSNP:a_|=QPxB4DBG c?'<݅VQqQqwIdk;ӟ͹UfG$s^rTu.5`c+V%89ҳo =!6Q}IA-d:6u5U7hLa֝y֫c ͌8ͬ404Alg/w]|y3V M7쎫1c.S H|<vj;Wy:k&ϲ>Β w* Ѡ$3Mm^]掰'c@4\j7" ""NE9Rqla>kpC뮸 %Ʌ\L5U̞@ؖFM\I|GTISLlJ}r'ߡ߷MadȠW1!qY+y%8_)[=e#?Sy+q|?dwo|g*ߑ)>?|2NS.UGpr!UWvZ1jjM!" Gʩ'Qi~n?xe:hΪY}ޟGΟ7Ł(ni+Yj]ȝV/#g]sp {H"Ė\Zu:5.yl3ItW2 : sXFj NF|Rl .5>x|)v3T(Ww~UȢ!';]oClj-tnmRٖO!~8ą_=wKX:ϛGt!Ioqvg՝ŚZyR3!k5 3v;Xk816ToR&'٢)y,W{;Z,:<ߗuSi7Ie>2qxnȗine.}wG+H/v{ a bQdKp敬C]uv)u/1q@3I$5BEL~ޛ~k8E>zI$?vH*<H&5=QF?6>e]eRן_ɚL}vm)m2f}W\giWZPW惗)AFSyUٛⵔ:By=`.8`νe'Q`4 _q0k{?E#(pm)FCu'gRfjL2.؄FO\o3aWߩʈFq5MoK٨lMËP|*tm *~E٦Ⳑdzwd?]@ ~ >`\ wC&8i;؅_o28:zo5#.l /WU{r%cO?T3,8uF`fKaO njG[m)*Ws鉩rzW{nCCw]bTnqE_mjzqm\f{xoB-ZԌm]yoϦ6Z&w}՛^k=NZý--bWPΚnut{U0`L]ipFjm[ ݠ؟w|XO2 Ow`{G>/G_ڡG/Rh-[o.1UfkrdHoꅕ|,}4ShH63.m$vr XxG(v{~O|&Wp-YKR.$b&%=e3͝d݈.?5 }$-:TE[ >smk*㶳+0u76A,cYEcAQ`j_|59#}M٢y/]jd:K3ICO R;r)(UD\I~ jw K}bzTIw$w]/ՅG/3 ~OIK4> >noCu6cvjT^7uHVI@=\Ey}C2AJNd P>qNx[4. v o!~|=RO1W"L-)/Õܔwnk^9pECXdxH*4e,F@>0ͰS;A^FZ[uBI3rSSde=vKd7qXdj gOȄN/Ewau}hN %KS(5=++ 蝼>7uyvv qWٙ|U EF܏{^;cs'w3Qyz@<;cIlWNj\+:Zcߩ&_ȻgY;^S5s%Y$2ŹS:BH<;Ѧkfg947I'$J!H^֘xi`7h&?jE.&poӫqit^q[> .Ӓ Oe&HrdE;Bv4~HC9#atϑy﷣|=O Vlz sc$ޝJtEgf8\dF[Q'+J~z"hO(OR>i @/~;FU?z(.J*HO7S$bk9ڰ3Kݸ)NaE{c Qcca_-n FG/ SY_~iVb }w_OէM1t&u č~dE{zfTnU>s1[;p gPdj8I@ڃO2ps_ A{.h!-ͼޞdaqx`OxjN]1feFr+|O0T{?bRr|"if{e+Zftdw/8oO ?;ⰴힿi890D.=uviY&/@/O)0ҮgZ[eRWr{Mܙq>gjxǷC<}~L/Eђ)8`q Σ H$ Q=j/EksӢ(Tw˯kX(7 MˁĉBna*Ll֭.7}9N6V:or1i:gš>zK.xB%yH, H/0mˣw{~I}^}FF/wс{|>gMM lvHH-7˜r֍6ՑQ˲!K¢oUC>Ś cݮ?n A,g[;G]6R~'\wF*i'[&pj":4j_Kmtim27&m[d"U7Q84ӚCe Pw)zvnݚh1+QM1wZTͮm³NF$ۻb,kD-@l9K'I\’57VLiPt1_'kڌVyBaJktKOS%RvW3齜 T)&l6g|GfPD=7PQ i+h8|hv^*_5WN>mwoA? N =5}퓀J8(oצnL/.~ƚ|F&_o%Fen! >M,ښzZKēX|aY'g f ҈}'#&SaU:׆ɜM^h͍|^lVi/Ŀ+|U?x@^5&VkrUj#E]MDV_>0p =%UzmI?J>=E[R@S>r 1c㚍Q %Ε.CG{+(_m3[/2ǚ^[v;(oy2/*߼g}(jvfZOc &ꎪcp{lS S`syUDk?Z:Ƚ{K[YJ`o|ȨT-9 lhƪX o7)9m:Z7Ӊ 3eXa^?q#ɑ߫EaÛU nMP+W5}buڙ=Av( hTVjau@cO to=fRf۽,/As 9|60g,5EV+ڗ8I D#LN aтJ6)2 Y ,$\jdR >HjK> dnojVOÚv_&8S.~oZi,ͣǕkq π)[JUL{\ ^1P.ɕ)9̬0>|@+Ю)^%2; ϣETrK&KJ*5vS"ⲉ.,M=wLDKo-,j) 8;rYx 2`95w+\<]k"1kݯ:Z*C! [>ѻso,2L~!:zrBf[Zt.udW96f h9?Jj>gc{QߪSmD)ߢ>zOxpAN~UWBddq"'_Ί:˾V&sg4CaSB3.pދzpw+I3Od)["2 rzHJYd:}ۢPxGUWin7XBF79vbK53%jf:{dF+lx4^ŁԎ)EN.KdY1?Lvqѣ_~豪cSaV+G'^_U'U*ƺ `%y^z /N8aPem4r 48;劋+~E=FB?Okũ*@.!y5R&9N%r[fXPtMk>v;C2M@5`}o2QhcZ ztieAKZonkJixx5aIW;'_\#rEZʃշ%+(_ 7+),j &otae fI&+ 1%O10bUDbuŎ~=jbQ' c&N%$?ݣ}΍ ~ SN GFlCtp n #3iOe :1}U ⢹95ݾ*Ry6c@KvW#j6khNO_M]ڜwOw_Hq6qu\UaEJx>@ʚ>I saL&4Եܞ32am ?Ԗ`4g_]&zcRAcבc(1yO.0+WՕV}ʓĬNS_W8J LVaL,hkWq56T\pKM&þxh ?@ԢO: ٙa$I3DYVm~WPugYu2}eǤ;;')R\oLw1%E[K&LdsO~yO*q/=8n؍ܛ4vK6ZO Ij)Uu23ޛKMK 龦?^ Ӡϩ^$/h)ߓ'lc|)I2yw86:pJ9 II=tay!2laB8Y9,.}C+1W2:˶:D?'Կ{πȧݿ)a`Z&Y@s`qw{t`a M S |L]T֛^"{0S`l M~6Cʅg7%QzśHs1ʌxrtZ#/~^'07ppeF:>7k? kwp%Bse}'w ̔G߿n ,"3YL!jgpݥyg\3 "{#< 9mOaOGۢӅ$5w AǞܐ1/V*kXp|K|8ƩA>A5M>Ij8Z.M"|ebhrN:P1>6^ k-'^}׃:Sxa1'"b(iD.W{Wޕ̶g">݊U$eڢ@7A\bnDFӵЃՋSȳ39! C<0?;wkaQAA,kU ^o%_*gȼGaikoŽ}ûO0ϼW(GTm+6߆Ԓ W[aҷ7^W$L7o_@i3uhI1d'Y=ܸ)'o+A|Rퟄ6,(H~у"nqί.#͝.}E7[Ԗ5Sg y9Zmq4깓[N 29քG)_Y5f7wrT,7uJȯIJ5n,S@xՂ1ԕ:ã|X;ʝx`-GV9;~Fb9&|pEƫ,F|i0hl?(WS.'$1QWlhF`c$ه|WE\O"9q8h+wžE<`BF2WNIy[_GM30Fԟ aB`4 Xz ˫p,.%, Oc<U$KDKW&3nlA5fMjJR{xg{\n2D;6e .i7M&Wh؊lMQi hTb9Z57EmV> s_)]gܒsd# E񏻁&7w2ΤЧ }Af2TyC* 79Z <沣 ~WYLd~Yt1Ln'(gHN3Д}yD>|c1f.zgHLOg+pݷEQ.=elNfb|v\H8筃d{nl=\r[?Ɠ7{GٞI7xq5x K#igRzcߖ{w rN2] 0=w-w6jpq$Uv RǖWse!u.>bJS9OI8W8TxT4;h*V%,W5s6|1 d;?"OW3˵4Vj/bis9V%ل6}%u#(ْK|SqFGw\Nݯx߹o},ST6}j6n U%G&tƟWTH#kFELfI. 3P(Sq RƔҤoLWRG4w7~{+u5jQj$X`yHy̲x?RO*'zwn6&v=t_jNf{~ 8cJ7U)vPꮏ )zܯ8U[TPdM˺vDIdx"S~5p1/)oq9n'Jߊ\++VCK^u](h I6YnrB˰Z:>WVO&B7 |Uqg voǍ }v#kq8+6iO&iw(ȹ-?Zy*sȚ*@lx7kr:KKI/EǝR52WuȐ(HCgHjl#FVwSoRhj3揬j.tA#[Rj#,:&3Ը$7#s8Vizܴ\K- {6N@p-lJ;Ԝ]EIE|}+gz*4i"ɞlecrJ3exyX:0-6lyOd*MjnQ`u]_ Uq瘽97U׺7,} w}js,m6OюMæfɦ49ϣHM7*;p !2g>f* 3x;ئL_y rѶ_Qfqiy:~X}r?ooЛB E;+gQd=Y|Z9X,5Q͵ ۏhF>v\$X{7p6oDH[8Sj#dld?&<ǫiJݬKo'xn}i;O"Kc6xSVu6s3J;hI[[CK7w"^Ic[٢o [|]gn6_Wf}^HTcG &+S!'ҶG ҳf:㼭@K䦀Ku:ޘ6-h@Ǘ`yTE:zQUՅ҃kd i 0wlz-SI|bXzl+i# 4  yӊEa>(zo>h5#6ƢjsO1<`˻:hZHSZTeFVSۉՖtal$aȗC{{QW6Ū|,Faq<[Mw{ԘE8C;WOH|η|wp6èq fx{v_q C/gs<0<|2bnmG= \9Dt\k ]>ɖii7^Ms :e@UO~*qINM WR"nXF߈}̘纚Jӽ~W<] ɤkU@ӶqwYFm xed+s ciU>iWkp]@ij(evQu.NeVR9]Y1Ի&1?4in ol>˭8)1K16Fa콿Jf FUlexuNvFܓH'Y|?^Wp}usIfxF~z9HQ#5\OHbzl2t NyT_EOvjE)cYv8w)]ٔFmvߴ++ul]ے0&CZqSێ (/=,|SwA[?Us0>Rk%ysRU:m7ODUzݛm3+|g RwA˕qz\ F4OI$R 5Urks6>"F )ZHt?&C0]} mc\13$6۔SOɬTLFj?^ox~aK7:9Kj7,:_,/[;:#y`y1U3dkQ%2T WKffb*l/Ej޺k}-LW6~59zY}.k VHLyxπrbYH=|D0clC}h0ٯc򿟦N31'ZJ edki=qa(m\l9=wt }m7&x5Ӆ&%ӣp7 w{g;vM`Yȋ}-D/.:#x3~}IUѳYv\T,āz-ϓ]æW1 NǸ 8ΫaX'u s3m0pZ7:i,A)A§_^-mN[y;U+@l[eFl\zP\nVJs"o|qώ3I .Ӟ捻p+TC.{w_xVEy>|¯S>DgF=й-Bb\4Aqz̘i8F?nZ&6{>v^@w+D`L'&g8v6JtӃ p1Կ2lQuL>jCeB5zM.fU1>{dz(2*4nX2v9m. efO⚫;T9}߰4_`OɌlUwUKF-?6Ŀts9zeꓻU_FHkUF9w04nSƇA1M{>h/zt'N<^cNNN7a !i\Dm-r8cd=Gbw^0W*z sʂdw)![QApσ>Oc%LM02tuwR~Jڰjj/L^=;g_5C?($rhοOx `kۖhL~LYP6s βқS?Es濔/}^pIٜ[_Yunn66l\?Fw߃#ϯj΀lȗ?a6&~x漴sNeZsp&M+m/+E?$moM U[Յbr*cD]{P\!r­ߧ2(ū^yyFK1j6 "~Q`&'o? G$%f{ufWgD=# B2_=tkF*/b>boOW1}Jۙ }S&d.2sgpnTJrNOMT۞r8Jc8/t[Oga3[~f=Bg)ڳqѕF)>+z h.l?hZQ{i~CmԭYo=!7OK:y"r%)$ʧas#_>)Z0b'{afX!8OObVjթ!΢؊G # &7+ݡLYyQ/@8Ocw-ڀC h;D}ɵ7e]~JNػPlMnzC_=gq_UvGFN] auy>YѮWv pQ{73ɑh[AJ.4?|VMgc6uWDW^="5TYg' 4!+ٙ+F>}S>X`d)kچo{cgO).tD%HϳebXu/9㮃tv=uk:6GRRy_'8>{m XgRd(LnӌOi|sK&SbwJoM5~ T8NYG3a*nHt3|**O9', eጳ[t5$w;K.;tNccsvq7b*'0Z8Ҽ_V_禐BÚ׉eXn2 ƅw<]UƳ(u[J:fj#&~jҍ4;# vsL3J#YJf1cq{SᗣhpN7}O9NIⓞՊcmׇ| bch]7'^l[tq t [8*8Ks À_B XKm~VҦ`,uVsuѲ5N@L=~;5 |̩?@|{8{j ;uA|ž|ۙD!4 Q."x,7U S<6P_m,OȺѤѧJe6Z$6OU]diGȴK#k<g88(/H3}B|YWnMzS.EyChC >ͰkԂPHbЛqO򽯈b*N&B)rAL4Z4~R3G`WqACƦ;aZw))Ji FKۉ@)ԢP)ZRŴnm~ќTU9շi^ɾF~\R2L\b񙕞 8O\Ux́J̽?[/ߕwlgEG_˚&X/OI|E}ڪJJNT3zf:^)tt2c/c>U|WQ.>WOF͔w=d]f6/*dawqaz v2QC`K9si{\;tEkcgX.]U9l|hWߡJ}^_mCuꄊΌ$šO ޣF0Iɺ]x=7sH1"DMl!A="E=tCe;~ |O`iu כjK2c/D3-$BSUneE!擧mɑ9hM*Dey>zoOY˭P'1/+7kG?Ow&: 3*Ok(O~u0_TӑI1N~G}feQST )#әyzr767[wqT2'WGj.s]ʍ~C3j5o9t|ԎAuRŹrqteeB#4@+C{$?.L|6֒"'oVtYХ0=qiѳj_P]?k&[2N>9g;iH{|%Yj0FQz'3s ˎK;C#؞qM 9ZM]xڟ`~L&܉7S<yˆUU6ڦ_Ic6ϡgo1il?>4iKpQ 50Q{qҁt,b 뉊wcmſKfҸeIAyf= wty}˧)+'kn>"{y!bM«N"AR='EaSᏊ3ؑtW ?}I(2#zehN"He:DcF;wObtvM TIP;Į-(Ezb491cCVHeiPҡlQǷdWt4cM< ֟3NMTɜH4H%N<֑o^8@t=qMfΞ|_ݚ[&pI$^'|hfY;z40&~] w<jE>Xaaj+܎ 8ma;Ǜ#/dnC$swZ H݃rZk҈u\O-r~htpZe}ΗBo#Yw{mZ~ُn 6,ШC˓UHD0gڶyYI]_/RuI\rrh:}$mSpJu3򇲻TcR5Q]7VpXa 6 |5D,$I 0]N=M/E?_z{)byW"+9]n>6mRݡ,QC|ڡ0qa633wsjwIL=75~ހ?,/EbaQi )S EE ؑ& "]bmq?Rl#cnt9p,A:xmz{Bcm9막u,Sö+1g ǧVIiI.l~/$;ήoc@Z8h$oĆ>6}]l\ ϋ0$vN[^8=c;Ym˩k.+&%#4rG5, AOO +vR;kk-ɾqtimGF"ؔSc)%KƿFt5n *c$fD 's6X)g_`a{6-Y;]2$1:DBo`אgo3z%ro#3$sy+;j|̹ևsOS#h8"!LpC%~1wѓ ]:F\zr:Z9uq4qC $|r5h8 W]^2{t{Qr),ou"㐓SY3cUS߻fې;w_(˶t<;ExT4_5Tn#QY1@ƵH.34=j"q2RԔ[p$u.@rcvP1`Gpλ:]I7q<tWZ_C&؜6`j jcM Yxݫn[z X^Dr TKs ~1ؤǾߣ_GֺE4Ng\A\LP(l=$uzHa50kDݍ5lS.K!VH2Z*wS6p&CE+mPƹ54:Q/R4asI>5SVUz^1?XCLGg87CiGlwWVo{@Kԍ]EU]G^eOi &,Kϼr$4;Je8W oJ@ߖi2ɗ;m,}+9FJutWN 6ǴwZ="+뎁-M|jE= >%W*ߪ KL; By~ly~suCQwH&舜ǡҧ|Z=̇glxEh㢣YR,#gBm|m7Ra7CQ%TiL^L+C4A̗?c99ԮLU|$f,| ]V xՠjZneMJ)GNjOѷJrURboz,2672 fEE"#ٸ792݊ʱ;ɐi-N%HdLkZԏK}mi:3rq_vr{\6L<wg[q z/]mXWOL'a wޟU\pt)ZN,*= 9RMj_5vڧܤ/jfƫq?ȇ旼hu?O; `A'+;r{} GQE*~TP;ַdL'%q5y!}[mЌ [fզERIa[ZxOG)o!rlԒ,B(?<-9[[SEOӍ #wd{,0poj F|dW&ZN[;ڍ5=*6~G>ga7|54cGd {fo1+ϒmy!s-G6uKjZeׄ{5U2t%E:޵k%4h[<]KuDCWp}c0ʍ:iK?_"ej)rɾ$ 6+|O^~OS5r1+O]:=LG FNb;UR+J2Lڿ+!i9?" S .iA93yU}HRY=0bfl_Z;սv* ²O]7(}/K+}}Onؖ_Spy՛V_ߩwpkej,/C+ʨ=Ёd*n~H8kG?t:_hʣg<ٲ?)RzO=c7T"wWFWxg]̈́z ʰ]?~O !%ԇ\42vܙt//hWLM6䎎Bes sfF|X*b0osǦi^FSަs)cp>m;*ovI)6 nK_zY tJ.OdjZ[oS/tu;Asޗ{)TcD[ }dդWwC$P ln;J2֒]d<}ڢee8{I)mXܴU~ZUR= &0>nb.O G-ڏFY' S) 5MmP qbkPĭH%[}=CQB珅lCkHe~i{^~i:}v]ЦAr$I;z tv^i<6٩DPcj>^˙2d dhuٟ\sR[M)R7޴`{lߙ \nC3KLg3FK>ֻUFpm\w"_YMt=GML({ %DLcUk bC_4eꞨ*9\V8H>ݴKP1ʔK_GϢRkњoG,tʝc9a*7pvnZ9,A߆ahȹH{u:F΍+Ku%tNJ/_4z>3cBٟFI9W4 Abq|Ej):cu\ !';M8,Lut{._C"'4V>xcc[ȞjoE9*ҝZ,zdc~mB=ST͑i,tWmv\Mxv)TOikkYf#E4Rq5tWFҏޠ?VUWXZR`N|_VT׌&2ɿ L)'zU ToGk鱥UOú= | [~z z)_(/0/eQw9QlhE@}'}޼1xLXӰY$3NlW>ǂ]jOŪ5*:ԵqeI#^R98)m/֭6Ij~FѷJ֐쓥>_Z/'hoBGdh ,W[m"U}yKzva#F_8)rY?_ BsOnqGUyAb*d[t_~Nb{Oaԙܯhl_4b/Dmg^krQB %{0+fs#}ĝ6ғ@ ˖LL+ld3Z'w^jCU.8Vw%rs$hvfI0(qmum-uKuQ`A>\qW*ژwk+]2 kw^D,7#SϺFPq0SUθ BP^?i"uyݽ~![[ Cr6d1Ә޽yByYM("[ adS[2>Nk95AU[m~Jb}Y:ӿ"FpUo(́>G͝(E |wzfbC22#ĎH+]8.S:TX4uWO?ߋUKF423}qG8JeKxjS[e{>1k3dQp`+?IbK ;кU5rCLw5;VS;'- B>I]L*+BT`U8QS">>l}R{;ʺO.}Gɯw{㹮 [cYۂfK3yOp$r1^flhʈUWtNL ߦמIbKcY7>^eq.3!׉v95 f.o;ע$w .O!\۴}*{6+v:tr" r%n\ 7lZ6cJJyn9{.OQwwa_lq,IᡌWBp4觌%|Q"UʝM3ʶS5EŵMw,Y$(ޘ{Yə䕁jUT,&|sU-+uҧcW_ݰV{֮kl&'$qL:}PWv'U>*h-E6Λa߮^i-?$0J{ӜuybtA}K[vũ:N+'h˲I5{22);K2oO7Y !V |еw#f7)pA_c pJK!Z|=N%1cJCû&kI2K{gv֪z}qڝgnR-SFH Xjvh:z5|̓f׀iy]ǰD9NshuN^ơn# ?n1ߨdJYoiV)!d;R!!t;&Q4V~ZZU?%&A$:TҜkUg[k@0)P9eا47noB$muŸW"1WAaY2ܕ=EIUNv#d#n(r23܈S 3񽝩{_|7֭4U{$N%.rioV[}3Mrf8i?Ժ̷ %yT8Xmx%?Y[&"Mu06}WC(Ϋ&% '(CpF뿕tܿ:_>k_F)W>2\c~+q3ȊwlkqQca W:O+nX[ޡ߿@;gVJٚ43\sz9*֪bg?9U?0YOrutbJY@^׉1e,-\QQM3E^@: sΚk]%/h.j6Drˍ顏z܅p%_KOݱ -ϹY{L>►d=c_N6쎤uVu^SjÔ% 1lYǿ̙%Zn* ѐfMwt Ʈj9lHVowR5蛁W^E'"X1s芕\n?,OCFWdq7rNٙ5oԥ(~T5S!"wH)!w*ɮ^wqO,$^Kn |ABWzJlCRz~-Ⱥ"VUj߇P@(| Zd**|r9|6OQ5QSuH,Va[C,,ngN")9=Rk >,Ğ [GES6:ʀeJHV̦OdXO澱?\,4NMqPӟYT|Zxݦryl9>}>кRv#w$,|pA{ xEqv)vWov{ t/ɚAu,ic 21Nz\\RSGxM' k{JMD-2sn=G =t:FuU#2Gb}˧'f<eIEDdH3muΠVΉW#nO$_m(Ǖ}b쿽Ey~t%J5W[]1%z)+6NPy6VA¡89I7ݷ"$tkoY~ŋpKgF a ueoNJ#s^<%NHlOSg xBʹ*$y:cU܌//mob 0\^x79\;Uv䃀=KV捹"L:lں4ht~\tؑzyo}:$ro$ZԼW:GGM?:C%ġ$_0ʘ6nQ )>a7g~* T!va>z웡, *Uxe`EV5J<{u)pxh{}BgW$PqMbtSt'>njG'g)d0a3ə*4%ZaM~ks:*D6{rʳ i5fn4)MmհSmM*}6.~u&ei?Ru#[?5vW72_꟮90Λﵤ#lzaHR]Q35)CgfM{ ^}Jޏ e;]j78^n>EȜom` 6C#c }CN|iʣZ{cTYr6sa(HAd%J$yFYw)xc 9-E˷JuY't K<2 .ɽOtC4ʺ8_ ڟ?{83X^wz9=6n)U݇>+|CjsQM3@Vk? w梟NJpF6S\%?]N7jg^ TFx@W1qZO7D(O]qe2t/5*\;3+W&&G2^Sa*ui(hi͢%)`=QN^VǡTNv<τ=g "WzFW~WhﰶqΟ}#: kښvOxЦ&`;PY/Օ{'puFR+Gҹ*EM ́u0T0D'k|3Q/}?_jn_7IaVkHtK!Yf"6R?7;{}= ؊M$pEN*˺i.%$WDGvdkC igP-z晹KuFLm0)7ǁ4^ݹbˣ;s`_Yc;_ͅ Mi4u2򍛭Or} {pn/GV-{=Ϫ[@6pmtߚ4%4E]h1S{F= uf[o-+o^.'{6?O["v@n컓kNfY1#|əf c>n(i8 /EEo'#Ψ {Cfr4e,2س+*w +P>^'.&OI?es*s~|+g8 bxܟ `/*ҏ殺P1D7`/ %瑏?vLȎb1]FUpQ{Үn_n>=銗ͺ楓__bUn>nF&FcKڧj'[T!ƅn]Ѭ1[j^{4O/O-3HpNod3k1v7H+M Z"ԡR>G_F$(u\yh^o@Sڄ)̙ZZO#} ©%}n{:tVn<f\l|v)wL +EͰK61¥K %Μ٘m9Ӗq'?,||Wُş(G-W#fZs,~FQ])ݪ삪..rI$S;ZZ#cK7 },$^򌚗s%{8^E*j.asԇJ^֎*NlXd]Ex>LR{z}TKGv$O'?,hUT7F۟4mՓ\K6s0;;ds };Z_n٤Sxls6RY<7&\oi/R64Q{L'_c8(8isOhم: 8?PF ZyM3|_ȡv:Uo"! ?|"dM^Zbk<=^7]s"'Ŧ9,_ՓˤaxYf? NܚjӶCu2@˝> Z# Du]|Dѕy>6&f'ʸ|;nP9r,u zxl3}z G1iVfXsIyy+(ǪwWe_~.XS%?ҬN z۾Sўgvvxgi 㯁L'5TYnl")Oԅ|tuSs5|B}SeI5.u=aLk#'̯ҳwXPOk{̃R|Le * /՟ݲQE?GVwZslGht=k6P9Px\D-mȓ b A"[a5#5Zc _^:+0NJ+:*f8|Db0s&F[kQE8)?{4@G궎W&JXudPg;-ML$< $Y1&TMfZq}?2]n &yl4~3Hȟ&bG$KU1~DO^܍^L۫;ģ/b/,[-tF4WSl \ڇuŠjyrWrV3 qz ;\'WvxJi.eK)IMAܟR[QU<U7Χ:{}s ,J=m|iėNQ=!d51PhY@9fvJlۦ **{4?!ضzgVH;zp&lsӯzV:OS®RS锍{tݻٮ_W—?IpoνΕ)s.5iQDo GuΞ3]c l/Jk "|]٥[/K_'?N}VHQ+8H[Ƣ'nFQ+QѡfF NaoL]%?iipV+bx+|_{9$شDGߙ޽'vB)YE5CRoI I:=%.5yB8:NiU4gs!> re}V>z"4]EMwvuG恅})R~NtUz7D@ws>D[|k-H9)^ e ֺYr^_7^vrm9oe>g~3|Kg'x3'mNl.B3 F*bQ )d*d?M{1)%D0,`,L\itg=-y$V< ~c;|u,>?ʀ6{Lxʏ' ؔ OF =(K Ugs/zJWWi.G8Gס oCoB4,k {V@!j-Rj9{dW3\%kH9 k.(/[ }|9^>|ͽkC:V O:7rܶY]`Cd iǃLEݘD˿H h-} lk+{k9;#{o\촬<̽q|gLVG_XWr$a-X:kQ^=CZ#2+e@D ~~4 j{{plҢC 7tz'ngDW.L!QHb_KOh֯vUEUQ ?I-xW pDЦ̈́1t&˂bдq$HTwg9Ɏnmx53dqߗW{Ų#x4)W_~\#;?{ WLt49ŊVe!y9pvN~tPN\]ĆoőbPUqTu:jtw݊|i 8CݓIwOLtGQKz~F>d kUY+/$wܖ*7uYSmJ+&s)6j_)u*0cF΃Ih{?.0㘷bM*԰>Uϣ*, }_G}^K%# Kk~=S0b9s~-=$?v1Uiaba?%~D7$iᝄmDuTKUy2kͶk l։x{ I}<=G+O̥~Ǥ[^咴Q- ߶ˁMzJKY"W7Ml[5Zm JWj}vhW251{5P.Rbg+;!h[*OlwıBQ|./Z"ǧ4#.>yL) 53+ paK+iT՜X^u#JjLQuhDS+~` sډ jn?mW]2`<ɗ8nB01|zIJ_u߰n2J`*, Y٠7QMb٘G-r?GbV*E.5-/H }WG-v⤮JkU*t߿2^{ |ei~ tB$xSǴw:cg@= l<_߇VkG99n!Nl|+!e.K'f`MܜFܚi' B tm~ sA#~M_WT^ĬhN.F LaZ~@HunvH^ƇM&!g'վzf6.* 8 hĵ^k<oSts񔆄L:g%o ^GHkCD6:b-[bH''1{wTisV_Cl Y@QPd;/"i ~vlTZ[_ww!:x%OhD3;m-b}H|4hO 1߯r/Х69}n%_-N4޹IAP0BTL5.DWy(B>'xLpZ8-+6@2ڤdD Wy Wf+l\-䡺mAa_T8ޗOa{nƪ]""|Q~%-&)%flJ_V<#b}k5GYLY_BHi*_@>58hmۢD;&`ۊ`}47i2c9-#nR>?j$ࣾqS.b`J>$ar?aɣ\/Vn7c E mot_Tc1h &',p`1R+~eqh&&[va{'ό#%}&ᨮq7HPŶPb^ِ"=N^'hEM+ iW>E ا^l-2oɌ9jB6J \;{͏q }VQ='sdGyGgn\3 s#1??(?^uZ>,h3Mo3i^h X0 +Ѵ(+IP3UbV p;;\_Ϫ&dnɿoUڅ1h􁖴 y通F^kJ]a|nkya!" 3|mŎ3XKvh{Abi-L]I@*d>*M:[&)k]y韻A|Q dp K'hҶ91=:wf~޺_%Rn𿛗%a. ɝ,)E\**[GP%FU뮧(ЧC0g2Woy[@bƧKtP& V5{6NK̺4/"g{tUN)q[z2mm6/|ZˬuRFoU3qT~AYctѩC@$[uYդPwҺHe֧Û7N"½}#'M_~ ;M|+˙J/eF\uO0%Z晏D\5oΕEg}ҺVcWnI$4m)ݳ"/,uoA 3pr_Ec+*.Q71Khrl׎{F \U]5>m_œX?B#O|K?ABfTG/Ocu}P+5M]QjEea/ [O@ܤ`;ήV/V~#2:yɏzp+(dgܼwZw&RwƟűGMUI5&ߓ ]GXOWӎ'Dže㡥#s?yc^u^kܮ lo) {jWQ5TU j\F5')HFCa"0 q^1XOF^ ٠7I,+h00 PEQL7v;AW Z0+y0,tFu!^ީE:0LSL>)XvFBםNv2Z-(}t%zۯ"&r ﺷxD-؍{闺|~UEvBi-[J(NEZ_zoTAqTRNx;:v [UaWeQ}G; V] o=d]ugFA6B"/m]QrxB.c32Ʒb3(7n:Z"8@o#YK=<tP3}$'ݝdi?<W t&c|-Y=Px1֙d|:?Co;,LVGӡq$gYYtx- KRߝFnNxkU*qIǺ_GQ5Ln,Ucšwx v$$P`h)F|N7b0Qy6V,o<贝'v`luv 8@1axo`BNRhOFx@G ddGj{џp3Q?]_Y^uw̟(ggT;{6qvUV߫hcCaBO [tW>M )S-{H8 K(qI@R&awgwhL=EDDAN:͐jߟ%kOf^5ڃd䶄ϑx%(n& M[ע{P5=u*~kſyrI eΈ;N* \R#6n<<UQ2Iqms& ,p/ftٵ2* XhA|;鎈զNF.{1Eq;9KZX$ў)i &߸b#}feAU^6-lR&w`k#Y_$d(,HxdTG*Kt8ԓ]4}!ؕE~J%d\g+<&A8gAMʉ\[U񽍦İ-lP%0CE%͞`)w uY}?&[lFdh4&%7e=ZxA{/dz-'@$#}nv!I`T]PXE,ֆb\翃7n1؜Gzm"Gwpgl$8 ,-Ł^%SBUGqf]`f?Ci ;bV*-(z}zg)^GaXNE ?>0=$d?݀QW"LVNcLD !q Q&Xzi2k <>Hyo˖M(!`u[F_Ē6l9D9צQ ݿT2g-6\jLc7Huy}HX8'1ڷGM@D:ےci^ |N Y[ʷG偢sqlĉz=Yo7xoE>, -F,Ǝ3*÷Fjκ#uzgJQ~ڪ翮$q߭$kݽoXypDOTjz# JCbIGHJkaH;;|>7cZdgڝ^ZsJOJA1'[ap, ^U|VO,gV[FW9tEn8gPY )T#,-ۍH߭x;\|0^5j![h>efjTﺯ <-o7\%HcMj H;Of6u![~xͣi,.sxZfRG MU6O=bxqg-nmCh;}9HJN#g4ڙT46Uku5E}& :b +pDZC !cbW[ UqNyBWzCD l*f9ǕF[T|c-k~>Ѧ&OAp2 >춤(\2B_f %J2t7jߪ?ɕ|)F ]?kD4+C"[b!FłwN*3E4OD[Ѻ* '`5TiG1HeC#7}S{vr#f"'Pý>*F'|əQ@c p_v |Uu')"!c?dF=MOCՂ,*CF}^~R a?Y_VX~Q.ho$ NJm]=e8^튵YMϩ1%0-F"l֤֐<@s)6bK˓8^i?uJ'{\KR{1CQb́ %x}P )\ygx ɻa߷ҽTՙxH |bÜ,KNf ۪Flog~|N?'pL?^ufsgdKXs?8]TR܌i!^v:Ofs g;vD J0hF&uG֌밁 .K5uK@qEk)p1l@H#[lQ ܽ?/ ,iD=fp{(m_8 na:Z.K"cOoĎ6ML^LUǿ^ḧ޼aHH)zbgnSQK٭FY}F2h򣭅TYT&fhVnnvTPRV>Z=t_ЋR6:Ps ʦG]78!L @z+Lq\zAFAw 1̿;~T]%/*3==^i(T3{vj|]\uSGmz8K%}_V:wT5A6,i3Zj0<)vķ(QWfn_=5qbSNuY:8,\l{ȇ埔h>vxF#޸:{*OlA|aO; 2_`½r̿)-ºҽkn_Ɂ xE'ATS'm?,}RJaXqLoR3CXǩs5{6"F臭Avj9&(3'70@  B pV6+@0 :|Cq}.D㍶k݇hVܾ`gIk؝/üagE3⭽ {N=aG 2IOiJ13f/12^ ~F'JۤsW7xlH!OUNU^2θ[lBn%`~(܇׾Vm7<õD#|)&Afϒ+DDcr W\ {nV!v*z6'j uէY0XFŝ|@T!AZ7Aq1KGM-1"aunC Ayk ܱ&G5&\ 'VŠZȟI־w~iGoCC4KS?`L4 Q3A3H@`@HPG[)#= Y ’}+/l&C%՞ӴJ])hu {WW zy_'?{y: '-a"( {๰I߄cF))9zKcA{մ?~(K~$bq$sqL'ޏPF5@cÏ-5a@fa軞#6@ ƣiY|ʈ4X$k.6{4?@A9þS!IckC5Fֿ;qrjUO=m ݲE# 43cz]gC'_J`xt"O_3[7ƌqrʔN2Ɯ? &QTYAۉЮz<~iH:۝^cTSu+}aLau (Ѻ Uq;ֲb,H+;3}UI""ﳱUcꓤ~~վk\o5ʁPP/j6٠7uGd~ ~tqC=?p #s@? Yd9MnUJg}gP%z[9‰wVGBo~e+&uEM)!A*nKGƲhR4W?{췈9;D=Yѱ=2w/Q٦ OH$j]jqKC1x7'oh ܎ ?;FlstADTu[XȠջT+x%>G+oeN'Ԑ OVK/AVd>k$o1Uʮj^)8wxN?u5` S?L_W<_6mztR!7B-m0250% χE}?PU<@W$sFDcCX56!1_ q/u?O n[ :Q[Oݳ ٝ'lAxl=WoPoK0@ǣ'ڰqGŠQ7r! ;EoX5wbd'S]TۜU}MYbgjIoZkl0}f2}?778xķgx(JO߫a,0| ; (WQ̥>4A^?USL1#`Y5}Ȭfn=QXk w m0Wx-i1:Xh'r-1?P⬟v TEInXǁ!dȂݨvGO<( BxEp-' VziR+Re|P^} ]J-YUQzQhp-y]tfn"?5 -p=evt[D=u{bDF_ I  wcH Фl9@+C^d@v)>i p3zUiQ]sz~o^~ܚ H7T$Rȥ=Ϊ9d~LLM^KjiE}^Ǫ՜D߽&k[{N.@ diAB/yEXitj8/|PeOETiA&g@Lt%큎j0mFZw$~fjITY*'P^ʿ?b]o0cgjG}}DJ!Wxm*T(n*KОŅ/#yΟCejϳ332Ǖ3824WzY{.[f29ڶڝ-jW .bqP㐨ZsUC@v͙//grY:pawuts%gT/dOϜ%4*ȣ_!)C%5+><1F7/w̬hSd@:p†K~f.K(^z[9qz# .DNvz )-$%7}R+mmʅ%ή]Os#~01PnuE ]رPKAAcdF̿2f^ח[>l5x(FRv=g{ANXf)-9H_R0cK1H^IԛΦn'`z'IƭOeu^# mN|6Kᣀ9HCު:s.&ѓW8L~~ 5[n+l#4&~D!'#+8$O޸(CѱE,+'C&={PRp7Hv_s{:,6Tw@o(jp\dD{׵XSH^ɐ8#Ǻ/ul,4Iúg6v+(tOLKAy; kJ,0i ͧ XVzY } Q[BH*smrt }sBU?6蜜;m>Ws%Nҵ$to\M?1 ۘSۋk"-&jKzJ]G`6há൹G3߲6]-wwn7U%-I틋 ; XUerhgrϷMhͷVlQ1P$~0 $ԙ%:E=oG^g?5vh.nCGkv?X*sK.<5km՟g6N3\,gkX%^8lJx}2S5* }qOiQTj;)&b%]Fp"$VK?}uoH`q_#~kJRC\Ba_V)?'G!;''=geV&iƝX0ޠ޹/nL PsGd]X}V*4u-i)VԢ ̢vp/q>h+@ +$jBT53/oST9XM:ntpr_wk5x@,uuˠ &T&Gw%HC[7{oxYcu%7Us>S= jj=Piq]og/ggQ(Ft+)/ooj7U8Ǔ*ز_xڀn~O$͂t +D(|!Z~Hݜ's>,CBLMҬwvf)>;L^.Z$.UP,K3ޗZS5 Y I]O|89#ԋ"7s13!d}E73ډ2G  wu G~nn̢n\ M:Cu isnv?²䂶I(C`ߙrtKywp$ÁE4ެ>h >yDm<ITa=*nb}{2tʥ5in;2@ʩSu.ѶՑ:2f~JoK5?V*uk*hoĜ/ړfVdL{9FdA#t[;hXjd;ϭv4qGªcQ^ڛ_$L5~5k*2*gD(u 1h ! Ȗ@8^/@ԧ0|s1rDťkesXrYiL!YɷUGض_q#pNߡ/|%XPY>ix`IYoNj 2}WV%;sg qWz cOG%zh̩'97{o?gpPiORD EGί4u),`I;ee<-ŎӪCzaٓqHRd-=x)t*]P|@2ISAؿCEd܃4D=:sOACRFs<1Dy`f0t{ɱ+:y*]=@P{5,鬥:dkvf<^SA _5 }8 1{ɞ"}esJ`+޽=ԯ$2^!k)\|K6J)<~t !w ,~O`o$,_Mgw5Pܝ3zt]!;YuSx9+g_QރQaBḠr01w1b</?-r1; D>:j>7hOa,mڬV) 0;!*:;-<‡򽘪Tvh:`o?΢Lk0j3qƭ G1L?-([$U@6aei Ɗ8t?Uİ歞C0|I__`M/:D`EG߹9^At3vԹɯJn_vO^ǰMVn|ƼcQ"W=DUR{HZڢ|AvBOMTryk0,d[AWm,%#\ vT G2Nc1$'U:ܨi?)y ء1'뫩Trg*BAU뫆2s1VT}I7ğN2&`#(Do"xoKb4ΐ2:B7 ?8#-`zyNt$yҟʄ$!r`#͜o־2{ #q7NRER^`n^6^OpZ%_tp Jx#]@GlԧTm'RQZͧ2?UK GAHOK_^ofj}^}A!R>hgҬ'ȺDb:GvPfn3QKrP)wր/p^o "-e-?ԠftSy)x 1'/-C"}X+`#p^B*sv o[ghxwnOٿER!()+`vN2 ଛ=ZQb %s"JnR.oZF#K}? *Zv5L oyL{?C8b]R5Z!!3CZDZOOf:/\b46 apos@ VCXݑTqv?~Ϣ,t.:ٙ sy1m@!EX{S`a<fdj7FY+z*\(./tH4QW摆sЬcPV"hZFx ÝL7|Pdd{xz? 2=h僮D#x:b/2r`ׄy+kӗ 1|>WSw,X(:?5\#0wFOy?S*Îeppp^KcN0n?GFyCkO"a~#m:Jpgl /VAcoEFHhۆ3%zhBeg#bz9_(s>;L[ZTwΗ|r>ʠ \NyBV/4FcZj@H'TT .~D_>P8AMG 0h9#pу-2? =$XBR 2_l# u]ECV7"%L!6ѥs0(gݩJGk})s(F_c[-~ڍ+ґeSCv%@И*b3WE),H6”=B+9 u qvt~N7+ӟIDxuTq2􀑩9%k|[85[ 6&3H8(EQI^F$rɴuJ$О\vsfUMQ*Mox&by<*?9l=ΘV_M:9IϜ*WIyӹ:}|x1F;Whhu{тVI]^CjYeS~'&EfG:oGl Oҟt߷2M"9r8,a :NIv[ӂK fTM՘ͧ­ȝJ1Ȳk\CwCDDO7Z!G&4M0 %x@ HrV?zaZZtpg(^'s-ZFf45lt}}X=3QN϶z^֖Ĥ(6 k%=(1A+7YN7īt{gEnrӭ=- u:kc]a׫i$FqYYLh>SP@V 3G.ZE#pL%'!"s}MBM_B:"ǦHe EJ}6lKRA-{D gO+řqyiWQo/ܬS?k|Bc6x+otV kK@1 >DebyJ FE|' S bΪLhG3 h?R; CWϥճ?sΊ?P1b~̱E:ϛ&l>O'oAd|䍗Iͧ7[ uw&tO;BdD˟=k*/GgL=plKUszYd~>s"BqU'V-¯K}kȽ1"p 5xƜt"w|u4/M`uSgZ6nZぎ-2"2(~E-.g&M1ķ̖`LyJت|un¦tP]vzh덹6xajn7 f/N?w"QxpoAJeK;P)窢pm1MpwA9TD:xdadz{aoUJo\4w{{lc4:hl+4͇:oFٔ11ۄ_gf D4W'17CD ~&E@13kZ"Vӿ>R/VD?b'om'5xp.9:Ɠy($sDGzK6oIp2;D8}5jzė)ATaMwsRS]Ϥb~&#M¾yݼN $35WL"(ILȀZjG9k6q {6$G| %5.b;D|)QWvꞗ2}n%EHblP]syMNI:/*~݅_U m'mf}8̵O d SWl.eՏσnSb^nrz>B7D1inbi[-a\5|~)!Sur4s"JiO:aDŽ;eNmH*סMZ񿐉^d#]U\rל =jS Û(  e4}sdə\z%;itB/Stg%4RÂ٥([MP߮ ـ'#&„"woy9Xs e+&Aq+2ې,zJƤ¼xY>lߴ:풑C`wBK=NUOgw.G,#dz~#Tg4s$7ewxcJ;6tpAS9Fv;iX0ei6߈X "C!K2D +1F KiTv cuv dl;dѹX -_;h " 4&>,"~.`/O1͓I r$y1~:7# wA(')-/v&$qo@hÇ(lVuA:aΡ!aYOGKНANTj2pH I${ ߞR\[h7ȻAM 7cDNj ^r",ݭQtuG-:;ϔP-]\-π]s`!w亵X:qn?KpT 9zncǜMB/<"W nN{i>=tpHR坰 P볏Fޞ^AblNUn*?(͂'?&t-0׉}v!srrpr2{jTs ?ĜdږO'UԋO6 9:X浢KߊϞBen%H?K 5]^yK=3 Uݛ~3`o '/|OtC_DfAGȱ>aA9ިsFpx&u(gn)Y?dE,m"5t<+Za4}tI_ĬN>>D}yYD^>ǾO\3V^baf O}z~4).lP=~q,FmO>yTWatuSF jrO7+4@#ηrMB9wn&b^_wl}HU*~lz~+C{s%b벘݀Y׬sЎYҾVGj? ;"㾬|GhyrT֙d{.$׮[ʐ{OS:3~u|A 0?$IN3u[ZUo|TJ JZuYБI)^MopO&i| Oφ-i gk{r W@'hwritZL+_MxRl'hSCw[ISLPVׇVJw-ۜƛ#9R}Sמ7H:dEZB  1v*`sԙGCs ixC"O-, M$_}o_ZU)ih_ϩ^.( zVƧ@b¨Η8+ H:ssN9yK9ceO}*RN%~|ZH\wGhc$XM}O[)7NgMP?}|& :MB٧,k{:n3?tJ,PBL2 Aǒ4|R(绷2No;/#ַZM״hNdv{uTHe&d*Tyhn=8wdl(NڌN:H%DdE,zFus;jG@R4MN)>H9J'!%/c.Z2j@a)\ekJt2̧#? r<*3- <4T҈'̢HHM#|B` GҎNb߫JlpPkn$};vzOiiw3SmuU^+N1f"!M%A3YʸKౡ"nm}KQyW2__ + DMW4T?:$+=/!H+oʺZPm6puB^􎸈 U:$B:{onʁ짢sI(TU]dpr/+}ЕY(k6fcP2;Ϩ9xL'k{* -8;]G|k 쒬CaN㔿{)Z.;VGA%*n|*SGzg=KR5[%+"ۿ>&B׈eOq5B}e_tfqO9:P~5-[*(2֦~ȝWQ $'lS1LQ_"7Olqr ѿɄ읚mxxh'3UJ^%}5MjqS &_Jbڻ-"h׵w"O `WP':^ 8ܞBo@h*ϓ'Rn^.pnj/ܼKwZ~Jst&E9kMԩ\v]Vd1n٪L/eDAݟo%ozָ4A_o K RS3i=ط<_sqdގ-};j&J̜Aݝ;܀ӥI4~Mt=Nm)/FS(bm}aw^3ywj]L;[#2:;hkKq}E+ήM:3r r d/\9tIk[c 5Ar){wd_%T-MR5Z+t9-ܐ[:S뎝&[Wf@-1NpygnqRA1)c8_OţmȐ>T:Y\.SJY桠ޡqkyE=IHYngYfrY݋Y: LQ $zk!˓ ?'w}0-{zF.S$d`>GOh.1-D҈Zu N91395p!/)a A$≇\pSc7I)·"ZkFfrs Vğq7Z`kONԜ)4y oo&GቅVtGCq"56TQJO_1?X|xro]οw;}HF<%!D2tϷ]|U~vڧ1 em]ax0 .<7 gcߓARyܤ|qT jS/a.|/Hl[ǪjL-?eYȍD0{YϥL@Llzi FO$q'۬(K/S][zN`R?Rr~w~B}א)g4ihQSJ$B_ja[O_XLIaYzfSݾVݹѽuQz{ Y \`tոm/.8'Msίohȳ8snYbMOwntlfw_i$P/OD)HhiokaŐy Zm"ͫϹX1T*DDOD܍GeX3zɬ~[7F /4xl+ϛ܅`v54oTAPU5?+k9t k8KWj7+/,&1VE_b d"Ŝ@#6mz1K-[BٹTUR溁vfu u!Nh/LtEk=|` \:ܪip WSG+ dkޟ3dA޼0  _ξP"}IW!G։tH袮0gu9V1/Ɲ\]JKS {#f@|Ky=N'Mov_H)0}v= ϟ Is(jsbQG|wt4Ỳ`.$MxFmuѷJy49=`f[("3w@zh0hZ϶u |(-Ӈgzc_/-aϛyl'i$ih k1@IW4#?Rqê؅iBtx;?V߾7DoӋmoL)YW6f2,yбM\!Sw [ʥ%QNM W0 ;жݺ%fB Kɳj"CĤ0# :1ߧlKӻ}(zrqNRǾw&uJ]&Mޛ|r Ge\7i`-uO,oh_d!mx%ۃ]-Nft[lw{#>ЩzVY1{A֐|Zr P[DsVqgSt1xׁz=vT#_ """O>L1- /s 2#>[Qkz1̌qQmLl۸O^a"0R|==2/%~?X덧3ɀK3]IC!Gm#J_"@2 8`*L-@oK߿٣|!ic=@>)7p9:kF2`/N1ױkS=FëԂLi&r |*~$Aut܎_L犐}oꪮhW T})tۜ[6wxb#c v7dNw'G*\p$Tk-D}WRC_y܇m5L ˚Ϋ>^O!̌jwUvJ\T{_pzR%Wtdrõ87N/.DY AM>^¡Ouތz: 9jhT]M\@}c'N 摁GO;`,Q4Uml3p"o/ ڲ;^\`HETvnV1J͓ı0]YYmZ(ݾֽ|xg4q-2Z0E.6Ϟ|3oIy&) [5GC1ftbxR%/TLԓOY?!,fwcD= ml >vf F;,2>t}yE=i^ֿ0?![QlC83D\ЯbRҒ7?|:vdF#+`s7SKy @6-.%Qj=X5|d꼮E0O"fkmc9M UV5L΢w(o S_1Vэ~ iwo~T j+)v[I O}3VShuIn,2qnNE^+vkOvԖôX w %V,̨?ѶM :c@5Q^L}:ˇoVpmƹe]\oj]3pl"(pqSF@46=׀u5 g/dDU%S݉B yQ,!ip[f";7O7( r~ 2\M#H&dhĤrn0v?{h/Xnϥ0D ɰ'"-HC HTJVގ錐]Ε´CNJ۷R[ӿs'{7MuVߣP&QȵO5z_FHg;o]}聯o+!j p N4%-Dl&Gۇ|zmi[P曬>C޺4Pir'71cru.a;Ϣ >맵dIC$##1v2Ӟf7Xd:&MVN[XG/v!;s`7Ɍ;Ą$ WΓ;|퍆Z`N[u 멿h [(#ýEw@bk OBbQKJ 㼾dψaߴ3b̼a_%#K8Ef83^73; Xe ~[o :ysWW~z=}ƜFDʘ"! 9b[ f#,S)H墏1]/\IQPa#OLH1v 4W?ޤ->:n䭬yL֚tp޴g_-X׬(i@ӅoG*nڂ"6.`=ӾKS*^ܿjM)x_ƴ-rysqVh"`tx{rMߺplw_{poTYࡣ-񔑛SY\YN-8UL&Ef-/4!]>ft񿲏4yupE%'E| 8,I ȁ!Y?׶X'mbHޭw/ n6B_f*o̝c*~n<2)) "|>`zTa0bf%j .4*T͵?6+{$4oL ݱWt–DXAqJT . _McMB{ d+5͘+d۽4a`@?RZg43(blLsj|}Z=]4/)C@!"PFQ xtȦDTܒ`q٤Dh Mn**_nM&MYnma>08mG=g.xIgoUW|ᇴ(cEJ/TD>a2$n˵Pyf A!(ST'ஷh¬Ԛl)^|x'J.sPJ :KQiېCY_Vd~2l:dpTL$0Qe#x7[z`*?E`@#^BޱQ7X5@ouX(wqg.1:$a*G5bI**ؿ?@,y4LE7ӯYC5W mtV*U-k]$%9mNQD߿ʂ_Ȳҋ]n_;(\{=C*F ?n_Yms+x5_L?@."yhm't-Eܪ.?3퇋Wš}6b;+PE|F >5 }1ZCF$J &ВQ1chiWV]iu֓BUMyvp}{l5':0 8H煿J ?͖f!o*6Q0hz%3H9s)g׍xx 3+qAO^_y&)_oU:Ȥ숿A (gt~]}p>BMu'x**iLjX6kr `3V7Q3$E#fg[Y \sTG.M/:GJ\Equ5ETU$|nob5CCGLh1M|>ơt̚Sh (90Ɔ^FBDRy$cj_ 垤onljLv?^?YaOe9w C!0MtWL6VΟS[Tz-'J~_kRqg?k j ltJUh;38 ;V'DSa{0P=0krIzO {B_4Κ>prAs)n,]SwfH sHVn>۸o<\t&=R,B{[̈́ՖZԾ=.oU6 7壏PqB"Ǿ4uXEv :fOjFV 4s<ߟs ,-yMݾЗYi?6x۬?R,5~F2k)7DvG$md J2zК G&ߟW)IU~)}wgͯ޿Q.Dt+m$Ch_)2>KPʺj_m>T?Aߵ+ D$*;;Y],w_}݉Fӳx_*?z ߽9hJ[?;٠F_3t4u?Y^,QgCTz- ?L|ݪs6a% iVـ#pS'$2+>u &_V}_r PkˤbR[QWJM{ۻ51{ۑ>Akn)`~ιMlSz8Wn|'is"J:>Ui+s$"%Oup7Cm.+־|aou7|ѻtHAKVݍ);vl{/N>dY֚fmc=[_)^ӽlhKOc$ϷuPA@C#r"+'>DOchiueɭ9>sqf뵁]ǟee5sX?橓ϺP5Pj46 k-~v5zۓ1qMe ՍY^*?MY hZBc[5?Em?359#ߺsbk}ѽ#?wV/pQ%_9{?ALgV^xFэ> 0, ľ_ܬ]ȓ/b#UJ"f~a[UA:7l}Ar뛪C2 JFMQ/59i"+Bn},$}R@\\/OlrAiƖo . ӁTmK)}U3oDp#VtFsykZ/׼Xmo,m 4i50;f fDMa֔w^(yU2jnNK3}Nt{B~pj @1%N_ﲅ<|#?ΠׯEwS (cuT"WE##~W&50ӗmLk<%YRֿXRۮ¹G[͠;,'pZڗӾn{KZ#RӹX/M':9f5W!(+ڮ2݄2AtJ*m"2gKgM#әub+9qƲ8]QSvU߿}WE.k$#Sw^ 91_k1A{_2{)g-kkC]juxdEIS|tV]ILsdez ]teMt4:vm:IM eT?YnG}_Ojg!]uGd xWhI'V05,@m8JBNt`~;i4f~qCh=~ڷoDJ2o2"oK<B5koFV7њR@cvFҧ ٝUU4~}Y7$7OЌtTI{s2-KS%b\qnx+#X8_=^4"::El'`oN3'|Bc=)%tUB8eQ\t14~Q!PWk 4vS D^5/"}SzkQEZ[?!tzs_6kD,LeGn!7#;?fw>ѝ61E ϶Y=eL)5DZ3@b{U4&},i1zlVZ~tՒ61XpkdHM j*9,ׯ%`n۞R-j3}g%1'vmK]I,%.2}SЙ/6vjqYMCKMdǏ!?fW* 7C9?-קB `k[=nBϽjbDv} _:Q4{rݞB>YKz~KJH$k?sΠh5x-TuWw/_&{jeXE qxpYj3'첒c7ޣs,/&]w>$yʢ^JݬldDR>a o=E" GUB,K?[@iiBD_B fOڛ`3f)o*f M>mI\^UJw'agI݌-msUu]KU-\4=<~-PXĽ5ina#վޘ_tG OW0)9q̍?:qn:õ̚Fcc%zXZ)_lsCȎVp͕lK}3&F$r$fXn@b" bqQA+оg[WZ#A?Zlդia:NBp8 `(MLҁPn׋M) _IOX<5uQQC/OuL"!dI1{zvhO/P,W`Qy X=P 'ƉyY;L2#@vG3z҈=m_:RT xrBpt>"LCA:yȄ(0Z؏ѴA m2f EqT;T!g9:){#" m_E(rGbJM5T /oyu\Bq_E≤kYc̙q0yXv7_śfq;&&v[D_^fF+:ʨ*]=FR\0 ]A[ te ,k}nmyD(~t"%2T>"uSq!֖S+E2K˅\kߵh=pcc_z+{u0mAKYo?'Ay6pdz&$B\R?(ݯg+^rZlhHAI*x_Pz4~hGKCvUnX]zeHdhv`s?'RjɚRrz2;DX]۩JkSx->E=hEduN}l`fzkԭ+tfyLGL8Gκ`䔎,f48 \?׀KL?2f]I^N„yj.v| V}DO{@k ]>nӍnZY::jhgoFSⶋ0ݘ_}3CJ4;k|ou[`eLn+Pr;%Y_Cn÷4o96fj@ 'ǜyvx81~MJftmhm0gU# zgfV ;ZHpwKml-;𑲽TDJe?Ά`;gġƖt=gW7c'[hЁ^芩%>}lD{ɶHsdbE [w\o,qv3DU;qA+ ķrE }juǬYn&*5 |zՓln~0 ̦Bgрdz͝Fx3+Q},'p+#݅O|}n%YԤF#V*CѠm.m,kS>&3؍X?e.񕉚93:Z$U wDJՐ+.~l~׾S,|_`j% ";wC"<9 J7]pʊ)UbdJ5CwQU'DV:)>5 %%|<4PkS\KœN>Uo\nJf[Gtܖ+NdR׷l)&4?;\ k^;OfT``?"̥Dj~`!X%ɀ1 WfBm]v̒:Ј+xMlIe:`[(dw`%ԯ7SyH4@nӰNi_;}ǯ3?G] ;tiFW_j3ߺyYbye&ƝMI fFM۔/O>|fuB@4b}\clmmw4Yt7VZd k3#c)fu0D&T|c*߫nesw3PoGՐc7uQIUU"fqc2l3ߤvVe:0U?SfةS}>&GgYU]UYbbL/rV!p9i$_魳~Xm{ 48F|2c{(̋kyѥYQɯu^?WTU$Cb4sGo_r&!PJnwABTKw,* {%RݵnHnFq@<=zX.')T# m?4d5`ʫ|J6U+ռѱ|]Grja}w] 7P g62$q~_M,ۛ|D{3¶ŦN&7ܙU^R%5GwkZZacS_%1mzsqmZ_3>ʹ{LX~ ?a27E"3$tovfFܸ$u+d;͎L}/ ʣzr_7C_79w)3~}¶\;6ٚV_ģUԣW{vpbQѵ/ n#Zr0k[T}V;~ .y[^mKUcҝטGYA}nS5:@@UKwO7bl&rAӫS({MGAe֗AŇ~A]8ДoE/t3M_蕛X{{ĉKM+v{bDF{ tzVv6#N5fOqݕ uj8Ϳu%ޗkOw@VHu4Ѩ΀?9 k#$ ϻ{dC $؈҉ʈ@1> qdUOdىh4rE5s@ri1%@)-#Lzz^ ;cqXoz_Uɳ E%WeaciIgdoB+6Ѹ};okK`fytuW+6]g5gצ~hWќ]3RG@m_+'%]k ý>y(6|EEDhAYN~x8p }\g:>UM=[!rK!/Yx^+ |>ӭX8۠"g{.DsE\ [T,~FϚ+ 8-17pKV;^{KwgH~_h< xാGs"&a_w Y3!"snIf?:ktJU=Cv;]d{bؑu_6KV`W=n,!}֖0uؼHowG5|T7-RNc6{O1F>;4Lۡ98Gwuܷsޛ,s4D;Ezu;:{NFs}?,8ٻv`!.cUu gs${A7@I?*[aLbO5֎hfX~ժn4?ku.sl<|훍ҷo?P/m>LoT|ziVD8S|Qs$]^.YsӘȧ䎊l@pWmL ; [@HzSLIGfk)"j4MƆ艹ŗLcx] YWwuS &f~i{#z."1% #X%ڣ7v^o0_~|55-߲?/qm[ϥ 2 xߑTӥ6䊠7On\ ۹#9׹W$68eoh.s &Rc,fKdk)1{]_*_dνȐl+OLJgg }6n0*=9$9/oLsL-hZG7ƌCu.t>f|[Ue!/QY>\/}ScHW=vqbucKCuREuAXܲBeU]&ab3bI/ RSӧ&*!OyBt_\ H{k? qWO#uI["LYT*rO 7SYĂ<ƛ4-BDG_}ؤ|Zs4"QOhgQ)ԭ}K~0mXր@&+MFj cW=0774* ^;Z;euv^%>r>s,O}ɞ nM"|GM>J)V~qٲ?YpW8#zoM;F jx˖l4;;Wn"7H1ߝL]ŸuHr = T 74PoZ cB |Dڴ/EܠmX${sC梪Re&BTrp?ӳ .܏!J+6%}Qzh:L+wџn]lRgO|ry$nѐ\,U?7^hO\Oo:9z|ޚ;lh,:yp޵D__E_{g{xJBzĊe߲G!֋SK0yR06B@"zș'xԩzzkh7Py.4$i(项J_2?Bji"{n\ф n7'e3$p+ZD`ۮ8LtW)rV3 ]刦WdLCz,"H&ؑxvW}\p+k:@h4jǣ<vE/Wsv|Ɣ_yفRnG^z=m;of.Gce46쉗oa{|"Z!p%(i3Vȡ`1aȊl7Ls@³ '*_}osMfsޥU[O rG1 -k:!N}~?3!)z%e WCoFcw:WZ5 ސ.6ҽ"jzI]z4߰cnЗQ2G"lnEj5݉pPbzXĠAZc 6a9G嚌LA\juv1+vԄ[_8ˮJ=š,6#<P&rwkE{_Xl6IFLM ^ #9 J6wfI,-~^*+R?U{1EYZF‹{boz}3Rb Ӡp} |+ly;z/mYח9xhwTTB&ČH9'C[ɯUrVU*}G:Ay "e Ϊ!3Szinu-EM#qbHjg iݬ)/_A](U޾Rmoa+l2g{YMQ!WּH&kE[i2[4 s6T o O%7#lEQauZ sw STǴU0k뇴3Bߩ]_Vu)S+dHr[U-oQ?Yd#HoVR7r/n B# ]v;®mӧ̍G&U_1%ZЕ5we)UEFC |2iJ5/qw r\RaET?;c ^s!r1me'2p3 R‹O^To$? L?8hd>J>:D-Ӻ}6XϬI?6i޶쓢Lөͫm wz6j'Ԇ__A/?syjK>P+4<iIBHx-cZnOTyVZ/* "ZT-~GDGm~J[J*6"A8+T9Oc6b0!ںr݄h32es@Fͧib=)U=RO" _LbK勁oDϾϵ U]>H^7ooBG> XE m!}k2n9Ȼ}+9ej j* zMdIAM|9K޵K6sFJȏ5,0Af{ުW`LN;3e>OY6Y@9<;&-W~[z?9VBc#ýӹ;$a`ozzUrQ'|ێeB#0{k?`*-wi+3Rn̪ݣ]pW-4% 僸4#+$Rv)yF1˥/} Hzr]\)EsKE7[`-|I.>CGrJږ:7ҺeDg0Ednc.=Ӝ~Q 0}Wjra&J]g lLk4[~21XI,-u!ޑ>>*ߊ[rHۥYC m&S"SEkYO,]$i'ǣ6PӻE?@n,fw 28Iv_LD/7z&aͰ灙`z8`Q?vse4ܿkVd6?mhԙWS 8ۭKYǿQ7DzVZPEVLb{ ,|^k4xtc] ϧ/WHLwi&p"ı{(O0*RXh6ZO~ס 8pH8URb}E2ZBJe0MEDfQ[4~Y_+(#\OԤX 9h7OŒK3omqlwPؘWz%ыNu17gT77U&vt[vsbHW}?o,Cs ʢ_@N"bϞ[+ϼ?u ey[o+6i+٥;5:Iޗ옡|Qtzcw֩dfm;9밼w>Cnvh!_H]Oom[VUTAugI+jX3飲ʙ||\7)N_xS.io-y-7jRIa1wLmDh/ z-gs9swe2,[GA;uu^:%Y|wyUIRi]_d鑁?Z|5j%B͢8,c30d2HRq t7ѷjO)8ɷOWM_ݣ3X 9M?7|;/ yIp kQcKOnjD> N&nJ9$kqп׍T?kflɄ(:Og鶌Uc?y~V3ߘV]h,kQ %%-usH\U nX4N2٩ >C:fH+ЛȹĜD'۔y*~ya48;JrYy^Ʒ Yvw[Y獕iD+FHfT.ab~q;[*v-*|]MnUO_g=/sx RMweCMB,(h]zm9w{?3?6@zPFsr^٪l]bDM\JG[_׉~4푣׳G9q\~4;~`zkRL rwoUC)#/y#zY){K+<;k|7 ,BsDzC7&NehӶD?KUH;v'=Ӧo ]`yn{Bj: sGQ.4t3f¦Ln.$XŦ]~π͘) ͘rbA?֏2x<գqX~{]}؀06FگYZׁŭfyΨyq> ,cbA0{.6EE=L!(U[Sl/fPC E&զ`wm-!7@^2za>%`uZ"l=ĽKM||JF}>LhjjFfgKR+V:~)E>^_o~U[8Е"[ޣzCj@u;XC=/ԃ<6 ln[ǃ-HZ>*w [|ʕ#UAqKp׽8- E/*nIO4Z)^X߿ii~G5HЧ}WQs䵢F&IU~w}yp>倹)dJfY64d-ЬUhq-ɜI͙ &m'O?@&;P" %0h7'*cT`)󍕿J=Zqm"JW}slqc\NNui5ᆰ5][)GTecdĘ\iEyi|Fh3%3p} f.g9|?;jܧ-{+Dߕ޾BsIٛ?Hc{BDetmɼC&1~$[Ç̿l^>ĺ=8ؔIJʲ+= Y zc͍#+K{Z'-uUm~LꎊLh!Pdȭo08WrǶU ]|'` 57ʏ)U{9gXfeT ڌ!??mz8'Ú:QciN0ΚY-<"Ű\!ld*$N; | _tMg5Jv;27RHhOI2Ȣ߬Bm\f5dur48㲴d"[&9ztt Gp娯wsob?"O|(举Rv;ߡUIhʷFۙzqmU ө~ /EBdb投Rk/3`AL>RI5!TXƽE-(,{$s$$SI_ Ze*7з"YY f(FZq#ogA-<H1Ry{=i%WtfWDkYurڧԮq@Or9У_^31>o}AwM zpǫ\﷋pqJuv"&z3-JwރMB~=-BL`]8*QOP[{ee֎@$Sy!T(Q}t.XUr5nf$tWs@`.?P( UQ_"'ܙ in>5XVdV,2_;2vkޝ{ [;.Jyv͞ VFΘ4m(M͍~lv~UF\=W}FBql$02֮r5|f豥!a^IҊ C j~05\L@)my؎ġZwoӍڨf%*w?COi_L 6$d*Wpg |V-&"tR АN s'QH#. 4g9҉gUOtx'#e=dF=f.? OJtyP诛?M[g^\ m?uzނjuqAd4t>ŁcW' gyx?H 2Ų|5G X`o3g2/Je&u) 쒞=@kwM PΖj*"Zm'|ҹ^4ɍϾ#:_AVOar_ؽЇA=d֭.CXkn͉%zt2QmgjSDfHjR&wR>:Zq̌O\nkoH;a䙳"*ݶbH;ˆj߽A3HVPI]ʈʕZ4?x'L` {JoD/tVB {|m-9+u-H}Hٚ9Xs؅?;dcI{WO c-mEǑ.{kfDW!@dr+gbY}DY?H/6@o(sa/DQ weaxH:GbDBDVn̯F/^kOUgn~X}-xc)vW4}hY>-On /3lOr¡r!>s 6H͍ f̮ m%_ZMaT|_r-i;[cz+.Z$c}~NV>R׊"[4IԜfvbZ%?DoДoS{Dի-_ɳ$Uz-Hʹz:x5_Bd$|A*HdK}13椈:A_6#16f}O+{$إ?уuk0};BZEjaIWw'7fAHe n+-R6eJt"/j.So I)nyk4E"?VKJn4ѐ[@8gv*y~H3~ήG dž ltR`ԇ5ntw/T|IGY*?f:SJSDvѪ>qT柋wqɕc ٦;Мq9d=͑^Ψ74cc3-kfaBg8@o#긧%RA*#xiܵ7 Q\hG;q4*D؏=S=8s,>9¿t`eM2bGuM?wvZ׾4lx9lq_OuA9"Qxg^/uy:vZ՝1zk휄scNit؊+azr^OtZYF{Dܚ"0QW }-> s4IVJG=pR;XSwDg{ 8 ǒQ,Mhm&Rn`+fJͳcOO),u|8ij zh~@݁'o _B쾻r7O~CE.J^H՞}s"Zb;v$7+ĪHo `w7w$nUɘU]e{b}KHUs&HYf>Ϲ.C8G f_8 -n.&?N 5t1-vW #0^Ƴ&t Y>n>rSo2,=N>R+?Mm?U5Q?1`vo&v_Jhb.HjF# Hӓ?wI^Yw l#3/|d}E8Rxdl;z{To9 F85ӿ1RWuLu?/IK.@ (w-U|7vE!c|`G32[2͐!T;`4 "!{2ex}K}|ogY|S|[w$׵p# 3;>Q;ښhյEWCLx{!dKE_ﲈVjQ6*xvg7#s4{Fg2ea ѓϫUӉ588 JfHyRX÷kvLEE.qF DZS6 gq">H={$ Hpjs17Э!n)EE߂Ep[S2sG-GIe%>"[K~jΆSuKu#cr%I{y*\"_Q,Cu\?>S]UU~M1*7ޱ ,k~[9odLp1*KD. $g2owb&V/)Gcxl8'Y6'9{Ge_.o$h 4 F(mJ{aH;~~ uuT`ҁ>)톤7Rc0߄^t{QJb/`6~qhG:gm^6wghHgr xa3h엟|- VfגN6D^χ 7 U o"&k&SH|.> *7h(AmvCwl+VuȌֹ}Kѝ \t$Urwڱ|,+F[&S֐̈٦;h_C.|a#üI~Tkq2zԗۊI:O #TY_]: kQüs_.nT~v&z1padfd _<wYVC"ňd|cM \_Etg)POHԚ9UL `}9 i馶4]dY1|K $.d{+o;A1[n)Y\C o5rԘȆgVx?j%,˻V.AB렶 l}b1{H]i(fQbzO2)TMJU>8zD "v「U%:s_mD^$;ΔMf}XO_0S8]30V=-eCLTI8y:Y zOD*W}O}teR?X\57j[obTjVvW;]O{[Mf7-?,(N2ㅶL'T0g{ ~ 9z$GeJR<;ik,ԠO_{Vύ t?q4q~#1/X5hz۽*f}dR(SU7TׇL>?D.`~5 =SV+nu.Lo}vyse\U#禎){[[j_C4SOى@괧@,f"K{|9:K޳B`ނ5i7MBUR%պ&tv_Lؐ:}B%Gۢ7U9rŽS툄|mUꍮcK>74kqIߑ3m2ۂףmfxC((sNk1tƐ],JeCkV7Ξ6{Vfh:Uctxq*3p!4Aww[.Z)'V>e,˸={q`Q}n{?'GyiPj*2g3L#Y훱yr/}'ӛI]f䴶<`*{D'Fd l?!֐Á&WGwF!9B,:4z7 #8VN.u%BDKO$ AC)HFvA)7MuT0l>dl.Ç&_(ou+l_usx  -[Sշ|7F)J\pTVg8O%)A:W:+~Yن\ޒsh:ĪƠ5PtF?·**Tbzy7(ߚxr$fcHb Xlwɿ{*dE_q)VFfL_IG1Ekm>#벑ZI#;e7NaAliAJo`sSHb[}h &&{P(Kb3lV#xoأ ۓh[FA2#~3Q<@_"eQ3Y^6Cq.ꞵɇwwBOSpR5X!c׫oOYn(<){qHءE+B[PWƎJ`dj ҾkuɉݡAtܖ,<FHZg~=ӽF5Nƺ1hNN_ NM79jp龧UrW1m?ݧp|NGxpb43ıLcr_v\děCZFjP_y1ugw4Ɍʞ|/bUdDDy*XZ0 E0E^ZnFz茥}ݱO_$\ +sƌ* =< tt.#a<9VH+՞&.)HI9/%f;S,AvQR}ѕ7IB:>еoeԑZçmmmf<,t}φSןB_ږR?D?MiٍD Di#qd^}ϞIb{Wi38f)b4yNl,EqQ 5`RܥҿW!Q6}O_(. elߢ"w)p5 ?NYz{~{+Mk(ֈݿ?#|-v9S̈NKԭ-|[ڦٸOWߵ]K )Yn-)HmTæ([!U"c:ߓֈA[lCCMC dŝIXhN3~ˍ*%m/TSDP/{ *}5v5iW"eW'}\U.\N\< ucSq*os/_t- 6|YҠ(.l?i]6 |E}I|N} q}d8_CS~O–)#sO~d}$,5yθYhT[h H횒K(#]T}DW[%/`YuY/-/1[mLTef }.tG|vChzCpftuΓ{1A}t"e%G%h|DNo}Ep;jU<{?MyjP7ضI5\}L9gz~n7 #/^.uwVEZ0U&<bNu̟}Be_|ܣhh*hE2l.&Oy_iPoͿh]vuU txoSzg]sjt?rWZ3u.|p _1ܯF3ܧ gQk%VKpi$oĿEԮRo">"2G}ӑw(LʻMMU6F=I HRbnNGg[J f80cMM0BTp9~@r>hoZ}F#VSjs鬿?ϧOC4Bg.O_t{=~J}[ͯS<:Jw^1wS&$tJHԄgoIj蹋*YL W#vQͽG{8o N>cNft,?i{1җ oZpwmNw< CAᗵ 68EN^HT&*KyK*+0(kgYǖбcKM5ŭEՓ տ2hLsnW{ٵ3X/J.m^U (*d D&2ʼn%} CqP3ɯ|FY﫡̽4cMɾ\';*q!URKY̴v327|e/]{ o=tB/bF<]Tɐd9Kـ |= ҫ*\$qJ+Q ABN'pM\9(r;$Fkσ ꪡj{=~t=GlBw'  NY/}4%&mzL.suy;:8'?kʣ ˘tLK~PWl6Q}JV sBp݈*/@T{7yv*ަOY% e:IXN ^RYnqAN{!zqEP{9(/jk}$l5TMWd?$Օ9)ey(ʈO>R'D#?d9nw#W ش({1_SW{^HL,*|={?1))~R-c>ޘ #Mu7¯"f^L˯Kj&;|hNtLaiD '|f7X\ RRVrܗ[~qTGy|H?Γw o1:G?ݲ6'Ço'atgfzDi<=` B3ET?/? u;eS|̌#+Y"v#Sh` KH=yځ%>;IQ@EYeFX {NP+rmovP%o3N7ώD,MBE|i/7vo8o_EXg'RSЯx #'NdX&~ }'e_Knտ幻JWj$ʅ9X,&ɵSz4}v@` *ΤEGTn'p >Ifwe |վ6J F)oa̺ʨƲ%ro 5_{AkodQiU<Ů 52tU pnV!6`!֫{8elq*g2V~e m0{T-4T'u~k.⣸$Y]7 x!?Cذ=a#0}XЍ뽮ܑv^c0=r1}9jomTͰo| 9DX?!r'U"bݭ9TH;X5s*7`NmjA&+zi>2xױͳ1#V4QevhnuUqwF>B֌oPvr7k,ͥ~J<؇/-!˙5vMvةh`Hk쎑i6CY9zV>0Eq㱛KOEI]fP.L;&JsJw˯LgЬ}z P;c,?[]d5O /ntnv9x'fw:trH(8clCtTyJޏ3B|T^T$XH&DOЍ(vpL*}FQpee11M;u [$lXj|*+OS3dXWGV532gz+k9R:"OtAǼ/wAsQF3K!~sQ ?{'jP ?nΓRbA?1eɠz6EKbܵ,cjVjw}P~ݕ48/*#*6lȡ(WI٭~DK;c{kS7o?S@S~}9)P?͡#Φkc-ɉSlmLOcM+zʲrQWȓU񡘙zZQPjKzƹĦMaVZo[ $_hTEK~)L6 }z QP=k٘t9DUޡRi_^3:+dη)^i$L]nMqV!U9d"DtJ kasϙjt:&Se^"ueWMԢ\aF%_r#\@}[J_EIE=]9YNWɭ6L;5jsVŹkJYhkWF?c ԷJ#^j\fa[Øȍ}_ۛIG<utcĠ-OibĒ[eJT'`lc/\nd﷯θIO4g9u!lG@XHxQ i~8b]ZTͅq#Lo։=>#Nd %nKvpuJG.XiG4%`$4"9[[l|G~A]'S "i6ӦYD __V@Jsz閩u)?e.*̣C{o+SuSpri벪ibO\ UVH?KV b>[!ђU jߔ w)qCtm2[e#е׳|smgypT_iiVq۹ Ms!"jbR/U/+z*h h~KN:'z^߽ g!3( J9ZʶtK^u_=qf|vJ *}d_8o}F?!٪ݳkTϗ ZI{!ɔ.2\ؓߵSLro2E'leRVٕ;CHŜd֒^qøԾdk1W RUy, cWʔ!;T+'N3鈹fVO,]cG[ٹt1pgfN'j/CӼf|l)L?Y |U߫4+[>|ոS񱥿AP}I]X:&If?zh.V)4͟MVޮm$[|]Youh#&9Fr26>QsvRO9߼x=VC]1ch*m7M>'\ܶFt继ov[mjSWmzEqe{96 f:S(hi{2=$3fDC>Ꭷo#@;0ݗ#%Pwt:tz_K6!/h onSEj8>|}Zt2Zk/Ǩg4$X5srw~Zv-iM8bj :B,hMMC.{<_]ַe/Ҩ69 ©HϹO0ongU. Ve?_/mO  (Iʙבh>v3vG:?x"mԖCW+OrThik~e+ |)P{3)@9MRV+2y/z*3ϊ %7rsDTx58̀_Z`~ 4vZ3ο #`i:? Rمk>1at%Ͷq~fxn~JZ q`#׸"LR߾߿ʴWΩK,~_}eՒµ;:և N:EGgqF+/2ti>'F2Bq8ci\AR)_TUP]ȗ~[Ql6\@[Q͠ory ~#eb .ZoμU<X@E`B7_oV'TFWnV5U{Ƒ3f>Nn {<<ۿdͳj<\%7h:㞥͔րӿ$*u332U=u-o陵YnC{y콡'Ko A3,/XU#^G` b֊20,ϝ} .v鯭] 73yƟ1j7 sOѣr?VO4S^c9@BdQ6HQ“N73ҍ _y5hۜQ֎AbM?yWKUp Xcx'G ͆?mNw7t=ubC&GV$^.uKU9DAoBCOGڭ,v-nPZ1aje_NbvnA#m<u^0NW Ug< {Swrf{*;=M?&j覣My|_Ť+K=Q.B<M :;fVt7AF^3`΅g'{xB \E]c;t!4-eJ4;CٷI)Bw:Nc"MSׁt#6C e__#U4EŁ)hz?ǜ:lـAv?0.}U@p|Ny vP!sҒGlK`ky,"wwOV/B]όwOY[Qeڞ;Sڄ^?Ez5}}:ρb_Rd7Wm-z 1v!PqP!/'Vӣ\@Fר*04DRU{\^#g_*MdW\uHg*s,E9Fʤsʿ ~Fij O~'5f?+RE""˵2nQdwkB wU:[HOIiy$G~Cb3&>*{ dVkQPuO~1)MԋYTUB,'zGef:,֌ͻ9KOE+W?%n&uh,d戌SWA',?huPg8Io:[-h~K*BbE36U|>v%QoM7k5p4q%XSQQG;߼)p{5}^͗H6g8|(Jg3)et$0֚/.@#%=p0 R)u XFaH_!]kkR4ycs̏ ?69+K0QFj'{SszO#k1kͿ/?xrwT )@]SXRYIaSqn RVkߧ엲M,شώ`".|GgWK#$Ih3%uvv9+m[X[׹]qg}HթiӮy}0+}PIV˘x%_z"6BEZөAevΗYtZE:Pe{y P8klSc?Ǯƾ{de?pq~ŭ/؀jnWUPb̭5T4ģsb1sBFTZMq[bOT$U +)Cn #Cx] z]Ŕ{ݳhݍs6h>Jvi0%YDH;|+)ՆCDMhiaχXD ݄Ww7qb{Y8 fK^ɰoW7f5bṰkDzvF>P6u}AsEq8uug6}OA-h䯜ٰ8ڰS L PvEf n5hP tY&_m&<ͷΚs=ޖr_iY?6^K`P3{/67 & iiW8 G]En~3jAFfRyEҗHmw_0^*qUE>#P:E uxWIh*Wѣ}M25}ٔW2a?` U22hm^Ghn{W KnZUpy^KX%cR1n؂vSۈ?Qb#U ]tB#xBVϦ2#č%9YvQH̰֠xTWуZUl/r`o{aҍtZ7ýY"<Zй^b-Z]{ڌ| ?ZJ]߽FVngC5 hhz{__A8 w請aBLV)sNEQ ut %k!Kݶ"Rkp~sLAaWD?N\lX ЌN۫:g:zULw)}[V_*Wؿ d|fT>n/ĕ6 sj<Ԭ=5T#9@T,hoq: Ѩid|8ILjS`w3ٰ'Š]'T`Eӆa07|JdGq}Ew\ވ}}?6vOo}T1WD_x= Ek.r~[_] 20򒲙}. r@P w>~'xiPr+N__V4i)K|ibix ou<}ԺoYSøMMz}33&wB*e=B*A.ꑋti8;\vysv$2,.홞w) UJ{v?@|Bz ) 5lŦY8!ǿ#1lo5 jdd CfqB;Ї.dj!wK앻-(8sh>э#ijͯ)+ў^\a3S6&qk=){;c6{Zz5vGTl֘qL+ 0|%p"x]ճan,,7OC:iHO^zyWڹ!7Wl;y86~ "h'tXʘ0!F6LkթsU"u*D 35ri,8|#luzͤ?"[_,,bkn *k_׸lidF;M6ⰿV_wN:-x Qkr[7֥!ދ+6@{j<`vL]1G O9)0iƣllv;ݷ^j[ aΪc%txJ>7 U'9{xwoҕL BM ,UMRu2CGWww??m7g{\~M,~M\a\O?@Z/ \ΫU̕;|x ̇7{sK/Dks!o;c|k0Qk^O}0#oA]*-8!!Ht'B.2=vUn `xO,ӡ-r}w ZhL"!r?Zӕp/3=VF7޽s'5!+W XGη޳}ΝvhudV# 09=ܧbåKCgKCZ'gaWaDZ1\U6F%k"c+m>_QΓ~pHT4KO-Np[ j6 eZm ϖjqtF#/ӉWܛDQS9kخ@w ȥR̳JmL~_nI G Zҧ${ ]*, _: yB*&ӱn)a.tK`H\x{yl5 Bq<E?Wk:V+ՠ%7dCWMb˳Wmg սb%REmւk%/gwI@ގDکJzʚtڕFjԐ3pra GXVkA41Rku;ov`sҭ?{Fi4'CR\ܝ3G,uZVօ{To֏MNb87 n4m6"Š'v2 `=N|1K[̌0;NA+Nj{{2ue;6aP7Gz~5t9 *RilGHqstH9Lz& UڇzפWl.tILCRZ*[ m[sL_%]PE*&d]$)Ҷw VWܗ%c$Wx>^\ ^e'_Z8U}xnR۴/ڴt5P~4-sTZx1|Skvyg7Y&@ T#7 ׼`26Nw(ζ!LrÞ>δU7ZwDA;J3J_?8>YYo&Ws#7tLZ{xeu>ps1vy w_4RuZޮ"ʐ_θHޥFz;~ Z~i#Xfh=̂y=|j }M]|Bշ̥6fR3(Wl{zZW?dD_(n{cν(vϯT7~\$]z[ɸq;MX@2ꊟ_ߒ)Yu(2׀{LgJ? vpH<5ߦl}|'_ ;s{x7I[muD]IJmeg u]WI8̪޿%j#yatQ06.l@9ٰ+%nώ.3cW50)pNAOz&ʧ}rKƸmS• Wbd6Mќ灨]'Zr҂ҳVF6(Tv߳ 3 Y[ ƞO2.HYWҠȉҩ݋^A72[߯JvJcPa3:P!tt>k{>ZU&b?O3L𼥰OdkYyJtb9bt̞gDBp5H{غ@.NX Ui}"Td$o\7ϯ& WeŔxm?P2ʹAUwSƏxgK_ Q89}/܃0 Nj[nʁ3bi$St37._Gŭ4Is BYA|#hwhlj սrUD<󃽾a~n;vaWS]TebmbgS)E$vl@:Trm.)d(Edn3Z`ZCp;@pS̀]׻7G_v6'V⇭IzY8OCsףQȜ>M>Wn_TigOY1{җ뮟mE(v4Z388v" L2yn7IͳNܩV<_VVS_dB9 &L{o_x&tDu6EG&^^<N~*z,ӊ$)y9,tP'Ndѐ‚izT~ _e^ۍ[?({d{> []!,4f>tJU/n <(R*o%ݰYŋ-~jpcY[/cB\'M| `@,ݛ[/#FR 6| t7l5  $[멞?EjL%KS]P `Cj;R)GfmiD2ftzj>bv>g0?#O7[S]w921\l XƯ+(|{8ůQL_/e#O !L.d桳GmȆ:PDj`at2|ҤpuF3)^Z1QY5y'3m\+oNzO#[N?C:ϩlcOC=߯{>dn}תT]1EV9;D~Jn1(Ûs!tGnƙe8 {W| `je9G#ymr,9$uDжr&:Jvq4|:ْ,wFˇH6;L&ÙgqnMڇk3̇d8+g]2"V֐<J٠=_㭬K~O\҈Jkݒs(o 2m"T'rm6u,يǭUq ȹB)nC/#u^jʊܬ_O&WQ)l;Qm-G}6tȍ]M(x&o Qf ޹%7 bۇj=Sz]b*Ft\.F~u4KC&_`5Tu(OuW|;FmD{QҌ֍[[nmh~:bv(2-Nk$K2@7"k͊ʎAԛ\kru6qL$ m2_ 5eKv!+<9rgmO L/k嚸682$i)CnTͤ4ĥ}l #ZX_3ڃ4Ƣaɿiy,76&d뮹:W6{͞XsX<{mr=w?{&BG'h? myʻJ~/ oS>#> Kia$UMn7*ؾzr->6y(@_K%NWJ(/7vD9_pF/uق˝e)wuu~zKSܷ3mu +e:Q_}9w~>ku;8$P1$"f5qЕJ(Vڪ0蔅!3!~ S1;O2F]T7Z'5$h}e<8cDh:Jsg:(.HRv޵׸qqD PοB?Nt<Ϭo>^hlX-A4GlAOK$$"FBv";uJ{"m^/ި7@R(cG92X5vuЇG4WH,uOSm'CԐ튘Գu:NI!}TSi{4I;]0v%kݘYYЀw7јXta˯(v[/  )vGs16-Ga9dqV >[OrŠ(2] ?a12+AGc_;KÝ7wU#G*ts~S84k22?5U#ԨS7-[4x*gC;/\HMMֵWhrxw2'u\ sPrO`V}0 +9w|ϠZ!ԐF -U{kmN[fHgD-]]KVoL3XX.SneFH7Πqy%]:O1qZ~2_PE5V4>s1 Nja^=&OXZi&J[$nK1wt`jB*% +HڰrO +b4\z5;@qmh{5B;9'UkyhSlΞRR)_t&8CEE:/2%)5ך vRdc-]ju~ ItZ#ys.CwnOzr 2)yy3Ze7D[P_!7i4]L/m5hz%73v|;4uBs0jS΅T LLs?3],]{޸0ukWs܉f¢htgו^CCw0T> "6/u!ݤ;ԍ=g ^0jˢ%"śݖ/pI5$Wѕ~g?^|=v90-U-zty~LJZN@w\1=L=﫷6}; #{яl(BzHu48BzK6KI+drC7g|sR|=lٖn}K#9Ov՚~}A$tr Z>Lq ^&t}037A ΰ.BFnֆYn(jDj 1̽̑L`kf-e {~nֹœe~KK?G^hKs'fy S bO6l%mЂ 5:C| g|޿/-gp=wyz_QSwd z[j!Ʊ3y[LL0!n5v1!aXH|Pʋ!pk}won_92O2؍ (NB*=J 4*Y-{AOil#7ijWn}_u6vgGl7 v~$z8} ;C>( ۄ4aIcFF-E?;5pp_6~(\3bTOCfԅg5$H=+2Kr_dKS'8E6+njFMÚCѡm&Cn=0wxyp5[}&rS_秬ާ /\yzKLK<ĝH֛;G ȾZO}"܎0׫Od~%r9Q^{ҮgCssbеI-O8WI울֎GN͗ ޒSԏg[gvrxɫϙ? Л$xh6uCUtD2?#yy,ăP/oϫ>fm^?GёD/O[6oԳ?-~dN?]voIFUKTX\DKrI"^FU0搢۽νO y -PHwFzqiQ]{SڝyУpW: n&(Us^Ih;Zuq,K5=w&ӭ+B'*(i>52G~Ü!NcK"HY|t} {룥&$ GXsX߻ϿCawA{{ɁB7MYyl}<;cqe]ݤ2gz 0xyuo$qAi cF|Zi/:VUk?UMnG_=Y)+=Ph~]WW})!c^)"N!(YwB7^,w^Uz%}k}p:{~u9"U EOB{>[[`Wu^_>jWsd!7W^>Y`F}l骈8zs.m%;";dO怱1zK,la Y@Yd,6cA;Zy 0CShmUi/ij/_*lDKxR]u ҵ$X[ _%%:pjpq؉jމ$ח4=~sn/"x|ih?KaA-Ձ0B)vfn}@mtO?RnBdt7࡬w'pU&ucÙfزHt%NjU*hHƩE%ڣ8-7o4 @Wߺ]߿6- Î]FzeIE#nSh<xHKL?QهkLgw.Xݑ?Dz?M\s%C_5|:-a߳z^%#ZbBZ|Y'9s&giu #!1==gԭhy8٫S$e 7&^fcԌ/E`3ϐ~W, Ϲ^//"]pMu4(_R5= ɕ"xݳT7.',=wPe'yM *#݉Oyse#'eE$phu3r}^Fq`w#O|_" B*폍]ؘ/Lf qQP}F&{: I鴙 LƋw;VLfG-oK~#|d¬&}vȼ}j?9y8dxN ^t8t;@TaFs1w+R 2<r?7Sl*~xS'3RIRsz|NQN݅7CIj M5o$p9o9d#sfF+ Kwm@OXf `mYHdTc{XAJրf`cdV!4-^X;&#>@&:-3pOFJ [1NܥaCW]e2$WJ}= ,qr^"H7qU ɍșXbv x@ЅNfܷyҶ3̭GFF#/ ̞{|OQɱEMϧP+0M+'m8IW5Ok/:Nz~p0A믡й)2Kit{n"xx2_ض =efԓU2܅PMuݺT6[_oCdտ((7Z>q+/aP;p~o &h7Jp,hZÃ~B{T_UQ!RѾg7Ƚ)haʍ_keIbG|NgM %JUF.H6o82Pd;l3*1\ّEm*߳fԔM~^οYpt[~?-9%hޜx7n;ihw7]U K=#zO4̦x7J8lc[/pQG-U*h(wg?3p͠?lzDΘy]X_T*( \o!%O׎2f[J!KK##PWCB-d 'cTD+*?)`z\o0%]'_K>)nTdM:+"N+cE`PĝLPߴ;?Bj'1}mͿh[xE{_*?IIPщճ=#V'aSEp2Rz)A7Sտ2hi"A (iӋIm5 }秥oNhްП:dlJ`h$FKwuqϸTz7 Q+vC>Q uIb}5 .M k?I UI@f9m H/:V&4]3dy/LRn2e? YN?$]߉~S^JTmR#2 `wj%vng_9I}ST}ٴ;\}Bp c<8o m)m3|:LT?g#BbunY*h5egCue T74vaqJ6h8>3S sV?̋S"Cg^ܪ<6DdfN{J1G{V>VCUD$W'&t,`l}dM Tdg:N^]]O^E4.U.]W|G9n d)̟yIvϺEm3+E ۝ҭN|>FWO79~{~%닣 HѬDwqZȺƒISw%DdhutG8_&YE]QJOrJẺ HɤcLoNE<q~zi \}"D`hK784kuXԯ6a>+Hmt[~ '2# CH_"K"N#5Wy$`l7ecg23/2ԦjB Ca9.k#l TJΎ&;hygr8oucnLjH W*>^s-v}[qJO }}K֩uOBwO^\QMH5̀paa}?yŁw1 o\ZՍg}FvDY07┣J$.rqJ&N ,mS)9j4>MDom S |z59Ηq'چm7njK5ո+P~m K:LR֯_U$ԅYn ?{_N TFC ˏp.U[WȚ="Z7Bevg&M .YGX+%xS8cx oяZX_O(̼eQcpuDR[mx|`60S䅴)nr0?VeJµmYҾ 7o;}KA:S8_fNo|X2x㤓 mD|IHP36ȿ/N)+jM_4.&^FK砰nF:{G/k}rY}9 X1T1,5ȀA`C*'˞)Hx E>{32zzaF֡14J_԰(]9= 0eӑ:  4Fe)AVm?_3֍xD'M޾qw|c?@kLyϷ9܈KAVN-[w$OыW%߹kAnԷ4>yoSwQWu/#5H/829>3eHiDS8}}'&yjzf/#bEfŹP|@$fR9'?;C 3F{8nO:䇠is< eg;2q !5ӇL@}Ya#D?'6[,!"hQ%ˏPe㿞<`6|JEmfwx \϶V 9KeV>{glxm{@pl:/1z򐫥r%Ő۫z^+b+/Qk E84ypS>9Qyydr C{6"?e?Hh-9kruw ƮmFo,W#20=bo;7w`VBuiFS!\2^pUj4ȫB7NETM/4֡#_M (+„R3d2o%(d;Kn̲ڌiA@/k :d(S\[O+ddQs{mmzrAjDt\>颯wӼpgߜ3zOԛz`SBThGyuZd[M_ئ 5ؗe0A]amR{dIIN'WQyTܘ2x)ߩTM(žJCkN ZwS?/z$9ode+ eۥQw{͘uȽF~dLs&'" ) \h3jE_dz>lq*2ͦ_6Q]=]|/RCSA"@ ^tHHik"uM&}" ){*A'؝&Fו}~߽_}r3 HO2yR'M o+p=@Hf`H+#j89+wM!kAԼhSB33m%UA5n4ή#DO%cF7U}a mG3љ0}Lftg7+n'Fq;H6[i=&#FhyC-;vLF{xޤ$#~S nXI.gD hYl3,ZBEmaΌas}@_+%o{ MЈƷy#y6Ny+02Ga:V%:;Mx[D (fY; 7xh2!=}4֨e`>ų kyNQXE:wzzs 㿮.0lIe@YqS8V:s+KͲ2"‰pLIQ:ďX]1Ǯq/B`*dX8$~/oz5^a&[U^+3>w]iC1Ӂp%1zQϚ!##Ԙ=h! ?_@O "a=mn뎲\ϯ½tӯoͰDy4>Ԏ~T!wt%[u~b{!WrtPkOfLtMZĚH|c l>W7O7Dv?ئ֦1Qܣ8>noso"6aBHYSˠ$W6%q'OZV2!{fidLwI\-dul͍=;EQAȠAHa~I7w%պMT$d:}C#ۏ 4y9?9Us۫M1;UoTy"MKWUVnM?ћ MwD?tWi⑾ֶhʏ+Drep0R|[6z8*VFTSrGb/h9> U fiPz}) U| #o_FX{ФVL".9bI;s= f}&#PcWb5n2#a٭71g6ܹAdX-F&};axy{>y ^;Uӣf̟S NnN߾_Sn1_",NUWI k`rWn+UM{x|S!7YSgoA"xq4KceVmx b36>Ry/4":#)y}z l ]  \3d[-w20kVnXG>%J:0g$5$7ph |2ur1LV|Md*f/{~#']=7N(NbZR@jsxs*oFF K!=TЊK$zkۿլ*WJL214;dՅM#;H{ݎtD᥮74UfA*aL`&#4i˹{-CJ0T-T{3+9m]9m6|GSwcNGؑ+1Šq2~x"•_roHNn]S5&JOA7x߁7@zr芏GI7j8c:ğ3W~I65rbDu>qPog|ARq%Or;;֭^?;eeW7Ǘڸ*,irZ+:W5v쐉t?0&I?0_2CynF!kE}JQmG%]|OV<߼%S;J%9Bom#MHUOLmB2 ZmX?!#iQNۼ|UBO$!NucN ''?y[ZQ4Ѓ0-N{ߙe{b/!Q%OL>ܳ$%24߮`CGi[NQ6> SqD -bS%ތM|Ѹ J=NL򼉓'OLUSږӣZojԾb(okkn|'pn4nŁ!.! G‰d?Z8,9o_qD=wd*YkJ+;%X7RE+!RNӀXpT-"58< ylq 4p B, R(w2`6`^]^Qc`Gب>7iT`JcyB㇋>Ăd`k}Lu L)3hNS,ߵ1✆=Y}m4fHJz?+{׌(29Goa4=a,8$rLC vXV+@[-~kV࠯~^߮O<9?س{z az+M;x>e iq=Ľ=W0烕quҒbG._e>Kȸz]eI[K x|`=Y8?,Ts1璭tHn)D GAR@G }%1܅]/-oa~׶{j wo/ Ӛ hX7T+L.H R..@.[}a e+|. ;8)?b) |w>;xA#;&ܨGb<]Ű='_{^ C%pߘb 1,rv{q1XwsEp%@;\9N .+dM G[lhdl拋. S ٹaVG;w|&@YF*LZub֪nm`_VSTh$SYxAA~m ䷴ow{|c691ZT^KLe=-Y5Z>@GttB-DLS`Ok@F|{-P;%f=~+,AP5jl-.Z]F䇋}}=w]{x4-˅/>c,4v ;z4fxG:4d0Fiu^/Kf;ZZ`Cѝ~]3!ŒkW%א@~bueuWkOAtHZgOQ/KI?kb l_kz_ 5YB\us8 |ݴ/.io Jkeba%^ciW.lK^z2Qs.փ+K$랿o7* :G _{-^It~[o91/c:߈5Kuֹ9{Z~'+_G̶>Z?a{4Wu]=M}moŻ|Z%.K+7FG|͠;i>֖zzNR~d_O뗵\]_ٝ͂)/)?ݭ.1-#ւEg]*_7`_{ fZ?oz'栺v_`{ݻ\ak_RS1:U؛xD\BͥE wYwamvN➋~d׮}93z=/=_A":V] BڣWg ɞ0̏z۰^>ajjE6Of*iT#|bf#vOj㨙voZ{X]R U5=F6ѧf t+Oz:/}WMz]UUQU|zAIb[إ}Uv밅$h`E0kU+tK=ckQ^!=qT].]a|]꺌k@Y ֺW=?*_}[c%ڷ+yڣ Oll?E:e! z _^ V\ T/M~0+i2>s -k~YT.~.fLc@BԳe[CbvxR}c: 8GUtz9l^z55iT/K%`}[\WU_fpJarAWӺ'%kAjKJ.szqk^a  IBh1` mfJV0~q _TO coc|ĚDaQȘKNJq%iZLh(!cȯ [hV(cD@ŶV޿&O7` -FVM)rFR{T 5M hL;7+UX:UGOĿy }.;//+4]Z&Q-F%6Iqbi KQս!WM6K89)4yp7/z+5K/T˰C@ t*7~au`jhanB.@>@ jrP@K}!SbAj 52So;(#)ԻwCY(#}|l{kEsM}_X@`pQ ACTRTv{tĐF ^W(Dq8LaQQfi2mDQ:³+rzf&nVxc4c&cqAL\7堋GUC3Аe+z ֞=Nz\`{j@I+kXբ79s K}׌꬛pt_J,AY3V|U[2pB[~*!lҤ$gl6ʴ (E_aOL8Y?t~/Iz#A~\ipZD-1q$Oy} Zݡq_?>:3ql!F[ԣQE4ʶ@li>G?CQc,::BY:c-%(h"|d` x^pLyn)N 2hE`1{j|ވ 6"ERrQ  7B ƒS&15b@~h;i]g ʔgbzucxgh B sd&`2'FRX=\>C1&*4)8կKeLm y/`bo,#j'FiQ| ۇR|R?z3F ;iBjx8-=7~-#c2X>H?0NlHQՙxlxlQJ8W{d>N|k\ʂ$ ,Ԫr7\c4e\e!}|/#vr{BQy] d6ZdGDݩ8iEc{ MtSc*%׵~6"2>`(rk[I, @ `Bݓ9+Zd aKRus,\'7jKRq*7NLE.{"W UgcsԦ> YmT,L Dmꔽuxu rvimϨBU9! -IDwvWN!!RƢ+2*73{[ypL-ETM/.5ʤ3V?X%w* 9%*mث#/̎Z.П0#="n@epFY T̕;ҮƷ0WhW,كxX.Hxd:|j?eMNJ '~)~{Vc?;T,h!D<N`%h=,7+OF Og%?c 9X @,Fmő1,]"x~ySub,Ĝ//,c]Ү[h/|^׭(B:iJ_H[pCC񏐞chғ1 J[8~TT:OQ Д%HMG*,p? ,>qez}DFVX1F1sA(3grUe|Lbwv5UWܠ WS^Ӛv'y7/֒:Sݥp-=$sQ^^ dZ=NP|H+90\jBL gPKn =2N--k0%,F  Sx|0  nm&gg Jq}~һxz̬ >UcV=aXl1g~?ۭ`GTz/hpah$ClEW}՗Q^avQݕK=(=:{a6|hn EvD f?Nv-.0PF80)O)2"CP>l`5&6丁4*A4G'q3BA{mJ}hq?>`?o~1rN K{Ev˿Q.c&<54`?@F^!nM6P.{RoL[{1-j36+<9ͱLqWa6͕EqP,_</_*C.)cR遹QEMՅqYocsc*;F;#kgLJƽT B$]ЪL"R8R/N)V̟*o (T= 1ʠЮZO`/wyxơphޙrpNHstF~] &hy$:,9/sD{DQ8xQ,n*Ezk8$|i{[˸&_f0nvp-p*i[obs1ptb9!Կ͒qpyde]F ?ّ-y(tF[@~Ծ`?e f~^cTM/**HF덍do1e.֟f,1gf ݜ<-.+WH@R]X%XVc{Uhq&(o#$]=zt%0 ¸ ,3?.G(@0gw&d ' %)ePmpWHc2l\]UT]Ufs̕9*PwW]3^iW%w><9~UMY]jo2L4A]T߹f_$H,9xcTWT3P~ ފlDQ5|x{BvoA4h8[sKvH{ _V[s۹y2* +hxv_6I"5h~~Q\:sCtNǝ,$fX>o/ث 49*jOBVt?[-hF4Q Rw8B.8t)㖍pFr]cߌ8V@k5bh/[S_St2ֽ/YƸ5v=Kj1PjK#4>NmHpYNLIHZﶔ`˯)`yŠ~`?b'X0Y*`6Ӡ!8/]*]Dx' l|oJ6czCEp.Gc#C] k,ż9,v |Xk+rrD N!o0 ]FiS^acOT Q9Tuc$ѸTr 11H<#zyKRy؍`O`ĺ1KBՐitѸ Z?!D߿ . ΅^z43*^osa+-t=WoǤ/u/N2@@ yf̟,7`|y#g v&zJz00{1@I(S#߿ƣجc`ǿԈ٭žl| =&bGnt ĭ&>U4x f<#U0-G9t bx͝H^y#06v >ZqaH NlNĭ7 >5SvX&l>: aImRG~_/P@# l!YaU\pM$ t~\@H_t}>/t꾵Fm 躅wMƳ[UkDM/м |ױ /)(_[$}٢ߥ^TG(i 3n oJnÇv@)o4&g ߦa'++O`~h@9Bkl}eJUĺ0}zhI~HDQ,ZvbgUi/qyRJ5CR A"};;B`Au:Y?5lO_ A )` Vp)+L$}z{Uob`kx E5 G<v 'eo+=sk.טG:{ O; !3O~/a~ ô@>r0dր TRszZ"lK5scQv^VC-{?eg'>~ϱEVݗݿt/,~b8z 0[馄̘w8g kk{r#ALSVuV9쒇_JwG?`$`RG s"lTt_E?L$ht.IwB~(~"COG*_[/kVqI4m8 Lg4_l|r6{49/] Zz''_y\댖{ ˗I* \[}#8ԣu~=CivL àm&[} ܃?Ogjm1;k00?;%+A##{LrhG=ߎ?Þ<ҽ^[wUA42 M{d`p[Ag+/tAe8u,C:iOn\/VT+_ h/g?8@&+-"y At *6$)EEֺM4i ׯK;?K-{]K}ȝ,&ߧc\#'j\)Al(`4 q7[`^L/~3`CG,ת'{= Cx{?fQlq^Ga.eat+[ISѶNTh0 OWAE -غ]",=4K`!-$f@7ߖ+΍YE3 [UcI]+\¿`[3Юv @b8W $k-qE@{/]h`/nʋ9bA\B:"oŒ_k: =YRw4m=AJhUƪ&a a@ #zHSb ٻ'~x!Y~EljF^! ZK$FϽ^3@*Ҥ'%Z1*v$ XA:S=!/')dΣZ7 +؟Nb }\^|VYY~*>/̴? :L[z` L 8oRU܅_uf}7;~W$= NJ $_?-Cc8u1 ( X+2 ~1K`)67m O&uBh_a:]t `~_a32iav ?ia{Dž 6f<J3Pxkz q Q{ {a6^ցWX,cYŬl_cH_Oؼɇpv&<5v?z*q%+`tяx,`CFb(IG˽tVK 6"gK##kMIԤW ;dYy Ѡ6]c~E@-s- @"}/2?h*?`T=79}Bl ŐgKHyn$!oAx.bZ-C2C-z-V?a0aZh5);V.?d/C˟6;}̶жSk>ucO/yK.S 16$q 6 %?A/`};:e8[_zڤ,vl ]"bzttdgb<_&S*Ekch"]egLٮ;bT:'?] ( "c~"C~ʞ-0.Az6*V H?h=ta#БXz]*cAl.*`r* w,Mv_oE`L R#o PK1| D`&aK~^ؼ\Η6B~,?j,LlH/-X}%v)oT](I4c"0#Łhv&Mv@֊#6 ]G.:hk} ?Z8$z?4/n4~"')zKS]WV1Z(c@Q@uA3׊%d=D_? @: h1hɵ/.ų'CAҭ[$KC>Q1.V@`WDD?פ\ B  Dtx8C~BP}:v\Jab@;ðlcz_ ZkbBa}{Yv?+z GU'2`4rT,GFv=!))Ap^"ĺ G@.|"h- Oa.1ET/};1WT9W!>`4K )Nfra?T;~<[fgKccnm1 i{4i#adZ)m-hA;ߒD6s$]/}oH,day/<,\,,ϘB/D Vc: j?4#vm/2]|yl ?IB C-Իv^;AAd2;}@2!Z)޷w=]plV/z9ИֽA|"{YNe'K5CjGؙoZ[#l!h?['J:}WvM~6$ˠ P|vn=~İ.۱ }q%}]wgPw.uZ]szAz2/`Z~!t5kI.A7iy_v2o/?E;.7E.{&L(Gzvuȶ**WZ>D?*]=kzC;Z >&tz H}В z*l~P!^0FTkoCkA=ta3 20 R .Շk-o&"X0=5Ukcw]<݉{_0!eU}nX16g.7XbtJL!RXmjx7k->gx&"|ZíL0O;^Q>G$ν+ Mﯲۼ10حv)?cl`u|ji& AT:"={myIxǘD|c\h! ]W ^]^G"[LL1EӳvY48Mc^} UjuӄGYlxZA;-ؙ0=l?xi[_/v.UQCI! GHLQ+UnqB+[7{ox߿|A-2A?V5wO_l ˆ{\2c-Pe嶀r %\]dQ>y0DBq]YC5wM`,v|Z]N~nz u}{[+)7T?]&Z^lF0{4 BK[6H.0kROpa!Œ\زc7w2쒯dUj&z4l$~՞ +F aX0 \x`<Tjr?gş/R?}{"Ww~0{-{Uw޿/ep/\Yܫ~xDO}-&=+Ge|aYY%1Kh1=6L05F!/H<{zVc:Ds?WBM9|S t-/_]/ae[t}, LHĘ>&?ȶ kcߺ/[ $ .ޡA"|8얪.*IU V+oF1140=lWff뻷"7G ܮeWGY%,|b1BlV(Č G}S';T)ayP&Jċͅf$_7/m$+M"@aD`L>F% 'O( t'&CȒ,4XU*́4 Թ⶞THƑ[m{N%xAQ1N !!sbǤj!@XV0PPl5nzwKY>^AfRzT e*K]W}jM.dVUzDև+3KK[R4zPJo#v,Y/.Q[vqKǿr=[qV]ƫJJ%2h%n\۸Wy$bjmfXR)uTeo]b8^SK<(/ITy1iZtZ4~]/|=߾쿬ch<|o,nKc= lǪ/'4wt 7%})m*&=uUST>A*h@ {QsxLQ\&fq~:1L%8G>/^{ݾs- 67w! 9mlwtQ1ly䱠5M1s_}'?>5{~lk7xiNST,풕pR~*tʛAg/Nht~d]=F6@V-kиit"(AXOGؾEWpEϖ>$K>VOWJ"WZCgO0>#Vaw=U7{K^->y1Qw~/ks8}<>4\>Q7\!*vIVÁ1b A=LN$99L}RGG"evR;[c; o"+`\r/Pit!Yu 3^30ےdՌE]Mu 3$gWC<{Ny6]WfPĉj@nDV izu2@ÊSkn-Ot$_ !/c︽_1T\\SUE|$uP?]|z\o{ nz&HaozD_DpYAsׯ$yZk.e5J3޸ၓ81~0 O3RwF `:^e͚BVRj,7V4.8\}}w| CBheYmb\-V /"8k(ˎx=Eh`)jʜ ӊ0J[X]*@0'V0E;e)m! #Rb;FTFqxv钀ttg_2ޡ֝uDz {-!"僟_[M?3~ $_X+[|RkM,ּA%Ώ*Vdr-lHgaLU?1z?1/T轮Uu+׿K>) .oVySVmߺ̻/eo]K][MK R3a|{@}yO]n*kfRh7k?nu~N:'zkڽvSܶ딽\o8Y]r0yh_IR.ED%_1Uڑo*#5}Eh KׯVv/nƥKG?k}Wzi!=.רEhW Zd]콒[J#=Ls@_b; qjt XךKUt1#NU{Tu{%f>VAuF?Gnޝ]Gb3^cQ~6?Z/).U[˾Seoyo~&}* O- 4쫓z.ɿs.n8NVA-݃I{*:.t!ty@!(E"_~ȟ3%`zGEF9[ƠT}?(y ^(l?vօ|+О?[}.v"&NZ/_a{_[ZuǮl/K诱zU/_*Htֽ QtK7b'#)W+`IՒ˷ɧBPş&(t(~b~_}\ v=;eܗߗ-jbl$u?Jt?[tbh6ʙߋ.WaQ/+ua#v-޾GWmR}gOSo>Z[16oKEW=>R?!(>)YL!"u]-z/%%=7{ViO\%)VwMź=~/c6_*߷}m?խ#4?[A`q{u/? u_i[/^$Fc4W0o֪d&ç%[uŔvaŨNt+~+MHަ:lآk\(гsGdt^5xox͛YW_^-lK/F&6Kk͝~^c/?+OTt~R}>8yb;e͈}xƔ5SG~/2ףQd! JXQbK%2[n;Bw}.6QvFs 4"ʂNF0CF W P%.Gt ZJwhLKh&}OȱoVӴ4#. 7!*4E|޽ ;-IfXk1c;5PZFowz(7Д[G {|EFz>=ᆳӫ_U[~K>}jVֹt-- 1 a ߽W_/Z^[e.۪6z:5z2vХv~똽.iX6$ IQ3#Y>kʕ:YWW.GI̤>e*^z4 >oo}2A5=LmxNbY9FX=o~0"Te8`wK: B\ݴ*}[޵\`E1wgoAtwޮzW/(ٿ aId6Ry o[ac%A?e b7f&Ų޿r/}Wuh$V J ~81!x߮΁#z?gK]\OAt zAR_T7(xBv luAWe 7:Oz ]/M}eߠo]SzOZn0+vgu,e=hRS4P _W]\WO0`ڪMw~}/7UoU֝ ` -ܫH%tZ,e{b4 ^;SX&cg{9j3$y/R"-޺]uUUU./7ukғE{[kZK~ f?H?d|/b NT`!n\PD4tڽ{Qq'J}["0ʨZ;& m\E{?(ӢvYDQ N#>߉TֆFt}eT&,ăg9K^žw"_U /cwq [-.?*  +w } /IP{QuLXRgtl1BZ,3TwJ{ۏ J~8n,#@<8X`F(¢{Ca(Z*E ^OZ%Rqxu"m2 j7>X{ׄkUyVUl*յs2dFcŷiӡL\rn?z`W kL)h+kP=A%xIޓؓo﬩(ߠ#!'1.FZa].bqOUWKʵbwi^swxQn^șun(^(.e DJ}RZa< ~,(Ȫ^êvlG|VqNУ]cf`)OMCssWFkKy>)hn{ԝg^-.=]-ro!]q_AKVw{|eWsl~RnzYq"XD}j~"סd~ݵ ,kM\ $ĸ.9I]KrwmCU}r Yz{n+߾D[؀* ,:ըj\K~O~0]^۪ot8^8ׯokz\83P=?~Q-bz`x%'ߋ0ⷾ~1W򳴿믚ߌuR-fb_vS*~9wY_} gOT>}zHiĜ'Ⱥ% _Sp`$!BݪߡD~$G'U'ĘrllU]dׯ_!%m>@SƒLeXa@O5f^/Vti=C+Ƽb1J'B&~ɭau]jUU%vk_hEwe 89{+Ih$_mWؠKV7$ т^!>1t<-9}#ַw0yaB;Nw]>nǮDk[믿 #`R^cz<}Qj`^]EEZ%a&<<0f~;jiĽ`@U`aDŊ0t*:@xK D]kZ0UU5\ŮCPTWXy쒳-cEZل|x†Y ȿg7lt9,Պb,S-bΤl[귴ٻ0HMʂ_Bؾ"YvO뼁B %~dsϾBoatG&včEv` 5pSg5@}UD`&ou`]ї v`VU} l1 !Ah9 Qi_Qi(ꣻyJ ?pVg6Ik5w{f!itM ~hNP&w{k^_0=/ůf0tON`-=:> vF~O[.Uaf離#ܓ(нﻜ@{N=ʩñ=H |Y)wyvשPB(Nñ苽_->. iB7! }Ug ;[M6I U[^+ x+ ? Ut4oK}>^H!(0en#jb2{GM t'q`vn/]^S2ht/KeU K%US_%UF )c?@>&Z^\z2pK>c*۷W/ӵkL T=C6E7K _K^~u !+Yi[ܕM@R}𝇩j@zCx6`'q/3[\WIҺ`Fо%uE~a 2cدZO3 $C > (z:%OrI=:K|&n= m1*=M+JlzhN열 1^p.#FeM"Øe'חh0{`FH<ƴb8-',ZQX)Ύ@Uvi1@Ff`f#Ga3aM"W*sh/@&4JZ ?v^ZF [zԷk ١]'aGo1:xam_[~w}~v*]ڡS*Ѕ2(bM޾ q~z 즺vV@ Iwx`؊q<ރ^;(;D: ~i^آv=KV!O{׭iW#N5޴0M-&u[˿YcVޭoZ޽kOҽ޿%Ҹ@'H{p $JcBsNtzBr/0&v$v"k!$AeK奾޾jO_z4^e/jV1x `/]5pRNI°!jOPTC|kL]3J롋(CƁ\\" Z]R۽R;q83"Lat31p&/rӫ[1wp̖U]-6)e,ݢiE.Q~6عKK}t|`$`_6IY5V,/Z[<˞}M !kO7{WOP|OU:?GA컿iwwf5}zt2H`ǯb;'O6]xo؄+t gC7}߯9և{}%z$]okU%߮K?_F'hw]߯u]V݃߿w.&}:Cl)nCWS;TߜKgi}Woԛ=f-#'NW]/!}Uo0lٿn]O&JON}m.{ĈNg$]Wy}K&I?E\ޗ.*sz}IJbuԺ{nĈrKKzv}pQZIoZKD.k/`.^f.\zVE5Zֵ֟5.eZR?$Cv}%u^)ֽ-;ߢ7!+\$KnojL_ <#DLjNdL)21G+}&wcww1Z\r۽`-]+KW}!w^K˛ z꺭UkIcojmeW!1U:4D^ㅠ}:4'gBG{-f_(H:0 o UY \gH{kw?Kj[E/(JUV.ꪾ9T_*؇*j{N,w'm=ϗX|n`+?;*ׄ_U~_mVQ?MOSZ̦'q[MY4{}9zKP0{Ï)i-sc{g'#J@^X$ `0kh$N0,ju_1z/2k^UEvb/LWr}b>wzbX, L/{P\hV5ZUVzZ} 5zneG8C4XTC<,8r5Ap}Ծ(]@ HH3( k?/S7i>Z)-BLċ V^a]r0k`־1JԂZL˪+_ϰ9sn+{.+HV5P:*.z+KZԪ|7Q"B}곮Ӂo|ကon]n8Q:Wh("wr@݃+nk*w_Y/sM(=hoBQ05^gkZ̭\?I]\"۲~ĝ>_U7ĿۼenجV|WDz+[E 'uQ}˝kJjU&^k{pJ!+ʽ`y*+;Dϕʝ̼ ~ ߗ.hO1-_O.V oը@'qXw7ZkkmFNq[w}lw^ﯧwcv\\\SyɈ9=|z7aG"v+UWKK|V~.U0OJvr2(@YL+HI+U&b\@dH+t2ؤ9>jx mU y}?av+]~3Xַpwޠ;ݾfq>Vƴwul&n2l;FEĒF{Q!/.ϝ jK,2ߖ}{Z j0b|~_Oh`%qUlb/F@[]w|xj0{[w]7?Vgs!X|"_"v9f3Y'1֧[iGR) b*ɗ힟{%E$1iIŜSUQz5Q:\]j2|}]VdM ^ك2=H7[zr+?v.@㣆ňgK9{kI#.Q>.MF\rW혿Hw>y@=!]\иREq[7ww.`.c;+ ")}xhkhRVTk0d /&]GnK*ɑ@{5>9`Lu'#MDcQQMzB~ڽ"ywrƸD/(_)*o8O;!u_ڠ߉j}|!:ɭ|% -Ӷާ!Q"N=WConԕ%?N-bXw˯ pzBk_mq=$@K_ի_w)}^og<Ocz^!wU/n/ϥy6eh:^A]y~jKXuk_dmɎ\K;ԜP`&(uyW;0q}0ti* =W##?-tI߬)"g= }{ޮϏGZ﮷{\Yh/("@JK4.*nZRrBWn#s-*&nya~Q{sh?^O'w-}>Wܮo/ '(.w߭/-z޵Jt'wկ*ڑ]oR׭}/JIȘ`_#7@˺QR˪eh*ut }?mJYD3ɹ5.) {NRګֽ[V,λ%ঃYw^vM{\ּ}ʙtsoԼ@[?b[Ĉ'FԽح_K_Kň^eEK{\jK_N ?۫زbfҋ\h2$揋]K/ň;F^Rj/o 쫗wUΗaHV_ [rh5xlꞷNKZToݱ]M~_wkyN}{߄w~)/q>L&g?cd߿M}>Rw{n zW޽aSG+5U گ1K[ڲ4}#{6j4Gon ThJ Ω׭{'^::4kߥ߽oO^ONӌ7jZUԜ}ZBIFquy|G؂y94/8s?޻n[T}VU$;]E/5uk=*UUOhD$C7_:=p޴>~M4V}'1tZ%.'+-=uIn}WiM"=U):=m|C z{bZQqUkkor5BQ<6-]q׽Vg_ϮOM櫩UZ$Wיw%~1oo ˭W.۽޿ܝ N_ . ֻ&]}n/ww[Id%uĭjBhqgw&`ݼuzZ \Y)vu$j+w 5pv ڻ(ʶ߰GAv5'>$% +yטնwU'kjkֵ7_=%򤞊Hq$X! 4Xh5j79~V1BYLؒf ek1 'Q08`s &rx`rbԝ|_}T[_c?&Bl{[aUȐ~Q*֟5lm|ʟξ8LiSa׸+{Z_Ʋ''AGoҧx$oG%.bTQmi;|M?*%=hݽQ"6Z&YsXBn~{=1={by4P~C󅽝hQ<'8svxjH)JsIzSbs}aܟBUB't nf4Go9vI޻ Vlb\տU+74b(:rn.)BSW {H=b2 gU[-"|[a~Z&KRFR( }k.!{f`aZhc< cUILqj)$is ;uhgl r((F7Pץu1螂wv{ wEX_k]W ]}v{Wn A`ǜ{Wt} V^7=b^++??z ۪ޟR.(_Q}]DcVn0Tt;2w{~x ?k c|HAP"g61q,e~U_{ hi d7W%xcַϬd=/Lj͔x^<Σ{ j⯋u¼@gY[1L b/'U *9 /K]Ujj-4J}m_:hƖQX{#]O]{o^,eScȊ6.fhCCސʞ8ڀ7෥!v0 ' g):@}a;4K5(&&[~~z->J!cgމn+GP]B/.,T@8,3WeʉKufzlz=I}JzDZE꺪֑"e0& ax%^dl _t+߰[jS Ugt >{-Boʟ3ײNU{ oe SIX?䮿)maU˱fbUtA1y{ c f ,'p*X/-0}oPߕȳA觡Y\W]tn/[#cUbw{Q&>.K ^ V-V+f|w:r@h 8+@c8w-5?w!›o|^X Wfk!8r\hBbN0Tn d:nvp&pɳ^pCo-wJx{`Lށ -˚˷ MB K{E,%63"Z_c$z||"N> 7deҤQK!|& /J0y,6 0.9mڐ Wj!gS~Rs`o}yFPHFlurucS5AWk@JT L׈.AaT:SJVܞK̼ehֺ}^m]@\FQ[\gQ/[C>V4q|…+!IEdg[Q]߽G*zZ ]+Oɭe-VT@vcP q`X#/oKES+W%݀|# R=A>7/tF0|'}e*Q"f6q7a+Yw|"YF  Fot׾AF#ϑ-YR+yrpָ@ٰg"irP,KB'~z9 || 4d}q,: WWˠy}i[RTQ]d\z^O_IolZչB"r'H0 ڿ LJz-v]?~=rN'Nͺۦ$Z ߚM[~ׯ-k?ĝ._o^}Q+H[zTwk=vd뫕U`Nn=P_"~۫/@}Sߣ- uί5zȇA45h?ko۱u?{Um|OfߠQ*Cˑ0~zrr*R0\&z?^RXYq&*.!wdQg%@Rt]%Y{ci}j%΅z]T/q%t}Yd.P?JoN~խG^}}_͠z}UoO}{|ĵJ,]oȻ}rA[rw$ c_ 2ו׭uW+B#k;s?,F_1꽡eÿPˍ!@m~Rqܼ`Zݨ~e /7TY=FYw.!|ZcF8;,pg/5^\bSzxk_*kk+:^c 'K$;bϴx'ixmomT !=A FaEVѴ*T#u(Խv}{ZC״)"-,lJߣI Q,w$"Ηz?(_ǝpͧc}ʑ=z;=\Ntֽ-_eRu l=@இm7{K!Lo˯^~<[{ia7_}R {N'3H_;z =h}|%қ }.C-&L{-v`3 6>oa}KA%<߿/G߿j=.^%td}?6Rr?t'(&7'~ʫ}[4}goKJ;gd4CGz+:{Mܟ+_쏳.>zޢz; 겭hZgL;)u]K{_}|$ͷҮ:Y_A=jN7[i\BlT޵2׮֗Z_mtzh_f2ٟ"jIM^~WK':W~.]WPE_vzjn$}k\ VBr'I9a7&\p.VUZoMnP[kڠz|C o'i E.6Ԏo`UbZUU֩W_@j ZߕWkVDW |*{\S_eZ o}D)]߮GZ6Q9zʋעS}^MWat5F긏]tw6}ܸ'w>3 tMoKw#ǷҠ}foXT&+yfĐ. 7'-fg-\똝%^߳'Fjbv$\E{}D*Z5A=ػ~3nUE7[qX|0a4@[">|@+>ֵX3Pph<\\28+XYٝf+9F{H&YM ^OS.%uԫ_qNaxƵUZJHG1/]{C3xQ=ęx`[Rug1Qs`Y-ÈI=PE r4DEuzp}W'Ɲ+߸|']O2u0cl@VYCC5mWCh^{)dۢ'd/8r.6QU_;&OʫKU_ E{%"V!ْXeݠѽ9 } ߾…,1<4/W6)Ǘk/UT}~]| @{j4Z CW`[z3X+WQ]b_n4t[ Zж-x0]E]^7%ɬ:]!omRqP8g_YiiVA }]ˇ8{%Ke.T?l脴6r_04XfƄ>[ cfv@nm~dX3 nsߠ@׻{\o TQ.o{6/[G!J?5>͡|I Eߨ~+2 8jl証(QxQ蘪7.9Dy Ft]E̝{OԁE3P@c.ǰ{,V8ƪxSO@VWU}rۦɥ$ٵgZK 2˷GÅ/XK~]Gkwvo5DZHURІLk:$.63knt};?վC/$.߂T-|av8+'0uԜjs)Ehgk6_M(XeUrjdc(tx=,0o(n1/o!!;{M.߿\SU 1f"mDyv/[H/Uz%nl:^a[ǻ9b' /96jeSyrJ\߄ Ex"ۣm UQw?Z\MRB#Mwڪ/[|U^6 ,j 10oCnK;޵[H>𐭋Mf>}BAUyּ'FB:1biğ>낪o'w섰k =;n+wwi='L~6R7{پy ^/ /+_C ~`+/Cܷ~2yw)jxcO5~E]WnkV_OxcL Ot 5Yl!?+IZ7Lj|[D[~QW =6;-0DB\q7^O$p0=ooH0Lyr-vרۺ\ ډR4 6a=u_"ZVw RQK!c0vL('O_gthZ_AVF y)hP_N7 zׯ&+~+<ӽ|"-}a7ڸ0|=%TtzDtG߿C,[ܗ;kA:ӺHBO^yc1HYacI`0AU|˯.B ̱,0Ynw.mRvbG ,v6sRo'sxIzC$鴧{iC^`&,OWnk$Mv {B\`B3E²wuZz' Ví)W_vK*9}`a/= V2r ⍕Dro[U )xIKF^ݗ?uk<ga5RU{rx.m>ֽzť܎]% 2 [nr M.$S ;vDĪeF(6x8_iUUv'c_Pz.s=~65%v{~o_]WVG?DmjRXuI~0""7"$L}-hޢyP߳|Ҙ3ڽue@~u7e6V$k @ǕJ@ѡѥfPI%đQ/:MM?CR*N/}B. %ڡH|roe_:^wJA6_Y8`l?I&+S^K>~J90~됻oȵW~kI lP\EJ_L?֙E?]WV ~_.}MB:6:(_H9P& uAiytl~/`BN%on-d&UH{ |>=[ ͵yYnRvz޴Պ_Cu09L]?78(7hK@rKU:^K]m/` hR39qd-~jD:O~.V1{=ڱv]ɠO%z~Dvf}$0SlRTBqf= BIXGAkP#8zč]'hFmmԢ(됱D.U NPפ bUu_-, =?>o;ּYh.}z"ҮG_k݋^ַA=(Nzf\u؟ r>z^n)t>钏 oГr| ת^Wl}iuBGBck@1K[?)+Ϟ|ǰNgvw1O_3w]2hz^*D]*" J/tOIEx>Xf}G+^Ž/)"d Fֵ|wlxW4MPC1m=gax=r^n\ٚX.-^Ioʻ,5un-hyP$N!Ì:WqZHǖ~} ^AOA_O{}锷OBos)CN~SdTe/mɞ.V ^^*=zV{E}QKݎ$LZ3_#QMe[bϯNl#_if?gߙ7M靪erLKq/@WRvrֻ?~VG?A-ZIZE\ɹzn_~+Ү/}%A5@pW]Rgȯz]$(t}[/gz[?VmR_e֮Guyimk?=~z_ˡOMkwb]}VkG*B\s~*oUO_NnRF-E_]LJd.;J}ZVww.rz*rU}=)WRo_?ߥ߼_9G[_ -֌Մ[/믮w|V3ww{\&2ǝ ٧ޖ{Ub e?Ii*Ob ޑi{*ǻ^OtCWV%< ׹K~z-Www;o|"f+x>목J{_0CC, `^oA]8]eZUU)4uQ#[1 [쾵Vo9k#nUQ3~핆XGb֗FLFwqYW@WR0תֵ_];/dq|¼[İ@WQn_ []?Dtkwǫ){m2aL~Rsv֜"LpauZ/]_M~ [wy~;io6(gAk_ȑ{Qcw"v^w@];ɿFSOɱL:2@^߶8MﻚZ$G{(AvA Ai׷o}jx.oqZ(Q47S>tz06߿I>wJuwϟ}-}^|o,,_Vť<l3*̏0عyn+{řVOʷ9 ۪׿Ux]Z˵gw߮l[gF~z%^YGK|ӄCGHHpq^+K$BPLwbc ?K5 m8Q^F+}|>6 ]2L զ )JLF1N+oL蘐 +}wo4MH%UUTUUUUUVuͭ9DXlȗ=3]{=i-j"n˝߲ ^ww^֢ Zk=; _x鎆 ؼ—_~gj/}/]xW<c~ƞnSisT{/'.}T sGFbܶFqecQ ⷾOֺQ^E^/JO4 w}4RV!lVYm/wwv?wQ6t {H3|2}/C\\n}UqePG9,DB ,y^Ybx) N>9&&boaˊZ;SAywJ$(jJan>M}W疼%]t8/|$jww_^@-]' p;L/XiדOI+$O'ҭD rKhs ܤbG,t_չnp}VmĊ UAhSM1,ZD_n:crZh]o7ks+ ^(M' x6Al.1OdYI'wU֫lJ]M֘?]}K;}\q%dL˴W EiYpUd!w[M\ܪᕽW;ݶ_qM_kM"7d):\u~EyMUzZDPz&?s'g%eK#}=A*ؿHg֯W^=hLv/ŮkUBD[W^'TdWׯ]ғ"݀3?+ĉKZSuck;F}'u 6zr ı{&}K={9ߋ4{%UN0}nq"쿷}_]穅P^/_J';'-|)SW"2GIk')]Dz1D[ :~IRhD7i_BܝGޖeV\9+'qó|gl.?{v-}o^_&ji_]z}A-}_CU3l>!v?R4D g {ھ߿A# _{ .ŭ.@*UI%4tJ h9 ʘ/Wȶ`OoZ򭞯?\aX:%}[V_rVB{&mj0'[y ӧZIl ey)um ~yEuu|gʣ[`[M}[o2KۂUЗ*i׿zT$;Ⱥkio!.)bPduzֿbXUZ#wkyee"6KL[%ۤV߭^Fwܝ ̾-dNϒޮ};WEC~Cd6 ?Դ_;E\ZKOٽ|k_3,ݽ׹ސD,kQJمwh{U3,]*F˨8}T4^)ߋ[ ط0z/_atZD#Q߁ ! Xz{m"Hǒv]Vؚ_ezo!vv+Omv޿lzggAkӬ]uJKcu fE5u)z_ϔ~Ĕ͠~kȷ~#㻻Rg<߿Zm ߮k%MV])os.bYlgmğIm_f>}&$]YK߭ؗX{}@o/udޖڿ@0Ĵ_JOּ~G"Kޕ[v5E@og&-j.KV~߭|G7Z^Ru7 ==.sk%7Fu] K_Zڽ_JϯV޵k}yF~e²z]Ggȗ_o>վSw|Y>ekFv{u*G]U-kଽjo۟^y+T{=u7W;ĭ޽뾛UU-s.ȬrU̝ͣ$}SZ[^_ŵ[=kd~WNb_F%r넞 {&v}_˻0ȫD{-Nbv ~ǥ}W7k"|}}g.=v߸»+]o/ٙ}~Z=Loe|t`nYhݦYܻgom_St~wݸ;]dQ_=uwv̵"Re ε͂a{~LKzV7?2_ [[p@=2 >6k]}~m,&ڰ~jetŽ^ˊ_zw]Yr+H"ѩgňߪPiWSt|a30 um2lr.'N|eL4q޷0xmKM-7u[5I߿me&eX@[FIt}t|o)M~<2dUkRUqwUCZu$I}z`H0e'_]4']\{}O*Vs[/U , ˿+yGz}>xz թ]qau[>F 2^֒).Zog3.ZH׈Җy'6:[_T_h({}tqrKȫG02gGͷra^U- >*z=XP죇ꍄN=[ěZt_؃@~gn']aoHVy?V,~C[V [*{{B 3_Ơh?]LـT}sv#~>{#K FiwT6_z4OFm4lR=J׃ʄ0\mIa攝m~w1 E}?7a>c֢ڛ<؎/H\_yQ eJՠ0 ;H&޷6kʽ 7Gg2z'@{a^w-7X}Akc|ٮQ;[{~uSB|bicvoՃ{V"Ւ61Z?WW[Z׫A tw}0M?w}[Z.A!@`{R|=i~ֺ~k{wJ+VW xi47ݷӫ̼4gDʰe1疕 \{nK(7t^)[1{% +q5L]7rzp &OInHۊr:0"HzAc^S ҉c;:!H]$ " W}w0RJwn{ =fۜĬcNiPaTV1OtܡnwN+r|' .e4 ?ZTM(`챓Й,}o6)-f(OݾB"\/]) c]t심d'>}1bҫ4ŖDsS \|}{(LM3pϹt +_O\ֻ KwwٷSu7qK(E|aQC1_h5i"&~&_|s9pXW8Q>4sRcOvQI-/S7/^VUłWZTΉM#򰇪滻&CD#o}޺+k~D> ̻l/G5-޵Z[yWYWHh,AlIYY{= _+E]Wz?ּs {zlnw,z>1hͅfP^$}j:uп( Z L>$K<_my*1_Bkk!hAskS?amV5X@i鯺Tဠ K@H.VVRV#eД5}obDoԷ~Cjh MkS=~}6FSNGaorde[E?b+@6LL-3lf֓ԍnޗY!BztlSB&(a3c>&ĉÚw5JU%ŗ`+ct W֫'ZvVz_ɪA+b6mwg@ėAw|/#ֲr _)=W/eQ ?%?@߱$j_Ͼ]z-w> 6t}Fh_+_iRBNcuo]{UEvWLбqk^}lh2@/MWC{0?*'v4\YtMj}NʩHvح$H5BOByo] iz㋰t#,!_[1v/Uv t܋2zk^ݚש?q-!y_^^zȴ'+ @ 'X/`$yn~ K[Ū`>%_}[ _aE0}$((C}^UtVktb~?g\8(|gkR>]{m'֌V?}@? ^Uj߯Dz]ėCu >wroZ_}tC|l\{WWb4/OU}J%('Rǽ_ɭo&^ٴ/ѽU^>7vyB oeE_^A{b^ B6ѪP6)C:{2a]R0*?r?K^|]Z'CBꭲ+!e`m}*&=//%m-TK]m{%" Y;={>TO{^'&˰eyI-k~bPM}, u!$=6 FU{"rqNE)'C?ԫ_VU_^_#b`V_#^s7;/LH >K: GIt U]~ܽZҿ}>n <;^v?UyO]1]pw!ӽ1WkZo?]򈷿HHߴ?@srkR~Йc9Ѕѣgo>zr޿^TYH5Ry-}ZULVu?W׮;U_6zWA7տww9[76[їI:\vɺ&IMl*ߴUu]}V^}oMSrK/잾!]trri}wI۲U׳h?Lw~,*޵O@ ,6~bw~w}}6k\.wN+}v~Mq^~|.=|V)jh?z\Xݫ(o!6}*O~2{MnY~F G޵k.*X/+锁s;"=ǣD߼NV_}/oU7KKz뭾V0*^8=15`v[훽5azhYg=Ss#WwJ⽱w1].z^-+okV~;2yK l hb^mLP2-ّCQo UxQۖ o$N{_b|wZ쪻u!5.Rw߽iCL(gHϲYEߕ-,'\LLBI].emwwݛqw~&[|5^Wz\::K_ɋՇQ2dNa&VQW׿zuJz~W³A].o≰zOAlRjTIhk34@]PUߣ_'sPwwrଶTĢ|{xVnO6>M޽ "Wʼn3K,>%ZE } _P @&gm!A*>fq1UDi'0YO0}$qxT{_.]_gde})?el;Ks#a]/Hok֔-Hzh(F0}UkqM_pR[{^rv_DܫzKdbt~PNj]WYO'TM ͻLILu]d]i~0[}<:˸ QoPWN꘳﬩X 7A]9@E *+wR_@x#Ifi;EDj;V_`^JF 8s}C7 tQ#DU}VN(E>~?wwG{ˆm[y_[ ۧ"Ϣ= ^[]_W=:|+w{*{C ]lU?‚r.$Œުf,V#/wndb>}:_bŮQW^VҤQwn wA <0ea\o-+A6`K*x)ЋT7I𣓿Z~ꫯ\uC\%Kܕm-n!ߊi&\ʿh: qUV`лr:`Wa7}w>[ޛrwWГޡ!O]~m5{D %u~lOfZݬ.*Vm *V]TAKx'ZzT)/0Hun+H4<%eMnt>i }UW|ґyK޹ ֛߱c:;(NX^aGZatUAX ʉ=ރ ?h%_rVK~/h"}ݽ~V]&j?t~q&l)Y]8ęg/^[޾1u]Wתȷֽe^)kko^. Ė$/K˿^dcn$O`bwUW (il~NzMr!(>v,~%;NĭI+2Zz>ɿ⩺ct8vWA[p[÷^}#? 5tKH;{2a+;cgCtsZ{v^-vVmL[^ k]x!W+}rlVs ~KH$~>LU#hldbvH߶{>"}v[t{Uپ9j+ F#w3GIskjG*ux&k)m7oo')? oe W^3[hao6~ko^ݟ#u3Rmudu_߾oZ!n9;*_{=K}{?J$/?t[U%/u[/O&GKɯ[nYmv֩7}F-/*}[_E=OϾ SmJSU\C==+^ 1S~i*ޫF[egt^k2޹_6}P__]>]z))Uj/mUU )sR[L r#ZŤ*~D~$O uǻ:(΂`Bb־:{@\}_M&ET[qtN?eya|sGhldyڨV(it]3Ot};Xԟeq]kR}w'黻a/-xna~$:^ ZOP?ʼtwz'1TQl&5;PKh_dW53걅+]E="U-'iJz~ >&x.^ ձ~Z"n6>Wih¿}mHG}+v~~U@ktp\w}RHUƿ} W4m)lV/|aN [ I{'e=J]85ܮ|(k?+^#7WKf;{{*G_\6I ¼L; ?w|zt@0ԒX&O7ң}ܶ+_zyt_^.]Za.n_ai~#񦺷7`[!u˭hUnr >h熥*^gtAn^:W:wv+.\jtn].a#bI HH._+!$I޿ĜʫTa4{t˚{-}hXyUCw{Ϗ4i.GzhӘI_V!aW9Gz{m=ӧfgg*r!V \?fҕ'|ٗgtGp= ?$e,kc kO+ov3hGf[d4eH@o &'n4zx^G讦/e[eLa-WU^ئv؉۞}"OƔ|ွzkI ,0׻eu_QkA_;P.g&~Darw%]A~ ˵K^/lv'U s׭Դ޷^or/=~_?qa,PMlk s܎`{\\+[HV4+ M罚#BH| Z%T 6[9/&כS tdV+wwq[߸> EۨJ?@?KjG+{xg{@~]`.s9r5yv}tZֻwrtZ3OOVu+䷝o7HzVïdH/$x",q.)R(,6^+a#?@0v?/`}r/ϮV1UUT]E,"gꪺr!J/}AQ)sktﻺ{>đ /?ʑ̵XtX@廷-pf5LzڙC]_=zK[AϤh?_c%,;Y:Vmd]E>*E;̹kM]>6I,{/0VwP7-vN.?= .D͆f UEySc$~ڧ*wn!waS1 u׭sguA6e Ia=#/i EYI%:05^3>EȫwYcu|G{$eTxdG~&⬺DϳG&-rg|_ k/uO]ĝUUuCм9Ronv4Jw{v2+A rs rx^b*ؠc ĥ.j){K7ֻL˭h@^ïaOj&ݒCR!Yޗ?{Ĺ=1țoq:*i:'}d2`fF_غv&P- l?* c}k Hk}]WW>%!}\4LaembTI_#ǪUW:m?BsvKĘxzBګTgZƀS /OW7K {Yz1<[%$}{mW1W7Z+ p:O_Z ByB\:]B9sjUZG)vUY;'ϸ/WUؙj2cP%{[ Hmkؗ^׽s %ٿ%Ϲ1({/zRBB}>H} t '2)?}.@%BOu{V?d>z9;%߿Z^y2ɾ+9t-W}lz\e y3>Jj$A)#3 ZiE>uOo_袗%tWԵ=+v9/wuȘ |uXTn3~Rh}}؝+K^in^J~'aOf^|I޷}uvS?|v]@e.J9ZR-?dCtb]Bi.AW{'ę}:[фJOIouj}ou^/Oֿ(X{vUkoף7ݻֱOo!,=3֬kO _(G~~E5۰Y5ONWm0{Vlt?.Ǽ+]O߿PU.(:E}f=X0Jf/R5Dz P۽CQ>?fwd~kǶͷ'OɰNjO˥11XgcomEv.Jv1 9o\_[\A-M<$>u퐚}kk6ݦ ;.kvG[}rv6޿IW7svYWO%/`ߥG)]WV=پ%߲t_+Jiwҭऽ6vr#}m{혹)K_U.7c*\WwZuz}zl(z>ݿ~{owz!l%iT7;k7b+~^M_'Sikr_^/r֯eK>*e]*ȻZ_}v2߽O,]W*TO5zk#뮾z}~dsv./y>g+_^}eZfa eMHG؃X?^a4!v)5I'}GޯJv~oo̸ZB-uI1.?:7sPwIG訙hd#IeGj^"QFu<-sw ǟE.Eo5;WA_K?9T_]~+0`>Uٯ0{ j¸q Q}Jh({vpQ!R,JO,C}VMq"ׁ&&M2.xVS߻~WtG%o|ܰq n1$E?_OJ hbx$"6B^x߻]']@LO/YueE/,gf%zJjrߗ]`ل3LB{]5-?]2o/.o8u{w~ww56L\8WK^Y3Κ̬ԩ_6UΪC?}NI m ]II3;؁|-t{=*xQn[O#mݸg{CbؓV~l-vUcDo4v+秫Ⱥփn:M {?/QMDpaZdQmKҮYn ;\hőNu3Cdd+ U ;vkyp:^RwER Ӣ(gʡ0uVW0bGw}}W|K/zCk~E^3ljwN72 ?CǾ }mkW!ⱂsAu׏i_ +$bXG,U񉵪c! O[_c̺]ı%I-u=' ~2P^/H*y"`6 T]bmW Z(zh>u@[Ev{&֖وSLSKv}/ey|t@F7IrS@ φ㽇w|v z _a^%5]wg}Av`#L>:ps)\dTG/\a}\.dr6׌*\Og~[ez*՟uꪪv9(;9ex懲J{`!;{W/D{t5QK 5΃NL~ev՟ |JZMZvt-M)_GT#ds¾"iqԟ?Cc~!|p>~8~AJ`/0-pǿUUj.uww{|}R!. {'c~(/I_gaLߎK7:GIJRg'ӴUݯ_"ݹߋ> TuSyn$&8RO3boiZo\2ӵG`J+t2]ŋ֢[}{FW[ a-vKZyL{q^Fw]|,K\q4߳i]v|9ۿ.4 cJ/^S&*OI9U#<8 p}ZbAEmC+Ogtw|y,➇+VK{b/qj˯UA5X`|}7$dAMgkXmrUȩTS gA`HĹ_5ݔkUVK*4H ƻh좙$엂6>KEhjݹK߿Y)W~Bz~w{~;?@^ESYh~%sg]PEl<%hq?U]}Vr1<քokya"Dtu^I߾}}Ϻ&M_92$!! ?L pA1`m;^o)߿] cd}bO?هW߯n?޼!K̴-hy^ڥ'S}dI 4ԭowZ .HۧV8D;Z+կC#tml.ڻZ{{}{ Ob=uGAWZpH}ȵ[!(>wY(L_PYRK5_Vs%JbjR!(}]GK*auM$$8Ub2+BVͿІ`),ڿq?^8&Xrb[~Fg]7oM.o7AеKg>mtsWg\Gzאb:K~򳸒5E۵J-mֺWW^!7~߱kF{ ^ֻ߫#?K֯=Uַh$o2 t\}oA7wGO8KO[?j ߮oY/{?^]{6[ҥ~D'&wGA~EOW2V]i):?+-L-{m-Jkҷmڿ'̫ARuBo׿߼g+.nۣ>;U]kMu' -Ĕ{8?ƺw3_U|cUQuZǪKإ0ׄÐYN%AILVׯw=*gb~ 4cGw4+=*{: ;/s.3Z~ֻ7M/.E.MK2%-ZN/'Z&FJ>^\m\->n tfq_L,ZGOk}5K-?A$D _.ɏmoY#L/l!ʱPq/{oNX&;v[C9u*`{E2QA8E{V+_MtTֵzKˈ­߶4{%V}++;>LSݺbXL M̸~4 YXKJhA{ʆ:GnAS)s] Mֵ[&VbRHLaKU̞}~cUVN¬^W!ZH w(4Vt{{wZ}fk1VdB$ gJUK1V1Җ/Ju_l!S Z' Fgq] UZӴouW~c[nKEj^^.[[dXm ^I,{hԸQk.ȫk /\_o z瞗웖 E hf "+:W%R=iNOBmΨs&+WgrzV?:w@&?JtwwP1XҴ~<ߞrC+ t;ogO8{b\|͕Vح>ߍi[qrX=ƤТ|&f^.}{y}ޠַb\ 57֐I=NAhҴvKd%)!KzξM^|/L'D4O=ƢDx<`{TV[Kv(LѱXuњ!!±ӽLyglqq1۫#Im~a#tiL{=޽{c>_w^}FVg>ƕS僽^aZpl]3[Ge7q]r2\ / q9Zg w|(g E ۨÝGׯX{ޟQ{ 'gqX\Wan%{cJaݿh=?߿}FwZ{ńXj!"C,K<'{!+Pa1uìFL˚UU.V%z_g@ϹZW^IS؟/'=j ,~LjEUU5]%wwwr]ƉVFM7t;e}3)*qR}]*߯_跟5-m〣 m|d{wt:a_^v!\ N#L0><2U[b!)KJJjI Y?{iEb=_3+)_X_M} _Py o Z"+M_~^/)IKD-**]ߠ>E|A7wu-lEմjh.>y`z]v>@vn r(L1vm-&Mkau+AUגw}Ȗ}O@ AǑw$w+qDx=}ϷJJ{3a;e<̻j{g*i$+y ۔ G̃3/P&<\iio]>zXl?$=k￉oF&\V߯1/ޝ++XQϰv Bp#!Gڮ8NGa6sƅ"]uχ<1aTTkU\V}  |{ R@N[p T+wAkA&>?^%dQ}/B X更Y-=`˷?x ^k"K=#?F߮Ͽd^,:JUZ_slBoA%. R?!5ɓ]UTEz-fы`l͘%~c񴜦6~ou߾^2jHjO^֊u؞ZNoGO˓]gD{dwޭ]M}W㉠;\(\fɩ9W7vR¬"?O$gG=j%Z?.?}}̗v9ً:pav@}7aĝCO_vkڳ۪F}5fa~jKq#3r^\}B$-$"b>됌W3_ݻC+^[rZ=Ьo{LS$ZeOaS&z?+\QF^^g!=>}] ݫQ<N~~rUQEgjٕ @h &}uysCkX ֝1@v/4~]_q(l`35au9KdE?^W1{%D!_=q+['@ޅ]}q$$e>oR\J+-ޅ; 1!owy9 Klw]z}bXZܽ^j/o܇`rrد]Iq)֪߫Bh?v)fܽv|NV|_'-ݿ)hzl>K׷]d ݎ3}ıs[p-qbtr^%u8I>g~^ ֿ# 7~ ~՞߮ג[֯97ʳ5{G[֪ͱB5]QQI!4=d'52 Ǿ~˾ձYUtyUz}ط3{(=~-:5o~*G"];V}ۨDLwH~Q$z+Zm-ޗ+kw=^uAu=C}=5vܙ{7H"K.0v]PW}ȏ fn4קߨdh2?e~̺ 5ԯ@O#.D;h$~v{~&)uZwAϯUeđޝ}-ْ?K {z>&}ξ.KkWiuQ=ٿK[Cٜ@s zRE誸zKU^kRG>eo/u֏;/mH˿)SzMz!Q^"gߴ*}߿U6vӠZ׿_N։J~ޯۥ+R.J]߿벗9kw{!;b}u~n/uon߯RsdOĈYs&NMKWWJ_ߢl-_Mu=/= c:^)d-ut^{׹FM_˶WiZVNUWaFwS=v޵&foغ}KEU :'_k/w['վ^q$V?k֤% z)kI }U+^]=-{oկתECM&7Zr@~w+O A{!ߢ?_<-F"ߧw0GZtC.0Z֨u`ʂl4SQuQqu^qCCOxuQFij;G_6Aw@6{T]"UF~^U豿C~V'vKٜ:{bck;Գ싚a5:lǟHaI>Ȱc}U,?PEUǔZpD,9)#C0ѷ*}S[&Ma~-[$H=u\y{Nv }rʏ 5n YT-qHW-- !XZ|V3[I:Cmt̖5ᅤܧz"^6Svzu ]+ _o9߅y+":lieJI+^6SPHAI QWUYϚF+ޯ Jvz W?mL/f"_tLO*m_q{w!}9sc1]~Q_xCh1w. aõkQZ]UUEr@v*/cL`qPo$ߴȪ#V}XRo9tiSN*7RSQ굿8q=EUUUCjDBNUWFXJib)qX}4.ߊ| ';9Fe~x *{Jԥz%O_7ܷAĹ~%E})}D~1oI|l?-<4kxFoĽ Jc,,ww|.ws1o jt6R3 WMB[;߽6ߣlpzZVB..&rr@HxP!:2y&vU]*aV-eRaEj6rݙa+ۯ$[|޻]:櫻 դ ya6.9}JG,S׷V.wd&IF j9o/X?X`"_ѯ-i/p@ӳ`^lԍx[7+(֌Ǿ`r ߤ9~Qonˏ: Vi)d 4ٽM 9\]EF* ֝(F~%.Gxj|©Ҏ%onXVvXj}H@s|V+h k+k:Fe{ZuYU5g'/ZP3'y* zPC:CQ".{r-P*|qn~ M+ wsnw պwNB36Wq{T1l#T>/ukZU}˫8:=w]Ʈ\n_Z,=_ծ?lz_}i wXtzzI6Dw~ֹ?&TM`ycǒþI_V>Ϊ+zFNTI='D_}uV&i0lͅO^ݰ%oݭol6CÕ[BkWI N#-qr&*׿p߆Z<}+q]k)J"*80>c3W)oY;"^&]}6zTljd Z]L`ZE?z$R@ q#y>[]*n{=lA5UėE3a7X>bt{dޕe++ i'7By X0> kE`/@.?RvOV/eqħGK>5#{=E,: ݭwVoUw~OӾRM7~G>{A]_E`z3˱XשdNen]dFo+:[q7"^.0ŢGP7]I;e}ĠBJ{>:5؞#Y+Bi!rooۊ~SjZW|bl]?Z cW~Y[^5~+2=\"J *lк+gl7*I}󍓑"ȶ}C*=_uQWK|&dD0;U/(>'@]K]~ev:>XDw#_Ex(Uov[.G:]"lOoM$WZ~C BZ_;FʻU~c=i4j/c:i3FVfw'3AR-뾀!?b~z#@ę=Wuf;} &:͠Ѡ~[/E0aoWv1{=r_}{ t8n@;WM~eʨ!X_UzZv@O-MPz[脡_k-.?Aw8=]8*Rr`U_!&߿z_-MGst~h_~EoN}OOdOS!}}W/H+p0+ޝ%J{7Om]߷Bo׶$Iݫ.bkT'v?}߭|>Q؁!8>v >1oUX Lf~AQ=]|Dt+'o$;D]D{q>BGKQ{g}W17ݽ>)+.L&3? k}ܖ;{_QzJ1Aɛߏ[BתDUֵ^XI]֫گߡ׎f1RHbj[%?i1^*kY|2+_H{\t]T^.LUD,\SQ}t)9/aە%~=_k/z.-!]8:?ܦ_i;ߞudL#7~&W;]AG :;>t8K=o[lTFz5V[ŝ@4Ȩ{ >Zw o_hRTtvUutgk^ڂբ#e"._A/%똝Oėeg$>mV.OuS^j_Q.9da7Vؒv˥VV}~[k~mFϣ-}ף._|{'uע>N_G~^ܚ/o\΃+}[&Jrk{klϺn_g{_+&~LTCԖڥ')W0=wܟA XA_{EUBW&a'a}ߧ~ kҮeo[qoV^{߈}|yt)# {ݞ}\{e6RyKvh-ac}aK~z}ߦZݺ_^gѧ^}7U֪^X~۠-^n~ 釭5kc=akڳ [SO:Z(5?4mq}ʕB&?eF+o=Ͳ'3MF})ɡKxξ+6t{A>-ٜV7_kYF?\밣UU괒жaemZѷ{.AZkd T]{'˽$%@{{:@&o{ovi}e|X.NB{1j ?a궫țk+.P`EO Ϗb= :To~|l'*UK:T~t" *eTHDuk^$ SJ3_7+ œ; `q}Q-zBp;z{~o^P:/w,%a(sy?Wݤַ9| }[[_6uiKF Q"`ݔ^op.|v}U}?ּCk[yAHFH_Ui+4hCW5Ryk{-٧޿_Mc;8v,Bz_ǻܖ8<{G+wz>eKLԶfLJ,^NA~wue_|m v}|Sj.ba;׏g~Lp$] ק|]zM…_zo]W[vOOo : edƻZ/ȕ:<|a6W:7}"6aEk'U,аq/݅#}߿E}e`c]-:c#h-.|yfgIB:.1o}>HU[b)Φ?itRuQ.1.Krww[{+׶ k%C4Z(!sSI7పhU{>5֪HG:h;xZwwLW^EdL{-?'#5"[R(sT_=iV`Ni #CiE|ŸpppzuS/gdN7.V3PNV7}'q<*ROe`~ޑBEƵހOۚE%% TI37Elv% ,'M'B黺Bgsw{V\س51d,:M 09N4tKoNd6f(ϜV ro_%ˌhYG֖ EAWV mSLWc>n9gƐx= I{G5?/L}~@3kEKvI+ntIKR(u!~oOC-~ZC 2[^ǚ%xB1 W9XAf DB:\ww({9C_7-ZtOjw_Z+iw z [软c>λ4:(辵׾ S4au"h)D/ iT߿܄\}UU{|:YdI]5bSTmvcW3Y~d-p.s߾ӫ޿A(z'uҗIE5o 3_U?+@ޖj(G)}ibo]S C#A}n$6Y%S߽ry \$>Ty2ŪAmQ|&/+ARaCWo!;ɔ$676l|uK~%H}nsLm%ae_' ]('iCʾggۗ䩽.7غ GV򝏖#7VC3딻D7 _G`-“^']VW^)W$B Ct3LQw܁D#A_!oW{&s Eawvla{@&+)߯Ü'?л^R\1]htJ޿$3͎ zdo/7\a/az(s KНk0^۹}$7n,`l}=/!-ۊ N]ꗱ a_z*븖7&ͪrޓV^N(k}_F5@Tt$U(|@o_~GHE_vI+.ϭj 0]J]_]IޗhɟV_uMJ1f;."v[M{K:A?*]Yy 'e=ʐ}r%l$Z99DPo-c5"_ĵ{%g5|ͲA--w̏<|}o߿y/|R:L_*+55W_@[2]߱o4ٱ!)K{ dL^+ kTzNcvN]weoCu[*W٨z7?_ 5>|JI?MkoJ3.;^?R>wOBX>m[Ȼy'L !<a./DQq/…몪HkAcC?#=}ȫԚ_&1ړlx!Ql̏+~Oak'kQqqqqqu_oC7GUj'rnB} 3MG[/+*_db8L/P9+ZNϗ*o?˼IQo^8=~M]v%߿}:jwc"L|WRU]*Veߘ{>MG>!?%.]9Eʶoԗ֯_1z;_-.-}K^E}ֵW魟g?\֩v<'|^_uֺo߿~[fͳNa]K"/AjZMwvk^伝!+~](k{owԷD\{D{}^^Trڷ[D|WRxbq /؞f'߹֭EKo-I'7rzZ3{]=G }[BA;.r LG-җ}Oj|(Zjk_ծ: Dy_Q/]L*6=[eV1r,kso߾ݶ^jHBs6 x:U$Q3 /w{t˂~]^,q^1WN\?,w:֗ijֽ/o!~R3>{+˕ۿ[h/ꫯ6_y!Z\qo/^"U n:[mh }u@2W vXM*֙DOA1zO>ᄇǮgʶw;oʫ ݟȷw{h)qK~[n} WED=sD `u/Tt6j+;L A6 :!p j:<[AY+c}ж[^}?_߯x7I.D?g^-y+Mrڵ?Sh6g4KwקTWwsg=au }޿EUϯ`m[}@R<+[{h`>$?EhI w|ǚSV ly|kImΣ֌?Zb+0$v0\&+ogz] ~ᓭkÊ_}SoxMn {hJMQ[ I˹Rdbh:g":׷']{ /ad]-F^;Kk8QcаS]v]szW{gI@(%@-r)~tI]{waŕ'4bXqiUAseտQyKqu>땚 |WZ":U^g }~RM+J'̥5N fԿV/3|Я5k5Lz.9:GH%X쑣4WvdNwRCw6Wr7-zӽGb%Ԃ}!Js ܃Z\UUWwX~/DU3/z@n+YozTs wKwb V.ko$Ic*+~uï{/ēS aȆ?ݞe~o?eHU* V}p|W Urx'௯^ϕ#S/_zC2URtq.w_KWޣP}+1:HaM}k&W~Hiu$X}fG8w[ހ:&xm6Q4I+AǛoh31U{/*2xѡ]_1[kׯDMk؂/rX_o[]܊؍-LC6~r[Scn?qRE5Zr6Lv;CmQ$$I^+}}$j{W2w J]n>kqo~'_I6x~$o}m""ZD|4 yf)U}uļci~Wk߼/9#j벣v _5. At?ꖵ^+uRGMMV)>J?%۲6{zOmk9ĬͿ7S u;>\B9h.F ʗ.߽U{H.ޞܵkTQ}jӽ}+a 3Z [oZd|_;}xcQ$Ye@|GoJ/f Eݍ+Ͽs`=zٺYN'jM{թ/(t^f޻߷[޿/fȿ֭nq`~ƦU}oGzl}BNt:Ċ${z g)k޷O}+jY޻G]o^]Q$G9E~Q4"Д9/:q(˼s4X"ě5M^N!@{ݯ;t8Q]Eꦴh6z¤jxFs3K]4=ϦLIOuRԽӈmwULF_ '"AWK$h_%j6V4Neaµ_+#UZj鿊Z't~KѮR]:F-}>vt_a$VUuZok@t!GK~*ؖo'[ #-G.ػl ݵej5_?ڳ̻[&=Z K/^l; o7ڤL.'+t(S_15S{Tizդw^-/Ѕw>]"Oޯ6+?Ѷy5ܤֺo {2%߾Iҿe@5U_}-/?Z] o_}N[&Vsmߥi;>miF1R^Aoֺ^^R޷TޫM/Gr[}/W^I0?Uo:z"˿&7&{KjL֫k}K菻 27$io߮ȯB w~]k?'+}%gԛ|ľݙLKlc~}Ž.긥߷Wzw&I_vWfZ%o,Z{T?\g`uߠ}߾JֽXIl.bez_%zٝ}wZιBuaX^^Kv 턶,'AmZn}m87 |rMOz%WɾJ'^ڱ&q/n1Wڧ?o*JAZ>"+FGV2s^|KU}~)51=\Q}+g% ']yX¿E_;Ž/jQv @wwo_!URiww}^.O=ԯR>tcՅV̸+ XJƹM_%_W+#/VWvt˷.SKm߻OO䴣*cOrкKVoQE͆U%Tj~\׆׳KݪOzʽG9i"q@W=EDcbw#+`X__n/YT'ThWGX|~rhws ~x ` toFܯOc\K8,fb=fdߔRVV-W@Sڧ8l?n\ʒjԺ#&SB̋j^ӥˮЍR3}Uƾo&ƸĵWupu @%6GJS:aM[[MG 7w}jOM3feeUpM҄86C9~ @bm>t4e~+K@[N.ʂ@]j&}+a?{趂*u@k_&fv. {+|:ਲ਼aƩ1:.~xZ_p5~>Kݾ-}_)"/S?6w:!'Q}߰T 1g}֏.#'w{EU_]h_Z}~3_E֫ĝ[v^)[0?;f/w_1ZCu.G_`{Pˊ'{NDd'])n"rS3}h@=f)sB<߶ fD{K0/\}+ ) !.+l+?cnA}FaWK"~~-gU#Z%BMew_H b:^ [M^ĭka{}yyrm?>EU!=~aOC cҞJߘ?3=W㸅6Fbq z#}N|ku{}kk[B`vŭl/n^ zcO;Jc,=bD\ϰ}bVB/k{ZVXª|S6=vEf}|ûڐ֤߰뻑|]^'DJbQl)v5^ԒHU_ xkQ6sRHWed.W*^֦B>ˠIZɢ@7at$ ]\g|mߤd&ȔYe ZޔX_D(N[wwbiKu(q}޸@W@\xp}u%#N_-B;r+ހϭjaV?Rؓ笘ڃ{!v{[wHZ&;vnܝGߏ#HԩׯcĘRJ.{m7COs{[lub9L>.kQ̸%\c-=f~{!; v,}yM_(W{`]z}^]ڱLuZqT-Kys߽s:]{O7!D. ߿Rʎ~u*kzcRݾ|٬\']HDޞi|?^‚c&!I|v&3*wqK}NdЬ"jN{I,Z/@&.$o֫WͅSB%vm>kFp}o _NQj%ZRwT;wK%ڻܓ\w\z"r.3]{OKl!_UȻ~G?%ݾ"+KMܛ)߮MRijʺ_]k*n]+߯[|]!=}߳xK߿M=W ߽^W.|ށn9(V9?U~ת{Ro\Ͻvosni{ $)m[߶W׿}_/)okr2o}鉽jwa5~u_g~d_olV=TKۿ"Ar}Wߎᗨ_99KAdJeA_!vꗭ8 P;Y\e=; [{#~Mjvz[}~)z(Mk)\>z9pR}l]8wte#T3۪ʺşrp~r^q7ɐ e[Cە _FOa'M4Az׋{4 e2>]޵㲯W+{s#}WrjQGY߿z]ke*ڮFƨLAڲ=Goy|}˺ oI,(^z^X_w~ߩ->ާaQ; $uߔ^lI/Kf4t,t_˪EGYX"]q0#CGWA׈6ȾX*K _@nभ?WwvxW)Pޗ%oKG~!iUwGZ[R&f3W}dvad^/h]Lv=cZ1滋'{S:A`\ϡƩ$I+e3ٿ98Av?z6Zw : %]k^WGT\_]UEb rNJפ]4ۗ3qd I⍆g|UzQ۸,BlK_gqwM qQ,K[g;#~ޟ;]fVɨs a~ bQϪoz} ip)&)ϻG|bw1-1wBz*]WÞR1;? v..cSTd2UhF ޳g#NGLOGyxL&Uj|JOZDN-3.faF[pze4;:?޽{Q 0.?nv-ϣiaAKp0K~UEy3q56Z}!ɒ"SC~l@^2Ď>ʨ @:]} ?(U}{?I6>32W{벻ȋan;q[wZF׽rZ^w`t.^{rCSZ/GQb(]$Jޟݵ$gȓt2!:],XyZ4nfVEu|\"ag]^hY#{eJ0R\=`B-o^ʽt tU;cp`=t@gn1?n8̇z,o ԷH-}N'^"+˵onG^ƌ_/IhRV\Y,~c۷wU{~ۊiVО)zMoZwU3}>4n^7k^Ako׫SK⸭ 'vSS&$"޽oUK u]udc]j PL /W{ti)_WksT)UoUȦ >m^e2p!MhlRA eP._[oSZc6:gc[La1~l6G2Y"GhI,jҰ;;﫿"V[[I;ʉD%U*9}|:Q/0ѽhi N cDXdY~Wm7}鎥wpÀ@ᧂ;>/f(ϋY뗯#}?K>)>K~Lֿ#]`"Z>$E:}JZY,ݾ&[^[IZnw!;\S>Eʻ]EeDGk%J0Cxː1OdZ'WZQF#%"W5q4-Uk_Q/ k=]Щ@-T8q!V Zi{I[vJ'MW*֫#5^ip0[!Xbqxը= NUu}*v~!U\_8ɱ:[˗܇o37dHML"42u UfȬ?{>E~?׾Zd+Vucy&_awp.-N+ӿ;?o~ r.3_ĉ6"},uͿ_os |B r?]־$K3wJ[^ -bm3`u}q$?lC@~N+s֯\܄ljYͳ]kL ; >l>9^)$[rc\go\Q ?4%P|I5D׿]ޯ''t ?AKt׭&h{eH'aŗ#k$gN]s }٘_~Ѕ7#ӻ"krA^:Zw=K=}^}}q} k7c_+7gx9O>:d[tYo&/@߾W]MwP 1.t'\jy\3Ғ¢$_a\9){.W}zĪ|}kinwހoLU]|^D%ioXUę&q~Tz׾k_%QM5_+h_-j'h9oJqz?17TĖ%F9;wwC}._uR^~Dl|kK=@R&N%UU]Q~ ggUM,!_wVf +רg?}2Jոk/[]{ֿef&ε¬r_7 $%߿ =-Jӣw7}*~NyIkz}&r7w_p?[];#]^'ro]" ՟z}zKt{}߲}43*w/ol߼܏g\[wߟr'Yu5vU[Z=H7H݅]{4][Rk޸Iբk}|zZv[{]A'Z'~͓;|az?d5zAWwO&" :-\Z׫tw'~~.&1z;}d>R.׺{q&bc}í2OT?GF}֥]ĕTKַomGt)c`@ ]KPmŽ&jie>} o{ֵ|QwE]0h{V$ Q +ju0VT%io} mNϧ.£_n;|_Sʶg%.86 K%+־zauF'wf~_w}JX*H-qVvOgk+Vfմ7E`@{^zOnUc0N+5\*~[7]FKV${܋+yf2uX*#>ws] 6ϝ.[ˮ-{6'mw/v5J5GnX+Q>.w嚯GeXJ]eY~K)Oz2 z9㎬!!;c`g_֔U|Rw3~SL썻_v:CBW i<}>!Ǵ[ݿb/o}s!ҨHAW5$VTN-v=rlg+mo/֖jx5I+mu}gԎ'^s}BUb?n++(7uOa3_jRVJW.5(RKo,Ү"tYCt+3=cjNYǒ8xAXݓO!Y~W>ʶĭsl`u3SK^k6.J%n(J }\It6_~ E{3޿,zW'K=s^0ls忣U 2}\(E6Yk^4^ s9]zę#@ָ//EmR!ۯi~ӶVAZ/&ޛkJՒ?ì]WrIOsuǖЄ(?6m(;a޹hD>ѾLRDM?|Y졏0Qya[@l7n@߷Eٞfi%A ^`k|($S^P͋pE+hؒ?(n5_lq3V4QXo/to/}t.1\WA;w>^Mla- sT:O]'M kJ8|GY$]s~zK'DT\\^A=uˤ[th!{QSu681:{)3z`UEukxU. JN4}$'5mx[ixv!1YcP~ ս Lkqpɨ*Bmea7k8AKct J^tVKbYj>J_z@.kEI^ Ck9Ԣ/@H@YĔg벚$&ٽ1u~-OZ?E-y|\PzahVWt=c!=5[\{.V#F&LR, 0JF2uDq¾oWh˦/0E'mRLjtT{EUr*^P+Tyj^-_-qhwJdtߵ˨a?ÝlV9ԑB}DB~gY2g8%`KnF'n?$FxkU$PkM"_Qd5\Y:Wɿ{?%Ig}߸=qTseD!v~_j(c )`40i=o.n8ElV~m둄˲ xȿ 2KkO޻߬CVZv&nL_Oǵ:O[}[uI"nj($0)$LA| 'Aw ;zПtod'dxL +W]o jܵ͛b֪ڗzRCqj'R(Q2UUZmƷ @E~dwRru^ ?0RM-ߔvo.{g_$G(CbApmPx5ojVu=+7GXEnČᶏEk?轢^NU|޳L{zX>_6&cWeIzIsSȯYַ__KDBf]+Luo]t Mt} r){h-͔[ {"ؿ-<}5@}/vU_A|݇')-`VG-?@})_'/ˎhuy9͖\qdz:RXdӮa{W~$Q/ψ;Ҳ `ݑ;?siRץK]OsUцe^7?JJ;_WނW ]TMZK3|c$-)T4m ߵ]:T!6>ޘ8soscﺬʺTH~%uުU:-> ֦ Phy`!LCƈϝkYrmi9‰VZUcn_{1pӋ݂lHU++}H*3U']Uu P¥N9ILTw7 4m‚*ifY]j.5ۻd)t=߳Sm)C%YGXdUn ?iLTߡ:7wLnBU{Z^Cߺw@}lyv&:3ؗƩ׮(j.Nf'+֗P_U/QuߨA&+l _oOJdHS ]ߦ)eU c.'|^wGquUU:uCUV/Z//D׾(L~2?moL$|zVH?qO0^wW@zWɞ~ɯ"Ua;{ }D'`A=|b.p섿7]{uS{w7GZZ\}wUķCNғ;uz|7L$/}C `D[|}s{]޻%X 7 d-owCυ~ӷjONTtwFt~_ٮW*wjȟZ_Grv%ДYng}[o_*~Zi,zI>ݪ{=A/{뢦V_.˿~ᅲ}5{k޹.2޸OGZ\'[&׮oZMNDKϿM~OcR}{?wKG*ww_Gz߻^AoJX31֫7߾؋H vFnZ{M ׽S;WXNVܱŻX=xoOclq/GK޿nϴ[_ۢ=G.՞BR|` &[K)]v|H\KxKc$ȿZl$WE)XYRU} F6 Rj꺯_U}vN8mܬq{-r/AZDl?v5;Z~ -ҷB҈#? wwm(x}[d* .ҿ_]ꪒ3fq^ l_킓+xKS\G5_5ӧ<]ٷkb{;ma#?gk19MF5hc/~%?׾> y@ K\ceI}pk֑?‘>w2=DxM}i~X&2jUI z =q|oI+֮]!"cJQka"HBKPp_g$B$ ,M1oA W`{{ieF۰X@s+13.7ɡw craL CϞ_*ۏy;ୖ*T1uQG{kZITJ UV׺g@zHou;_"^<7͘=fֿx7ֿDH޶qOc_ /N2_S^pFrAN-By}͔g"{ E)Rb+RNFSn΅˗꿾Z&_.qVH1↾<~=_{w+? 4L Yi#&7ޒ;+ 0jv}E؇^w":~(kC1NQ>_]0jze%']z il}tIcIy<-Yd*ʶGoGK4=^(Uf]VӲ_UtKBUZT]EqD@ ,>3s~(w~0]67;zBAO꪿E8XӖH}xDfuǾ 8 q~fi;1~2}ϱK7MWgJį{~^miؔ}UU f :UT]UmkM Y: l# /4v1N vh/RS'$Hh`I[^(v)Wu <-'~.Π@P(b3[1`ǝc][t4WOku%8z_ ֺ--Sr7 -zjҺ_O H& icZ#r-R]ݔFzg4:$ayw)}GɯWC֪^Jowワ07{֛"/nB$S W'+4lrnʌ˨v# kE$\h |qr%0)ƨ(L9%\p8 Lz,:+gUė~޿R+4z.eMUl1Hd[ϊl~;zV+q[qwznVm0oEl~qߥ5Z?i-ZU_ꪫ\{X+JĵU]-5<3ric#74֢_" bxXׯMQ߾Cɠ?WkqǧG1 Iq$֩o먼G&9 e6Wk|k=g0|־c"UZkrz1L}0{R``ӱHN(k'Kֻ%OV+>hyZ+ٯ 9oK]䯲 A?VI9C;Ϫ~x}ڭoukzq%,)_TIiW ^bпlok\{Zr*^^N}a V_cDg)9i3kOk{Y;jw#{|S{vY&-Ʉ|&+t+3=zҽ˯t\>ǝ^:>{S(cWީ%dܿ#&96e?6}O~(MC?()tr\ZП0Q*/^I\Y4~z =Gˣ݁2Oc5k؃PlO-^O ?"W}/`RjĈ3O/[?Vg`Ziuk-^G:'߿&߿Zժ{rC3>#GV_ߐ}!гdAka_7%ycokZMWLEjv^{W,z7Am _Z|nml;[_D'-3Na7lC_{ 7 oO6u^Ļ{/?2޻H?*-h_M 4hash}-`|mœǦR] gsq=*tot}uk+_*C]ğB'wcBmNZiQ~šIP!P$L~q[FdUu߲J.US~/UӋzFSR.VO_ +C*m|b>1_ף.A"} @Z./_?2Ү%A!,! ]V~Cjׯ# A LUUWdڭK~A켢7TF9A0U@յ9R>nE&^7Z[J3'R_fO_)oI*{R-Fk}_.޿-.'LpJwH~V{}ϛCMߵ-&M[@ɿ{og:ͥE2=*GI{oh}}}z;ߵLt슏_W~m\wWɳȭ#7=+{{ -;ڠtbwO}:7|kZ&}\K˿wߓ۠1W''3owKH!A};Ȼ5{loO=O{w}9;ˢwI}R4}͗?~^?wiw{ܥkLrGM#˿[[]WZ./g6t'/_UR7M?7믔~t!/u1w߿oluݭ2wӽ>w?}!~g-z*KkU]0m~̿p~3{߽q^?+[}[k~ȿvcM7h$)ww.?ǤYa4$ *M[) ; //%'AYzbA}+ ]0~0Z R %=J$K}̝Ǩ/Djڋ+?#o,*|ƺ]}Yȝ6an6^&ǷҸw\4v zk^&eW_KarWAkG(rr:Rnaze,rϔ/e'">fm(?+U=Wpzﯕ,L@_!u^o[@Aڮ.#1ƽS,u^0!&=[kKυͮL\  a.ؙ޲# -j‹&˞(>M+wux?ň< !ҖE.U傎QqpV1]jw}|]ZUX|jy7]߮Tbwm -ح)|o=ŕP^-|ނOr*N־" nn[~ W k_ऽz5B4>#C4}e=ɿ!GRyU&VP ]eo7A/Lb}b)`N.Y! U#DždXs~#UWP޿Sw~;o%lDςjKn,7۞,+3;{r%z*~O5Z1w$OJk]VZu5ZlsZ 1U_cM'bB/Rz/#q_̻oSZU[z/ TaN) !u\N ^hW~/ E_iw._wQl6v{gסUEo]tAuu^G-i|_ m=OR>sKE@_+븭;JfV]u~$F~?B6VSqw;ZGL7I -B@b\a{hw{Bzu E2> nhOhfb/:=E.GQzRV%mzFQ_6oZȝXC}n0#ѡ*`=JOVZϺGVg:**ꈵ`Y}^ ǾZ)h_H_dv\73v }qk&i& w*3)kwDM z3֩{uyUEd"W|z}URjt5I1}t>.iշa׀>h1u|Op8,#תִ Iּw{cZ\:4dZ2XQ|H9'm/`^QE1?Q_|Hz^GCV|bأE,Kh^ج+t1{~ۘ&n?]E^0+֫uT`T.VUc\Nr+"۾Z-~ST9`d8S}WKq쪾6OW9/pX3ǖ«7Sd*@ʠ` W?OJIL)HrfyVǬ$<֗~g\0 "gZ?A->ǑѤ?e6E$`^ Bq;GUץo]^JZ߶"K1wջ^kRe_,^7^cboQEZ~Sxh?*Վx=sZr!'n_[ @F&;[MKdV;jt-)@+|vI;vTwɟmw~c_5`A}-қ oakLϟk}UE̓OEZ®Yش]V.64)lF^'G}8wUwN'dg8+!"d$UrxD[jZQ+6,#+&[*hSk95_Q*E-)}i91vݹ$FZIހvHWC}C+GK/A:-/O-BUWֹZyH/Ľ6=W%*o͖1d Eѫ~g$[?苺ϺN8DԞgooh_+4.^$e)_}߱6}?g-ߖ ~?b{_}{Kٞ{[e+a9Zh/A}:-o^=7{{T~}}|ϴ%+=W!, =_h쭤A; ]Oh]+[on'Mr^(ԕLXٕJ9~E߯i&!:>O~QM{Z>o: FJ.}׻Yz}+r-o|=h/\3G̯Kge;/wMev&j*8ƚΖ:#d~}-kk{?x|--n3_9RC%"˕sj}_!{ѝ4=z%c)޹E-^!F>DvZ}WׯQoV}?F)zos=auy/žZnoj װPybۤߵ Mn-1{|au@Q!T&$No벘UA)ztV%׻=>}k +"*ۇE?}{?  Md+ âD߭?%nnO e pwox+/s7q^#b}q7إiw($^B/\ UIwwL/oXuKn% چ_Rv?h[c+w7aV[b[5q^=G{G}\+6Oۉ>+վ-W1aGAo&Dr'~:jU+; GauO [Vˢ +GE.[U]l߾*9HOGW.޵[&[~5az4';M;#:[]T7 '޸LoG ?}KnNr+ћ?Ko@Ů70w{C}З~?w?6ؾHNۿ}#t}"z }u*ڭZ ;W}_+7c8{;烵}߭K'b='޻oo2_eo"7-_ᄐ`׭~̺4%/~~^nȯiHĕ_U}[=Ko|>&~Et{GϺ޺7;I>\}oj"mw&veweV&I{Ѯ$IvW\%œw~'~Ri1;N*{>.}q K5 <u6ڣ^O1wpשּׁ-k|~z_67Oߖ}r>ww}R2쫜EDKf]ւnà^O$! E>-uM{ gXE]e5ƶɿ7UKK_Y ٵٍC*BYlg4}k.:|{2vyQ w{J'Kua|]V :H(t}vBbU}wR{MumşAwcqEGka}̨//bP$ 1q>m>+%`wu$c@?IX|Wz{ߩVC~2]ޗ2a^' :Z>֩}lԛwge$Y#5CoʒQ}*oK }gT:zg} ٿĖ:vz7B ׵К)>OH%!:X|AlifśyJ| g}bW@*#Hmj-߇dlfVƞ޿cC4^co: W֗ԗtEØa9=ю׿̺͈6n>di$p a wD1w¢Z'B`Ēy6 @o[9C}<.I#4ѾwUWWx#X*.fDIR+vK0&VݸqGS~^[x5I] X8?ILGZFۧE[]bvu"I_8\xw X]s ^* Vw}՗~%iP36i}'AeEm|"z-U}P&;ⷿgeW5b-)'d_D8!\2cE,# zcx#[J^LY0uU\ˣU/oO_c͂ʟ֝>X߸ "M|~3C+J Xke`6J3 9=c 6֟/t _L[j.[wiu#bYukر=0/ߞ}~E_UI0=jVid)DHSqIjepwxzKqG?v∰Uv>VqC 1 .sH#]VݪcNЮa_Le*Q{>_AѪ*uǢQuRdZҾ/[kuQ;7:S#XURކU blO^rڪ.9:KwnԎ䷱ZΟ_n´I߯@*UU cUUUU^-j\(*J{1}ږIF.9Tt>]J+/7`H_1{^^WD[WPD)ɪ-*  W,j~~ˡIТLG}ژgabvrO]vnSK^#mw/1_IR2G~gĊڧ޻}vAw-t-@^!/Av?!BN?o\~*͂<<9o-KƵUg; GIߏمo/F|"y/hN\{;"kth;V~Z9ĊHBC{]]].+۵}[QFKFT}l@mnf.F/ Ǟqe8`LY>޽U^{Q[{#AaWcJj)п ?|~)lz\[kI!>`݊]I 1;[+Rs_K})E}$ˮj_k}z)2k e۱Ԋf߲_W+oc@D7ϔ_c侯=w{=5~OcV6?Ętݫp{h_3Eu_Ew܉M]&7oߖk/d~9nIEkJRjֵt*bygRyq!Xs~~cn+q]NIV"K]F$M&Ai~_@aw76zw-}!R[8wݻ(@nIz)ׄc˨7ϸ/aCXM~G {}V~ݻ~n+QIzͻ;.[7_+cKkߵܕ}c~z~qKWer_tw=wvMn= 쏷 9?L&F5F."|uD٧S߽q; ߮1W3Bo+B﩯K  /ݟ艟 !Z2N [׽L}s= [}_BNzmvM>z+}?׿Ci_uDM~/1)]qowwt8 {̝dDo1C.DWf߯^@o{>_?ERwI;߾(3lk-?lݥWF=Z}Q;"g|;-WOf˿{߸A$E}W v~::ׯ_~^EodR߿~_M66B{mo=F\3FV.U~Ľ[;䀘};-'{O>NUKۮeH.[a'}\Q7\qw߾*@}q~_뙿_v,K:K_)}\ߨIwPw~KmHo%)1>߿kdINM߿.6w=~\2\rEqoW?Is{%/}U/o}?BA(~'_Z^|߻ۭ79.'q$VNgGzRhֿF[ť|c\߮Ž'Cy YtQo'[w; }"MJ'^fk\c/\k_D,'URfu(.\y6~Ce]d|{_]]Mz׺+(DO!= K\}^k1I]WZhm{ -tZlm_|(ˊ7VVZ[NRogh"UD$ɽ5gAP.Z}:;hIx`aka;{nᇾom?]i5pI'vN^[=o9pVz[j>J}1/ZʃW(=;uE&~-,tv xW!0KrcU#f|WCB=K@~%{5@ڪDmE]U^?uoq _c/[t#㯛1qs+ĸAz41ƒyL1ؗ"n-%-Cwo UbƣupȫZexi|u?\+׸M͞w_H8Z|!kYւ@`-cJ%m?C.+ʪkݿPQu_H;uzVZ=  |A{^ͷ¨EE_UfZ}FUWUI+OO[!sZ M=ުt^OZU}U՚DUN0m{m#z#-Vޗq-~OUb Cwq[{[[#?DwU֢/өRr$Gn!l3z]qTN!6b!䄐w~4+XEb:}U+uF8paIwwe1z_ /qVRI_50H/nc4?`h;{]/m$ %cVcgFHE|xYM۷Z/d7U7^#k[J}z/D^+\V!a-;p1/]ȉR`K[6ݽU~/ƱzUjNaoX.A L+|il+iS>b\i|ʯu$CA?oߨ5͋]k] m*}?ܷiKfn6~L |yH A o^MҮ C4?Ox U]UE9?UUZUj./AIyD kcaw wqq}҉o"~E\x*wύCV{G}L^lE١7A^t=`Ө*[xś_Gz7[Cj*/{܇x.#+UUUZdY_Utwq7_=߮V{Iz.~Ekl6WeVVUj<s/rtLm?q a.A5Cb0MjUj$*I I8zeb)I>+www{"8w=Db^yDMeŜV_seQޛ41q]JbVM#} _l>ue}l/O|c5&~\]EWꪢ%{ ].E\WRup+<‹ ,W34?PdoOQRM+^3oɟ^ߓ7Z%ed~o_"U˗Ne=|[׳q*t*z `@w^Fk"kN.jN0@~)7: #0,b9^L5+]HqE TSRYu_|~kUEϗ-wo FJw |.К FR ]-6+%j5*Mu]zQn_7wwzm#ض>ͱlV87`cG>ح~Xۖ;%L} | U_6.G}~ꊲ~ECn*[&+>鯿DW~_o@fQ?>~gw+[-Zmz븑Cۧ־N?-X~T/=G{;wD7#&snOj֫'.UWuTCd,o>]*j+⽻~ʶ&Wu$G(}nl 7oKgun+ׯUzv$RH2~4j76NNEbׯU~f[쿚zE_/c)@}޸ylG1Rvo,~ } {99#޹h]w. T}S6D ~k_.Luqy_{TQ0{c_cjMgUJ޻Nǟ_R!\v$?;8P[+qXV+{Bw{޽N Oz"}+Q8lzb{'Qo{C]JKecz}iud5ok]wvJR#G ~Ṫ_1_j.bֽh {V@zSoU^$C߻ ~G'Sb1lQuU2/ }.=;& ĕ8 NU~ @޽D~jݫ׸hד%es^ ]HoN&͙e3I]wQD_Ncb_{~$۫`vOׄ ߾~K߿+}}!7W=%oϿވ_}!ծ]߿Ez_ޞpZ]0]a=7t!|R޴B=Ǟ?_׳-GߩI}[c~6듿$eW_w|OWy"ۿ W{#^'e~is^^e}lKީw-o݄!?&~G+w^&OW!fq~~[2_wo)woY_*Rzԯ]&N̦V]똗K^&/z&{ .]U/~]ݾw] Qnڿ]O!o#wg}3}w$**-KA'n~̷1/Ը{}?/}Cw[߿ʷuz{߾lIY}`S.ǕZg)o滿OނW !/wrp߻{Md}Rw\g{boe6{KO ˿P[E~F0kt }-됽%ھL/O`TEwA/j%lk4>ǿ}~{s#ڧ2]M_G tS]V~~a] w&T+YZvwϏOc%/!lU M6j_Y4aК=quXuwznqǍ[r^åz!Y/[bDLIװT>YWg6 v(a=:[$?+,}q;pտz&m򓻮_Ϡ o߰}$thL$oB>͞⻣}!HXMF~ww}ٔ?F{whYD+ż}?^LE;oܸ\}z',X?9MЕoJZOF ?z&Gw.Wkg6-UUz/V`xw J{}usq]f;'{Gmj1=gu].inn6m qatP巻*}w7"ÿl>q/DW~/]}_n?ӦB=T &  ]_^ISwzzaf^zr5aJ%% ?{ /߾5/Ocܸ[ww;~fwGUV3UUT٤RuLtbVA }BfyaARKӪ U6N.OPNK C ep+s\amu۸CIKRzw]Q4 ZeL6DD{\o gB:YUUB¯Wuj4=t F*L_B^)Ϫ+ALKߩ _e6/^3ZA7:h>旾9Xsju)_]=_j%Rz WŽX_t=W}߿Z*5o[WZV qSgA! ˦;y}(8܉ nsJ^,/Gmx0-+kRacRbV/ox('{ue˛1Pt?ݝAwdBj\gG{ D^o{ 6|&F]bنu/C <ð[pӝ}q{1o]?n~@M7{˛oK^1fJ"ElKU۸⻰ pVEnd,#/{KEKW1-h6=&k"/J6Ԇ-ݑG,1U[0~DvoptE8LmwIknM8 }T}V%# 7@Dt0*VM>1M{z rnbpS{)sb..{u|zQy3Qy3FZX2؋[&;~\`}oEQ >[߶ e9W%D3c ү.Iv_E{G=_zV2JkZvDr?/lv:tb-t>o9Б ]vͰeܮ'NBOb~UKoʺ6W.q]&5zx ķ)}q`+{j[Q L)sN2f\I׉$8{[l"hZƯgeVj?_"=ޱKE Գ]p[0 bwu/YAFЧ}bg j,\j+}&SC w^^=/Q@@lWw1;Ԝܿ6 '0pc[L9JQnLcn¸@rPeїLH&t26.^NA-\=|^Qk<OA߯$ɰ꫻ySKU՟p5U0.[A*ËLf^ү!RpV"{*OGgC`s[]C)D| ~]۠A~uoĺ]̵GHV6M^1 j/lM9-2/eU~땲#\WeľON~/~\'j]rN{w^Dɳ$]~k$}jE-͡\ݏ?{~_;8?":߸@M({?mZ'j}C%!rUa{_{fTO~ʬ(`L.IњD'}Z/4>RS}@L z Cֿ$]ؽko~u#/"atlF#%n]B/ks~oH{[Zu|T0N!X('bk|=򟱭=pハVˠ~n};z%Zz&ɵ9vy/U׽]n+CK_Ᾰgdv[kBeIZ>W%6ׯm(f]J?eߵ^ݟ3ޗzZW ]v}.K={.x["7w̕\Q:>е .];~^zuV/[!uMeݒZ ܭ(az1&e}UbE9ׯv4̺&Yxoa|G_^qmw}ޟ?oCbo\űBo#^ C0W{h^u]vMNV/@t--HkMr j!`>rݹ *yDuһH ]"Gq] ߾i$9(E[?oՑ"g^k]—wV+wwgbEo [f+wLQ[m'&vIhzT*[]|KkVJ}+Sf\W{ y{+HK{wzS!u߂oU]^t*C_kQ jC}ozޤGTekd M߾~jxokG~w'Z¦d\zL_R祭LD ZүU!yyr-\[ٱw|Iuħ֍OeN޸bw}u_oy߮_s]!O?}פ;?7"u"_ ="-w޸]"cw~dNM3aw̟_7~- [Y/]g_uk%/߾[*TYeok딺9yO yL/]|WlZ`˷4W~Kf]E_gne_L[^򌯰2|f}~_ / Y0~Q:.& )e#R\:wܗI{)~iu]= \um?+UU |/7gI:Z}dcl)wuoR,Gθ:xG/u￰wWuw{klu4`_2קkkyuӭ0=6z~cvfD ޽7(Iw@> [9*mm]׶*5wz֫~׾x<@&=U?U]x+7Mr*{"i񎸸gp.~yĊ}_o~-uĖ$26MY֧@?/AuSkrt >x: L|ItU{)_1:/Uϖ߻oJ#y?!WZKV'i% 7OG>&1J N|J9u+-zDcLɤ(`c֫zPiV>]c/%*CԳ. 2"_]w-%[2}ްl{˟U45 "UUy5r='uQׂPAA]\ΝEzwBrD]׭־}uWw &^ ĔES_])}E* n鍭 347[z#[ .\d=?j'*gߖc;wL]3֊M4[Ir7ǧ>zsk޾M{؎}h-Ș:۾MɩNg_~i; =Wnc1}_)yw[[❖*6}V]_ay/sZ{~I\$^oNv?.[&}Uv)=,?<jW{@,,̾lvuK+}Ai+߶B߷P3~cwqX|I}T?~^W}HM~/cׯ{߽_!,7mi}Jz:_VY7Ůw}HudOS;k#CgoJ%{"w/}=7 azﰍ451z ;z-LGUNlZEqA[a'%Fp넖~놋_hwm? k~ĕc;=:].']uUUUU;޾[IڵTu\'K뮪JT7/ZEf3Q?(M Kj/C!)6d^Czz|Wu?d.t)F"S3Gk >w}>6CvW>^%jUkk׹mtG |fT4^У-GZ =f}T"^OaRZm2oKLZBZn6o?XIuQy~CEOKҟ :oJʶQߊDWԴ2|鷻w|"~ ?);KN_)lZl kUּ_9`^X1]Ocu{1:-;gx8k\Num¯( W`tBWJ,H`V^`:DU.XM˛ۊM}=I 6k8WuGx0NN'ⷡ0]EK${}RXMDkDx#{]?O(oySd1M$h??C%z߿u^YWK $1R?{vw=wBt[?1)=KI6jZ}1kk^YjO?)D~x{k5sʼ= Uf(X@swĶ_0LҧJܢzfFZ7߱_p 5Qu?+XQ]1YmtWJ"ReLnVQOߡˢkӵU ΉO~5z-mjWLu8zi{)%H,n7}.+حJ5:$^^7{N:_7ݧi ,#aay3\WA}W__OYZI E67/uZuCZ|߸,{Qyx"qu]kqrf5~St;-Hǒ;Ǡq*߻{вo4[l}w_vZjAչ?f/m;]&{y<7We]uX(u*ZwC5CEt:!˺ٝhO=kt.\ɫ'bm,j}}:?1{2s$&[cʗߺa]o^uL7ˠk_ e =%tNK_2~I.oa})|ʵֵ\Hnd_kM߾;nMn}Ĉj=}^wܜ"=ޟUJM6kPW+ؽ{i]FT]rP}9;w\&]^TMV_ourkb} ~u/Uc!hS[k{Wiҟ_,Aʯ@K߽$CƷAe657;-+zύ}v=RgOD']ϿZܮجx}! ߢ?KkG^)#^8.W}|@ _H.wb{q wO}P(G5=W6<+~mfq^ONZ/dӷӱF ?)ub?]y?ɽr߸}-q '{7w엿A"2w}q߻n.mS~>'Wɿj{{N3w*؞~a}Dϥ_CW)QM ~ܞo^_OQW[#/Doͻ\{\$ķX~OH7}/_zBJkVe~(GwW(@Ykz/WF}[3{̟!oD?.+wpX_^+uVq~"7= z_8☦#斆DKqS<9^1Pu_2#]Vʒb?::]\e\_kf8Cel{~~ G)8 vcZگI a$&k/ؽPk6(ZfqOiIwIR+{|~Jgnjo)/GZek!:[(_fgouL yn~_kc OץjzO9#{L뢍gY׾t˿ۯvᇻo0'{~w~jmvl][`?fhJ h8I{]G}#^KEŮVߥ߾}Ϸx ~֔aAz" ֹ~Z~}>D{Β(l籎V:&<|$Rd WalGZIA~oǒZP&[I٫&H66im}=@cMO‚?gC3@}k{;o6 "Ki_AVqF:F'}w}s|ROQxe]%eDiSfޅ} TVZ %t?7Slz4w~WOW}M13gu d0U%}y?UθSo`@Fw{Īߓ:_]Ryɍb:_)uZ׫t;w!w6E#Ca1~?'HXK_Nֺ-XHU׺pckzbJBmw`Rd{5Z7@-*6TMޞ'ֵjk窓e#dN-$'(C빏2X֪-Nw}uZ e6q]VUl kbaF }fbj.M}>i|"]ދw^pB<O6Wl+3nowXJRh["$);-U\C Wmݴ6|;}z-zOĢa>k:үߡIhksDVmbnh(Unj _^Q.uXf9Ĕ1[Q?&lk8ԋH#roA՚Kv*2$>|~B;_w#}OnF42|-o2yfqa:1$JUlZpFQq Y4XSrZ6x1N|XU߳ؗBZmWU\+{=Z{UUUZF{Q)%|$C] ӯaw*E)z?31Ҭ_V~*꿑êf C-쇰!c㗹VZwuտ^ؐ(?⋠~\ϱt|>{2 r$4o Z/}usw%΃޶.Y<݅_{G2lQgKD_ >ž֕r)흀~t魔?7ʬO^{ol !CwvK]kY]U%/bge1&˱ Hk>gE`˧̻^ճ&~$Toӿʨ|Й^C#i<EEl^*&!-]jt6;vN %%~S %{Btߢb6uċ?RNƸFkswWܿB_ @}a߱wW]gza<=C[~/%+ngGw]~IQ{H?w]]_q4~G넄|Vz+Cc#e&>Ǫe }A1f9*=~C*cv/oo}hnpR&zag}%Jſ"[o.M_ESď)q[~ߑeM:̯'G=/^{&Upg .yU|D{T!lSQ/S aT->w-NqXwi 8ROػ_ѻgOMD8D BV.]Ah{ "õ }sPKI8m[8l);e_L-A[}+׳"r%{A-;c;Ͼw>| ?ϖzoZ$W]~b Jxؿ >w{׻?!;>7߭wا|p2?,G;TP|4.^S|;98"إ}5j΂닳ƕ Jf}&߯/o> ])o zrpo{W tw~qogE6Umoz;r_U}^RlCwZ wW0V~WwϾ):)w@|Sȯ(O/wT\_@~O>Uqn{ ~1RwԿ ni]+{w!;A =BG"G[6㖎O>~M߿; ]#t2޹7 >}^)~~c\!zMo۽^N0WV[qq/jv}}'>~AW &[ow}q{&B(B29Zo}J`]V~ȯ^'wS-2}&[Dͽq~B~&1we.+g޹׿{huė ;_o߲23~Oܩ>t}jϿ\_I__עrĕwY/ЇfvK0?\%GnB_W ]}D~)oeeYB} (߿_\"{o:) }_tɠ?i/w~~wV1%=2Ͽ=0\EaDk]uiU]uOނZ{b?긓Kh{}%}o`֊#}<&m *t[cl UF1{$.~>߂{{l%Oz?ФG{Oz4UC!l vֹŪHF O:s"G~-Pf (ߋVG@*=MIW \V"v}oӻ {査7_nmg71Rha'?M}DkgR5 .U:$4m믔ٕk^>˻wvNw{ o_Oa:jkR[fv|/:Z'd0'C޴@~.U?8k{w__ke@wIZD\cw:UU^=oֻu*~"_^%.._ MoI( e;ݫw8_qG,v`Gϻҷj1]Tp¾ ZRQzȺ‘t !Z:ȎOW9]ƈĸ[-}ONAAiw. waʽ]t9ݎԦ@HzN3P.9ms]a{ [n[ȿo`ִaXtnⱳxw}FcD,-6 }g0J.o~¶ǣIw]5'危[iLkvBtN}$[_Qt; $ ףqB{Ll^0Γ̪U3 V1QZm}(BUvliʳHW/Mpr} -%v ueR> ?cw>*|'k^}`Gyqu{[˝sb?Ľ?Nj7cꟿ4IK}kt\ޫSZv<qzVwl_[)jxD0F6A".|8G_6!uͷ^lt6oXSo7~eyΪsgy_Ē^u?Hi}#2tw|G=hUDǼS>v+]&X0ddӵ]60TZ<'C%G?S/~8M+אJ_4W?6<66_ɋuUUYUI3w+WyslS__+f5~k݈z.li23~N\e=DBNaJY1Ҝ䏡ZaS,2+7O]M/k)/cQ`MJꪽZ~8 fLc7"/$Zy9lI_P9c";^>Ǿ(8mօLWKcZ 1J忻 .M]WL!0~WZP1&E q_X 5I޺QȶA"7c8D'`[[ )0":"a{J7@ "V.4([w'~LbZVK>o ֪$yǓ _Uika5UZ}u&ֳiL,U(5Qֵ~Lsbe }*ܡAeqfj} *vv>;=v/佘(f}Q[$[*7"!=B 2Nz߿WUTwѥk|C6L}ּkr^Cmbj!l_ w@M_q @%IȺ_ Z׾:T /Xij(ɞ\\\S{9hSTf8U2WOB㸓Jzr3 䎼7w?7"7䓻wiDz += }X>Nn­U&JĶ濌:V>Grnz&)UU֪y⻓jT%_6Sv-ӻlO]v;UUvS̕;Xi?UUU{}dtaA_^TEX{"xJ~[⻼VRKn{kٿđD}vװտqYM}aZuc[wxRoӠ~4c}ޯ{\ݨ, i#ykquii5B Цa/ֳ3#l~(ln°]ī;ݝ wa}};zE{XWK/LZ-| ťx64 !U StnFs .Kꯙ {quK#}]ľZm1>.^.UUbꫤX?!~.mMJ\|mHU'>%,xy/^r/;CuC]=lwaw[X{ lbAgsjxki_?.=q[w^ Z Kovsmb+fʏ-骧j+w5_3M/_u7A}%]{LW+>zbi܂X|߽rkk~_Cv.ކ}˱{שHԣ}.oHߺײ|0}:tfa_Iz8qF+)ʒgk]&꘣8H픚?,O5_}k3IX}nc#K~(Q;jܡ ձ/t^1}AFbh?vd4+ X?]W*}F?H.D!B]]ߘu_IZ{Wb"O\{ay~; }; .z&ĺ`~}LyAZ\a^ڶB_y7N">)COZ7AGC)폷|${uoПaJ%Wb|ofŋ~u}~f,njDm?c3{O߱[}BN}/ʙf\Yt;ZuR_' nc>~..ϥD Cds_b RǗC žUܚ*z] ߿}=0Oby?C$.Jk {wbPubLk{z> .ܝߪHWNˁ!p=J>(ǻ!dZ;~|.s4jeb e.,~V<;Gϱ S4/N~AS>5|zok\A'Hc*_ۻ>yQ/-؎A=}ޚㆥ}q'fM?wj$+}K߱Eo޹ }qdou) +HF{e]"Vn~dVvoݻi_{{NB'tmK}[Z;(K|Ek$}ϥg97FVG]fv' ~B_U5e_[]̻|_e[.w]B#n\Q/UTվ2gr\KWI%3;s|Y7ܼ{/}rzѝ.{oy;o+g;ܻI17;~zG'/NN}ɹ9HzY56ۥr_=$d'޽[]gQDn9W~ꕹ߾T~ȷњ5ev?}_1_(z]M|]OK w~k/W7zS3DkZ]'.hJﲄJVЉߚEߺ7_we&Wou}Ke7DOH@D4m~Aŵ_{n[q]z}wwww޶*-ooCǰ:W޷)u-=-%/gL=B^9L]v=oOCv+U_m~ArC6 }%]jLo`?W: Nzb"We߯bׄJ~KBe%Kr[v.~wa_ү^/*_Z3/Z}sM)z-_o@ݾQ"kXҿ)W]/I$!mm~HgW -{տ^0wb R){>+-+:}O~|~T}䜫%>t7$@uu7wtf<lٝ>3•ߧ^ }!'7%wAjO'ʋUȟ*}es=Sq[5 Iڿ߷~ APo7bI׆Z.LOwwK~*t_Fbuzb_.\"^( /~+x-U=cݦ}ӥW6{{(S^k{bvAU\$DRd_w똽Euj%w=֢j1zuB.}׏Hk+we\@"[znS5M߮Lchco߸~Q'}]$[ n%Mjbʽ}ְI_ +s85Nk_MO,~Ӄ&T)|q.ėa?굪k*EZyXLx' 6׌u_wEKZC5k5*e+.2r3>̏gL`v?c|CXϏTjkʨ/%"7'K?I?4ܵ=sW@})^[P2k"0?AnyC3ydB T.L/R64=6$M=ڿݓ_~BW[ЪTvV( | }pad&{>_x1#uuu_̕k {q^e߷_}F*+#a%6K}['u^H%dkz͝[8hmPR?< SЗ3/![qZ$}zSkUV!Yo;ww\%c4oAvZAbCݯ:ṊdZeu1 kZ;*!wi]ʿY߶$xWqZ_+k_.5U )!޲[Mߖqk)r#>\[avcQ}UUuJLrY~2wwchGz61E ХO)"]j'm8Q}-+J+tiVʖ=HCm^%}15.e/:~&AݐeZ}'),. ވ ł:APfA^L<C7_N+ֵ@]}Q*ْ1߾I~Ҫ.k0Q[׉Oo4 K5TV o_7oc5eO'XA^}/Mv֫ش<&W1i2$O&uk53Xf߈s]Lkd!4:_֯K_$V_%; +?߳:/jk| /GʃS_tQ\G c"r?J__n[\`*^EB +ĮYzU}|Z3ea:9DP&-zނ_Ujo"|& n߿w}0oD\p/@E}}Y%.V84^׿+7a.R?5d(JR$IOa ~߭s¸h]^^o]~[ׯRսRǼOZ+.^Cg|N(O{\WV딽L__f jܜ_r[}zua'Ec~ܛl[z)tēy/)6-_au{zJzbS-Wz/'w_Duo4|O !t>->Z]TCM?zd~/Ҹ}7'~[~ wBC?gI/贄(ELj{v~n"mL?D]bF@$=؂Ra @dW*/'zЅw{{]^t!.Wn$؍}]L_EoERe뵿%e ': nuz[קuخ.gɭBVFͻrgoW]Uo}k{'W);'}3]7 c?ogGٳZ"fք:߸/~[7zr#b艟]g[kuϡȻכ$'i.޴c?VR? &ζG[vwbPweom[="gKt~!{"\Jȶuevokz&.ߖ=WoZ{ 'ߵfVp9VrY-Ͽ}Sf\'$-Abk\%~s'ob*хewq+3~+_>R_^ɿnB\Tۮ+_muZ"rrNgs+W!{E.K%rY)0H{c4&VR%@ػ U|2~t{L&8%Kuea-ok]o;&k+=lG/}.]? '^e6_1=[wX%1{Hf-֛Z l[߼ UݗKq+eU(Eq;g/~0wĂ,/|J"TlV/wo/@]jKA/ {b7){=LײcBSw޸MO{yK bJ4~Ť!k_&ֻ )[l>7UU]mkZU_+=%=!2:O13DKQʺ}}v. wڵUɿ(w[E.mE'aֿߤ+A֓+${΃Ja_U}juOC +Vcw+sۊQWE}AQtZʇ[P't,G*{˞վ2wwwLcw}Uz{^-hI?ބX?.²__%;w~z`L5$nЪ1m/HzW@^}5 woU߾H=ePF}KWtl/ {\Zoɷb(A:_UTzd^+nﲌ{'i{ o D;wr-?I،yl7A_{Kh-26STkۻЈi׻wu&%c֋ww2}W 77}4;#[+*Z-&.{ Æ߱o`2HZV671rzq^UU~]~UZ1UZײ~Ak/],3=ǻw}VT3ؐVՏ@N,1{A9p^Eށ9ΈyEʿUU^Cߠ' :{'_כ?ZV65NqsG=ᶕkIU.̬(Է9SWK(Uy7,TWOD΂N-tuU5{WR뒇z/}"K|lT#>(9д H䪪_UUUV8UIEVԑi/ LoArcf ;"^  l/˾L?{zֹO`Zԝ%>n_ {ܕ?2#c_ʟB߭K|g[ ̯}̺܂~Bo'eG̚!BD➀fm2m;}޹l>_a?%h:4>~rl~n^G鷴IdZ~ղ%\wv_ʎOܦw~|kCM&N#̘߯Jv&]6h?3}w[KJ^ܛ9ECu!M %KanZ8 ^d+ƃ`X!`W>>Sgm\w1/?1z- 9ti!:' /TBpY@詔ޅ` oV jtdW AaH(1+^i8DRC&n*i("=L *AE.ȷA=hA: ^*N֓0ƎБ`n>aLO Um62(> 4[ct@,a]e049p~7B';8p&m #c柦U3OЭ@MNF/'Ҍ0^;Y h(U$5-Ěe;-Y2kLo=4&?=8?_C\!V*Av2΀wfe1ߞ"MakPc+U[@=& 5nwģcs['mu̩^*Kl+qx Lw:{ƆXn }7X $@:1d!hFn֐oˋyln6okƋ룭+.À&xqS8Qy?Y&^6?O>35 @̍ua22R/k8<5jfym+M(ce]⩆H56 c (qi|Ўҝ<%3iUfd[l@:S@foK%9=G?/WZ.8yVD|V5."(u$ i.rKӤ?2n6ZLg{yW!T_Oeh,9;-@nǹpco?o3Xk.b(i/ؙ,7UDp2Uo7T*˚cD;TUn)hU+爏Vez{٫㦋{Woh5'm)Vv҇::֍$Jӕg|^(D?%^] KW5US =REvMƒG2 'XpR?wޤ UIHu[ oaUZ4|t0(qߚ]I#ɥhcoYl]ﺂ57* Iu^wY 4~f1對/F,?7a͍{=]ɅDN%e2(%sO2rH[ؙP6fqÜua>/U`YFJqyӜ ^`4sX D*l|vY)x4(T3y*r[K/@+lW=H3o RTwB'l,{GgQ_tf3vH'A"qRNTb'Ҙbt-x ,e|A@LaB¢V6f^c BU%`)C%u$vufw\\yo#GJc,k棕j'UErAZhڬ_B# ѝDJ|o  o9c\Nn9M2=r5Ex23rj/v,1sؐ6pC| _ApWZ8|>j SHG6g* s,XPN26UAnwnyWS:+ڈ-LcEA/r|]ĆGi <,!μ+[8yzr1k:_#ks8ww~Řvhhq?гSB4 -[n&Q.-POiq<^w%yYJK/`cuBTtqY6`Oo/\.0MG%qiTzB$/ 8N:E^ѵ;5,+ &3RQLgdWQDV,ܯ- o9–QJ\mDU2  9 bJq3T"bt-k!4C=`@EP6Ǭڎu^! x4 |dvFgZT2T/Tw':+e*uZLp YБ9,gtXm UiIгƫhݚ 2fGUur5H/ÀHJpn Sw/$B^Xw xewlfW5d.!!}-ǃTdH}a(695s>T S$cՄ%e2eebB]8;V6NiJ#Z!>IڧoXZAޓaBs^$+{Z>H3?u@lDm־GWRıUXQe]{n&#*A9s,>^^4]=XXM#Ӹ:86U,@g3O ƝyH  &ȝ??ݢY$VEmwL$ Wh92/V|h2 Knݾ(.ݬ1'MesƵŨaZW9g\W~xz뵔CW~A齟@u.Zr.NqϲHXYE*mRldbram2FUB|SQDG{*x˫[, ;Cp1 iJ$N ]mʍm W^mD7&K6L,XW7QFv ̬ZΠIFN̄BTs\4747A;9a&mp@JFͤe@ok>˦A0\n+idRa [BvQpT4/.Zb֮(w 3'O&K cm2TE":ޙ_ZS~PxWM?Z Z{clZq;'Ur(7,/d!ĠJX9[o2g(߹c Rܢ%Ʋy*f|8T Yp㑞, ~h fl[椮J%JP0#UWTTMT-[(8vG !h QY ns֘M$icKȞVGk5- zΏNMtVߖbɼq+!a0[X[͖;72LTE5-?Vm$tژ#r!;3n{UW)%ѓ"z{WfjZUSLfh}i5 z;B&Eif nruu`E:s@gSn77vjSj'}ue"??).j: Da^mBL4eY;b/Pc짪%0ӦY}vۛDB.,>1_hS>)Z5QEtSXCCzO\ %78äXAg5qHCB\6 qoԘ-Ë*O$CdT]5:4H9PuV)=!TRi ,Y:PmKX9H}L?-OG|!Ve%#fd4LldzQVZ0q)m+0y)9lj`C)|3ktMܴyPl4 G6`8ENvvr49VG.:q- ^5GdTB&/V.FlDnOW]I$9bW"!^nH: zF&?:ϣ&)]zmr祎{C:Uۮ[T~Vm&crjQ*l_柆6eRTw6Tfܑ҃ݹOqU Gd" *Ȏ&R_RԻ%<14aVFlsEՌij7lk\Ԅƈ)IS[;( g@2-Y TV$Ӂ=a>U,͇0ȤbLٺ(hyfv5ѳ;pUX`'J-􆫾}:`fdh,{Ѿ=HksU(&n!)ϝV_;-s#\uVEbĢfӿ\V z{ަ} l-lohqWDH^lW HL:Pjj%a)XJᕖgj# 7TMk%>{[p7zHQ(,2ƞ| `1k'LV| Hd|D*\ أXrdYfߌ2k"Z4uL6fR^dyZλF3&lz*{\lUz3tU#DVTɨ5]w嬃:3 ڗCtCPPd_ ;aJ{*4w'Hĉrj&=n¨Zjm&EHi7ߊwWㄈ>/2-hQFlvݦLNtcچ-O 2Y.O]V:Iq4"kWIt]ck֢ N e{e;r&Q([n]q!-=IΙDjw{W$ŰW([e27UkBz wT35 L*jLTa*F.K7$oHc6b_StQSTm7ՏDAI/RԫI7]tG }O16ɳUQO{:V7Tw24œ+پѫQ@!j La0v[n:;6OrzlYo3eI񲢈ޱ*cq?X7-+@FussewoueȪgw{Zs0>-Uz~;1CT5}YfUsG'k!U~u@uny=UEjjnRg=c\RĒԈi NE{Ͳi^ZŽ[ >$3w,߇[t٨G*TTXnʹ @'̥W{BK#)x;t"1اZk7"p"!1 ;nˆx꒍@y+;-e:8jأکk~Kmph=zdxTJC뮅#غc-虚m>:f9ڸ-^]7P:Y3 nD4Ld׳'}NK- vQ>NTnܒoĒ6kK$ \’! 9!!vcҜvAޤ@EGQ}_T V{Eo}gdrd͓Xn[TGcktKs!|ݧ[yHVT"TAF#~fxvd9auUݛxhӊ7ZbOVsEjڍ9m2F\e'҄ Lo(LqV55X*yJͮ>jP:STkU*#::5femiqW]ӷVc\WxXŋWQoƷ`nl۝EιbҾܔ>K K -8ĺ+&尣-r.AOM]sdY:'f+llquVbNr#JeQXR8ƣ-V/cGaUdKyT# C~doj> *n{VgTޡd4+DGweWRqL2ŞQ$i-?'|̂$ mdj*Ḑ[bzשڸ΢ۛ6?לUfnؑ{X$5V0whm8)&Zל#c?WEUb)nٸ5Za AG_:xyjqLEyaVR,=Mb%W kP#)Ӓ ٘1dYo.z@5&SA7#y,6srIdĮ8x4V:g6*y*mb9&ogJ,La|jl J 9jA`pʠDEǀ ⶇ'uޑV^{[Mƌ֮5)čn.ujƜ}zM'/ڧ6r#l̴X5Xb$3'ԣ9L؆#z&[~ٛcwt=j=~Cq+(U|4VewA b.# 5Y%Y7$]mp*By&EYj./iĘl揑G+%}P1IgW#"RC{JEQ~ #45]I8Hi˔lVHjw0v5Q}*f"+Rq2,/&AN|>=%`ηԭ^*!egXxgt+]R/jxũQL x\=D_Q{HEX3(yb썤O)QW ѿS5"цTD#YΑ51K#i{B`2F1 MMd,oFi$h;q7 URe߶*EV- zi.HBOPNRt""(2CIq7YUE#9 _Ԑ2dP`%M\JyaW#SfhkiU^ UfvLV+ֱIҍL5ATzi!QIU-G#=Em1U1_*z#FG-[:w"u^g6׾?%̇[~7wlHFXJj:6e$McP7Sd%jcŵPe1{2Iz=Ĕ{.T"0y#f)n33Yv2WD  ]yb*mGP dQ13Yn}! |/aef򨘊2Wih3jOpp(ap'6#x:ԅtssG"BimÈImK?-UR[E,)to4gjnK=˯.-~]̤F|!lF"Y hDz ]AbZ[t+MVJ} gI'JvĔwMV7큡)Ňک6Sa]Lj(kYJpdL2a$ ByuU]̞FfNn1yGDw;:ş3RKn<9W8K6!aZĴ_"kd1FwwDwFVŕ) .Oe:z jLLULs2n*Xz NǍ`X HԧNmd$GUTUgTf[Qxi?o tHeKHhniQ!M2ec%,a gTW+1;NL_͕R˹ZKiބFkw!M] (ftO|(+1]:!4TCifq; dz5j[3SwE\;k]ES{Eɤۉ)|娋=30K w+}LE'a{?T%đ߲9HVI_޸ܻ:;;T払~[`Ӆ30C$캐9J% 䓩j]-JxUiCFeTL-\TZ&򨱔;=]!{M$d#tt8ZӉ\GcbYt&>֗ΗRnRCב$3.ZZ`uzYZhfZQhJ_^\DEJCzT\PƴλǩN@Ԝe&^lhT#va |̘](;=FuoTdYd%X&(flE.F0GgafDRʔqБTck-7lO!(/g}Fl<ŖVn_Yi~pSTg;;dcZPfMo%.FMu ӘK{XN Y6Ƕ(8Rp&9YpakEwMbB9HO %\%w#YqnZiL2nmH9m ^dOg+HM"Ft}cS_5M޾j&F!ӚIP֤hYf{}lU8 ܝmoj JCZgVoXmUoQuecbП uOX,A^ux{}Ghsj7ARpZ.29JS9uTc۽ y9ݪ:(}ڔyI}/[&N&x|(ip&F vOyM}zj^8.Q Jm<'pqr\O;iDm֎L$d;V,Mb*@S/;M8T:ow)LJW(:$] QKyb{3],F92\Φ}MI2ZMě3!LJ2d^s{Au|A6Π3vr>S˘CN*P)j5Y9Cq5[}QaH#k>&j(Jۭ8tZa\L..pMY0Fy,ݣX*چ8oj_$73[M6p'sTF%b+Uohu㌻<)傶czSܑ8h$1="oF:&s(+3;;X<RE3u^ӁU| ^RGKFhO]eOOd;UM7ivkD#&ΜrU&g$~ȕbmPn >-D+c,Ќc}fNsʆCO"9;U[*AU1/k8,3aq/Mn(Fb/S[ZNꤝ/f &PW!+YCB{$j.ĹOMSb0wfL٘JVUa:Uqwa3CsE5}R|jCYB4sS5B7Rq GVx(gawF-_L{*,"䢋l,ӤG@й͛P=nˣ DFKqv G3%C\{"*&7_wϱB.|Qؽ)[CϗKH춿>g@mx>zW& U;VʶH5c 2َ 1iY4.[H1®]g B3x>`c'Nl6quCs֣X{$ZW=\Wi'RGAZ٦ ]r;^讧#7Pϩ*P3V/QŎB!2 2'tͶ6Y 7gdPDж*& 7c"ԗW3HPȲr=X%c'uKͫx|# dn>Ly7یӫa8$OaVWS$wQma^1s^FO+̶İt됞3#Tf髜Ho, w˸g:*gD(cܯ'srͽF> -KU3SR2xvrIy#jh\QRަ+u|N9±Վei) &Juz[⤹5sJ`;@M\74˻`jcb)HZ5l[حeN5>V#=BK&n` : 荰}mOmU>Ty_J.:,wjS!"ROmGtw[%%UF{+rjB*'ݦǟ#>I*{$Yj*Y4U V-m4N,}pQXDl#(V:21 Ǚ_u:jXfX{%ʙ7<:ޥbOQ$q!i)R$֏M? 2R{MU]-5RF2ΟI.9p D4:j≥ى hbn*g7W* C"FJ|zFo.bXc4A#C4`Xv:=T5'~nj1]ֱ9ڑi_5Ë\"n7q"\pp'#F ]kI+鋯3ĭ7iȕԇ0fhe:'9*|dsvjr~,(DGӉUP/}|!5=TWբKe:n_٤to{lGaXGUC{h8C%B췊dWEe04.58Od{UqAxķdHtes#џYmRw#mv]l66x|KᡑO- m7 !dUA8veo[#l85U1{#ݱԛ'$`P46OWq[l`K+?ۏN6tn#4cF [C\*Lbo\z<1`7br;U?KMj&"Lbbwz"^fưʺGaC#?J #HJJV؈m|z4;wS3$bë-qZfMcKc:xoJ&9q TUz(mk0eMP EӊO:EtX uѱS۬=Te3Yʨ8O#;Dtv;\ do7L n&ouMofV1 q%n"5f-$gND^a sq{+A'e :UdТ>4zgӓr7 O+-HOj6N̅L@Q\蔜a}32+.[mQŹL)c7D]_)>L gمZUgٌNZl&MAk/IQƃ*'%jl4|3sQcִ;k l#9 ٫K7C.!4*H2IgQv$ј?Ddl2԰:bi}2nzgr'*PdɌ8:i3ja DTeSZ+_-A{! 1n د]FC)k$ }Z5D?.5t]`3WtbgOU{ m2gSd`oUQ ^å̖yĝ5MUQ.ې+챓thvתB\3ٞ(VSM%:"-'YTFi7a6hwކgEo$Iΰcl_j1Q"E ]uXDP cՒM1nHh$rȫ1 zbgq^lgj.M>ԃEdWY9LL!^34Ƿ7ed5}P-TjӚ0TH2]*Y{HeseV|L]= SF-7j%XÝ*G)wTb ,=L+i2)S֗~LoSY\N5)n> X ."-˓ [K#]Kw!wKQ@["fuuަ%7Vkp2fk効m7WncP%֯4f "`(Dk*""1pf!Vju,c(uˈFxwGJ'JfO)ls퍛{%u Zn/wt3|E MU3;VH+y D9jHN.dB[c͹yk 1 _9u#g츿žq&%~1Re*i&EZ4frDx%}]E*tQ>U,4pA[o>Q\hw3C^Dp٬HVKԳN^fRwA4k3drE+gQ.V=rgu€~l;{BI#>}')@QײAot̫tד7v\fI¼vr9ѾɍE[9oK'\es{͂B"wjT7MsHRV5E J!/PT$sn*M3[3Nl}J!:V`UfJ *otH67! ?Ř ܥt7!Kms:’-Z2Eҟ&ojׅzfi- ĆJL b̙4C;Iwqm7Ğhܘ*9Y ,.D?BR{'6ٝ,deAv][Lĺ:cM]vr5H@fI5/ө"5"T1]~/U&Oja S$CA UI!q$zgsF*PD]bEZuǯOC7?Nԝ;PLUY+id$}"Y1 t11L^*sOTiu­kv?0HP#s]guTVdkM)%y_5FMҋCKʢ0_$Ink;>#uKo˹:%z- :m9f2mHL8Y]*e^FY*v}gI*9M\i HjkTbGLClOnJa*^ɤZjM$쨔N1FOȶݸ;'Nn`-Lv"Ml!n:/CFog? GQ;䛟Ѭ!I@|åKgz*6W%Wȝݚ3|&2ys#rƾx#!?~*Hb_ߍ^cQ7rv'ad^d+\i:N^ى\ 75{\Kd&`60e*] R[ߑͳWiWc2/tbEWmWBv :WQM %|/H+RsUB+ c yu,a5:Lt1SKFl5'$V?6/YIɛ[06ׇ!Qp8֍34'40GISIf195P欔|qtXXhdx9~ rţck&y_玙h2Џ_8|5^Qy Jx]?;CI "4H7]gr07@\}WuQx)hfTɴZon'N6ήf&J]E" *ِ}?K6z4vK "q0w9F=#QmwS;C1W'|,L1|[/gUXZ1GQ{Mӎ4C$Lݲ5$&e*2 X4?9Sja1X>-oP^W~xWӤ o{thTD^o:韨 ?JsȀQړZQZܩmȚm4(e]T ֲʉ嫂5} A)Q*uܑijw[ue| Y삮l?&̎`􍍩Zf8BŐٍ36h1 r3uzz䵍p EsS\mR!#![{%I-CF0 ȥQ귻ܜr!aA-j[HU/yEbE>$`ɳv=V;7~ ;!t0III%olu||oeUܫXЦϿjG2&HT+ ިxRҁ.63kxiʃAfHYڴ,1b]a9>4d]BGC6⪬P=;* >'8j"p"1%69R 5Rai%j$pM%:a]`T; ?3~|cglm@3[t$j(7yXcUސt-Ș][Tft*y듁c&\SeDT( Ph EN.dɬC՘ ʬ!^= & @́TEK[M:kHWލVP{@OiQTjq537_tDVpa2WJ:~1lxw~?_YqJʪnSN8t))iL# dbA.anȷ[GZ1΢ң$$jt@pƬ.uiwYClйvIfW!UʈwJiVf['1Xct-kX]d abĵRS`gU% >r2E=ڑ +P<27o"+75\VMbTE[M5T%Z@y/ӕc./+&ƪL"B.[Pi|itѝk>;UnZF[\Z%!GYS&ᅘ59܅gna>f[MFLQVJ,0K [Z}K=q$Av*`뭨[bQLw9MUY)Zދ2m-;bBSNc=ōJ]]Uk]n\suՃK5tNHj;Lk7b mgy%?ޣ\*,k^Doݙݵq=H$jyZżθO#8p1!ⳮMIg8 zd[.&>FQݩ?@5fQjx۵܂N6J]tk߃uϻ-7D{L`)4 }ZR.:ji"mgtEDnr$1"vܽ:oK} v|JS)+*UUzzq%BY)fI oI]WnǨ(FP;I:-,3\_ TZ ՃP *LjY25abĪ.329xqS3T;U* u"uu{RI^L[$<@ճ<6MEt#{Bi3;=\x* !j-&N3lä.\ue69Z쮊z0Pkq@n( T0-wGr;8җ+UlMr5멱TjpN4Q@i}"wz>rd y0/@W,2'u$M_jt.x@.܍2X!!L>^xvN΅MКao4FHN'% %jl++7^niH<m[lByv!"1рxu:4he܄Gc1txq3OKq;ϊq%ڋjV?ZYKtttJ")F]33ͮVd}6}i27' Be3b7Ãvs QQZ?2f3"Pr)1J̊bK{ȎCU\ MgWoUB5K}M*1f5l;zT#35lF*,;&w>r l|EF|y]M1v$6F}ļ;^ 1eT;YRa휄%zl2)9]-$fl3UMxbƶcS)[40$h_UPu\[r"%B#bk)#tA^AVj:_^F hrbi4# T7af5ܠf,&y"D7~Ÿʪ9w,$ư>JVn801'BL2 `'"r.P`;2ܑ70V2aG?@- b0g=Ao\IxU0'e|It失bM`a2uHL=DDG+&CBRۼ*b-2^ q@p?.D=F`́VNv7pR>ndM˶D+1l9n>B91==u&oj);Ll-P*Z]EIIKU_HD80Jjj:C-Dyʻ~fjq5̣xETU {{S!C4p ߟU 浪Fkvfw-[aj›5h^o]k:AsnrxJ,$fּlkc)R usUR6w`;XfAuP":er MH&i,d'CKOS"4|է?S H$O2V 檄2q]d)`oO9RUU*p*X 1w([c.9|UQf-TJ~"UQF!gn\% Gwzpk^tr&ظHӁ ݠ{E1^Ѭ8#L:.--\㶇Z*>$պG}):xg9(/ g~+ ܈KqLYmh>iDO~JNWM|I[o;/-n*KuyhYu'zqڬgy@= ݨ; '&ٟ?䞨Qg@ j$I=j#"'LhnԺ$~ cNʒ':HereRđ.71s~e@;UӌpI!i V UҸ.: %l-#q$s9*8|5ga+7qt3YU$4zel+[Bۃk^\ k)7Ƚ,w)$SOF4rޟ;A8 go㍌ gW?>!g| MyϠP›.WŘ_vI2rS`—fڥ~4dn\<xLݝPE`[sӢ„!8ڻb5%ި2ѻ)#mVf̓'9/0nimֆrL*#1u>&]Z`mLd QۅSvnp%ASGTT$~YD=UK`bGK N [NA®BL.E{f CJW44Lb*ӷYM2(ڼQZQ ia)(ЩHTIIlG'v-ȖY"Яucl"yӑ77_ۻm Y~oT﹊Vv2"mzMZ( vVܥUcwsa='S.$-k0ɱ¡oy">ξ Ņ2ӥTf&d ;Z7+W4\wr.¢##"i)iq7jf 7 %QUwO5T7)ԟ~c[a%CEkUESeR{{B`3?@UZܽu[S7O:u/ґaR^5?u|^mQ/wF0E71qlDMMe:ٞ'Ӥᨀݛ@9FUXX\qcR"T +I2AykUEɯIH+S4X~]yy9;DnSeT_ ᾰ$gz/ ᡉ ÒlGB)wn"-jq}\wvBGc#ŠJE++7f69$#̪;Tڳ>5+Æ.M_MJ)}齖P ѹ%J7XeԐk9hnp>{ {s' ֻ98O t1C9NV :3?-1W"b`K[|$֬˩@:fJR48ES`\0AG-GX` w͟Y9|؋C^o9 Tpu̅s)%~2Alͩcj遅m7: uN!,ġ|7k'x n-iy9"P∽Q}SXQ$ ^Z 7V[5S٭U%r @vGᎮ/?gb )A]*!r^B/=_ZnJ:c8̰|{HnkϙO橷@KvnD29V=/pSz4u2ZSa & h)1}LDv8PBxîk[gƴ;- sP0h$` Bb">9fX3T*RxCAA%=fsw(umǐ֍ WoZq[Oh,$'T=M}شVIͩ?a֤ȑNηP[R(}RXYj@yZFq4U4mxx#0.tKZl];:9H9C|(3_EuL[p1Vr. `ֈkIuiyn4(`{ARl r ]#\ q3EI5[cӸE($4ײ’vV]z )͂;XX[k<13Ef:تVNRQJf ``kvڙF.%KQ)U/>)sJ]_+|惺evŔ~h_K=SnBߠ8ý5[F @HZj8BՍ?Wzu 2)'#t~`e-6/v(Sf@zFF: Pa^Շ ,η/* 6J+WZȼ3d|, `ܱ`.!j1b؉= K50$Y!8ܞ.o}3E3su޲tYtjm6gpc{reʣ_])D"T,RcN:Dۂ\tP7w+Qk1;5K<Ǘɚu[urH$qw5wvpi<X)4 ~}$%E?٥^ tJ_m}$铲TfJ'FJ%6g k^[+Kxў6c1(lYfLBeFh84n~t2 0S"‘ĶP v֤`9N ډWN Բ#s5#JH.n_P*)۴0 ]Mb̷hԁ\0*+;8ZbyJ_v\U_@vYR+/W] ݹ3aNLfbC29*h]kMXwd2ղejQj|Ph`1gfjt4v'9#VfŔo701)6bՌWc\nz Yri֍z.-wRC jїZEqY[[fURMUHYB5] Y֍C@?6뿉N0$HԯFVY=gwA&:eL]Nsf5-6VC~K* ػAt7a\wE>ޣԙDnXTeܻ)x0|f/@A0X]硜0gJ>2_ghN %/U얲ne5э2݂MY{Hݜ 0y81*&D!vW6M' zqd˴KpEyp]]'ջ8"PضUaTKHn(RI44hi~)W5|xi6ɛeә@`^ 3uc0MdKq$*ꢈNtFXSI0H0=9Ňdx @\PvђI8댩QR/w!w#oTU&A6bb4 Ԝ¼٪JO }ۧ@̜H]ۤu<]0TW̗9.Ъ|VFL^UifesWHFcTCw0;8Fsa"[6tN:ՎK=ZNDmG%b9Qx^jdtm%TٮX (98l&N{O.0.o-aj ͼ4n=x7#&:^Q3\Osȕki4޺:H%ZKư)!&/t, jm[s(K@XHF| VҕDzMY 'fܪw/-(m?H֬MޔCJMU#ߥn_n >Ԝ!#w[Fa:1ƪTbjo(fmꡱXkZtCsO߸: +)̵:Y509igs^hē9 E(tTB˩! ݺOjg5">ݹg7^WL[Efd٧rEw1}[rXkk?V17bݧU$Z&cRPjH*k`vFb c90F}*N1&?DŜԷ 碋d5|&g}0!rOĜq&cw E? /^k[ѝuFZu4 u1*# |y4-').$k<52ݪCiS&%y~7oxpnhKøkc~2J#R1~>z;8W'vUb TdmEjf 1lSHN0hAg2Tw}_L|q7'wv-((ҵ"%E XkTձ,>AI!Ѧ0qԮ~6cZ-' s1Dͯ0W1&*F?tұ%S+eڇkpe+r*51m㥄nWr}0ouQueKtݔO2ZDBr2ˮ0ot@ۄ=#@J](u[q?'OdDY6wzWF= I wǻ{#ZΧTjX..[ׂw}aWBEn^M*\pw70@|>~/x-e/+,`LPYkgB~]- zETB~D;iFHTis 3 \.*_xAHu#|@2Nx#dɫ}mNOl.T}LnM-߷$ (ow:ܨFCj ucd]%Hڏ˜6ff7)U1TCUj0H>>K+ZOw`%H~==kBA5|n>[`m>G\N_$bǢXo5yʞ\LRUr^kIõ /`qd 8߾}"D|r'Ы1#t|-TZ}cM?;a6:Na2TmeљnwJ?J4[5o\zPR~bfZ6>#DeŽeOGYюtW@k[5FɌa7!G-j?]OV ƉtF,pȉd)ޠK^nô:nG.f%!I*v+ nϙǙgbܟ"DE/wcS{_ C޺XCzcr.G*?SϗfBcc\]KF.EĭgvHz>v-B^ 4˜>)ٴbZdW>V 9YH,'h;MA#PM^&oD1 [Lq1]T$J.6SO)2G9ˀ g/ oeM."Cg.j;.8 s;ƦҒUB2^V^yk*>ܹP+Ԝf\k SA}#e>Ukj[̻یJPhk۲^j `[dXU.^'"_ dEB#cM {]v ? \Y -4py"ו\, =W.E2@&XjHO^2g(AΗ&`"&%=NUa[Bgɷf$⑗ E#Jkm7ıaVaarFBɑ:rX;MTdA-$votf Я/EJ=0(tWZ,E~OC,DD@{|h \c`L Z<`2aޟa ?HD4 @,0),)_6V'?8`@z=s/?aNtJZ+n]8&(.G:_V6Jvˋ𤺗\y\#&<ZZ&R*.`5/}̏oW:LZ5VqDLA0C>ZQJ8V=eG7RJǰcHgaG1 bQi#Ub79x4k×-o]f:&`N5}7^ ǻS\!}LttR.[Q?cJ 9P,d䖨N|&@w@џzm pm u_"OF&v<8@”N:]-Ag-F(:x7}#Y}t$6)Y o7Z-k諩Rcg5s/u'1uQh^H_?ɳ}ޗ?.`7yr%Ig&j-NhV4mj/$!.Ff5.JÞ<"-N~k >3ۿ ,Y?!]ɉhA;!IsavnkgAs8íB1qNNwM HǫiOZEȏ褜4i$unS#PQXȞ!7tcy#{|/4A-;ep0.eq2&"N9/jt5L&nu^X#mP8_NLoGhxHCޅ!fi/.J#i#i7o/0!x~P_MY~a.^XSh%y{ŽN1]nZn]t팹!!VkHE jۡjGICx%!{728#)5]sB;s3L;q-?6fh V1}M* 1khX3GO M1\c9jbu-|M,]26cUubr ՍAI쾄;[kgY=E v̝!B~FWr1uGXOB Dhܾ,wqCBuS~hb[z{dc*tb (юZz},'sY85|,1\N-Lh}y qWLszWnݹZ^!}@la֥33U_"mьUڌR7j0C[h<9XDm\VtoSuucIv2 N;?q2F+1 ~>3fIr&t5񍯿mvppphb#H&VL H^SHK3\RtZn&:fѠ,RbǼr#N.ZM4e7>y T)x쌛Jb{ǼV\y|ELp[KHN+i?D?oiošHh4ex0ޤOUa)u.՚&&2g4S"%b6ӳre=Nnc^R|7"g{Jy%[ z9N*CnاʚJʹT;P0Dr=ŕPd+"VlŔ(JDFŶt'5GJMLjaQk4sEIl5W-1z Eu)vխo 9+Fm T?ȧoy)' "dVϬчܕB:֊ !͒k52{aK| 7%f=u֠[s_q/I ͷKALqčaI_eZ4ducҨJtLeW+qf_ Za5b L`iհ?|GcU`z+FUwf ziU5u#Cxx]Vvj_pq6` EDβ^m*o#*t459#wWrǣ.ۚ'obo=# Bx,CvvY5kv#+d5&.v}øo+%PTfh)?P1K%F|.BFxAAFk9fuddsrSUb#_ -YfMsj^$W %/f2nBde_gm'beȓ+fTO5@iHH5L* ͉R ldTtGj^]4[$HMK"jFuoyVuf$ }N3Qh7j5. mޖ&Pf>y_+FtBjJ@S@3+ahڮ{]`MF^iN4Dׄ,nO"GϟnHb%_g}˿G5}ڇ帓45Sk1kM}&,t}# &&su eȹo4$6%bj-=v)⹔ XƄȸR EƲ{g.X&pٻ+ǽQ)%:"_f'5v0H^jҡgpD֛hD^Ck٘lH?SLA#"V^e4^զTm>u]׭a$32tB¼zD\6*Fz #e sa[]2"U i'qv% 젟Af?H_46ZH7@ěJueؕ|1x*#sC*Ghg.;m캰ݵ+Ӡd;!i7'aW Mq\VmQb|JoXo y6K!4ۗ{QiRbnma/P>o%3[iW4N+udx*,b0}LRӶuj%Rڸf|{*Lh%C)ǡ\XsV[n85>i8^6О<xMIlbћ=fޝu 7j*6V(&e[J5ђwO:L\-dRߋ'Nr˔woRf[]F)TFZ8{6PYELۨdwJc}AWSR2-fYrF$t36xh8DEv~뜸]o8|"/RXC }ߒͨ~19 7gBJ>F~܉  0f0iY, ;389/_/ըT\i\iO@ʺzt^n\w47iZ%BCYG<Ե/rY~ 3@V9Lgfr4[6uO4?s9acҒXd.yN j0@\)NĹar޸]{26$^LݓKaeK1iU jkqt$tNy8H}ґLkQsz=6tܪx3*7 pD ϹVzl1 Pm) u&b\ !C}S{q]y[D6ٍsi8RmBX;@ s$}!QrId7aN2vJKjZbFwR aoiDdW%OtCXTY.Qr6B{aϔԂ7?3N1?qk婗jhU'])_h rF-E>eƻP;;vp:ڏtso/M+!jKk}Gy4o0FT1"YxBbxXeuڍRR;GlgnwdgEnw=1 gyӀ;?x,;9a2Kv6w.R]\Ε#嘤I`NƣШ̽I:(#BTGL3|9Mn4Xd<kвyZd̵k:㛃áPfe5fp:Am}"d,hgMnXtO H泡K/]. v&CI~B@M YV訣%l&OʆnDkdO.y1qNqǜ B@nKѳ&ޮrfd8o##h$?zqJt(\|ҍ#&mu=+ )ĮBD;!ť {jaȀZ+')4*q 0+RCiY I #trƢF0TQ+Wby 8LWpssg`I%ǰqC}M(Y t%-ނH+Bf?Cm,*&\xL?ɞ6Π pĮT蝕k7-݀,K+3d K('_Vk$loMX̦)A;тo<(c^|n5tIVD1#dx)l?6x#p֫9+~#K)Uxb%Iƅ`48xvp;) n[bWƦ-'mλnQ7Lfi_nˬ*nFBfg%L2PlLQĂt`E^K.Vlhf^LwY)NJ geQM!ǩm׌#>VqUӖr%o;Z^x%sI&y :YHs6Zޑc?ç]܄;(T wƱK|+V_Ս +C u!Nn7o z4[cS޴"3uI>bݝ88X6uC  &7\H\%rSMy9|x6n[D6Ŭ:TE@%&MmRP;u]%QR:Ძ*]uT5iF=# .ըkΑ-4JE%S%4OsO\; BT9xż4-'Ԙ"s.{5hCi%9 F[72,ooՃ;Q >;b͜ԘJxڼdUѐYEia+9Gb4%1yƒdɷ0C zٻ:(P ҅|pBmwO]9\&סv#KZ|Ib䖢f'qmxyq+X詎Nu.W4sg~j,f\7U'$ТRZ#bA!4#E ( G.HrJe4Q7yHPA2jDv+^<|9-kF]$ihSr/5ᩣ]pb-:1ZU ļK0G3Hoo[ԢGpU8[cMԬ"5uF^pVi5tB0ޕsNR(JeHϺaukSuD$I3 g & 4,d7FYʺR[5Cmj, #uQnkNt 6фY+_n.B,㦘_aPW~qL&6ؑ[iMpD5FQ,AZٗ0pf%5Y'95siYk PFsFHg7UL] |l2ص4ԚlTq9[7Xs`Tr.{#HtC#{@Abl=e$mmkЎA}Vx^vT[ &Mvɩ[{f'8gWށt%&L]drNLO*H5o0R[W`9،`>c"۱xi]"ΠM+De#j՞ES[K}mr3)G6[ok%yU2a+jmŌLTham_.{aLĿ} @NgddD}1evbM)Y0՜nqMEYu^K/ޡvvZ`ẜ)KfrZ1MnU?쭳:mAUqXGuH"j\$C䇺cHTFlVro FgzRw +.Io߉Z cHA27,DtiDevh@N&5I:Wȵ;#jHp3\)66kKyTYku&5%k15J|#=Qe^^298DMPMFGׄ\\adhlꟓcZ$UQN@`tP|g|J]FbWc Ħ#C(´dw#{ Nf9YqzBэIIؕMՏUHMemMlV+]1r빍TV71HWC=Q*m w=8X%bý%3V?ޞz[Dõ.p xDeE: E#{Uc4IysEw"e]V120W5rN;M,X{ёq&OWBvɱ]<>}?IYQU%n(骫&BŵFQ{'Ml}%?} fQjӻ;_C'N:Y!l 2ݺgGw mxZ߮L:%&'7nyN*q+&6ss*¬l -i4WSnIud$M."I ]^짶ݼ^nPtc"qS?Cm3{ F]J }R` 5 &hZʓ+zk%>ϫJxmmd]o!\JNI9h#&_$ho\\gn9"L,HWqbLdw+z +$65Gn! ZM/J;m]D } q{f.wj2C*~Lw&7WLGlׅ6\UCy"sxw__2L*wS'Qؐ>i1%f05i&dgc  }Յ1ncҩLB.=ru3ƒQ/ P h)4u-mt^גSccx=$oN`JyVgگKqfd6hdgSqּMCm Sj v'r(l!2aL!;52oqn\uu\jRtІKu}ܻ0 >FJ.h^k)k6mס(Z;S,e;1|㠿BCFsR:]f1)6$:B4֊oKd6&N);#'S}+(,pk/鐒Gvnf4̢FeY{Rt`pg$EeC7حqr/TWlOJ(rFk64RmKvv !P"O9n:wYIB$ ī92昌sYt'{4$Wu@kn(lK~KAƷ2Xqy$PW7M©1eF7ʖK$md@([$Юj.`QEɁ( FŽV+ly~-Υbܠ_m@sKrR4ed~jUtn%qRW ɇ'&7_Yns%>*EcSdAtݎH핋 '9$_9j4n34k:Kn b2G@KL{AF#,ˁ*$0!#V;Et3MuY s끑J.Lu+HM22 (˭_E&XXE|:mQt%ly̶ۦw5g Nk/uԮ,@[%]D">K5Jfp@ZCcmVϫ2 ٞ׬@Dʎ J]̬)(dzywuG9-Xb̰]k9]چP5'4T2"6sCM.6L-\(-k?%V;M:ܨ.'`[5E}]Sq[+ipr؁fz4bU^so-TvsY}նMBOU)qٯvV{ж5ք$ pI )b^:k"a3MWĩ\mOY le7rpMxP4\}=YlK[ mRxߺ5z]Aq ii-N;V5o~AR-O:^M5:T]MDJ#,lFml*zq詸rJ&nF  ٩-kЧ(w(0e ț64W#(K_ܶgYh]bIRw0BDT da aSy׏F#0VI`rUd/9^dx'[ei Ǩ#*Ԛu"VQ26l!C2 }óRC; . &2H5\ t+ I$G^lǺt*W9@1ar=%>&~kyl !'x LX4Nm"{2MUєc#"$Ix>ZЧ9VV9ּ]y7W:@F\}Q`bw|UJlAflnvyX8vya}s fuS };$]tKb ]' %DZ*[Uy%4mǶ}"Zg\5bB0bR f?Y㬺t~~lx}Y8ajlDltqdGw擖ו (Z)S9ae]:8Dٞ8r%^|C 49w9Hd{kUS1PeMwaUVϫݱ CdQ5hz G RBQn ď >! :zY -7sXlEIoDA4pu wvKp[fVܳ/!SM^%0=BYS\F[ z $&׷> @r-]H:[^U7v6M} _)Nd8[qڕ7~c:<@w*1aX+$~!"6D]#\r#FpEv^M3K|]Ơ ő"3FR 7$348&~HR"nIG9OnHʺG]EJ uGxY$e#~m`WG= n0:b8wН_[QJ!z,.e<<\oq.G_ܑld* * Q{r΅aG#ajL='6՝ʛp8lЮY%>*ʗpj,$I+RmHʉ5voh.YgA6;Qr5& Atl7H5ő6Ls t :'g޷,}z-53©QYb "6T_/xMo)j+8rp:>9kˇ{!+g)SL୑%.F`W:e-ϷpNN,km F +] }ƛF0?mվ/ѱgfC-zKBt}j^˵^H8a-2VZFPhzWT['!3TPVUFeZ4~Ac]Y{i;.蹑lv(pWfd,7j6%o7 % 2wc1wn̦\i+cy 40a;|,U 'd3MvM92̉?ݍ3F81`Վ Le/YOrXLW;O7JͿY-TGIn2^.֯: {Ke,z65"-,LڪFkdN͆gedUۡ*K2HzJhv\JemR ڠ o;fm7Yfpf]ܘ캨kšN)G\ds$W^.]S+_ W#܁kL&(;iҔ:ʬVNHވ;"ۘKv1跔&>Ԓ6>󛺬X#[ӱi;Q3^aM9! +4$B+D6)5G=RUBWrH7;JHYQլ3>eP eWU} -Ueex]%khc, 4T#D0jIJl#1rhBrLw40@@&j(w$%!Ll" B ¯NXCx"ȷʅNCB6wOM ͓N:tYb-Q7_FUӛ$Mqx=0_S&qV̺**:=.8Pg)!F$RFg4E֜g]V^0;NE3ۯ3>?pIȜe 7I%1uoLvXǞ,L1͡ٵS#kg(>,yWuvZ8h̟N`ݕ;sƭWn.XP#FC;ٜ;At\ne9y7%LLK؉8w[] ԕLM`lrtVЈhcwY6t<5$eQʼn&vJƑfn"w,GU6jΒZ!p*&ot;ևvjj-ɶ ?[J }lD3|KRѽY1,=ZTFkb{hXuncԭS{&{\ĕġeqhȍ˅a ku$GjgU0p)(LMd#=g6)O/7WVR(ֽ݈b.Ib%/Jc֊TFIFQçMIH\34!NaXH!hhaXVTqnȼUڨfNʹ3U J*씕(A fW5.^ L"oAa^{Cry*LS5 UG,'A.)Wn)4R9| ҽ6W_"騒IfnHv'-U Ζ\S^#sFRˌs>lWm zs2lnlXp3l\ \ [ s}ETfH#I/YUQʳq3'ך $++%q37|ŵCbo4o@YvEC5 yf3,hRYU'ʫ05u:;ł{YFzZppIRǝL_u+7yvx*%C= gYF2IKsV[ݐܓ-^rfY3U75yDXʊ'?cL7p:GKVIΆakjtCFfO"! vk-H3չi0')"bĂ4ܿ& [Ym#1\~oclD+Eˑ)HvaNMd y!ao3u[!,@;2ɗQIzj%Uv![;J6Ȧ_ V'"@WLcRyJ7*h MVF(j*BzmYPwd,!LMI+fem6_p]tmcE"pӁ~62#w#Knb-r WŨLO.K*ds7zcwfLԁI%f#e#VL5$%VZxn} .IC{ sfoq!-7#ID=?ֻXBڶ޲X!%F p﵇IjJogG 3]tQw0)l(lehF}!IRvhS"Zj-PϢQViQ mVq&T3n=i[w>܄ 8L9¬sM5DFU OۜAWf,7~c#s#ٓ3+ږrGMc|'S]^BD BueSl1ݳqA[sU/3^[5A;%kHW!f<db+7C% Lk!eI7nCpų0I ט!S|aqdLu4Ul͜.Z]=1tR>!.[s;zmiS5nMN-^YW2'ߘQ3G{ϙ|!2V܂fgOs̫ҜkChuYOţy^ ~;qҋc’mE~o ߼`%N)>ZDbf$LRPfF5V)DI.LveJ*73OщQ*:V3#W]m+9BE#XH[wSܻt F޼C6Hhnee5fn74д~IˬkvVE=ܐrIlf'5s-%#QrƄcQm1[iV9$Uۊ DwǣP1s8f/C”+MݻMkJMݕ_CF1(ȅON[32̚?xv2ӯƨٓ& ƻ ]6pgbb'W,5RbAֽ[Xh"f*P:nYs-sdv[ѝy Xr+vU3.ݚc.s]^yuW X f@98Q[/\x }n Z[ pҢٳcwcDkVqѭʣٵzYZ%Ya*ֹs+jfLG"*5NFJlָ s_, L1+1!y~Jm d27x&L$)\<0N'6Uچi{CJl%s&hAXͭCx+gvʹR1> D!8q\^Nvt[џ Qg(+='EYnDc7Fw&=,nvВjTSd;&VЇf.INkp|5FFYO檑 $jKlq5 M \W;Mb&3Dzю%͆fK $."h;:keM7wKХSd5I'] ds4.J]JݹF5Ypr3bSvqZIfLE%Dea͌5w @ɥue.(oLMZ[!@vp@SHLHNZXo2}+} FhuŦ賲S|:uVtY;)=!c-A[4F6# w{d#sjƪTVg]hbʨHV^^yά`(QMą_:dPm{L t:8bGU+,qb$ڳx&3FocI+b_~KYcPMDޯY lqo9e^Ti5kO 6 z<'7_P{dvY{$.]6i/}h$'Rqt=jnZL'%Y 7.+P!&P"nۑJ*Cjye1@Q:oQsΥ0U[il 6.b>v;XƋU ͒kJs.4\-9w\KY yQW]3 EؐorY 9h!(4 YPrMә !3;Lrq3aeʁ\ <$ &+o[fcy("u֥}MXơfm&o6^7n6 d$XhvMMcY[z Ь#P\4bQFfڇs}|JTMʼdnDCwDF́V7kȿj:KQE^=3I_ghp?m{[ 3 M)₊Šr*nq |58HmMYɼVtj1tF P K\ܚۤt$ǫ^[-,Wmh+VβZE%, PgFgsNvwL!Z}TkVك:/6UώYt ԴX\j`j_N;4gvk>"gq^G>Z"B#IfK)`4S@pHʛa kx!}O5#Xt;ǦUq]#M>hȟ㷢M#Ps9Vv N!3.\&%"GХsrV|E=`ÍATH 3g6KDfMz'&80>"!.k{&S_kJr 5Vee}HoGՎ;818Y]S I cm<JُrRp6N8D5[#x(WSN5L21+-j*>Tn3tT x0 3IgB4J܁(fMf=qʒ|0In졆;,&ƏʁJk=c:8DZ iuĀID]śs|ӨP쓈jNbf SZuI6WoiCy-*״$H(G?RuiT3oB[LAX^rYVj2s8 hhh D qp c7UB&=N uW'ln*="0M QЍ&E9#h1hPjjU F= .{;sB%98E56!],v[M{}wWPx3gf׮n-C[>\L?02td\:N4y˕m}];+Zt?ui[ߖ%S%F Of "V PMdQGqE)8en\)c÷ nQ5G6**y3Bњ-ZP1!=QgFy.ROHb&BȟyÓT UКREt[kGyv0}E3F3rY@u FTULqdPF4F5{uS(-+6P6ɵ*nF^8: !~Bv[{3#1nC/xRTKـ:ϑm58娡t ~1J9Yr6eZe@ƅsUG*|b^Bf֢3cWg\Q0rjXMGhr*[e3yk7r X*fjH覬@FYPG) N)g"jh*,2hƅWJNvMZnʠy!+& n̺H-GX4}0DdGὛ9u˨˵tXIrٍ .Uh戈%0b25|e$VDֳf0Z{ $Nn 46.y+7?Z5I6aW-=p l4u9#= ɡQ `ُhZ;-&G{XHcg k,ulWYM>TWQAy*d4w K2c 8*KIE[k)#C]$*承rZrre%Ib#WܫM :Z(LB2W0fvomO% ]{pDnMm/h"}?ejm.`ǶCAa&sV4'ZH;_4FD"0 +i4\îa~5mcbT@~Dua>)96VΒMPӤ&_uMKj.j޽dd\uފ?CVZa5b/eU~t\̈́+=Zh.DnjdUa>,37=} G\rGh$*M_A ͺ=_ W?̸Pfr>Uܢ>T̅v}V,sRA.-̋+&(OɕS="?3ngcSwj7amٻo^!zO5.P6*ac!3uƫKԤ_9O1/34GXb&yuq>O&z.m]Pw~6od*dAwA;cFmE5J3D"GdVD=Hեy!3p$19i@ZXܙ@N۹J/Tw\u.TwwtӽJ)B F5C%ʚV3-˶&%u\?Յ=dkf3T'ڻipuM2dַp;m83WUP*#H* x,K$5l_sY DݫLWpZ{[~ 6d &r5%lzGl%FP;REwϺ<[sޞ‹g9Tޣ e4) dK[rcßЙ,46O£s7 1|Yi %e4Ji"ٯZ0Di$Qt{P5c}ym֞@gۉ'^Q62#,{7Oy1mPs(_j`4*1!"HŭȀJN}*z nR/ֻ:;b+6quKIh"1531$uTEdARBKfjkuO_wYyr-f1IEvBDA:Tr]:ڭnA;"Am'(.EmoF6PY;+X )kMIGj] Tʜ:ІVo!M[#\\*ďlj%'UPEm`*1UND 5tIpo4u >[{'^uChl$l[a}7lNn7u8p+=\2Ԣb{el9{P_׎эn7i-F$.T8!Hsl4Xˊ).߽xiq֬ޣڪ=}nd`ެ騌{g/U5)7Z B:['{ ǘAyD Qȭs^f1B)}c!abk.X$bn{R_mXmBmol s[tTMQ6<CxmM8 35n-(l_gnjMY=Vڅ\N&ZQTLLV@ckc/zء4(,U)"4--G\cl{x+~i*4?dz99jHS%lfZ jHHl@\j\ X+sXZaYkBl:16&ȭTڑޗG f?` v MTCVufH;*zh**J q9j˗k LHڬ{>4#̋ۺZ@LlhBBC30O m{<8m@?y\uyM*pԆاf HH XG3+z0bi%Ppv ɒEkG/44^~64.芷hp22; ͔Yv MM #TW M:T@))2먤2YԬɻG̒44UX#,$ ;<#.dF&:g Df#sڃ.42!ݛȱv.D-okJwWMۇGx1Q dq,;uXrT:<FC%!iU+CT{pn0(C^fv ' Ur$4\qTv|S8 H{yÊ#[ " %qk@ PJ.[r~gVj a ehY͟~Ȧ/ڄ5jwUr]D/-BԮ.͆H'ug`f*b`}XזYcF{(u -! ټdp3xD?]1CM'"V:_Xhbf /ZFI fw 50 (ik)^WHnYn pMT=z؎+##mtibRJ$Elt斃K˦7Q|z>p' JCEw!Rj6'dYB#k,Bc]ӒEzmSHyý.}pC Rjj+b+cПtI=:"ScL&dpkN` Y]Q+ƻja2Bz2НC>s/ Տ-:T (l܂;J$FlI?˶ȣɋ\-CW(8=`ʼnlP@͹P\pz=5'6kR6rk q`u{Fe5("21OnGCCPg҈`$cП0lx`d`z/gSڥMʺFGlFM lfM5Q=ˎ95ޮSi*%5ϑ E\ަi)) RosV5D_%^,Ȫӂh<(m4ql#2!7+:D⏌7*CNF"Zlm T6%k[czp1$*Dlf['(Dod[JߕB꿕zWlENQzgoޭdo[u\V+mC66-E;w) i/} wHK.RTL׿'Z8ZKx(Uz=T:L_Z[#?]{~Ͼk}ll݃`gjV5ghWwkK}ݧ,N`L?K|;Ms{D"Z}ދWސMJ//~e%6'V{:hGUUU'ŵJm+ZuU_ߺN*md޿ѕԩ~}z꫉tQ? Uӟ胕Uu0@ \5 NUUjW}+JUZGZVNXvx@0WjFv.跿őW'b{=m\hRlcb]Z&GZ\BUUTUWBB޺MUɒBz^Bv"-}HVʯ˿Gw+_@-UUA_]mn Rqo_e/~׵WKlfդT'-A]+{m;7tkoJJ23_zUEe֪..qP$w=6[bww)$QT'F{^Ciopԙ}֊saDuW`=ֺU؎ۭz/1?rfgk%|kҢ#|_>juBܜŵY9kKȭu~}>w"jJK]e_ZK7-/_쇠vja=U EkWnzg~N=rL?d]ֿЅZNܪWߴ5Y7e]s{}{Uۭ2aZ]oݿ~ҿ^~k LJG3$Z^EEFR߭r OG-DE7ovVe}bW/"u /orpfݮ aw*۵wnWa!IOɹ7NR5l')6QMjjunӵJĭuA4m}}0$F.C&! _$>?? Cw5(ɳ@?M5Е;-+u{׭__336"[{{!7/:2]Zš z{~_#uۿ߾߾)J~J.~m%.UԚ{?Ѕ{tRZ[_M{ܚo_UWrs.z#S^|ks^JWuʩjL[{O/^ɺ]jC[Zכ[]f+E-WU _yt]zsתĥBZ~Fj߻>M>rwڑ>~]}[]~0_~}{|{ZoI uuGf~ް ^Tu/Խ߿?w}TA**-kDֵ]\ꪵkzO Mݧ~un-v}lKz_깉O!+櫯{/wZQoob{]Z+*ﻻ[+tJꄯt]k߭%Wj{(ܼB~b/u5ϐ/ڪ-`Q^A-%=E]U!__~o}߸g^^d!/꞉-Už-xh`H ~RCU|O]-E_T",NWvOV_ZQķMހ zu*})Y-Hvu\_ǀIhwZֲqjbVt3^&4UZzUE_'}BwEM@~a_I_=/)/&y>CL;?[w]V$Uߓwj:bUZKM2W _R>W}wLT7GZ'|B=B =UVU݁wгW︮Qr5_UWͯ'GRd޿!b;ߣE~oUZk^3=ugʵ^U1\"]w_]k_rxuwLJ o=}ޮW&OR[wֽ}!}_>o߶ߗR߯o ]ۺ0ժK{F}MM{Bou?k#wG˼obWZ{!r&^Z^{[ S^߯z[*j[b[ܔXK5{z׷[~;{}IKuU{]-D^/߷%G2}5^߸oKz ]gN>+nu˪ԕMOYw{߿uoDd! LL[|Y34T֟#@*|oYL~w{#ɪ.ٗ^Gr=k%o /+]eԷbn~!ɽ/oJxV_ICzp俵P%߿z11TD^wn?Uv˹7ۭTGe#V.BNj#uJ]GQ|No"_{}s*+eߛjLE^~lٵER/Kg{k9D/VeRdjzZo>,_=s+=ӭm5wn])^W-u 7vW}lˮx4Y꿶Lۿ!)-k_-}Wf&NZ>ꎭDO[17ﵯ^ʪ?_~򧻒w;{} 0ⷾK꽿%[WOߤ!B>!3VLݩ^G餭L ~~lR8Z{U_NU{7M5\;|KdSW{s-u],lfaւEϥwoo;ס*#Y*C5Y=,MZ&߽ՒaZu=uzZH B- 'Z@:@/RW\JFQINiTy?K2gR%yU ֿ}~ɿŭzӒ~}딽zOd/ɪ~n"KB~rHZ k^uR]-?OUբmz7M~#U`s+Z(f~2Z:IN1{-/:9V+kA]d{޵KܛFUK\aﻻpq7MVɱr;%ړ-W|[ZrUK_%q[o׿TUh[VM˸e[^ߪ'[WnַyV}z}}>]8K5{w~hMUo~V/r/wn}oun52z߸F!wq}߶ +׷.Vס,pD H!i_fCuB_k? @ / p$X}B%|.}m~n^+ob_I|į:W׻rYuy/'o# {Mb\ϲЍ_ZWZJ#.'Do>"5ךҩ/ޯ[U#wz+ҭ+g~wW-ݹ?TEUnMPfnk{%Z:vԵq;y]҄e})uK'S~M;tQJ/9_~}iF+ܹ9`eŕ[DVZrHԯ +ܻz! [[ ԅR{ߦj y(fM[߮zeZƉȶ?-pw^\*{2w{Z󐊃 o|Zw]߮^Ⱥ¥Z]jnG˾ 2_W^<߾ԏL̻w;!t@oM.a4NG!L6B;]=Www~V[]վo ,_ܜJwq[WV5t>WjA@"\-;ɿ}J_OKԚ?EMH.-wh긟._o~qwww !z䮫IkV:.^Fo޸1FٷCo@$,ZsI1?E[tk]B{7(ecW(}ӽ ֲ߾^%tRoAv_f}|Xl['/&GAw/.+)T{d&ro#ĸ<\%BĽ~2`_Ad_7|n"kYGe']U_zNJ%pO[~WRUR~*_Yw:]-6/d*w[U_l@S"M W_gzi&ߡ5׈-lHiiOݯO\~FK#ۻ3 +suJo{ /f̯|l˺Qy)#w߿d}},NZ쾾Y$֪ſv_WkֽoR?7MKy_.5R?E#Mվ~!_*.ŭwD{u=NSKw+oY@ ۳z ^oߺ~MWvu w[3/];[&ѕ]G|ȑ"l.5ӓ%߼_WOVmR-fg~uIEnzz"(C}}/sn"/&F+uvV6~WrMԽwJ[ә?V%S{^=>ɿrɸoܛUmwE~_.^Fog!q|;}kߵKmmhobN£D*?dΗ R=1n*o=?+UFLƵFtOkV_IW!=vƻ®8'Z׮Bknׯ~gA_)-R3"zޭϹuMj"qwE-){TVWY/rhwe;BۭL~ߨ~WҌ߹?P/K,+-w[zn7"9=f(55+׿U^ O}+W밗ZZ._Ywس/: .Qr}Ʈ+Ϫ׮deG %}?h_WAt7]:KQ+ӻe]p]kyݛ_߿u{I]!?O)] ;w_dZUꕈ[fG.kFD/+KKw}]rڻ w|t4-[Ǖzq OoOcurV^4UJc~dN?vsw ^Wb/,O]o-pH!~^ߵG\YG馗&#NN̚b[gK.eBw}[dw2]TQGVrr-}~ULQ:>ILZ?uQq]O|wL~#nqIB![#g;.]{z]ofhr_BeXE[kk_fq ėwwy7&b_[X_7:d%yElխrk.j1Eqw} u)Uȵ]jLJI&'! 헻dzMW+Nku7=UUWzj߽vJi/jĻ+~HRվMO:_Uz}z߿etۼw{χRߊnm~UQ-UUz꾢E6bחn6-i/wC%W"J~~߹oUwȖN}tKn&sJ/&[ޥuܗɹZ.w~_2jwUX(E%9EZݧ}||{z)zF!pD5?.R%/?Ĺ-?. O o/dazz?_ls/|@]_@ [Ի/,4Wŕ~qbmWeUE믪ssj\AP^ɖ|$׻_{SֵFwT^Ο-5dWϟqhqKտ%^oI^J+~wz״e{S.jT#GRI]bvЅ}yj)׮>D\]w̷p%DQ\&&[MKvb%O} o6?Tew޻5gFתܿJֵy]e_gRjWU\ϰڠRl- Yy LZj:ߺ߿~S{E촉=:uWȋ.ٵ,Gرw1}HJM/R߿bϛ&]-+?;b+kYA $W~-6bD_Ⱥ:]kW0TzN]mF6R/[<+uėp(WCw%뉵Q֒t:_(|ؾv|qu_#!?﻾M8> /Hc2]E| jޫe*!f>ew{'N\]D|zH#yk]QWv _*s O{ߪl&;*}[b{z$?bO.aYHgKS7P~.a~$[0R!}lIݙQ5Mz.0Kgw jf'!]*~ՓON(dt|,n;z7oߩ,F'Z> sc{MUَ36\&9N?C`Ѡ{'kG+m}KZ %OGe׭lHd٥ُ gNNmѕr^~~W-{kZs]*s사ov}&Η@A%-j$C߿OQ9x䪪jbwֹ7 }M\}D]._ JZrKrU^Oq&U/[T1|{_n/uwwVUUkZE߿d?k߿IOثW^ls59%krfK{pg3E; j|!EW߱w"Aq}΄YzF'`#WЅ wɿ]{nk+^jSw{e{-LY;}'BD{kLSo_WwMDRj|}UUkZd X]yyEtio{UD-^.!K޻./˺wJ;w~u}~}˸B/".oӭJ'b{"j'.SɾԺr~oEd_-wou~M[ܕoF!F%Srl-yk_9o2l ]Ⱦp "BoB},!<[of/Oо11={U)2⵭mչk'/kku6>ϛe߽n+7B*HKW_-5\&}=K"]z+m_k_2~^Eg:DUSWV)uzn#ISݸU&]/{_w|}un{7"Ey72MKNNMnkt_D^{j.h'-v%zZߗNRgYw&wokZ]%=zߪJ"\%o{"7'&]j!v!oVtGmok+[O$^Qup~aSݑ?]}zz{14Z}~װ/.-..d^ %߻b)4$]zYiG콄֘NN6![]j?4ܟ+&}lַn%U|F)i=VR_{hz()u~/RY3W\}w_(Pߦ0wwW]ϪJ־钽L#E+M*\/ꆮImߊ" .־eI{n wS//?M..{dz]_b1О]mgk]=EOwEw~z=\jYz." D9]BK.֪01W):ur!zMV'b*Zyw%J_~z]apN}~CK']\Y/w_*C߯E([z&f7žUUGb]$≿~]}Ziio>۽!SMMw""C|w$5Zb5?F'K4{?vwkG ]d.VDo {7A5zM7[ꄮzoTIZ'.O~W'F[@}߳AI [u"[w}f8?J;bxu\ n3%m4G{f袻}ʽW!~w~I߱o}׍WvPq:y"u[R?ײeNFQϿwBY˪;*^ת+￾}_Mכ-UU{-l+{{2qq ĵֺĶ2RSєrVUU扭kot޵\K~˹!{}fd.J`;wɻZDUTrn܍M[{믑^M{WukگєFu%z&ۈF[rl/!r^7vJMꟻ~'9}rBۚ_+>~Ѕ-EU M! O}r\&}mA BUv~}oZKj5ۧAePW]BU͝7Nl_ݺJ&Js6\ꫵ/>[+UN]Doo+߿+{ԛ~DS[#}jm{%.pjJwvun'}kRS:o߿wn_"U'oI*}rٖ{iF[{[U^8]/}WQ 5/Nbw{%k~o^UUZ.7UzJI~Z=_Gu={Y5%뷮y 7!Ku 'U}bMSqk֫dB;\jo=Uu\W~,V>m{iW6uET[nKKe'O⍽L[/؎$[;K%t~eAkKcgh:ywf Rׯk.K︗^Rzdˮ:m k#}wZ.e/ֻ D ݟ~5{ V?ݐyYrfSL^,*L"Y-/_uN2Jל3PzVPJm}u3mo^fٳ;Z{U('0>%*Ft5qY?5vo/eG{B/v?#սؿoB/{ĭU..L Z4E_!׭7DSr>z֫+xKŬWzkS{R,Ojlgr%k3{y7;W;!{[@軐x]V2wu['|p%~%~C{uKC_bWu \ԩk_2޻#_B_ |QKB?$B7w~svw'ʄ I{Х.dqּ՚{()7ֵR_-uU*֢{ Uck]Uk(ꈫuZu_~-|~[?w[Rn&MI{};^~ܵq[t%VGN4Nz^|/2Xɻ-~kn^C~n=wFUxZH,!$,<5| ᧼w C3翭.vE֤އ/xz!oL>X7ɿpLk@ަq!S.[3 @/+YQ`k}=thTH? k%XSbeCےA#pFZuV_]*f' 'JBWqFꪫUj/pUUUUQuUUy6&M׷u:rb~_#khsyRgRuA:Xɫ2`-ڬL&{M_{8Uy{ݺrJ")߻ډ׿rڭ|a/J|c~N/znGrҤKǾ/]7&ޯYue}y5zIOGWK/)CY;߼=\!J&O'w]_zѦXe~(okYͺ>S5f+ܜ~}cJ" 5$ ԛN[ZU2/VeZjaO^תַ{%M~AIz\@_Z]?Do^+wIwz1;U~S ЕjR.nB/_ o|uZpOg~Z}Rd&]W#߿׾sOEk/Sl˛Q~t=G(>u}s-wKd;>W}/o~$%_3>Wʈ^鑃ѪLg+}hy1(w|o~׿_)¿ɠNX-{[53wtҿN*=+7wOu߮?2鐫UWUu[ ['mg{L G""XQK@{3@?6>oߧB UvzsS'~5U_=kwvBLUg$"?NrnN 4Yv%~XWԍjAIF?16}^3:v"rV0kCE{雯e| u ~NWʟl޹DOfcvi/ڳGjFs eOe wR^⛿{ ?t wyW\MWT^˲@ew^̻hZ'-菾^DFZ;=Q{^Q%^D>F_S&^`W( %r;¬E.Є7!\2UUUEzG T J_J^Fܫ٪.є~ů֠uKwRD?#-euyF֯(_w®7{ߩ{S_A+E% b>_FSۓo߮K|FyM Re赿~~ou&[]dm, 콿ްZkr/ 2 @\m`Uk\UYS{u~o_5z{\_ֹM]k{E3ՖT&k}j*]uzU^R=GZkՓ_w]uzDd׮gcϹ+~WVzw ߩޫ\~/wK[jU^߿w~V6 Z+[ɺ_[UEO[=OF]+[[\_Mܾ5t _=n&j;1/~*}]j߾]%œw]{HM!(< ߵ~XU_L5EP>.謻v.Q= ;!4_cH%_V./uByZ/ ux,*qqu_UhweٚuEn|u_QquUBMUUkUQuUuZȺ`6uV]MEWn ]B!=ޛPw~^_9Wޭ5Vz2k޶Iwk~N^]׽Uv\/t]Qw-;߿/dK {6!}#.AC$߯'N%\ߨ~̟.;!n}KFUlj/".uUYoj7ro"b/tE۾qrRʟ~>{V/uOB_˒K}tMEnj%kJ#Ӣu =eWW]?Z WAwb{+gת!'b7_5z}}G) KF wE_&^G&יX(>'JEUʺ*{D#/]/\I^됪6x.+ Z#/6W~D ֽso-wS!!'LANtWwaP~(׭Og:p[}K}կ][_T!Y/.^7avXk|5@_ص[߶MbovI KiBrVcwQBo+x0A;=sG-nGԕ1G/oVfI1:{ꎯvx}A{e%BG][e߷}Ow\qoO;-wl_%3}&ʶS)s%uK})˯7-u b{F"_fgr- DmQ(hP=4Z/v MdOrgwod{ӻi.a[!_^EUWhO .0Q+]si~ =.pVw} }aY{\v 3m~&J߶!_orǠ;ZL=q{r̓-VjH~Z2Gg ->{+{~!3g턎fľ]}W"3e~#~=ny;-︄׿Y4Vo?wFK߽`Xb _%}W\,W#@~fܰEG ׯ)7gG`0E^"W\'{\JnLM)/"A7G% %#믿uŻW=k۾=%xAlbAЪhBT]hW~O}*/-#~B2~|{}]̥I '< &￉g=&j {C ךּ#VpuJI"Fܗ"oW~J#e}Y}n 1DU'];}z2-^"u..g笿"\-uUTvSu')6BvvzwRea^߿~O[[w]Xdkֹj%&;~j{')}W﷫~ߺK+[-eJ3ߪ"t{_WuRߵ~B [?uʷw)KYMnۓ/ WߦeLߺZf>߿^?.wW}O)jiHρo!,εcU1_B 몪um8{CHjpX%zad޽_+_7Sg1DL!7oA _PWC;nϕ{L=gTX0oy'/A6 J|7KK/#k!_ -%*C?BURZ|IoVkdחk ůikMm[צ+Y;${ JhGZ]|U~>TOBLQ'LZ־]UMQҹS>oW|${{rSu~[s7%,}C35߸G_3RYo='%^W"]Vb7=Ezw'}濪WNWߣk&_)|ozn[ꔺiqFRnNA/ܵK".Jɸ-ww $wtk_ \IIŕ{Mw|׽~gI}j_%^ ST-~=kMWt'sugOw ȗI.@{0w?{\&k{nӪtR];a5o{#Ní#_{LBtj@'~+_v''CWmohߪjgA<|}'($MkUoV/^Y:_o.œj{ꊾEkb q }똛$]~ WSSGBuKX=5QܸAD]YI,ؖI7mꫳѣ'ZH7KĽC/Ӿa]H\u^uL|}WFV|B~\A/)ʽ^#?KwD?Rݳc.Y$rH#Iċ߱{~A?~-]wwV˷~ }S{_?@G_u0{o/Y_|0|Kǥ-(TA)D>z'[^"t ]-tu]Aoۻ#뵶Rmv"t^g } 1o~`ֶǣkC J}6=nU3E]F>қ:R~=kU;~w+}}d$n_ Cp/A&~cw[f/,UV(ړ_!߲*^ kQ6H6B vcu^.MkW`j%6}QPJSɪZ\59)" ~)8¿߾}ū{w߉LV~}TR~Tۡ?IѕO߿^V9akUDz=[Fh B{X}0M UN|{wwk{$ކzHY0({Ϳܙz-r-ߊ:rhmUu[]"k U}4|~IL_rAE_)\-;yH vŽQdU;T::O? ]?e]Lԇ--n^>}˾R컪H7{-wZoקٓ2%_.=jl}ouUUef\Ikֹ̻~˿[ָZcdA_苷{BuI߿wWhַ߿u 弻u!;IVe6=oro߹߫qD| R_߶^}OCUoM;߹w[|\o')W[/[^ߺZ _~~nM{^BwgMm]joWi{^q>wVMa}F{s!0>(]kᠳZ`+ZrHiXǭjBZj$&MaP}א_ UU"._ O%LlE8LϨfm M/nv_% QqZB }~mgZ +J/E]UVƿU_Wn֪e& ukL$5u_})~zRW_O%箢구jEʂ^r_V会f1MkB Mz_KrjjEo_苯[R>^MJ]z%{Ϻ^IwoV,j[uߦmaUJmIZߩ){IN&J3U3Q[v#*Gvo߸DI_7q]?s2]ݵSr1._q;tE&򓿷C41u^FR FME"Yۭɮ}>(B~66?뷠jj3!U]V^}6N; "O:RZ־q^Qt|Žw-wӮS _U`Vs*_3rnşS!kL̝?/Z1=_1w^ӹ !vwVK]IG[w3AZGf@Iޯ8U"#v:}ÿ=鱗^NzVU2_R.B=ֻЬ>B\Kwt(g{* gb?1_:~j߿#E-O#lc7-Fi j~W[*WŖRb>7~ʟ8}u ܤꚔD~I z7Eb;׋?g[]UUmp-bb}Z>Cv5˫_n&fgi)l'rk7}%ʶ}J߾Uv5}mCz*$W,}L;5}5D#Mv| l"]9;Kހ\B+]0}HSĪ%juľ/Z!_;o3=sҚ!{'@Mjwh6j*7}{_u'WA; '_Y 㯻}d3DR;^G$[2^W)=ot|ɿ~\VҐQ{8NrKUS'zFYޮ^,Bşɽ{GlWۺ־*b'nOoOȻs ߺn^c+ޥZC^^xf۫~їɾ#u({喲)Wչ-#U\ǮׯP[b{&whB6f=BV]t寺4%VͻVN_uɧ$=5kzn+ӈ߿}4oSr߾߻߹w_Znۛu(E&ݭr7[o_t}2_uXC,gF!47D!~w ~A-9CwO5L;Wb_D%?0|p4?޵_+mߠJ,8TcΝ3e"u4R`/V ee@: ?n|kk+_ANQz&t(0// |CnDʪX(ů"STW~noeuǪx[ K۪wԤZUjֹkH)4+w/5PVˡ W_6_/GoS{U|KZ]7y4m^vzU}W6޾EVɨͯw!|PVBsYk$'Uz뮵Ԥ~NVEb+?#tꌤs.d!Sͪ\Pv?%;}]n|:^GՋEdRU#K߿wT-XI"YW_ꈺ/0$w`ɿ_\.Vum)+$RWY;]Eiufֺ*X}:S*<[]VjxZUZk=42߭V^Gŕսh{zM~gTǞ}z]o'w\O+};Jz/Eh3%m|s&|:@j2ŒǷF}8{~؇tK Ԍ5Ky-v]Uߕs[ԛ p_'KAb]UjzDV}=;DUt^ͽqﵣ~k▙ PFȂin+,ZR|Gٖ/]_(Q:.X !~}A2U-:wŽ_kW6SԞus~~3߿t5nI?3u/%Sku֩EB 8 b_!WNQRS#GF/)xvK~*cɗ{RdZ*C8+clVwo^).-" ~B[|FWz;{}_uڿ_MS+au{?K_}Pw0$oȥ"qv4Er|&8~ŧ{ͽfv:%۱e~ܟ߳7uYw,{+߾{ܿ:s"6OB ޲\^A6}؋5%Y%_gֳ) B^ pŮ+_qjӯ+Ӿcw RTk#kf+\߽W+޹"N(!~*.ۻoշu{T1|&Ǟww{v->FWY9VEyw&n\/ꆩYw{4E?uN6WٷU_ӈ߸(G{n߿}>OVnR7_UUXOw_T~=hJ~pJJKnw*Mo_To߿wߧWot"7|y6Vf+P|Ew-/J* "!8amj߯`eW;x|iF(_Y*ԄM+}=k%{U|(g_UoԂyc uK3g'"Wh|{ht;k-xZdߩ&:.VtF1 L}xvj:o7oz_h.;A@ݣnwP_҈8^Ož]ַB*/UoLE|T\]uJ/UU/˪u^ar^V=|R^џ/3"U]}k-uUU]EchY/~ʵ^uYꪪ_+G}NeOʕts-W5몪ğL"/'O`kY|`2‚bĽkZ EuIݵaz>Է}un]*߿J&ĮeW"ezҷij$/u?Io#R'ke;J$گ|_uoK?~嬗VEgrӾE>!z שtt4WU[6ju[QZBF]~B-bk%fz[+_WY+߻NKFRɗ5K!.sTU}> ~޹-?ĕj+~ _!{|c1/aǧĮFϞp7Ż}{MŬnm_YK߮Kw{E ߰Tym>Ge֏Z{[ /3#xCj=Jbr~n@ Jյh`E}-Ąio6BvhJ1Bd}7n/LP%ONk2ZҢ>M"mi1zgo\ۻ{/r.<\K/uV^~U_DfI+1{hhil4k'A __X+ߦ[}Dn׷Y$]u Uu]t/B^Ȍwz>YA!-} ^=uiKm:WI-}y55/z6A/1WvňwkN;GrR$G/{=޷~߻oW'Sub#~Cu{#^rIR~jSgެsE/OSq?R# .zwLz _ll ^ȟwdz!GS0b?}/|u sLg>Nx&%_Yg9AؙK|vOi0rc}/>hY8_Tĕi敝/UnUL!f|?ԤP^ߣ}?3ߌvq_tQ4 U $ࠏϽqWG@X:A/w]W-?wjUyѠv3}s7t&w DT>=]p%~Оrr;cɾI-~8Wo \hh$eA]?=9(oCsKJ^ag-PvNM.cN{bgDbaKu̯YgsW{.fɿ%߼rŊg.>>R9HA1Z;*ws=6d(zo߱B;e3_}%rLGϥByIoqA /|ťNb˿}Ӡ䜆頉b$ת}딗g|̯Ϡľ1ٺv]ӭE/-Vxwww*ߞg'9E57JhN8N&ُK[Er=-?&\]?CW_2z+F߉wمw\:Uuȯ存K[Բ+_q7az6~ *ܔ}d߿ukzkQ'yu6~n܂wrozDM%M1x+V]Ϳ}m-W>߭>uBo߭rw#$y}u˿W%H~ܴϿw_O'#c"{7M}d;Q>%W}jywyF_xGrj!<dž!HhUֿmv#"&P`adn5~dG8˴ߏ,$]~ Ă}l^1E"\qg߲!bD >wY3w'<]_a'F jNg&}4a6R{tBk_.)9b: y\ߐ~lo/ImhiU~ Z`ZNnp0JȸUVU#.k/nr-Z[er ^ֿY@n$lYZނ]@u=XU]~$UWȯQ9|YzHO.v!^~L+WDe)/Lou}9+\E뻽'EzE_^רG!QZTY}B++ZD^3ד E-d{.\e,c U/}Է&^+ͮn)NM}eXbo˾N?wĭ͹+UХH'zpF_owԍ.8Co'Ԟd '̻]uWܼ].W@_n[E]zf7_*|J1ꊽK^>gzfyDWi1U+}vQ$/(N*_OZ M3c?a/}%O=odO5 ]OQkmzwbf)}G NQDO=z(~uH׮Z+=Ln7]{2[}o_ ^3]Ε_~'ww{zޒ;1?#JBthYZ/]99"ʝ9f߿7Y~{whbg]t,ܹa_NK#BUrٍkIuL{ZtxwO]lfZJH$g\tPG4F/{놖{x$w?J!ߓ__$߹D=TGoxV V&O7I`fe_C_3>WʚO՚/^TrzYg]]u[iK&~+.z|"D}>zh>z$JvoȯQhB%9A }z6z$wDv.; N^/zwXwB[w RA93GNq_t{^ e4;P?q'nV5vP[[jF4:\馞(UzhV{3%'g:>*ZaTBTY=_3"9%:%?v!?uoA_䬜ǿάCnq-CֵjY{/g"/){-3rW^np~{Z*Rs=yI3sk'W!_MRIIS{F|ϙoש76567t|ao.*}UWLFZfֵ=;שH&tc,寙5OUUC }oR >!;c/oE4" ~g}W&++}W3"z6{ _UӡG]yG w߻(ZӪ:C/>f]wU%G[>(W}pD˫W7>?_ZO }rEw Z=z5KxGG}w*cֻ{WT.ʹ>Aő^qF^j"]}0ֹMxKfi>EU_T9PO_lv|Q{=jk\3-rEr]n(-IctwUsEy!K+v0[[ɵGU7UO4Yo|ľVɿͅFWc} 'L}4"p^CCĘúꅩ1զw~"V)6U2m#\k7f׭bF,d1 b~xnBRfh;$[>bʌn~F%{\D;Qo s_w혷ߤfO:ُ `}u!kXuB,v7+?#{w͵o]9KٮW!/uJ 5Q)Dh_rMO6_I)_}΃ߺ;6V_"nzv_wO{q6Žz[i>05J).O^~ɿ{ gA|PQUryߟףHߟŒe%'gޤDv!ޔo~ꟻvk5g꜓\P]GT_]w6|UrsVR#J~B_Y؞O} bK{PB/Ut/ĕ5&k}u/Twb?|RI""}r/r/}tNfk\_0^JoO'ud}_C-c-0K!Y;պӤ{E&1][߿%~MU=kU_osq3v.߿}6Gv7ߥ+{^-ֹ}[]ܵ ~gw "k߿uw&t^m\~T'R"/N^'~et~LڀH7!D SYOs0I;ݽY`]Fz5Z$M_qaf/yӧxAOߘVۊA@_Ֆ\e_%>َ~}q=v9-ZЃXT\*~!`U/HyW@~ B=OD^@RWxV qn[fI~*|rw ={N{Ewx^G&\ֵ} \Nyʼn#F?V%G`,d8,ݧ~ݐ^_Ī=Z}ы}\PJ}Cӻ0{j~뮓zlD7w0SY{K_ to[wwߡhE~JRq +}?UV}vVBYBޝԶ}۷|ܚYxڋֿJۆ>/Zz^^egg}vizsſ+/vDw\/2%=9)]bJMK_zwuE׭)+uQ/Ԛz!^Oe&뾵KnNRoJ`ꈫ_)g/kX(eo5֤n+ɿ71;o7~b|)=G_o=«ꊪr¬D)d uZ3UӔ3/"KJ~+jD,QM\auuK3M*꠼>F1DZntO]7U֯!a5w}sp`{,=Z?3ʞ~ NMt#)$[,Q/K/w}DT9/S>u"=~̺WvGW\-_W|/~ްyK}߯^̷OD| 5* eZhiŭb |X?"~CſߺL"eޟ ,煓/}>tCtWOr\vo^`qi.K?whuޟ)D9HJI_N,; ^}`„_ܿwa"0Է*'gb;#e\cֈKԊaVdݍ7rP6z24?7]w&\,E_!oW7GinkYN4cň_K#,o}}}t!?cG=~z*V-[#= %z|LArGzL;]L6Wo{uBo]~ν{ +orw=QUr_u u[~:uɾߑz=ܟK-l牛Uԝ馺w[F~Kw?~7y9;"?1j܂a\ W__w__oߔ}WNN(F1)Z{}ke]+rUg<ֵ[տu?MU~B[)ow{}% ]f5'j-Jt]2/j)_Uny|= ˺ĝWJz7DG]z:o# M{Q= :ur>wJ]]XQ|_}w!;0k#'}9{.8黒̬7\~׽szUvMXMM]uOnJ՗M}J^=GOT]^ko]˿~{(_똏zlIoW1)pIX!H@\8}p( ./u~=oUU¤]$@)ﻻ{0{Q(˟O%=8$ *"p~kXpOd`U]{CȶI`ESy"ɞ,~_iE肯RcFo{{2GB~"v}[uAd i<^]G3JBǒߖ$I'~S˓e=7eD;@O%W}}ߩ,QmsC 1B{[VE6ly%Ѹ޷-s{ޯ߿Z'_OI|.՝ʄɷQuh(+>owwo ȷ,,}߯7E|/WU\{e\R{&S}uII*~"r|)4m߸nn2EW[[/w޻T_bo_1Ϲc97QO{Rv?6k]MKӪ}:]}do6פK^buJ(iwUEbu\޷]~t}똷ZD?\ű뛽.벿] s SIJyoh' 6c_ >EZ:.W/3Kku}r:뮮O^&Z# gQR3gHW]k)WQ"tWmj&<7>fb)(M;G:,^ hڥס+ޫs-)E+K?%WE\_Og23ʖխfZf-2Q_}oOR߻_+]6ؕq} *7DOh.,Z|W=||ģ \Qʻ}e4?zCz|WrUZc!dҕR!B&oRm.2Pn?/qfnF]{‰1Yymfz~e7צO[ jz "3:L>m=]t^B/z֢#Iɩw\_ǯ׾<[܊W]2oԫWGn6/}?a']+Z/ev|zO\Y v^}*6e}VqKq/W!ܴ5t6_ /$w{߾k^ƑDm(V #]Λ{1c @E^Gr7\M++&]􅬾ծ_h:LWggƆ3R{Zе|Œ+nRo_R>Dc[-\OW-O|Q ߿bENbR]S(/ R}eD}kC?nDQMoLеy_hu1}f(eaGUOnߖNRYH.[le?RW Wk;&Kk[uWݞWw5\ۓf~Z^O%-wk=L[«*R]\Y_\KwXP飫LKwrI|$KkWWk݅KM˾MR)zsJd|nNFEuIܚܛ#o߿^C4#[NBnKSzi.R~M&{)Dwcj{N]ַ&-ZEz{3:9+[z֪SWK߻{:F^fԧ߼WA Z{M^y3eh?Dž[j ^/~V(+ww< Ksy@)EqGqf~w|bnwwwxYٕ/RCJi0ӸD~=k&V!ɽ3~~ ݛ7/-qn[N2X&#ۻDz} w Rk/#Ī~2hH}B {>^ү$Zo[Z!huԦ_J鯓}zޭvwj$NwU][uuA=qQ%V)߿7zW;?c_UzE^[ޏ%z}-/\dlMW3޹S#=d߭O|V*)MT~ikrj싾GJ_i=qw|nt6Rjk?_1;d/a*ګ\};ZEol9$&Ie\͟BZs?l_}= g#>lfuâ߫l>KO;/G\"rNe`'sCFA0?/!dkgͦUd-՝z_m߿B5)PUOFmlt/}(d-3w-#=-*\u<ط{[k`{uگӳv^oe}Is=_Zg&ZBֺeW~|S{ZH&pf~ME Dg2{/jMUwL]++wm^xu^߱!ޕbszͿ;+~(G_蓼`O.&h5r=L#YhZP8DgϿ}I" .Χ)rӖ,ϟ6_u' Fh"rvB5/~:RK˺:_OCN[W;SG~(WNTeTku]QUT>)_G)~q6+̪w%tqN͇E|&cYVMFUhB~sMOQ wuo{U[[7yHn1;rsȻIW1ߑO7coFkEE]ɾN_)7S^u>Z/w ̻&N̯+o똛Yur 'ٟ}E+{eRow(U'7wc~)yʼnK,ܚR m߫rIW=}+NN@0Ew/lvvz7)" E0[,E/!;ijJ5zRwY}ޙW^bzBЕ;߾Hۗ]u_jL%o}u[wM޹}AF(}2Rő䊽?w力FĝnJy}_u7Vɿq%{Wߦ]SOj4]?"+Lnw/^n wF1ߴ+*So};i.n)ӪdS{{߫z^Eɽ^^[zK>n|F~!P/'~ IoKvHZ ~jQvE U}b XBˠc/{ѼOhBM@7|"_D_bW@gj0?O*ٗǴ:䠊\~S ww@R?~&sQ.4Iۻ_ &/~ZZ7[z& 􆯂~֤Q1Y{ 3 bs/UUVs}#u^)ᆴdަ5!_mq^U^}].zo_qAN/UVϯ{ߺk/"yy }}kr{|5ї-=T[JY5wEqCzV_uN/w*^:-B^7S=);ܵɩ]z".vW7*}T]dsoҊXIjfߧXUXXTgʯbYb{UܕKڨ޹Wu Ek? +>o+zeEu-٢6* z:Vי^'%Z՜MzW^ھa P|OYg>MuWQo~#ʫ3o]R[ɪ)xw]>">uk&zު`^KJt];KO7_BWTGV_9w#[Bץ-hCyoࣥeޑWnbjNhMO!u\A}zp؍Nė}߽~sa~r~EE)o^o}X^'/]fWz]wDaQ7ZZ*=:zN$F{/E~CWeqbb堿{~"׿BT5WŮ4cv>9oq߿.jIײM^g})Hʊ=k+U#o4{ ]kAɡlDU(m*:XƟn*^ĿX(UjQˮ?ʯZ+}vkS\l-[Au!ۊ ~^v+O"w˧]^Ӟd|P.UֹD}땿4Jּ2Un#Uoӫw?oKU\PIǪ1:x~Wy}D*o)X!S~b+K˿&~SV%Moȷ4O~~M}ӽ[;wzܵ$wk^F{ɚx܁ _i+\YQ\_N(U~hJ˯c[g1{[~/dЕ-/U B/B׾=q;M~wҾ(+n3~ܷ}9.^w^sӺWu3T+%:ю}8vM芹5oz׳ ~ne!w)AojYWXE|߬i;}۷F!T/ !oYzUmV \^ ǢJPu=B7R_%S+u!TJXƦWq&}S!}&~(ߠUO-z)9mtS骯|#ߪV߽Ԥokj|HQZֿ/uZV"+ӤNf1wz蚭mGeڮ(Ծ1kZU䗘#ץλtk5-3DuV"f]Hz~jvM&K^򮈜R1ٿӋ_6'(+}29wjޫTEґVi$++FWWWn/q\kjiWߡ r)w޲߈nF+~5_5߻{Wܴo*6z/DUS>5~,YzKy)&~L~[O1IquJZq~\&XwJ}/_[]Yx_jY5^&oIr%HW0Og=kW}**WMG-ܜ%]t]k_]z(-ࢺwDmjb1_ZF?>㙺`>Ŵ?u_GUku_~WǓUֿ_rExf#_ŶHR9?duVÁz֔ *29B'0xZ2=*ֹSZɔKnC_/|R}߾Y*-F(^jX/tIsTjĐ)M/a丁]]Sk}N!Jtv1j5=!AOsJqd;!6x_]U'kvQ}R|͟KTrW6]Ko .?S : 9ʖjFrY ik~P% ]{ewk߹5&vwg&WwM _S}2 v3@;.5.?̙=TGY[[Kt g9B;~e[1^#6*?]ZH_2\ws(%j;UHIdTד->R^ԕ$ /n2Qo]~]Q*Mկ7}TW~T{oݕۑor ޷R$z:k ]$ݮOu#Ԗɗ\P"&^_,]oDo5OLPK^(u ӼN+%MM_K]w.*GkMtGӧ>6-*߿E.Vj uy6Dv]rߧ%J#TwYwKw7[0JJSjuvOz֞?NjnjrQo,77ZB%~~zGGW)_M!wܽ\A6jV^xJف !X|^S&=]؛ [ZdȬV^[űX'eP 7d^MߔĿ~ >L'}/Zg~2px*,xo^Ӌ&7T S* kQs%C]ƔB .6VvoS_JN]'oWH) -j\?0e+zH XD[ֽ /_ }Eﯖ\GaH$}\/SΑJD3LR;O232DX]_wUA+YMO_{r7!7KK᧫-HZdk"|'_z hN(E$-;&UB%׮u룉 3OđujFb;ͯzw}%>xH߹\+~1o,>?)#(GjLKוּI_׻ѷj}--WLIeo񔤿s>F*5%k-f];{jT/NOoY+rdD+rj:;RbMUZVUojru+RҗXѩ W&>Vz5'"O:\+Q(}2=&\v;)_uN^S]}Gq:77{U.*ߒjWZ)q\x^3߾}-P?*/_td^ָwSa]{BWrj0}1whpIB-aY CT6)쫷a76D]/)WJS2Y'Iӓ}u"UU3ujK_jbZ53mkZ1}VYd[Y.*AkWǾ΍٨*߯{r_%x>v2fxl'[GiH/"x$.CWM|ޤ,,MWx,_nVDuɼѕޭh kN0RW='z#"hy'eE!(8~Տ7N9nf חV^l+KlWbw$IbӦ@Z7΋wblW[M_TȨ/ f$I{!p4;OK}Cֽ))Brd뗳p3p֙ǚ=H׾r\Pν}J(E}Y/\Ͻ]lC ޽U*/-}uN=hzLnY\ﲑ?g7'FG}K_gp &6i~Fk[>#2c?C1O"7^͸0]w}!wee-n|(Ulۚ跫'h&'NOލڪ70M0|UR[/GR͗w{Hv\AkaZPsoJ|EЍuOe>N%0B{U>V?UEw/{nR=:^*tw|a}4_g{so!iB&-^S?"LWO[I&ޢG8${{~~|>4MG3HqiKVK~7+Fvߦ{/(!پuI]Ncw֩kw_v__ Hǧ~B{uSebuO~2ru&/zuzڿqhlb&L}謷keo#z)_U̷oy+'-|Bw?]/$^s/le??!b''Mb%;{K%q]wnR_}ɽkݥ }Ot'!uM%^_싺6C]6]f/~߿6^%￸y~+V\7RU^{w*RԥӪdOz)7}22Wş'&Q%|y~ER qEӽQ=%Tľ@w"k~mW[뎿헿dW {̯ɾ@{"-7we#Ke~ q%k\~l_ufKcwLm>ߣJs k!\>uA:5!5=k2_ J}޼"O 4>%/W}>"Z߭exK^"^0V{uN_u zmQp4wt}'S߿ j2)G^=iydtYW'Ko]5{`V'-oA-9-=| -jzs{kD1^~Ws0`ڷkWʐ׿؋馑Ʈo=|~_vzj딗=B@8ڿ5Rok&/GNg%< -?ce#G-W9_-OZ,sr{|KN]Wz-]j|R_7~Wd܆~v%{["ܔU&Y:](WUkj:)|~L߈UدJEC9n:ETeN]֩K+)r7[V֢9Kte~VWGwjjZU}~k/}|C{Y=~AB]#w7/kȻ_w߻X!BwU;>''^#rl |SNczRVۭEs> 3+a7_5yMº~][\ί|Al{nAt]ܺU_CWMKoר#/y ?ڦ!Bz.LH(DyO% ]o]}F ޤ5$`ӿJkZ.ukR0~QuUtLsw~gӹZࡿw] :mB ZfrׯU~>fVzO^6W_]zI^SB"o8IzT$OΣ}[Q"ߩ ]VF7+}_32IN]."%,m 1@~O"\ƿOa!7r+BWC f$JO]y򗿙K }j6h賸Wzrcͳ~>w~1Ft'M7LNk}q.G:&Se֫גE{]ՄBw+VW}r_\!֟on̄99+ˮw,-{#"Wr{rCZON:^+̾B]t!{o~w{m/"DҥXv?ϫ}p1>zuGu?{9uiV+~蒣s%Y)=(I.MmvIYJi2uFKX@494sFVFFkM ?ERGt\Sw ߺ׻ǿD?~B:o0 ^>+iXG.[ĻL{X b''^U/%M鐈cxJ '~F"X;*(w6e\$З~_u] zڞUcptNOۓG}}߿n7/'n(CA [oc'#%iߋ+V ߸H|zջ.c'4nQ&;*k[RsC\OtSv͘T=+s#{{꛻}n}@]O\ _z]gn!wtS Zn}>c]y>0.-~߿'~$${2w&K}y2nR;KS{#L|\O_ݼҽO_!@UHoOmRͣ]p~MUTuyy_깖˟3]67y7MfvJw/+kKJz#M>Į/S.RST|}o}3ŷ K?tOZ̯V}:l}.7{+N+W{}qwMU2w{*M%y~۾}wnwE?Q˧꫄߾}?f}NݾH߭ M?,ެըtWrdD+}w׳;}A_QՑwwGތx_ wԅw)_oz؄񅿿"?~"]}Q5Jd4Eԗ%^vwWϾTƿQocw. U\B߱ ~]}Dޢ.%J_8EK"W}߾5{JT L!` [ȿ }&zꪯk77Ymk'M0*$tH|3 ,7;p"QFѹV ؁[d` &M<.\kws;|X*-7/u` :1p\-LcO ߺ/Bm>^Um5*w}oI[*z2rr-}rBNsV}֫WJ^;vwO3~U׊'0?o{){_g^]ͻZ2#Rlv{!\xKn8_Qn2Rl dַ=d%CtQԽv; qE/]^OYz3Vy<,vzR-OK}:}U __UkU63u'5Zq٠o MWz| BNz'J\?_6IHrVɿ+ ]UIw5[[\̩ś_Sd?|YѴ|]!dv!<|IVA Y3]~/W)u&ʞ?Kט=UO^BkP\H]E5 Zqt{*[h=Q$_<~c95~fGz! QvV_q(΋U?"o'k}Ow֊~蝩S{ա% k.R]:[YkjV7hS}_#ؽؒ\߿Efx{k}צ8%!} ^~cwԎ-!=OJ*_ r⦔OݍeE/mtwWC^-_XE:(WtoW\`MjH>^i4\eO>sp4KpVϻ.޹^^zA1k;/P!y[^uWpN޻uroK%<T]vIѶqCjr~"3Zڵ't_rNkN(b#K1b_,R딽%<¿?0k=_~v^J;ZWgJ}x,'a7#k_(_'_%/uwOͿ)yw ]+!w4FwZ\&^ w;;rV*|_\"n(7GneO~"M'~w)oVf-'Z_~.8SRznkS98i>˦a!/#~~w{kK}Z%}5ߧDM]+?L!7%z__;>L&~=3ܒLodo4ЊcoQ}w}W>$ Z wxmQ;'LLr,eiM[#گ>a:=VMͿk#%q{{6[߿W}[1'}OYBr17(_k߮9~V_1/*}-=3w_ٟ3~O]&[?v؁7򗿲-nYo)_ߨLw%cs8\w R+R{(,CwﯽDUX9߿%40$}74~+wJpA h!d [_w\jwwo#[X阬1ob^ {ɛ?0pkw7b7r gP}&|Jp8ʟ\goK Q>}.ǡGK],"n[FeG2?4!u/Hj_BmGhWo}͂҅CY_Q- c~1Mf>8X{n]V]U~!ԗU_ Uwww~?i߾ ([;Nt>:[I콾wʷ%$4nGfzeb?b$M}?N[s+{}0ȯG_{w{%KW]ž`o%'[(9 2j}7tW1wRR-#+_}/W5UJ֩+;=jB_\C_]߭zqbi}r|KwTr7bQ|ſ{˯|.ȭz S!w'ir]H~R򗻥.y ˚[S>^oҹ?F]k[\#V>KnL+ӭz֤#}O&/_.S;I.֪zɯ޿d;W}+f6]/]1~D{ WM䙡\DT |IoQ)^U[rgoٱ>JFJŵG߿>^*C[Y~~Е[!l ^PDm#/~C#UǭWHj 3w^_7$$NdoMD3..ƠlN0./regx`[DMYJ,70+WTrtz.$cm!~BE _&I|ߗ}E,A'Ŷ l  >"C^'e%DvƵD9 l[o= yK \e+RewZv:_;{N-(5dVşύvzS~ uR运=w(h-)92}wo%/}mA5ڿ#Q}~0Dކ>sZC11=K^7w}T{uأ@uʗ{5RW8U"Ae7(%#BWۿ'=eAcW~Z/yKHWK_k˾1wvoWdg|U[W"z*Nd\Er]IcCRkoܛw⩂\ֻ%LT4\1Bw孵JvjR~KMo6ת*Ŀ*MYX3߮)?~Q+I߿{-_~/Grr:뵼EXwog-*u[uh~fEH/wq}m_CWw0nޟ|{{{%)w|D$^|"u^}=]]G~c_^0'n R繾D _BI;Ga"+'}wf;!B| 'Aw[%o?֫'3| V?f'w[{K(U]{; Wro!7K{~_} ȯ$n/"-Y5}r=!9HE^(ﵯ[6IYsB"~J.}~|"c&{oZ-Ggw.wocɛ.?}ſR>S+V#~Jc !h.vA$t>4 B*2sm[L- "c~˹ g Ce%qWkx:?f> ;[(Je"WLx TT%Np|qⴜW: P@mԬ_©|"[n;YBକ7.W/>NQm?qB'o^G&TA0t(˒Wr>6;2 yJqJg 8 !;?NcSKSTo'k{סBO>wq^!o?jָg'7u#GFkA{V8+O]rWߑU[Zn. 3rV!^W/}Gvwh㚮)2WV+UuoZ]n3bY DSǭx5:QD➮ݽ -'KE#)Rw}~l]ENv6ϯL&'iV ĸQľQ /($}_'$Ÿ;;FTWKWFq/m]r%A{TiNӍi)Wk*atߘ1e|#+F m}ݻj9] w[߻ry IJﯢWFO"g~Lw^}gdf=~ ~N]ȘW-?D}l:oi[n,ʾUKǙEhӣfGR-G*Ĉ* ǪMUj0wգWBףd\ꢻ+4U}?BWnaQ;HSCmJ[ -6۪fL.w} o{7t!oakվnc2Ir]'w2&]t Y+ ĉ]KUZ&~R̒l/3A-3Gy<0Sk-p]+-ܪ]W%ة~^%Z_g©;7!^#ZQaUTU6f._+]}$^28-r ~N)=)'UՒIJ䠹p>]y+(G>}_ G@``^A/{ՖUwž>LDPzĊCޫ#wŒon.Q-2e>sZ2d]ɗl˿fS{d/6;|vfOgo[.EĵN^K~{q6QLDevGq{2 {7nA,JW 廌ww};OK/!_}ow_|uC}M D{d]2CW}6>~-zۻkO!_kk)L}߻pfK+z&owD=}rgȯO=w̻=ɿ}~QS~;wٷŷuĕ޹I; ~?ٞ"߿~*F @sg22i]W߾f_&4^o'7{*ʫ'2+޵o[ߺ{M}NeW{߽wd jDc])}qK~ow|Y/&^߽.aFO˶UקU!u77{n-I[4mWeDs~\Gz1;ħĿ{7B_ _r5>F!l/ ı^yA; {Q?n@ĭ7~z_j2^%A,gK_0(kmWLE]s{tΘ,]fn:O?#EKTOWBe u#ZC*k7V&>ZkeoF|z~h]{=乞'3GY]WB2ֹO3|,~G^:ĵא]-ڻ]UأCidwEsyU}r7UR媨OWJ}5J'sdhZ RҭMnJz,mt*ȺLz^ɨM&~{{+#UJ[}:Ѕطꔴ^O2^y;-^Iw&N_\4uӖ&~ ә0 :$4沑Pj $BP%Bfq Yv~50lL]ElgG"]SRV7HP;GEn:Dnދ?u#9RR[խnR(Q*&ތ݌߳l=r-レ*޿{ňcLu3B /2t [un1,#go iiuGR!_O$d ~_ ߾Nt_f/}z[[Ug]Y/-sokЂ7/3]N-oطyxR*I\w}?qT.妫߹x}!K8_gM(߿}S{rzUZ }Jw*]֊G딷'{Gwq[2|UvN듿Z[޸].wMmw˳ԀH!p/(KJ_qUUjmEÅ,bX \[+_ ܗK3\nꃟE.xE_bukEЄ?P齾o] bWֵUgTK\zi/5GuF߫pND[-dHA4?n2ExUߡRֿ6k7&R|΋%wF~R|%I[NEO}j[H}Е׺rr>h˒E%(WZquU=}zrjk߰Ty"J~ :tRW!~Ђ__uUZK~NMVvA1/Q7RRW&->Mޫ1;~N׭ ~mֺ^]m|RsK]E;j_Z2t^VMsת"6uI"wU:K|UL(k-Q&[Z,Tǣj&֯qꔜϥ2~+nu[j\ї}k.S}+mҊܜ2_0qzDRV>3Q< Ok_){o7sh!ʺ~btEQPYbK '}}6[ꊦG0(TsH#p/xKU?7lO1*mq w)}uaeHn߷iwrrҩ!#_^0_{J)k}|&!Z^=Z~~wޭ.PZ^VE9-Zԕ_W~uUA̻Cc]H5k_ԥPԃ_bo KWUuXH^|ݶ|]Fߣb4\Rɨ馮Фף%cÏwq߫%^Vx]ztŮֽ!NEA=;=2_"\&Dvf;]~O_0ZCU~ gU#~db&JB*Nw6}JfO_wCOf%7;x5VMcz:,$B)ҽ%L޹Ec70t73>dV-Za ס*"~b+?'bl̩=$^wyxjK<>)I SR&+c;a8wuZV#]Dz!އz0?گwאKu%KwvxݪuɋO{߾eP{:C~!غwh/azԾ]*-Kz[n+u0!vZt*_/~*KHXnv}ywY&{}w2]"}sU]ou!:E3z9 {*& ]V?ioXQJ~A臬?UEN+'vŮ,ﯪԙBғ}L^ e+{~Nv߭R%o _+~'w b W+u>\x?-;ŭ*r+{ɿS~NtFXpx^jKzW~䨖\STĿܜ'}򓿊-[4 Cʾ{!/UI^+wdWw~NV6߱ VI~Q~BEx=h$&ߧ|oB%=^눿&&}Yb-wmBEਢQu4oEb}]BA0|]Ƙ\\X׾S?HBN]ѺUneoNj^u~B_/ҹ/7UU&j]mk}ɾ5n zNWg~JB*.{~g{Jq"؝n&bW򓪯Zׯ~\xww!,@kankp}iͧ_W_E]Uj]S%boԍqZɚ0/aV?!sC+Rw.D ָȉmW%}z^eKE_^mIEjowkZk4tBISr"B1bJ{N"ZK%RUWKU}mऺzHNl 9=Ben&n^ȯ *.UUEɟg5"~o0~.2sAsVH tI~C[뿨:&_K; ,5%kHTecU Oc҆d%է{ϊ%~}bh;_J/m|Iy7Ϻ-)UȦ0?"ueM+~gR}ūMR~r.nָI6Ϯ"l{%]gd5:d_z,[9.v䨒vAYDo|`}p-/7gc}% յL/~8OSEsGrĿ gZ?|d۵G˗ʆ,_$:7d \ :4kO w}:{v>JZ 'z!V!ؖ_Ͳ|Q; o~j܁_/QwD~đilcctߓ;?gnܞE })_+zW"f zYZOk}B/i*֏j;uVagW`GJJwȿ7Ha}_M~It]nx3@~¡0SߘueܰJ ײn]roʷ}Lt_N+Z R~aҮK-DWUS䔯{Io+ -D>C_*yQywu/{yҽw{K{- GW^^'{y":..iL=/"'-/7o?{.P+'a3PE$[}|yۭGr[}K{Fo7ݏMo.P3NuĊ>4yls֏+/W/߿o#K ~MJA\(2zŒOCm+KoUr;߾ha"bN^#eeɳȾoQ/ܒ)y=y+iߩ ,Y#{_ވ$W;V}}rB_ԗ.+wָ@wzD_1{\Y^s߿[~%ߗnuN o}낢?w~Dw/#N0oLM_~p7qiwGbwnƻIwIL&N0nǓ}z{~+߿OuūL{}{R}qn}7Z/y w߄JoWQ[7uY¿݅+}. 7kw9C/kM7~N 僻[*1Sߤ1;}i a'w}=?{-[w/]}ȟu{{[zw-{Cw7+N(D߷cԂ_}[~HwB?|q]z3{ꙝ>LL#UAo}w}qBV[* A?߽Tw߾ŒD>?{ok98߽ ;l$W~Gu[nGWqoCu!pῄs8:У ~~% Hq^Lk[Hcᘨěߘ:~=Hu@KZWR7u;an/AG` tI1q8A"\W S3s\.zb ~To1tpv*r/}J6;qvnQw8cJ(z?cկv{}.c\Dn_}|!KaKv۸p1 =K]%NpSa-"|-{"E׌ꊞxOePaZGupO}]I4MnT+Rp@81/ tϨ&${dU㬜>wQIi(uGݐef1XRrT8rp8R+s))_TC1U+/HN)m MeTyUkEviNILu=gc%E^CBg5ȧ 'RM7(8↩ST܃QqQwFq`i()t 5o%a=ǩUzֹ)Az꛱ѕU$+ڽ;wǩ81=fXGX EյroOM?bf \O`-?_Vw3ʯ2o}}ZOJˌUWl Gu̝Uw =(ss5jaPG#ORTһuvbTT&K\XvL oRG?+VgA}ќRsڍg6V#WQecU nr0vmEa]8&1Q2k*F"dj49B:4ϥSUi#n@?߶ ||MEn<7Nw&ᦠAq1ߌ[u f t͉]whgE#hbzTv. R)-hQ?mdz53YX x8E)M̩Im˱Jƨ#o~|2Bkx>DӧB]Ғ4X!\ s&S <) _6/M2E,ԑpcDTb|.wr~0'8.0iՍ$ 4^1TJ!qE[g ufcSY=rz^` $BۭdmXDu; [d.6QsŒ ̴̺NlrH1E_d\Qm8eSd 5X-DN!c' D B9ƠfdS .FBju  (2(rw]z2\e[S0634rb7^若?~cNb-T7,5m]>J5蜉MR Ns" wD$_Una]nlջ"hc§,z&)FgYo% a`]4B5IVcO5Թ֗ ZfL.ݷΛ#ۡCUj庌9!a^4 n֣r ^, &S*̉7Ow:4:U~\dfJSS5{ |dv< y"™uAg5<.1-̩3빩C ,=z4]R};mEP~^z蚺YLP9_Z0&p^hK_~0`AI)5šǻ!c-\8Y T?끘q8»'H-<'"7r]eؘJ?r:QžJ zc-l^| LѡI/ћ_4R NlJGG&]56 5EBwMN =]o,5 Ek̙i€9…0%Rv )#%#9{$giV]"dNqd2&BV:@ 5Ũsb!s%:D9p]=c[ʌG.3 ^$TP"EaM/o]mT)RS C-"X U)^" y~#%|үp1Ё!@ٴOsPZn=߁8QuKK[֭Dw %a]4Gۈ«;eg|q((&w'B q65N fPHI4^􄏬2qUGb*A0_W.9ti?;~[Zb#oU%rq6(tջ]@Qh RٜU5"`L~A\EB:ⴍ2ZOW&9H8=F]HIHwUƆDw,7`ߏUROiR;~lٗ5X$psA X (1HΊ_F2fi$aB o\zi6Lܑ`}4R5= =XpvDŽZ"\޿T^E^G,WPs[91.PMS䙶ύ'6=;mm2]q^v`:J5Gɗ R~j+K姛v!ңna[9K8]G/Mհ94=G6 B\Y= oeZE$9h|ޑxg=M"M.2ѭO뒣zmSnI 3g߄ʴԵm3q1\sdYmuZTԩ!GG6%ǭ[}q[1 jQ|M3-<Ƴ"ZgjWBgF̌-Sq<7R).|[l+6DlؑZ7Fٓxk][(k,>NH~d"H4' NɼWh,.WMTFƣMgd\UHh{'Yȭ V]ZdȒHԂN_p 70i>2}+[Ga+c>aZ嚒n.*kO]tgc]\'_a~ l7+wK8Wu1<+1\lEճHKxBP:%s?OeDwȟEΚS@v]74RV! <63~UwvR*H ZqDlgϾ~ȃjLi{%IuUbٮ$6; )g!Jkl[6+U@C~j,U$=A*b?uIn*+r:26-Д!0>-9V1O Eho'⾥f]͆[g1璪% '*en-h7ofo~ 9h|Èl/}tכHLDҦ%lF,}XγEz<7w0kSmV6-qUR舚Aj"u^ưj -UEWhA$Zb J}tqMħu5^ua1uiіv[M-'p} aE˙W"Oik_ԗhܦϮ$Snf  6?Hوr2Wzmrb0hD/18L~olwQfş=U]իch;_ gBd58-,Tk\mZ5'?az#On<*>mSR %RҥM#@%hj|݁ ʂXܘI3DnJ8}ZUM ދM7$e:mz;@<٩KY9OlۥJJG=]ݝ[2~.к:D|b۾T+>SJrnۥS+i3;hSlΎ6߇mi+WFҤ컸ESwӥm Rsqd.S'(h謗ٓ5yJFT+t:FØZ:/{JCM~%F\HnZ@*t?;]j@j'WʑL%VOݿWQW6Y_q  Q,WF5%1o Gߟ +C6ϫWTHosfSIUf{2${!iYZjI5zv}V$I'hfM ~F[WΫ:lyʯdURn􍱙bʮFQ(ƣI++58S}O=PzTu%ڎK)e*hudI ho ^ha%PT>2#wm4 Fqki۶v]I]8Ӿ^y¤1ɐ{cx,٨њt7˻E ཤlxId9"Ā3cŋcm/^Ѩړ_]96fy;=6m^J*2эU(v YD_y3Km|t2/ Yh`I:*zA:mSaf .vR61)Wi6ysdA1jkvuTU7IնZD/MUg' HZG'RuN4 YthTb;o&hnIMj\vnQG-nf o'3SndY'DuDHjNUhsStGvRet22_eޕ!^y&>6u*9mjqgr?bX΄,+dِuV}hFˆGViϝj@qJi[nm$&T(mF;ѠCe7#Oc:S@isvwt[A +=9TPįmj6eMP".r4졢U4Wֶ!#$@kojV\awE-"6Br!@ܮԩj;iq(+ kfs;Ob1/%znTFچZ1c6+%:El!տj \1*&D^ѵN-IjN,~T,4m?G^)og.gZIiV4r0MrxzxԜ(FIZNoiqS-%|o+ˡtꇃpWsr]FC̐!`ÑN:ȈFbd{nCd V, p[nd j- M&\:uUq̪*=fѥ앙qhߙU㾗F\eT /$BA7LvqSu_jǻI榭)ZMV.=ۥ6Mm7)Ƅ&qՙlc|P$ 9J= ωaNmUrGJ_Ԕq{T1\:h>8֮$hljƻ]&wQJkg\TDB$u˂˧626-(ғƳ}v>V1d]b+jkK.Q{$Q2gTB9sw|˧Tɜ\225u[<,usbʹ f]']$IGoSukm٪mzS3;3N*55jw>N19iZhp? C(;NOV0UNOmk?8h(iJ"4ށOfdWN#a(笵!.)րCJ:Vmb'A0"+iFuUq>њaleNNc|!F]a8bB-jy6J+4V}m1&yRkۤĝf3;D GOM"BrWMVv&[EEwVZcjR}a$B7e[\ZV䴥^.nr mLOe?H?*.c1{q]Y5v׉L"f;誛bX GU1^OB`-&H6j[tg20 "FE4m<'O@7덲9Z["Zq`[+d6.#^ZdoP5>12p~d麉Id/jt >zOoKgv-O\[=$I4gہ4ԛU nޔٷ5EIVC={es0g#6o>! Zƍ:_-oj Ֆ9x ރ'%Zxe Qsl296cC!9)2p`!XoӦdF;|Q[ѹr7nUTq~mY=Ƭ BVD'}הy'9spAaI1`G)pRftj~6lH}z4"5h_)/ZR[kڼdj렎ęHaC7dBCE*6^+1\ gyc]Ҙߛ.kc4)5sZ˖vhBJZm{=m7IqX[mF5M҇*J'uӉ65Fkz#_)oCCCG4 GT'$y,JԠQPXCRTLb\Sg\ݠU \Cƍ}j0ɤ(`DIA6' p BU.|iDpy|ȯJQ;?k4H[l٣\#Q{lo,{SBiqj,MZ2=ܪUFƓU/Q\Z'Mu4ZWR}dbJ22.5]Q=-d{߯t>p*}6g#k#|Mh$^dI7QA?Zh~vFJWTa_b'd6A{ڄ+u8-Z&d^0 ŭzav;K6_.b!66EF}T{Qeh&֪bJ*FݟV:[M2ҤQyeܞ)[9Ihfna9:3=N sTf=H!` fb/vs&Qb8}m"Lgķ\4 aw%-g4n^醙:TP'iMt tu{͕H-*]J4m'خLPؙ61?! Űٖ2_@mI1vQH "&͜sevBP^[hSsxۢ|ɳxҾTQ'^mx߶SZ>˄7F}uC0F{_s'VVsp| F:/5>em^[1fHBA/j2Quݑ6Ŝv1,"t>|oɢܠ7~*yz>ˋ?cR}889`v隬z.h҄0 DjÓ\]ݵ&m2=6)S:F$g(rX:u}26%I ;L6ɉYgrR1edvBcDo]"BiUnۍuU}{4Q^  %d#ͺ.Vd8' hRLGڡ#kF`-}V%C@pTrU[tdPes s$k$FɩUɿ $pqfmR/U]jRҏ3HV݄Y'הEk|ȣ 0N~v:O(JoZ3 M:칹e'0{mf7 +dKnJMW[eHgP ac딺tUqwvh1ruNH21) eKi`~[P}3 Ăg`/fxi=+8AI~5&n]sVSu_*N!ޅN4Tɩ1FEm̓+C}f=u dfVۻLzY݁I`-:xLN~EtuN5WanXd>Â;C{pw(7Ylvb:݅OedbpBT-&Y]Y;M.f5ѨAEoV$1*mB7+r[N^y*'(;T{q\M;:FBmu^虆ivlAuQ:jM)ĻWH/+ Q W2Of5Qf>D{ϖt=IQBfsm}6Yۦ\Im͕dPRPvutϦEo[PR \ix̶N: uw CiyᦝKRi_כ 2޸1ҪǎȓXbhixGs2NF֫'ZiC𰞜KugZ&wY w6o,dJ((IdƖ@k l@M,3Qz3s.5Ms-dql9v")2yGWN7K뗗UFJWeZVbI_ g 996Tꈵ‘` -b:r; ^3߶3]cFeV`iyzDØ]?,j{}Y$ykaWl?~[٢;6K9ၞb88slEzW]՘ryj O dvqIM+T"qw|<w~^xSL;q́UV9GB;6~}' BLt>hEWtq/"WG1a%6f)?X2#.f ק""87X^(ĪM>T_zeG7W$}Nc'\ʞo%w"UnZݦ N{fȷ{ cHM Jku16:3sUIuI/D"E[+i.= ݆NTwٯVjX0!:\cJ>feM9ȋ}PЙ  ^7'U鼔<,ۈZki7UR?o҆*vyѐƍ|9w'W ixT5Qfվ^9;y"~a|@'m83,fycu-͑{znQBwzODYRVt}C:ߔZPS47aXh$zIgaZrN&{d(N9N"< ʊ!X$4m{H] Gé-KgSmq5aECn╂HWRyd˲GLY@XڴZL)Χb@K38Vޯnj'v8ool4n.9oj*rVۊdD`SVwnHMXӃ53[N_VF`]`yuLoKbA*hϝDžOeg͓!CMGro԰X^Iu+Lx paXG<@%S棽0wEK?A;%yQC^lF|cyˑH -Pܸ# Ʋ>jC톑17񵥃+?MӾ}}O{0 W'|`Y.ŰURyzʈ,L5pPȗ?Ӄ^`NQx-o8QD߅u37s!dilKڏ\u:܁GTHZX9Z1*,q\;vݒ'kinlk%aYTiɆڨ97 `gﳼ$Aȕ4h7v}d\B$.[t6yTYW%v!}ΰ$wT[lFi{TW wÄqns/<J\{8:\ND 58K58+4zTڟ-2dG@TQ_J̿9H cНQ¦4,']hhrd;w a5iR)=K[T)Uu,*ƴ,v#*:0mu%+1d854z};in"G'5Z&3m[Ɵw%j';8zѵ$ZS\f ˁո(N01?i;|G;fnƦi QZ74iN$Χ2W6gݏ\3;K[o0;rRInQén{t Bqr/WWmJt\䪍%7Ֆݺ4d7)9,o}4ę>֠=8TG0cThB$9@̓)=,%Tӿe]hg0!dH7PZ5XWzOCp]Ի,lǟV#j|Tj=P0v}ƨP'aRSk!PBNL%]yQ VZ*䦗 "7 뉰n@?S |߫viWܪ.DYy|v,*օpa=LMX)# R [". ̝G|F䵆04\•&lIu WwlWVM53IT0zm]:.DIǞTZ߿I<: &5O~C_\ǩicv^jkTJj*E}RS.y}ڎKǚ*ht+WJU[tۤ14@"7OVGas}'MZ,de7&gBn)]یcO_RK2_,Z*zj`(&X b! 1Mhj"St< RA g]QqLVt =O7b|+Enƻf˘IlOUqƋqg0A',/4 ҡtt Kl*\0Eu17Z\ f?6K0BsY&fJ\!o?EAI#q$mOjk_DtV)N7zy5Fpf%܍uD @3y: 'עp)~o62ϧd!R1m3FI.-l(Ua>΍#S|pupdliXF!j5߱83e61] qٜrޠ_L) lV4^-G說Zc^& 1eL+2 Fb7d)Ct`aM RS#Dd\v!^<ޓ#emSzZ-ke6ӯR#cViw`UdlD":z#kWNv] W)ӋOuʧdFmtU%j*zD߻GIXbE# ^Lv?6fe>CF1Z&}L]Q"}.og2B 8 Fj9#^Fyسm(A.i/|fv1'.!`.mOgf1gk 0GBVeN5m7I?G[?\oiVvB5^rn፥d_-Q`-7;\ɄC R# %D.o{7%`|;ևOY9M\~5$n]p!m9?.lx)@{&~kB*d ǼP=J9N<JomA2_ & ߈饦P%(.4Bj̵:)In8üZM5s0ORS&Ǟ#M&Ywr$ɘ}"U=c]k斞(Srw^ǨÍKpodBb~Ć` \fb>wfEXƙC`J̾KdwyKFKȱ3-@Ma_ zEkrE}}DP7# hͶ2cYFU)uY94x#GGHܵU43m͡{4D@6Ď3%.@clؑe^ur%ՌN []h(i<汚zIת^9Ƨ;Mfy52G»|3^b;~6_ o+b *a:ȟ |M"l3ԟm5;>U*LtmDC¤W+ z9T 43fc,vlCO+ Ԝr3Q`IC;fۏbSVДwm#Ɋbz̈Y796|-I wpr%`oM,2N`]"e' >9Y")e4h<׺qFw=~"`7?a; ajRB04SQ;ÃdgF8=",inD'!gu^E W'fh5Mi 6H 怫&u 2t-vJ!n^k)ɔy¹mRmVd6c$1fyB}77r2j a_\Ro^T\ꦨ׭٥[V^URLtrv}u~xUEl= jZߊ)TN͜3> n{,9#}5%-"!-/"]&;3ﹷLg^3uTY! =rI7_ݐ`d k- e ۿ ׏ 18da87W#fzjM:|n&x\Fʶv+\aw8KicittNeJJ1_oy .yyn7 >l\IuW)GR<تh"$.:Vu6` jwaD O~_4t `i=} ._נ=/Ͳ(vd1nDu_B7]'̈́bi4녰֨32Tڵ|2pv3n%Q!LPm\FAu03 P"y(OS(4H :BTݻ}'^T8OHU?O9͟ф$06frg[S#.U' k@=(kO8 &e%W5^z箪uJ\uo~U5ASH/5F υx勐IMfs=e% YuYZY7!YZ0R̿ Qܞ޷2dRbNF{u 59H\JVf ^>J6{1SʕqCrH4U>Z'+f5$Z fM\حM$OW>&NyLn^ pKd:eV[EGO:Q?B3A@jnb[הs 6 .|kl+wl(zVل VfAn4S9LN`dkf41 ތ6M6B?iɴ쑽LQR8;gaJiE֫Ӱ%Rȃ il'rÂB1exv#٨6.6USceۯ5ȡ>^EEWUIT>6s59s?\Q2^C[ÜYYO4+6_yM43Sm^ZԺyicVZT%j!V(9imS޼r&"~?2+ F8r`61|Z2*4vvV̺0;׿mbj0V?15Yucwr{v|JB2K+:cKU6Nekaw* FZ׬$?%-!LvZNzQ BiODQM^a { Ω:ng-2523l/uPd 5|,?͓F9#aac2#ݪVJ7$a ]}j;Z g**'ڥ* :ޏG Y";QG)i3.RY 8 %ǎ}V}?b͵Qi؎G;q֗l˞|@Ϋ Ǭk_\㠷\2Y :dF]+!nSU P}wM KK*]bIVWz gJl@\)콋Q uUOMrU?3 nK''K:/Ru_f\p+Ϟ1oF`?݀PL=wft>^grDiѡb)1hʑF>MӠ]3AK<%a.nNXFTYŒǗ2-vc+ [r'a5<ބPq( 癰c8E@HՐdm\dQCͲm`F 8HXV#H =cVݶԯesQ(p>v(hu~М} g,rYo{4uLkDs4-ZVlZ$koPn>jσ4TBS9[s#3iz 2sRgR4o1#0 E5Z{ m.mjHɋaz֟qXˮBEkbC<7.r9Z-nDZ-PI4Qw?nӭܜ9ef/+I7{[NJn-__NŽo)J{"{9cte#^!s,c MJk.%1$a9 ݡ$Ӄe f6GT-Wst[bmGk'2 AGgMYJY3!]5D 4Q360WܾTJ1HOv"ICq&I יN/]Aڈ!v%ȴՠb"H{~YL8#l1^-ÊG N Gt f\c,m2AkdȘ!` mަAb=Ċn-ͶٯnDzSg!<$?GRzll{UZz̀?B_af+JODoS`@C~/G`IrD_ulץFeQͮƑ;*&.י!u 1E 1V]`i#fTT^ Q\btUPΉΒfSck"*(Cr`.h{)i}@ Ʀq~/b@qKg"aeU#AB&VsA+*8`)qKgbPjȔ/8}8obɁjqT-f67^03AP8F`D4 ̵lLq ,سk{i?N 35$g64 &kn 60ƙ,hʄaMʦlڸ!Gڞ[X'gkM IFXxҸt~*L ujIʥꩍg8{CE\Ici;PA}77jJeYa?%u-VKLM:u?\Lo{Y`!"sZ7 Yqf niRg%꭭=B6T { v2TP>œz^ &K» GFGS13:10O >G|O:,3kf*})iЂ %| i:l4H 06K$BdJ:kҚ0Rybۥh*h s#uG.qȀ3_@HIԤ65ۓ*n\d-^_"#^?A!f#ASTTV5RբrBBJZgsL=bi.>Wi68nRFZS^_%[fcѠk Y&d2(MB$V>?^d]Oӌ4̎[4Jb;1&Իq{{csY|/XXcLM!LWA"3Wcٮ4v<)WUc f\47>npYΕ=Ɖ7:a n-U#ѯT~:kЁ:hF,(XnQ3vm "D$*I}4445#WA\`Y#QwEcHЗNSNQMHwj+H%ڣi8'F>LB)4;T1[;ƈ#nɦ53TDs Dnl%.c$Վ+QIߒ]6ddDav.ҕNroQ [a3713p:,uw)}2d>3S"5;Mh'G.R6 1_*76.XM~m+joex6w[x9`j-50Udq0ܸ+ލ+h=q#.Ge})q8DZwFdo~}ezYW:+_m-GeZ)M9ʥ- |uEЖS$ܬ֠hBǷ6Ȼ2)=یdLjo/cx|σ2>n:rI%mU3뷌W->x:/ߢKVicm3DBlQko"}*Hmo:3bJ)JRƦd'o33L\lx8@7Vtjqp䴫PЌ?ReAݦ㤧Jˬ=*>cg 4>h\iN(fPF1u&TeiZqNYUїY.oI0#|#]7%[Ư@Ǥ5}iz 6fcК#z hȢv|iK\p2Hls˻ow2):Q G.Q+},ar"U D@?/7֟%2Kl#J`B* ɩ{ ^ԉ,fmB S<|_44&|(͊XEMjo@;.?exʞjnFBfn\ԐgiEntg")=NSbFFQD8,tR;`BTң ꜟ+24t͉H{Zbv\rѣnKKhGeƉ9@g cA^irg9H:s%LfEj~䉛D&7.;M0,9n1QR/; `Ss#͈Mig4$ #m6 / QQ J, 52ԛ)+1g C9atg:_Hqp"yC|Hϡ$%iUz$}Ɗd1]rf.M*e2 UY%kҠ| 5{{m"x'j#|KT@qk2(mRǮ NC g }[;+I{hQq$hTBͪ^xB &qHN"&6ظ3aD-r+PƥY#oEDR#JEie\sW]Hjae:] X@ySw91;-“271h6Hu}c{3N$<Ics_ a_ϝۂ1#{V_ XSg a^Neqփ@уCC$ؔxOܯ;/LvFzE?wAVDO_R2F7a&N} ;L\2=Q=Jþ7#'f&RJlڌ, jՏhm79A2A' &o@4$NekzTǼ-kr $ȖG7K. a ]܊btHuͤE'HQcY>k\]6_mƶvĸs ڿ0BP"k+a*țd9ݢf510ʈV߹f7`1u5`0i$e|I#xR(ϧr9+;͘M`dYZsG^U%%lIb*eә,]bc#$)@_h?"V"RZ4LE'+ A3$j0ѹ+t/k xfF[):fk\Z= HD [[d;i- ԗLxl=pY5ȴi&|g()!ʐ Y*Jۏcsջ#5D™rD9'H@{9 "HI\c[lr4wp|-= kpr,@ Pe ܖZHqxlCG<&lTP؋IkXю -_DF2nŶ"h~Iin\9U)n+tڰhcU&z챟iڬ#c3@M F@K)F3fC֏,즛5z744V!v@ShD\lu{} ={a,$ojH7zAύF5L%;i Jd/*>C{hP3D;m~G=x*8 ᐟf2* [|"Uo66K%C\ HGס}MQg;mi+;hi2a5 #R|3JM]JkI} oyD+[L55/9F3 $zR3p^;Ɍ>hzNDs,O>ے;) 't|W75,wX+uHٳF:X elM`!"҄7q+3A}szR;j~, 9᫭hGDOlq6>и}BsMpX7A"ׁwl_މM%~{q)P2t46c'5Ai1f^etzw6;1FjӜ+T/h 49_0<6y'm(ьpKMU*"lD{'ݚ 0V}V(%9%K$jHXэkU+ 6Ji̦tJFr!aYi@JP ~FR4ǿ TL !wYX60qH~4*h>bތQtA3U/TzI-c(.?.Ldd_f X3}cc3fܷXA t6!dz].#|QgR20H66M1L&9i(u0 :6X1̱){1"(SpiF9:a LЩЭ62-$V z+mW h(+eK:{j %Se<Ԓ&IL4XݩfHٴB,9xm5){+f)"T`,أBm)G|q.YB[3ssTZSRWS:21dF :|tc; m6,"BmhUŗj2mam0a#J[ޓÊgwD٥l w  2͡_ rCKqWD!Cm"7¼x\~$òEe]5Ih& W&\f2MFh ]}nӎW,I $ݰ!@GɌ ;l|&Bݵ L5hۆhb5$kd;3#7kL-aפ-HbѵffomD~;@bmHR64U>ٌقl؍۱&$H!M-Yh.c&#.1r0U{ F{)2;eF|IPJGL~pU!B\kAA"=Seda'fU(ZH텉;!9+MM#F2$hU]BZoTt!((>S42˕_'*8 @f+{oõhp`Z7Y9!5&%RLfB *%os"&S٬AEnO#.FN84O@^=k)k?S 'جtG IzfƗ@^ӯ[pf!n6r#HcF\n5}D5Ԧmr\ZْgGF,nx_耊?{¡GATQ i BK@slĜVq[(B>h&#c{NrX2<&ٌ.t[Qa"4ğJVRgGpY&)_(21ΛpwD/=\Ö  #BX5xwA5q#M)eU{p70‰|'=YȱvqJhv}|q\uWp3MJ.v$M_&1Yִ,9-M`C9-;113Te11O$Bf FxUETudQkV,iڂZq= NMQ@͌m*g68ȓ Q:!C'ۺtǪ'zT[ؑmFeM7Ļ^)dTB=8hH?FН2NW5X |$lQ<}O'E<ߑ̊&&!mn@`b=6uB<$N,nQC\X5B[{PF>InJ񍑈ۅERX 9z I4{%:WJsvRz4l(ŕC;X癚6Ү"vަIÝ)XgTK>:cʵ -]#6mGg$4:u+{]1tQEzZ<fd?s*mmBk07ek<.UNU_LvIcY ~ݗF00{G?̲n<\Ua{(VӪ)fL2љ6 {o]\箓GUB{$e'0}|IȊ&+{A`ٳiBe&MȤmi[HmK `x~Pp^`fZoD9f>ƃq hf `5F'Zd}Cɦ2B7Ɍs|3JL)6r3ԛ$[Cnnm&}˦=.n^yᴱ: j٬iZ*0 7k,6U1+D6#@٘]6M"W}5|R`-CXXLr`%7CI1TRp6r@-4ݍ65F΄3d]Fҷ4 ^G2C^PK^23E{:),FkZ1t^qJM]6$n4}(M^>OS0]J"tSH܌AVHiSqHW֕ۤnmMw5Yf➖ V+WQ2ZgGZ=0qC3 QN6dz5f'Idɛ'2w(JXFN/`'67h%Y`weL"BԻJuEG]Pd-5YÏ(hG!!;͞*h2 pRqD 3Lׄ9/_s*{0 C%~ve٧ {j(' D{3MN+lwO_޽\"MF =eNwk$+>]2`>lFFt@4/:$VWa#eҘMw 'c=UH\inF8WK-zԖ7YY*M b_wiuH|Kb(bhK$yU}XCT-V]ZwGU^KF'k% /Qqu֫ޮznd ꗚU[AHJ־D!*W [@$@x]tUqu]t'zmVw}#Se} ]5}fBw#d$܇]ޖBvBtZwS͓ɺ/RjI&k.'7NRoHY~:+IMNWhc;nNiR1kU"/['ꌦLV]ϤM:YׯW^{Jd{1:Hw0Wv  g:KV_LZhSQD}[OjN(1˗W^޶0[ Bֹ+YbXbeoD pd{4&No dm8.s3d-_V7ӥ\uJ}a5k\-l/l8=|-޷W\"_2)w{)ׯu3PKJV,2qFtZv߿U%*+J iۻحJ^ra%5vZ^!wwsoE"L%+R}8D()kڨ\t^"ԕ%ry/0:"Rj}zں'*<_ꈥr5//{W'lf>Z}#7XC_۪U}*_"s.n񼋣׹yެDޫ1Wj M7lKv}"BWܤgzO[Y;|j9d&Wv^%'#"5=z{tRN+,Z?UY/SYs ͻV0^ kTq

o֣Fd! /7C߾{1ipC(9{CS^) {ĝ:{0.pU6b >00ZUO_׭*~O}z>cb[Oy^f>  U:_x>\Z~l3P3.UWUɱQ3{p O)7weKO7K,  {-|Mь"~Xz%+7w}bw=j] Ql'CA*Ȭ:rE\۪z6nUu> E_2wZk"⛽G}7O2ਗ.1 UWőku(?/cOu^6^a\ ]DުL w}x*V[w/o׸H_uJ=߽lQcwwXjUUiW$(]jY8͔r5Urnz'Q?275?*-9"}jڭɿ~똕U6$f7J](U*QN%*ry2W͌%{^bFW?"^nR7fy3+U{{Roҏ5MIYلaEW[Bj̹['Ɉ\i&Yz M"ĿT+RRpQt|i~ZE>dJ%jnN(Ȳ}Uz1s&F'#U. S{dDXajd%jB>+E߭:bZ{\»8w"zu)bdWߺW.}}ֽU{`ѯ1+וkCw __֫/rʯ}wO޽Q<L꽽8.z ˙k[Ur}W}x(G?0jZs.u]ſV)o_7V^EWJד[uOW_jJ̅BϵߥY+=~YI[IjuKjި"]v̦5Jml\Jݒ)r'GOV(QkEK+cg;zENGe!zRCz/y9W~ͽW>\3 Rv!:"Wět!ya]z@hT6^BUc{-b/Xh;GYxA$n{3Խ~Gi8\; )-I9z.oW}BOuj=W% ^7}ӗSj'"~w혗־[%+?BZ&䂍KO"S丽W.{嘛EU&;1tiuaSc-?9e^cu5{ȯ|ީ퐝yo=~E_е%n4i^aCT!nZ˫jZֹAUvl_\}}k-z[}EfNnWuGۯKYyKr,ͧ}FoSۚ'vn+5|Zseuw(G]Ϟ9|]۵;ZkפeǻTv'nJ5I̻ʹ}2,_=]G!/Fe'cC\ȫ^⵭k$kϊqG;;ٳķ~ߎ Jk­}׿W_PpN/Y8'__hR76 M} i|9vwY!WUѳǻU}UtN%$n_"jU|_ϊR3F'oY?. __C+ǯ*Y+֫zֵqM u~ZЭް4VEߩ0;{~pbƣ%Rjg)bꪫ^-`!Zn+,>;_+5ֵS'|qk^!:ʽ 4w4&sg7淖$߬{S15%̨/GVzMK_&ʳn@Y&%GWGUUz E\]E먿_ UEkUl]dֻkFRnzS[jZTk.k?|wu깍TԜzz>I4grW$RB'XAvIIɿܗM-׬Qyy_%n?){wb9Vߪ9VnBb+%wUU֤)jgw޹n!*\e̹oL9IHi.t]W1vh !7fZuB~ئBt 1.Z>!IO>y8'"[_DBB_i?Mt{Og~"'\ˤjnA], ]򒿄ķz$ޫ&{wsk^#́a_=z]%k/2\.+aZjQ/֫^ y|~j~JO{]Bj׬^Ȃ=Ukyķc%~|J|{79CB=vAWz+.H]\$E^ _/턅W?Ezwֵz]u#F4wO''VJ^w'g`dC%G d~{^faZ~ ^.e2~roFd]k8=mUuZ־(ݩu{j>#̹sŽRu|_nT UE.ĉ΂dhʻU/OŗTD“U-#>#5}g9W_-2 Ѳx_,O޻˹zw}(:qK#wKY.c7cDw}s{3zZmWԣv?`z+x=0Ӿs*#Wֺ)t?}{; {f_&.p H׽_.NMǙ->34I<,1\ tC=JW2_o6X}Y9Vi06Idw_mկf'0*7&됽"[_ߍ-uͣ[sDWl-WoxM;6JK~ܢ{Iosr{Ŀ:sL~^"LOc7Ϣzw/{ۗL>+?bjе6θxtj긡UPTng]fc:X/'^.^B_)z7jӗFlWJtwKu=U+Nj7dϟq_]/Eҭz^EHүԝيԥNUAgwHZVmKn(UMkTiW-A5}k[~OV&HK- 7,|&^e}._0'qH!/XfẪP `qÅl__-kCp6G"@3~+ VNo:Bz<ʪC[^:0n޽ " e|S; C-/~tY]#Kj]~@UUW~-q^q'Z{%|i$T7~n´ V_A攟U_y|D41vΗUym.ޑC=^n[*H??mbbz4+Z|šī^[sL**L] s]oVDiu0WItU ww7{oe^fԋפaW]E]}zJ.k3\^$ؐsUU#Y^ZʐߵoV_ UU('}$u%dm"KR'J]*/u&.Nc_3IX|;ꊦ$e}>aV_?MH$G_ ^w}U%Ư誖/կt򯄞Ud/yuQnߙ '{ 5_ b1+^O7 !rww䇓?._*.bk,6+_. f'Gk\;.WOj_D1~W\k\ЃR7ZXW]jb"WEW}kn^zz(]Ў.^(7|?}%@=B"9R~Ȼ_07__OJ{)A5VK y;W(EײW).ؒÚs6~3x@떊]rw/t!|A7Qtk%u $K"C넓 ^7it fЕvZɫ/'?#z*I}.ou+)K^3GMPMw-OHPB+{{3b?|W`tu& uzhzѓ+o=@;CXe%kU_F w%CԲ~c|7 zXgskV^bZK>c۹]қGKT-UOIL;iwRZz\/}HU^Ty[7wM&k\}W)~Ͻr-EA"V~b_\&WwsU}T՗kEY$ӮcQnn}rߑfQN-o% kUrz+RwMU'ZI0ZWjuW}UoN]DZ|p}l?v_ݱ>>E&M[W>//(}7bRok')u._b4>>;H!/lyd? .$ v___Vo{ wb4J;lPME)RTSZPUUVx.B֪/i}{~ݨҮ=tKAlٮ f?g% qcӴSE"}z ‚5ڬ^\wa\]k_DD~!ꨈWZk߁p *L΀C#ḱ>8eP kUXW묜PC/^6Y{oݔכ5K'|*CUۀlc|)E|~%w''~֒GUb쮗Eb5GbRU?(Rd:яMK^}/IDr=*SMQ]}ߖ6#}5-oK\$ WVRU[+: :ꪽ|ʺU#㗯8']_D2bDU]]r~Bz?~D.W5Ȼ}};Žnוj"%Q;!/GVשZRh[ gOl&DrJ-_ _߽R!U࣠î!kY4Ci_F`yo_z=$+wu'#[cܟ;& K2_lOuqyi-D, ^(T:6!jd~M不3gBJX?Nzӏ>+`úe=w}hUZ[E&.vWt~zW)t+&+;'|O;QsRt$}n?EYW+7c?D%hC߷j9~\ۘS Yҽ;_v&]~fT5= U߻wMЗ#Q=D{Ckw^Dvw~b[w~!;ѪC/P.|S'ww3}C ֵ&j UqAWɡ}z]t2w[F/_!:Kj%K]+|xN$N+w~|ʸ({_ziw"JnC\R|O{ۻktתX?{I_m1NFS!orod~6J"mwu&NK &~)"i*nҫȯLߒWB} $]+W!vRswO k5ċ~r'1/S?c%/UŞjk_*֩W'!}.Ek}ˢ)z;F]*?|1FM_N1/q/Ft,RWIﻺ7%d'],o a]^Eݗ}uk߽'ON땻#mܼkJ%Uj]Q ~Ay%UOwU"-_}-!y_!ZaWַ^U.8156.tpX9n{F%vPNΣ[fC?}"{{= ܄(yw/1U]gG$_ɞ0$ oOֺpuTb}_^8ڪZe}F./k! KF TٳmW0L٥*3Ƞgz%/sߗ)3%_Ǖuٮeܜƒ b{ s ˕-gkguUW֩VjS^kdCUq,3yȹ_Q}}жZߓN.5U\Rqw=w$}[_d"m&g= ?]:[׫GaUPYwZ5W~ܒ麊W4m{e'JmS@鲐yv%_t3#|Yz7}Iŷ􌯭iIiv_N}>EZ]V=-/!PEb7{o.2 l7 ntp0˗ݾQc->zh#Vwu޹Ϳ'"lt\(a<2seyB":McBTS_̂O~ҷ2TaA}/B.$C-&RV%\z=W3Z*~/O>]- U/{M!\]=w͒X[ѽ/kUW7~;oxչ9wZ_}~3ZOJz+=F%y)z+ _-K;uu.u wK7tK/(+&-e<+r= RqwK{6n?2>71*NSQYiVUQ.`#%똻MzEg*>˾&d_Z+荮RzK{%)dV.UU؎mEUľSl]qlJW KuM%uov"=m֯Gkg^RʻEEu߿^UϸUkٻKTfKw\º!깊b_6Uv6='5כ_N*"&@)^Re/I2^^=E+WZeXI ! /OM5G-cj5W]_\8AuUUUuZcv=չ,&ke#IV'X>]Z}1"Cvdz͋ol:׮H4TACW%qww{/{F{]p,[ /]tcu_̺~#|(Zjj[+5Bp\!߻W&ȟ(ww`Gi(`Z+:U_B ]z'1:?7UqB. &{~-#k[&R w~[=+fABͯ MֱY_Armw4](HDqg{G\% w~E/~M[d]s;n}zU}o~` eUt_IO$SO.52o"ߕEs=RVK~닿[$WTڏ)k>b;~^+GKT/5._2Ep}MOi{K֎#zJWJ!O7p FoIK%1 Ye]KaV+[KK#tag'"P!޾TRj^+VEB;I"tzp)wT]/1MzL*,VUk'*ҧFBVja4~@hZ!.&yUߧn)?ָA]zOYoP@'7oAn" >&M%|V0/_)e^arD>utAZ!`r@w-}믥[m}}8٤ *%us e#kj60?%فIֽ~C/Z6b_Nu{n_ 93UVieZw-ɿ2!',_\_O붺KU3ՏC\·^u뙈8y0b8ֽVUꪩu_ |cP|k'v}5~'?OoEM{);{=^O:C=UjEwWw%k~EghEi|.. 2W EၴB_̕d" '9]zl eBv@J_MVE\t# z}̃b; vo׎;9nNǦ+z۪k}z~;m _ZBOO߿Z_ZʉJǮpk}@R_y\~%ʡ*kIMig#C6@?PGs~⏳_Co{_#_U=]▟UA-bew'{О{~W!-=an+ne]gĻJor#'sw-/e^/Us {Ǟ[K?Cm6}Vz%߿|s7/[똗0wW/ynkީ|DVEq疥/uf-s˯Wℿ%#ozbUWDV_"_BW޹O$~IzGo_\$Q֤ԜRUZ}~^Fv{53ߥm)5*}!)_NW}%^c'K -Kd55vV;\ޖNQ|xu[WrWk]rnn(R^}W1_JS)oGS=됛׭kVs%R"?* N˽kV|zRҭE -$|:oLޫ3rqMuٯV.z.[W/]}r FwkJooŭy|.^ ]!Lmqel~-|X.6[|[ׯE쵮Q~$-ooʻ/cJb, Z!$/PaT8@QDww'uV7`k*SZA }l1%~ /qB)j((=r}gܧDhN ғ8ωׯ%UqZ([we{ WT>](!ߔ  Wmb {+ 8WđU}Pvy%\jd=N0kщ|)^J.Z+{KqncyIi˯{_m4#.s>f|_hun*&nK~LWxWF?߶{ŭ{G}:K-}G[*3_v+|Ȼw倭7}/}wEhT% ,?v8 ص}{w{$Od+BWXZ7˾lNM_p;D}.yqWD&UoboR~פ73])&VJnS̊]AO/Rr ^n9Oe+]*]$ֽ^w'wy=+UR|VQ>C'j9o_RLU]^&}o6~o~hͪ{'*F^gܚmzSiG߹UtO]TR?Y5׿~f DmKI {OUe'SW'_7NcGk0=ItwK䂟ww}Y俿ғ:UQ=1I#أ"?ĭ޸_9p67YfywL}tuV=ZmJ%&/^Mkߦ]Yڥ3tYu-ihY;+]S g?׽*l,XU}OgjM zB!7ݿ٨*o]k֫\y}׷uK}0VWGWzn\ _%ǕuNRwZf^`BHWU ZGeW {ۉW6d#lii_Mo}WZ' =id2%+ޗ ]mEwnWK;}פjр w5Ky&߯Ul N?h2]5%kL^p^JU^% 4^UiόmV"w'  N }w_[oŋ-Xտu4t%/MqC:W8_];}=!fa{!ݮ#>m+Xr}UhAi=VNtٙY~̴j բ\g~~({#;.oס]A 'a?My`~_@d苾O_=+ֹ苠.8~Et2߻{Z{Y2|&+KϞ#d/_*ߐU-USy-ٌ(Nf}VZtZ'!+7e~̯RڭI+ĿNԔ!^נ+|PWhǿwb?.HZ8-eijM?{K/b脿'~"~޵'  t_W޻ԾV^7O?ꚓZ4O]k}s-P'Ւ8BoWk)ߦEkj;Y7${;ad)buB~>ߧ'cy]SeNDb}aY,L_2:sBK_r?V[JLM D!(/o}L7w8{6_7 7p7 k@e-(g!2\< zEtڽ ճ|I~;ъ{H4mܹg`HOwvŸ>y= Nc}X;fK~`YכePNBq_/}%~_KZ\a+d#-߮*vB^*{jҬ˽3[{͗{~#+wbҸ%{LYۻ5L߾}CaJ|]\ 5W}߻ 7{~ox4_O( 2quWlǝ}]G|qO{w{1㞅$Pw'@C>;sX@SzkEbkW]Z|+?w A/PKwx[}*\U׿D/~^jn?7b_֥/Ir_}^so%W6+LnA;|ɗ|W$lN}dO)~їUYUU˾wm>WħmIH?e5Tף;Ukf.W{DmT^N^k9Kϳk|Bwҭzp},AAKkEG!6Z߸b"O_)Liۿb$_tv'T T.k?�A}p/ノEka+|*%ۢc/o5ק7=}J֞VOD^feM_~~qfww%w}D=~r̪Z|V-b4A/KߪU "v/u_Zһm}F};'몭#^E# Qx9 MukBzW WI֕*D:_wwn< Pē>wUdVtL.uC~o2w=tKһkxb:-c`0{.k%}w#eT@^uow T-DFAyBt^u]d$%=v ײO^vqĭ{kCtZquw~i |++׮S?^OB0_rCz]u-{~*Yߤy3]pUK_)jN괵ZPDd&+K&!±B[C[{Ew&=n51V:k2.,]Q}U" ¡6ȯ~3Q$p_f)h"?ky朧gp},{k^0&4>z~UOYsUBuKIU &ȷc_eB--̨ M#jR Eֵ j(9|^qZq]^#oo\"6jϢ$UN|ķcE_7}Ͻ_3hT>EI-T[NKQJIB˺eߓs"',ԩ{C+{FיwR}&+ZZ!;zmW<ߔm BWEv7~e:_1y9w.EU^Ws./ޱ6)M9+җ!R%N[ZMj+v9}2]Sr |_I=;zҗ]. G}O߿rw%}vwLQ\Ko+~#~^RoW*k7uidswj}W(~A=JK}/+LU?KnCvS|yxK.b?7Mɯ%;Uz [S'}zz';\89z_r }do|$2 ~W #NRo'w̻7~}w~o{ީ5꤯ʻԝVw~(W[1;w\Vߒ/o/uQJH_i <6+ޖG_~w/şSBJv?M+\]jW(M7K,?oY^-u➟kUM/푅Ҁ!\mt[{G{os!,O(kVyCZ\{Po~'=p[ ;x2F𬃉yaԆ64l["(`Pu0#*'Fe_xM(!aqR?AWL{~Mo^E {wwZ'j/!;T߰D>a!Oww/wLadBCkB }w?( wwA+~]V {w3[8wC:W`B}!zi{y{߿3pkJoP~0SߺӿŮT K^^ĝuw}G{7w}M_ ww6=W/&'fog?F ބO}F1|po~KEQ<~/{=@} ];c;?}ԜϿ/Oetb8=zZOޮ]oTu].%s(wt%BzJw7!~R>(앒kr%Eˌ)/rdzN!J$Qz_)oԜ)_P_-SRMDQ]'ѝE7wK?~FR,':+w:h؝Fi|{dw Hfb}z8lթKwMzoRmZy.][Mؑc7Ђk'w~vǑ_k?C*5f7/ܜ \?GC!˯6MDr7 j Kc >Gt_CT'}r'TZfׯBU~-&{]|NɗV\W~+GR΋|_s{uj#Dv]>5WfS,G7Z+Y+?+bYjTUu[^>tޮyw_#ߩ}v] RBTܥW|JM^NCQ~dszRrL.T|{ɪת⍠i?+co;+eԴLjAhH+D/}^blqF}7MO&щ}#H/ +'^ש+?2޵|& _1wߩ6k/(gr{V|N,w$w9_}ߺS6%Zs_W&"Ds+%ҾR]kԕ;bwO\A\wo2Ӯ-k}|W_Ouh?#~yEkœxu[~VK !0/c(P'+,|{Ǟww7@' l?`V4WT5"jceq w//- }@1we ﻷ}H)=vQq +w]4&q.owwwJk}  dw{1ўZ(]7HoчMww{?o{iND$^78@JVL3Dq&t;킃>q_oQ{񵻻+6w| GyUVc"[{r{ E?f(ܽܶ+?\WMxQ K]Cx"}ߌBƼ9Akv[7OX1;|(M=-+bEn^Ek_EWY|c޹S{d3/{;mOMob;ۻfL0N q qEw~Cn :_u^'-V=>r+_opʗ|Qo w_~ 6_wUKeᅱlIu*Wkj |YQ}wk' }g\AK/w^o6yŖouj߿]Z%e"~KȫwҖb-%ׯu;#NTw߮e"W-jwFio1d䟷^n輄tkxMߤg}jN6o[*_N-uK&Sz]r'%MLMJ_2?}4骽j s'?y T_eb655gRa.~J%w)wI^t~7wbk6bꥥ-~-L,?\t0[O}~Ow&RׯKׯG^WH٢b+,]z2Nc)f(z ":>w+hd*Oԓ_K =W{uU^/I|cY1:꼅.[;׻F`U[JΗOS@⍩ _Rr5 _2A3߽{[b>nE35Q NBI4&|B_kV}n)rd0F5 ꈂ~0W[,W{&ֹ,ޫQu_{?ZoV!Ƙ3歵Ǿx]?k :/ϕj^wKگǻ ]{6tB%_{#%rοݙL{:?\w ޸UK r[Fcd|jٱEWU'!~aؐ(ݓtA?2ѽXW˟ {(/UZkT@ѰzESАvu@~CrnB'Q-}˱2"nts.>\ 1`ӾGKDgk7[w+bO}E~={2lu؄V]BDQHw=w~\"n2'Rƭvčҳϔ;q)e.!9XS"&q/"Aw޾A }ĄtY@rRoZ)6aI{s\cMѯQi?LIk| ^7CxEi?}CU O}oULB{m*7~(%ׂȠFq)~oO$?Ha,uh=E6y[\q.Ћ wom{$Ģɮm? =>!\>?{]V߻WMu;9u"[#~ii!Uza=jēn(eo -wݠ)쩒Rz>UH oU\ 'ww^Mo =%M:ys/1o~V %C.\]~2kBWʟ߿]wWUw߾wy[\&~IZ{/~_Ky;&~zWf/M_Oɓo'߿^ʻW"{"{~N}Вo{v -A'_/z+둽I9U.Z UOŞnܜ]Sj_C\UҪC}>'!7e~N־U hD3 o핎 ; Kr:IK޸Ͽ.Bw.B;}*'1~$|{3~~*D#rﷷ|~̻7&uò%;BmYL- 9xL_l_OסW/ΊK^ŭ{*\^Ma].H|j+ckb[ԯM5sʻOHl~R[c?;m?{|lڷG!4O&aV?lHX-X5\瞅6?^z<]Fc+w{LPioAPWO…ww{wK$[x;D]{d-/J˹'ȑ֋FcG["t='F`K'{o7bA7oNGw{ހ6<Bw{ﰚau_{=KkGwWwwwn{+.Hї ~k2>{ ?l {AWKRq~ʯBޞOz-_k 7~Zn伜;Е&qnߨ8]~05Ul.^ˢ;/ߥU듿r;*M{Kvb/>h3rq}Ng|KuK׻HK׹o#=ע+|uI(R&^mΐؽdB+Z70C"V=oe_|TE,w9Q_SNBu.O_0'DUI(GͨnjhnMt".y wuIK3/g\V*=;RW0RUG߽-ת"+r-o|0|4Mk{Fw'5s~R 'w\ֹ*ט!}\J\\ߣk(h)$_"]O[$ 42H_km0"FBM}my{־!W"Kzm,ɦ+W|o6t)m+ Jg_ ~ _*1W\u_zK+o˪dBց9W]n'F֫Fҽg)dg{$g/hZ)UО(L7g"/_G^UmvntoO+Hyo{ݟT뿶)W~ϏfDŽKkbM1J==Ec)_^_7t*[&ZI]N8Gc rޕW%JU6^s۾]"R?}ޞDžPyJ%EL gn*+V,bv-KWes¨"W|ݱJ)5tD5}'7*KG߱ijM־c^*\ұok%KRs7,[+/ v]٭^qC;VO'Gn\j~@CTծCߣ_g]DJD|ܗ3gU?)zU3'>v^9~g{]d:0 RfIW)EtWn+N=R_еNmZ]#~JRr]_Du~]IZ`~>ׯnԍR?y/K'yu\SQ=k_*:-WͪW1)5{6z_!oI6iVdUYooMRj6c_$zbdWźm=?hY{}5N}./mW-~,.sgO!ӽ{#!˟)7Ů_"sgZˢOmu2_wJ6 .!8/q? {Mss2!EӱZ׀q3 Ij7=9 Sw~98O߮$wUuAN "wwᅯ"Z[T?n߾C;+=bˏ^阝--x;cW9F-A3Ox akVo5g7Z_wI_ ߊ&6@}P%*$#.~s*` E\6렓}2vHwC]载UٻKU {[ }w~)w+?*\_XDQxTxVgo]c݂So#ǗUe=w\UO[_Ur.ln=׻_t-~DUU㪫@.a^4'~]FﻻJU&|R!l/nGAoݲ^^Yd)7|\>]߽ {vKѿܝBo]&)tW߭Fj^~Uͥw-5Z VTv_^rˈu >.b_Z9 k!vO]#)xLMCzbt~M-o^+F_mw|ߵ2騎$OK~O5}/wɿފNVy/]u\KH\N9&=dEs/+f#: P[#GK{Qn.oGfڽkzJڬbU?׽'R_g` }s OȤkB[ '6ayzB_خ!;OXQKȺUF~J]U$ \%tGoсORe]Vŗ%z A%[W}߻:^a$~VZzJt3^ QO]%__p)UuUZ֑"_}} W~;~/fmLcctp_]z*wWCUĭkF>uQuUVuKmDWݪ/]_I9KOЕ窪]}BX=d>wY'}eb)/a;_OfԜŕ\4=5Cȫ7Wu7ȝ{zA؅/zZu^EmZT \_D"GuiW_lmkqk.!L5\Qu:!+OwvkA|o Z~ט_b7[c뒧 ^ׯ|qVwH$lAWw(G%(~d Ugt%bU vPH%!V΍sQ3ɘyaYᄏN>qZ 6+N˺&5 UUjZym WHYq{6u֔fk Nߢw {m! ?w]߮ q"ʕ ~]"o!v.3Dj^]v'A#^h3+{)nm~`Eqb@T˾y/ٺ*׮KK7RoHA~wI toiwr &y;ŏ/7Z6Ŧq[2{.6`jMQ}>r\ڊ_K_#pw\ 7ru_|'I-.EHa+.EU/+.IWc|H֫Tk5Ia{Q&~Q~,M넖ߢBϾ&'[wV[^zj{oߗ0$߿z"z~E}h]}"s;#%$-m{_!}1ﬗYuDQUJW _ }qks'B.Bּ똽%DeQ HZW1w\ھUܚ$]!;zgyEZ6w~K?.OSеw{V@ߓʟorww"_kywz]~Nɿ-&UAWR<-)5TwnTjBn#=]^o|r߻~޹wM+|'eJ_*өH_iK|ƷHK=$]r/Qqu+5Me'K'o㝹_-.\WKOD~/]TƲ!Z/ꟄJB^^} gްy1^RŽMI7 /!</ǍOOq}+ֽybꪵFF_(aEu~XID'orwwEwwޯB+ϗW.E'UUUUUj9$ y3Uw<_5[ybוv%߿P/{&Z?@UUZ5c k8sVi/ⱳ_+UU]oNR71}Mz._vScs0Rwk8}?^:z+:մ$FU ~M-lm{*_hOK/;U؍/{:սX#! ꫷ ͛-l !S'TE@~b;kJBz^+E*~C]D_g9O.W}z_2Iv/U\>K%[lܓH#}BjMOoB%Uo^jy2N G>tN>ˣ%nK7'7JI(M޹']މMF]n[RkzB-q-.ҭVrHBs?#mL߯tRv|wvJ>goҗSZ)~#Nտ"!o#xUk$%ER:9AЩ#/}@}UQWF7U"{߻N+{k_m k^kFco{fgfկ:W$y-_*&t/֟#UoԛWIw눝/^*!k\6̲bruBWʷrdQ"Njӿ7_߯օmꖕpPɩUZ#?nC_:@ͭȵSXy4a`;]{;<ҨFcӿ~CQ}oH>W9oo2kk։I}H(a1jzG{ߡm)}Rסo_ItjE|$.u|JZדG\A ->.^q+ z+x_z$߭vC7%_з-zw|_gUͦ7UEÉ|M)h:)};WIuW\YB-?Bnhu^,߄IڥEnFrMw[ ItWb잉i{{WG$^*#}w﷩h$ZtwM]_dfs;/Uь_o#xEoEߤb6ZH){%v'E-^1V_bܜ)u1ey3! nmvbFd d9S¨JlNPD޵k{L 5Z J{~qʛ 'J-/tݒ_o\ s0~7~UJ#_NJ֫!Ae?Gߗ)W׻ _ȐWr:=Deu ^,{H~)ܜv־Q:3}O!WekbkwJ0.K k|y^me?0rkWd!$7Wv{bҮjozUNiA'W>(o Uw'kޯWN嗡*KLLߩe.v% Z}z7eE^ߪo2Ie[ߩ9w\Qi͍UD]irs>ݭ*ԝ!oZ]c0lwvNMk,)ԞZߧɒDԭ*U+[Զ_ ;ʇT]$ƿjKߓIܔ5B;. Wr_wjkھ-e}$5y/~I-,~?ߺӗ\.YtMRʉkUoo/m|Z[zRu>oE}`Ez[Ee*W_y .y?"7O"{Nx]//co:Oin,F~$Tm/oE!@OvnWq[_J]VeZZֽsɴ$$_(JZN;aJ1o_^orFS{}>յv^41ZbT^־w6/ԛqq^?rw'ʵD#M9KpwIBo]?;]R0_ak\;] W}qt__eZ U^Nb.uTgE\)9KGEtyZ?ֻBH^.E"%/d*}חu^~bQ[ӽ({SjIx Q)$](ؚǖҢ PΤU&-{^gU6W/ɬt$~bn\;KkJmD/բk5ϯNѵlvzH^Dz#腰Uy>A/d #?w=tߨU!ˢ_(GeҭAYk]RNyIba}/8w>_w/_J*f&^ !v6ԏZ:3%Λ+{1w]uܪw]#2]Ya'waCkW\c;'z.ٕwIr\,ժs k\Z~rjbw]T"U΃~65[:\Jﯯ@_̻Kn[NЪa}m?^9=/ꄫr}wv!]>\[-kB^&an`A|ZⶾfbQCpDEts_oUBHiyo=S}ϹVn'BbB(zƾA{;tQW~H>E_8\f AkcsUAQ?I{[бbTVwv]{b(7w~isc™'w;j]5}ek - qOJ}M*~~Kew"^ A^Ūbo\>+XKߣ.R uo?RIG~qMԻj#D^F'W*KW zy]]*o鯲'3NB'&UKKBkxU)_j7'WfG]^OUٻWb]|%W}}ORJO'Ssj+ZO'Q~]?0b׮k%U))K>߯UJ Q6OrlzMKFrW޾e'} eKrEi &?\6QblZw1,ҵ9.ה &7l\Do_[_JOF^7V!DO^_P}j@׀#_U  _^'uzom" }/ͮ47jɚZlSQ߿a*ޏjk__YwҰ*̆RZ?K_iUUqomzZ𧮻zҷQ:}&zsB*⛥ ^z"kU3(UU֫Z%{WS.QOp}UW _^=:U]PO|xU O\+z^5תUT>UH-l,gIT^_+sj#nXz'EjuO0.LFE?1C/q<Ϥr>!NQwˢڋFW.K֤Q:!IjNSb^MNעkJU(^MymB_jw \.]i)^Jڮ;W"2=բ RҬ|Au|K'7A6o{u C쀶'[F|؏Vk_EA!޿6]ﮮ\}]Z"ZMu1(/;mw-wgs~uuNHޗ"p|&]&KO3rk߻߰a;\[C׸+վyySn]]3myd!7ےR]W 1^E|{_k]2])wb7]k̓zN$9WZԿjBOzbkY:|zީۉ})7E^B)?Jz4(oelr =ʖ?e|lZ323 V7zkB>|;\brf!|B\`yz}ݮe_ۗ } jЁ=բ~@$O}J%nn~8"隋hAW 8KFO׽ȫD Y ɻNU.(~gi*~XK%{Eq˭z4_/x~O]/߹o OvZMYӎN()_+ړkzo?KvKNuɿm-dyqܣS%N;ݸaUč}kׯ^ЁH?*Dk>s%tkڿW}zd0_T%|z%깽V7%\+v\f|$F]k^}j\'ڪRVbw'gEܜRj'R/=zSjum UȻY$׫Ԛa/CWz%j׫[MIKԗ֪fo[mݪIY=+xK|[\4KgO}`юf]M_V~`UH k렀*UZ׭0bʪUus5^߲Y~WMUnD_>V]U.ImZ𕯯ͽgR]kU%rrw_EUB3Z 7/|JG!:KWۮ^/ZOuwKv*KnWivE_/ZB~yJ^B\߮E}q-^+[HUۮUO!_SjRo~2??-RbE|'趋W,&5nRz">r=~muǓK֗Kޫ&/~ߩN̻DL"/ܶA|}߭Gqd*9_!߮bv bCm4/Rj} Uk[%jNVWo_^oj]_kegiuS34ֲO{Fr5}dUkVo%ޥ4_cٳwAO]wֽ }_'=RI׿KȊ2mx/kamWb7O_:A} FvF_o[7^ۓzӯuQm/Z"_%W[6:'MH qo_T 9Um /ܫC3˯苮ȭRUo(0{٥1Ls+{$7˾߿}W|uI1'%!త}m_HBBݟKъ{TNwӿw~Jf~ԔwzB8%'fW}z1oe2}Uqᅨ_ۣ_>gV_ݤeױᄒVO\iVrJoUC/

mzq콙Ziʟ-oF +BI~K~#7gW=oU|bW/~!?KAV *Uĉr^WW֫W-}}{Я4i| -O%|>]M{"~f4Ҷ͢ .%bߕ|˿foWZm2eoW*,kUʼns-^;ƒGa:!i~C_\#^Ot"e> ޭVE[_:}z"mrS +uEoUM S;ͅfoK]삞]/&+iW NMTMZ'!tqm$['yE&PZʊuzU}֊}Z"?~}}'{z VCy2Y/RWn~jro\?s+%A˩#<|/M|]x K]wm5i ^7MUYNU/ׯ^Jt^Uy=z}BPz&EXyO}߽JWvMUWB?TUf''o/:GWo&W]wIW[5#y71lcW闉IDp]o|i|sgtgkW'c.(F0N5ְ[":«_Uś~qo/3|[l/7C}VnM,H:ˏ𐮻^Ow-NlpHey]!L/w~H5Y$UwG^'1z |N 쪪mȵŴf'ﮙoEw|ag] Tg^ -b"ZUU:_]UZ%uTl~^Oe')|[d w)TGkJڽW"{!_kamzM&Wc_R/ *ﬢ<֥UEqUkU0(ޯ]{%ҭg0kIr:؇C-z|~adטQ국_\|0vGXJ%jU[U^|'Wإ3ky?Z˿oڟoI _ tNk|KR\(z~ w߿oK\M&.A1:־I&2I/j|g5ޞ e".}7kE-{vio@wBw~r,:goQwwA> ]< TWx[Qߊw2M{Wjwb;Y%j DVS ?kV^UNGeҭ_R̟&޻}3 &RdDpJU/\_nqZ*.7^AǾk J!__o_6'/Z^~qz;Zvev(_-; _`/Ciz_L1Ǽ^-R{fd?O6z^f>z| Uߔ'ׯEoalJ׭V1xRq(_ NWתz6Jסzj3&+xUp~K.R_{)^a =6JF_11篣%k[M?긡=]ٶ[&ZZQ?pu[hh}[VI|t%1[|F{ߺj E+=UˆZ"}z$˸geނgI>ro7p?[D^e, _/E|C5fJ'F&.Ȭ"-ծ+y{kUϿeN$r$Ne8vgޯ]+' 乻'~n>w+._U^%~ ߸|!'ow~߯w'+ۻ'}R꿑Mǽ&NN^Uni)*Լ{y^jZ)9}qNu̟ݭ-^: /^D=weȟUj]MUQ%גm Iu&y-̻RZf]o?*rj/ժ |VBrKڮTJ We~䪑?&.KM/\W"jKKW7]Z+\˯>h5k7+؟OFy1>#NOœv7T@|mv;TAӳ\7 K퇪L DWf8At1tŖѺ7&ZقWoгdGkc!P/wQCrW`Eja!]z@N_A#[~Bj_V ֿNkکyůo-~ }D1U)WsU躯RA 5{ ;bY~Ƚ{7{Rp@kMA.ߌ}|GE/|꾵ʼnR]>M/J]^FY[D4R\CKVUh.y}߭M=c7/2̫􈯲\&\o6[2z"67SХ?0y #rUr{{YMnɮZ!ozzRhUa R0IYw/]k9^rsO! ѻT5vů5в.޾ODLo5'rz%r$ou>_zgW篷=K{Cߢs*E:0ޝޭ^ yP{>nWkɲž7W=\JpwxhaV?TT޷n\zׯWsd'*xMy[z0\%ɽwi%mvNϲzjd'fe1tuݮײK4F/}z ~ώj~Ro\D#_kܖ?N&0=6+`W=^v̗M +7T?ЕXH_ܙ UeuG{IG7mo-#E%]\BJ|Е-W5U]V)#@OjjICvoѵ߻%ʻ̻˭v} Sh7iWַm$T u{bۢoQv~}˯HB׆/'MM?U9L^uҮ#}޿'}Nkn]|#񡄗޳%U$-QEeg =7U_K2};/_ybX$#O1VSߤ,ܿ;]}Q;n޽? =K\Y)Mv?Tn&[Dg1G !T/^   G׎꺡p`hAkZ32Z'UU^ /ٝPp;^Mui~EvmU+jNϻ_}'F8⼦)cݯUtrY>z+a-w|..wO{uo{!K.kʯj2w^~eoaVy*{~)o+VV7?˾'+Wf}%n;ClKޥ{[W[!j]J~Swy9_rr{U;IE{*߷r/wŧ[Yrk^sn.ne[&_.r[!W(&WߨB)7ev_wĻ͐Rߒ7-_v*x/$wӓFRVTI3U픻3e]%-vsnzWO?}^\ZLԯ㊺kwU֫u-D'_o=vG蚠WWwߞz\Y%s{G>B']#͚h 1~bJ-~mOִީ!s!$Լѻ' Wvn+Zo' Wy/ɝL5&w_f=[w)/ܶߐB*bkZI:Zoo'mWvox;5|8D_G"4Mzw'7|".wwZ脠W5f{V&|[_H˲?Rjyu~GwJе+WY7 !Uw[ߥ2.)nX_䐷?@ UEĵd|jָDUyo;5-_vF[ZҪ޸IW^\Av8|U~U1/jb)tzmpVF/toy֬zKY ޤ_Qt'5EVU+吗k|EJMwEp}yMz0^?O3ޞ%7%~UA%$]ֿ[߽Z.'3~ZR^ĈﲿTRR.oړ֬?MuשyK^cjs.K^/||\i˨>׫Zj1kYZ޾"}_UkԖc:{Ge55M}F_ EK\[EicJ6ءdݝ?OR/}1KkWZ-y~xtJ_"Wi~[ԟD_MC$ G!X/Kl`<QF+)t^뿿F_|DwB];_G|ם'~A0B}M_%z)7~ ;y4@\K˽w}~)_{w^Eoش|6MMEwV|{wwowy@wnM˻}D!?U{/OKF֓%#n]޴[}V_}+ԼKʯKe. JM"U.Mw~%u_RNroO#'/?2%\oY_._rHs^'g|$/j9 -%=\J2^ܖ߻Kr_~__}ZFO}Vȟ3~sy9ܟ"M|+M-t#w'wO?{WsYwn^a''ki)myW.Wxޕ)KU^$oW|I}~vG׵~I5${ ĹLƌ4*z'e]*'_!fAw}wYt]d QЖD]*܎+iX5Y_DoU{դSu%uv^"%?z*׽{]]?UGw-|fS}_#'~V]W oYŪ4{ZWmUk]kߐSk>r-U&%-F˾p4yyU믱 "as2Ѡ4ܯ\MA%[Om`}^;}uHfo@~s.&qA%WXroЂ_ֿwwRG) q;ּ}AJoZ_c:/Z|yv*!; ^/KrS7!eA{ʿa|]O^|CR?+xUqb_] -U? OjIOl70(G~W؎ҬϾ9=7jɯWr=2Qdߗ+g|70Z+ܥnUރݯ&MthvB;OWo.)F-*"Mz3טۤēEҽ|}/k$˳EO^JZ'kc{)R?s'U+/x?yO~%W}n?\E&j&!]%|'UIRִWk:C!m^Qy;}_쯷LBr I,B^ߙ?ۮI}2\Ső{/Uv`{68~| %{["{׋0ħxpa~iQ7Jgy\I~$z^/']-(fa|Jۈ*Hg7^ ')yF߿wwwc۝Ƿ gH?Wܻ {_wM>Rr ޸ۿ㏻V O1V+{V+qj{{)g/srKͻ{Et[}Kbw.{*z}܂_\Z^rKw)[-oI^ MiZ\Q~RM~W3 -.{Io-/]wemw57r}6'D_)W]sdrWoo{d}rI)4};)/1w])~{6EWe?ؒ߾2^zZ}n]/'){ {>rW[vN^}l~$_J˽K ]UWnB;|W;|zK'uw>W~K~WYܼQPb]UWA5^UK-k=vv})}?]kZׯbTUlz"R8H֮\|yUK֫פ2B֪Z7;& IW؎ѿ,%(F~n{Ϋ׿uʫ#|^bwN} )o"BS}w_!Avĸ;E≭{r3ok'{^&{S00n+_$[kTWf+O!lׯ2EIu_e4:w!Gnyq]]9nM w˼${ {xאUxXj79WH.pGUU`1 1oaIZڪH%ŚϢ:5Txu Z殪uʈ!ɱ }=?cl+uy5RrW!WUE">ZOAvJ-+')k$WWDIs9)+1W!V%і4^jWNNEypZ.-~#MRBI}m|µԘBfg˹5z5[}K*G&xKRBIWO!o$- u'A}y=ɸ^ ڬgX,[fժ&Ey~a=}ש/|A;6/r+ȷcߵ-;yđS&K}-.{ϻ.됗xOOnֿ2]o{wNdHߨKk6$ud)h/#Zȹ?+Z:߭I"[MZV^Uj]UkRҥג2~vs_7%Rvf{=-v?hOE~L-'Ů]֣Kա%}^kSZ+ .n7mT-u^&Z%%};UiZ/oЅ|^ܜھfש{ͯZzn)L딻]uZξbeͧ6xOjRg}-?}~?~"rdfo*.^]qdJ+~-j ?b{Lܣ;wc3 _T}_sc_J_bN^B#}Z]!_Tŕ5D*UÚu_~yoQiϴW(Gv7Ͽ/M>)iqABvk&֯+[w~Bo{\"Ij#\+ޫ(ĉ&WPW+0owm\T!/+<Ur: -t~v(=?_}bϞg}p~]y">IzoCZ?ys֪¶NUZ}~}/}z[ЧΗrqb)"&v khg`+Kĭ/wK;=rK._UBϿb^RM|*~*FgAf/7/'6ϣ^M Zu*[RI% nhUKb7TS)D Gޔ9TT~ͥhHޗ5\y/3ȥI/'1YС;Wkї[Z޵kj|BiFrM v_O}+VC:Wkzϙ/SUךVאl{w%wk?kZrWK\KhO~gv%S|yu;깟_5. |;oW1V7ľݯ+۾,UMmiߏZ\{=v57is׸uye+U,c~Q?-u@XV2甛HƁA!d/Ax.A7{bq__'آjq<ߘĚ_a{ O~ C~ ~%.JXzv(gw]O}ip.pk%UUՅ6q^ D޾X% M[[To}t**P_Uȝ$W3=V7www{ #jU^gvNrOw߹L﻽pV+ww{G7q[l/{k[U{DVl@?~;ҩ6n\OgO"+[)R}? v|i%wFWr˄n&_I*꧳|n;'.ue.IM-9_swtE7nWY{Z:+}3ߖUKʨF_ewu^vDٟ-~o!U>u%#߮RFU~[B)(u?o\o'!&.Y3ߙeO1߮><+'({ޮNYJL|щOթ }q;\-z"ojQ5= j%yL"~NG%eιV]]sq5U_ ZW-w3OO1:_IW!|L񝵺]Wߞ u^bK~(nuj_^cogߞDG~Y%j[󓑑_rVH"Fnm/nS~- +ڻev#+c?6ZFV<(  [|׽lt0[>ʂ}zXzFI~'MZkڻ8cߓW]y_|\$윾\=rME!=)(/;p[s/6y]_7zz [#P.XWvO`Zپ{o|AQL<"Gׯ}w_jvʻWoCԏ"5:xU/i7o<%nk3KŎxӷwފBJ0N>ٷ{EG~?hB9Q}p,u4(V\_(ϛ;%S\$[T[kЇN%ZgZAֶ_ Dʧ>NՂYW]u%k/EM|޸Lz1Wƪ;< 8ֹ͙un lCk/ZƓIÜ^J>_[wD~5񟏡*]*ǶC/e赯UbQ̷o@Fɿ#%W螗y? *{7#h\`S{[F«}*#OuLVny($ɿ[!+}ZԚVBZIؗ}Fs\7ytaVZ=.n~L,?o}/i3;_kKMwA7?7'y'3!/~_N|\7߮FonI|ں/!_b?ʻUK%כ|rs+g$Yy;OiokK]~!8%:'[^UU'rs.µy>,u&zś kkH=Z:>[JoZw}kxU Jc@[_j\UUֵ _')r7ٷf!R=[Z]UW\ZhSM~!ⷯ}˾]pHD?ģ]R~]_-]ZQ@+\PC'}w*uU[׽'js|rBy}vWjWBDlϐ# zMOw׍Px@wqd[DN7߹ {M g Wʯ{~Iw#O0+MZjZ-fgH{[ĉs>VJj붗NB^y.}eBQ2w&r|$׎5OF| ߽qdcݩym"Y?p Ci%Vۄ2IWq%]}UuЇӒ/}7o~̻]| kkML]?޸H{j Qڧaב5R%VWoU_b ]WOpOyuJғtbbkAzAHHX~9^xEj}ժ֛JM-| X)W5}2(7+/O_ׯ]IV->Z4x*;[~nKFʵ$9Y˓kWSd9fO*%Zk7D5Z%ZRRmn ,+mkP ±\^گֿ_#U|S_h&}Dv*y5z_꯺W˿fwH?+%?ϗ^nѽ{K[ȑrtw!i~k+Z /{3tʻ$R?0G( +~o|٦L>j&צfw{zBO{2_,{侻kUwbM?vuy+kVc߿K=o/;6D[}TyOi+D59oRR!SXPžNb'w6w~շ}\A❟|AɔliěO*VGwϒnDMAz].'!{W*Z]wzk+J/ת[' wͪz|Oe33ujNO}}%ַׯ]'mc>9oר ߲O?9bMZ!_{UߒzbyvZf^L/c}rY}73}{E6|Į%M_zNƘy˒T^H߅ry'%oDQv&{MuA͙)z]unڡfB{@;!W:J1/}wȯUD_ߑ{\@k_F} ֿk >;ߖZs/G/Zb{=m% OO^EA&"_1.Iޭ1eKqZfkګ h%ʹ֬0aֿ.OOt=V-,I7H᳜.IDwww+ƿb ]z#{/{'/ Nϳ_{ٿV﹆_{[TCn굢ibo|{*]DM\%"ow}kJK\5.o'.ezmyWwKF~7"|U,WS7+~N-tFWB{~Np\MRs=W/z؍$O|ȟܸ˵W|ԓr{]Ozʚ k2]Dowۻˢi$֕㹞ٟͫs^'n[*S$Zw}sgJ]^Lv~GkW} /ࡪwbEYWD~U/AzW95W^MZ¹?=1,'E' =ca| A'~]}{M3:6V?}K}'%1{zS__c_wk}(pm{տv5ku=Kw7~ݒ?S"fW48-O}WG!~&.Ԛ{ bt/X<]hB6|iD#Vvg+]*6";PEd׷&N!U{| /B쪋D^^C}Y?wwd)_7hVM:ԟaލ$Ou+{]W U}/oQbtb7_b/gW5Q@PEc&bu]CUJ >{B^0kzF_Yyu{^i )Ws,rס#Zm򿺔CB?!+FLEnAo|]g36\WZ&ID%wP>͟e!F󿗗)ϛU>xAM{H/5]k ɾ/uYY'(_'kֻ z [v6_Uu,$Pg=Z!]!_ A7ek]~oau-p>b ;$}EkIT/FGswL4r["%dMY&snAVԖ]N_|)>^|ֹm.~\|&ܿE=/DwCV^ȬO^V!wJϿULWb/]k~'#gֈ] KRrzU!=_Vײ_'~U'{ի^O!w%d*waݩouI߭jMzSBR~Mgޥ'Ժv_:V%߫^I5n͗=.$^)w%j]k{c/Od#nϓ7+VV_ծd[z3'ĭׯ_R˾e|ۭwk.&AE%>WKgݥ̻j.w^\ד굇7b˥614q*zIߪu2l\3uڮc}zXTtH΁!t/ o}/}V_q18PPb@7&]"}tH.hKvAfڹ05.|)t]{wHN~h>}/[|_O;UV꫋^)4 {wj @t/~zW};d5Wz/+#+2B|GoS&~.jzW}OwSw֕|w}xe￳@n[j .z^R?=>N˯骻Ŀ/)/{^WٮG~1/l~O#d%IȷW1ŷ-=_Rk5;&wyu]dK_E-zǚ_v}rQ\A?Cf#_)|­] %rцd4Җ!mY}>*q,?z Yih)^xLZP=_櫪P<%/U}wdU=/_k\Eo;З5[n+Ik!t`WY_.=k/ +Ze)Ŀ'yd?]\{>Nl!__i/ujj׶Jֈ٘e/o Y&uyW&RW@qX{%qFg}vU$NϷ^$us+tg&Kׯ'j!\\.I!W%ߕsJv'MvU|ԅw~AWݩ?q/o.]+}ȟk@F+~W*NIu/0~ci|%$%ZkTD~rzKoԜ|WZz~f<&nkz_ 7ʤIܶעw]^^&gڮ~_eOy6SY8o]o_ 6֦߲z-^nE$Y{t]^R]7zrRu\K_)*ά_W{[5l6'h-zUȗ\(BƮiDs>߲y<ՒNB_E},< .A3q~lטMjHӢO$,:tŒ=JzҴOTLy/o n_su'ya$?WꞾ,; c| u5'F#IuKCu w I jj %sd1yxK+67WlNWfkD0z-O0㼠.qa9JMLUg=;/Hx'*<37 iM(4%;%XGF0o`bpv9owI ~6) M' 8[qEp1Yv,Nk Ѝ{mצ3_:=62=~V+zy~/̀Ur \PB6Pyht#!Kg.Bo~ JA{;O85ޓɑ昞[Cpz֤Ce l6iz}B; kU)H|O6w~_`5mMIPkYf=(F\=hy%;6xzova8]ت&rÛF#}ݿE23x:ӔTHU(7W|*(EĻ3@CpdavC6c$?mr{=ZSAmE;dX*Q@ʉn/걟GƒEsX |fB 2@LPc8^ܴc̑Ƚ!!m~,Z7?鎕sxM̹z}:Tsf_:ӻ-!KcS+ ubeNUw&-ߒ4]׿E@k1r5[z8H 4k4 |_.<(ၲkЁG%Ϣ"ȆH2Q|]Jf#15Y"hl&z58?t7 , lۨD-7o-͙xamwNF2!s]M ADt!k\:3RdaqC[#2_$Hy_:Hzu -D:Ewcݍ͊' h@*4, 7Q򳗏]"N8wÊj̆X@3mwьT} 1h{Ϫ֬=6 vجKz]@!gY4ʤ7sNЈ-j_S>ǖG=6nOȤEkyf/͠#Dί݄#s70uf:Dng>j_9 \+A})YQ]PR98 / prSYl^Xߠtw;([s ڬ 2\u\XвG˙[%Ś+{^L~Gʗ߷_(O#1cQ+uJj/;@C KLbb-{LI zTg>]iW4G5뷙9`l(\j U? hjn3ZvVRo>?e<;jTJZ/Wf +TЫv/V֬f]Ɋ4!SDڕPh& /?峈ux33V?F98"ZgBR$w.,dcӇJB~yXkXO.Q/y=Gfy8ͧlK0R-WbnsAO{<ݪJlqT裏Ϩmzas_OBw s I+Xm3=̍/UzwU^j~1=mQїP*0ceSHM|#@M OZلp y mM9qM6{°F{\֛z[XrGxT-2t3T͠6D]ה7H]PLdv!CZw>]\PթCL?^6.t4WZ #6iXC roWokM84_Mv^ L'{-=bX6oq1曎~_j͚M)6,/Œ\2S S`E?>=? E2qmh0ږI/&dz$*&s|(?4)qY:N JL3 >}LhHg'>s z CO K[K o=9$ZrY' V*)-h˝TFYq*ڏJ8E@ACXc[͓H=8}#\{Q+V~Z#g~µtlzKݝu{a|_6g~ vQVImB}NjFbkZ $B[L_7#cC bnTO)OOm3¯#% #o]q9OMT>>+vUowf_>Zl91U/z!5>tq-ge,ǘQ6d05nIX5jQ]mo,h8~ORq}ꤢ#Gn>L.zpx []?E1"p=H ,rH%.a) 隝Bծni$Ss,nqW1U]Ev(LM8mi85nlu~A7e7mFZߊDLc=*+zNϣ-,D;&UN!_f.Uc*dsu;fX߯85JԚHϕr]jr[{puQ3JRPѦUS$5I[LuXkMҩKm;a3WV(GRLkQ ZJr|o,5TȐt:+t1D-WS_Mkλ,7P6cة{֛rPeaWCa\nD֪:dRVG[[MB mͶ7{SEJU洈Z:4HF4Wpqa6nEtFPjb2YTk1z|(*i3a6^"iϴf+.x\7*a@m=mIF(..bޯvt}uΚΑmT~y1铆cnIĎ'O͟}:_b)SWM3ǃL7j2z .0Υ]S$#3Sc+껛?KWVVrQײG_#QQOzWڬwZkADe[OIl5*zkji5k5i(/%1lhUIl QU7+J?7x*a/4T[<7oOiK\)>7E1ν]<,ME3j"^T&_"\KiU Yt_QJƫLuѣH bͪrQ&vlryQ4c^a)Fif "<%(zČ?{$uOWƪ3/џRQV^u槒Kw$o7{P J1FߊMMiԝ}@b)w"ŻpfcFLMw.ߺO̭棣WΡj\>`HӵۥOuVXBͧN߯5}5]m[$ ^+J9꣇FZǬl&D(*QKbVf*E1;ݕ{2irk#Mlڐ~M5l~wN?U}Lf( c{i Rj1s֓4,F^;<#7"tm6n!}e!9Sڝ!^1Dvk0WO>3W+-fD~6\]j&UڧdO0# h|ZZi*TsX.nkg+p_gCE=#@*Kit.|zX&$S]G1[e_L%YU<uW~g;'ު.Min.yR+4p;&6G!;[MlW2bCMP*BCu4Ϗ6[UwS{H9cZǖ*^ړ"9>(8*óE겾Xģ$iGr2މFM@?wVֺ#VrƤ !CƁޑRuKj8h*O."@ m1SzrHZM^^˴Iiw͌Y4xEa|w2c}KNIܨ6n0"n Jr2ZO藈'톧Voȳ57P؟IB6ժvߦ{;gR<+7)iԖ照ZG)cLd'{KejhJפQ FXFfRRFIY;I7aC%.*p.Trh]̞/ϻĈqt~MYjbޘ>VƿMI+{.r]~)7H >tMim9o0s_WJQYkL&Ü߶JZ+T-&}-uٷyA3!dm٠dJbu3o|Kz{k<ԡƉKP,SCU^vUôvjRѓ8HD G S}8⺪7]\c 5>iBgrVx{i69kƗs[PA*\ܕ~_Y۰qWm$ } bI#U7*V$V'Z?l O]a<8DoE&|')5nh7Kw!Ee4O9]rzZ>EnT¼.[9nuxAqSF"hKXѧjVBdi$?d(g!WҒS$sSeKJۤxgn4N1j7V%}߳ZQg f< Su HG{Y">FHjՖfVmvvx?u/vUo#0Ό.\R2rs{4z?S\ZFtOSQ,{.Y\ؗ:5׊[Z~ג449!ZHd<Өw Ԝ.WW BЭұ릩NˬtE.WkЅ5ӖziL *nփO#E+2ק4SUÅֹ3,.\ԇ}\]LЭ~2/Lvo3#1o6d/h!A'-=mtۄ%|5tɶG gW{uGC5oO_z:KUk('Vvh  qnioWXPIm/}W2S5핻S]d{ʣ5ϭM6ӛ3VL\WSYSj$]_̺,QGi'wƵ^WMZ85PQf(JwQ[+N֊ CErl[Jqj:EABlnʩbSB6$+GHcr厌[2[IA_W2N"'upYQviޫJd=*^M`YڷNo7+1Qt"*ͭ]q鹍-"Ad Lw2 XykRV7϶"g !)"{^lܔQkh/q, yJq(iQI6hִSJČܤSIkdnS[Q{_GYvG`/AxB@KAm#鶟!]R]X ~!gXF&3KD*kOZ+歶PmCۊe?*w4+SfѪ&"yF5Y"'JIM 21 XafVȑgk$IFu{C;-\S%7Jݜ cMק_0mL Y YagBex@ ZvV믈S/g3z+kyͫoţnD&i0Htܴp4祫# d66v̓*^zII,i5*f4+}Яmmy- N[O +r"ԬkF4Y̼pjfehZN{fhԯ%ċ{CQ*","dƱSЪBQYΙB%ƲE@3'#IwӿUACB| Ss_L8g KJQ/C"̻{kUmWI^sH!8/α!էUNJ"N*Q}͘=,zv6&EKJ+‚dbl*vŻagz8&v}8{i>دE<$1?/]lƱ,}w[v微' [Mx&=X}b1px^uT-kLw-!~;6}qm$+L4}4‹M7lJzDABMu-^oǔDdl7rR0|~TxEHR8_1UMnz\,]\5d>xN#!,(i1ƗV{(YKC9M6RH2qM(UH}țﭕCq/N W mՏPX:+Lal9,s}Q}^w6ݨ7{/461qW-_viiGu4)E,xTT0V9!ڒ "|wn Y?-9=М ?K_C-:TJ%"A`,= B_ϝ4T^qO7Hc`J\!}'{>ޙ?aSnc_z"۸a0'O)?ǍP*"?+8Um8C[m1mqGR|> z!I\dAl LM0g|NE{c,_+!aH—*5'~e3i5[h?b!P#jkFe0KeH/F.G= 5܇9Ҟ7a_7DkHM\a6ٟ0T`En jܪ?~uJu+j¬~' =+Umx󫦡 d.uV駓LUZw]߬_tiHm&7K4L#9yUyB^椞#]a5y>\UCkŦ]qm:\j_="Yq`%Ssx1]Q|hsSws)4=?0ם"u4(X7'MU3~Y 9xxG8W *j^c>TN`rߧ[ rwPc=0LTh>u'dJk- lls1i]o4Nl<' $N)u1X_~*%IV"d*B^s߃dF(w^wI#dç@p֒-K}ӽ\IIV2Slyi;*l'o3"˧!f9:a r`_}Qpr@w=7bS8Y8fSv*9{ϔ(2pNp$O>0~aS:V4M+nfce@ݺ&˺$MkyOn`F&"F}o2wY8|1DX `lLbI7i9lbN+t(hN6G69-WuCvKALIm3R\eCu b[|Tx`FB.ꕟb2TL4+u5 ^n B35G?iXڄ$eK64[T& <|Ui QHV$V$%YJo~X9`J~FyDr]9de_c(~N ]L|}u@ESRcYM% /_e!p PvIl1۾*̙m0_b !lfDbpXz;VW!=qJYʻw$le1Rl II@2',V;%x@.CkI[W !.ܝz;,0!>ݑHѕe'.Ore/" <Յ76wܥm3!eGlhn1zyWW w `=1YG g:C"v;[~֒ eY"Ii6Ze2/UNs, F(s7tfw45,$ Jݜ]|Ixi*t>Zk~;WN=f$\XcrJ'8Gu^IⱩl*w!Gqfhuϗ-2Įnpsn& =H/ %B#N_>kH &b' ?${hrYm,PX^b.M.9r.>7g8@@&[ԑRFM 'ej{Ll73\Rh8G%S0 =5TsۘcQ.n]-{{\ۓYSA V%_pA=+S7G:Hԕbpsj-9 |֙.m/Xߖj'ݟiK#!?UKC[j|W Ԓkjhm?, ԻM^j WHNi韉39H"9v0i3 5H֞E~[6mkҏ@Rz/1-VzhdVlrYFu6g(Dq]>v!D65Kz\/yF4N5Kt7 dn@\OgB_y]%!sS/xMIPtr!T{61' gR)/VdHG&|]nSVntk.N6э\ۖ\h(w_J5g6YQlۣ5=@[!,e^CO8]A~2y,  c8Ȏ;2lFnɎ*䑇ҵ:<݋(_ٳ5LEbT_y[A^x^߈A~ȊD^5ۚAcbz &qa4#)@;T6ږP5|n 4U޽ennhjBj+1PIVp?7-"SXtZ_$&sZzas[OHFxm薺DGЛhZU4sWB[ϝ]־wˉ ƿۀ]T_QqW7+:~qwZNi5G:itEoJT6V-`Ǝ=H4`_/w0"hgqF6L{黌 {:QQ+L!6z91\%=7_, UJB)QnM(<8QG1?JEA{I "94 >7"OUsݲ{L&.H/Ǧ=M_*ڧHEQc%mO[x,꿉R 3Z;;R9tO7 bG `oF@3F֬Z!ZJCVo9skӈɰULUz[cˮO2Mp42"sGѶwy\db5d?F(?T C5?Udk^?_~sqXP@1UZAFt̑CUu=~/E#+"z:KM.B'2~"ua%~Eqk}?Ov5С#vZ[VBD Qo*(rʙ34 PHn0϶Zk/k,ei0h&i1Rd]M g|BaZ ?ת&}1hdi r h[{?Ar^ňR'~bP.pJ+B}70K7X :" $#`K0heYPMV[MYzRbvb&rc.ވ3oV=(eɨ-1EkZ8]#RzzƝw^Hd^6J\O҄%CW2{#nVy4qW#@CwNZQ㋼g=W릆%}'Eyp IT|1SWrVlbIӗc ަ"UzZU]EWFa,$/ҫ , gbfXO=4֢GY5qjo2+tyqJ紐;`_8XFzZh7rK/U:Fu5y&ݐLl NA2pwԌKk[y +h"/BX8;z[P˗SgPG!6Φ{1ʫI~TX y{6:<5SsS7&tn;bdOHVҨx aB;;F֧h&#{)+UR罅,q{4h4Bu]crcBř*@kVHA',c, NwoRTc<뮟Snj }Zb ZV_9uYxbR+]`\~Z Pԃ:^֭D4iZg4\$k3]HL{m^bf?a|ȫx_!}*4T1l'b'q)/k~*"~iw^"ɥԤx;QP*bSB/c8dr#ջs͓J!D; ;ǤϽI˵]0@CV ZD鞊(*~c86xHj!A? 4ݔ1Bw:qm4˿+x k6h=̓LIC5vvF. H `fp'nVZGWݙ6T{\{A?`o jlj߯7vLrR]wwI-i6f>ZxjuCC6h\{w*K]"U O(C\ULP&E%S S9. DjhTypol! :ElӮL}4})|EowoT;b|ގ$-; ź'ռ+##K %&y[[YiOcZ8՞&djfNZA$m5v m?r@!a./EFْs$hmJ{٢d _o`,[I"y9dћ9I~K[{y-4دOk6}; C/R׽bVqXY+of0Еe6Fy K_*H/pG:Vj>t.W$^_oqdh/\r9 膕X9<!{n((<@rD6PDcG/"#[H"`fo#. ߚpkUgF#+8f7Hr[GHiwPjc2In2p%YНT,iB\Omdڏk*{eK[hsС5< f2%&b2X75 Ljb#\VcPdcXBFZ~]D{)>(nZ&~i{[f7zT|!?_Uoa ZїN+X ufȭZ^ oΧ=?~~Xd5+)N}"C5}5lEepV\81,/U1vH>V:ȸ6{'X/b#YG2fk}I[9X\E ]Djɼ6M}Д{ʵN̑뷶ldzdnͅޏ5.I=vMԦd2.:h&4ѢeRy]#[ \uӰY[L0WnkPBP hl}} }IϺnt!`V:mt'DvlidU)/IdOziޏ'pέ +mN+ND67ҿԋUr6 rG[%S^a wFJ˱mǓ D7ICk+]vD4*dirIWF 3ke:o{ 4~1==KqXIs=2vƆ$Ɗ߳Zz+F4yrVodƗ+=9rM''LN*txcdc3j{֋:7ep٦쎑\eZRA̿50PsCZzR N2! cʰlOHTojW 梛}h4?m2F$&yEMf0J⏶>-i1:Kos O+xUVNf#=bN]ӟp$o4_R C}qIkgE H,>u#V2G+*߂f [R*I\fnS>^E[ ѪK̒OEۏwUM9/;.x|̂Nv%횚ugrYit&)2N_n8 ϳ02ɍݬx[޾bm1} G#wIf1< %׆2 @j}}};o]eܹ6H,"it~?#KF#ғI #ah]?eheDfL֥ܾH/:&vJW(#YxJWCd>֫BCWQfm11qdeyH F Dm"dXYLufm0:Φ d ^|Xn &+ G6+*27G6\j_-+RgMьkwt HvTy}s=A\-We  c!d؍MMKFH@:'D>jr  \>{gl! T6v=iUV =ڭ۴f[ "`vڦvQtk1s?dߊ.E!4+v!FY aSB-{~В!E~:sxђMA@NskRL#("4?m7 ?>~ rL,;xAϵ0rT1 b0 nor]u`'\WrzSsyp!bG>t=3)-٭V@G&5)XMfvŴ G5Bwh>6zm [k͙"/f%>!Yߤ.0认a  Nմvۈ@ɉC,riJX;rG7kfhzWL$]TmlvDEBR4Dڥ *[&> HKW2-"XdzI`+; )o:&ћ⳻ی{E{nDK]͸B 2tk| =dHH>1TiZQ]O]0 &yѝzdt'* wõ%E!z&>ҭr8mUɖ8šLW*륆 tΡ+Mxᗏ\AHkWr UcCVu+"݋,2Ri:7H V|4rF+[B|KZ\qS[OF'7 mE!@LS/;:q=kսU-7Ap6}ۄ]/7~ڃyءTylѻ{i0فԬID HiV- m5הetԍu;*bii F͔-2RPyhևr)nfuU0BAݘ6*_j`雏R ʗwXJ-Fߙ1˃ih2T!jg=22ޖ22N27A%$ 3}ix! LsFn7)d5AE}V'A @gw(hͷʷܰ$ȊKOi7u6K'U"!U#4=4\i]#:"Ob-lHR7N;69{[ScTa gO %F("i&-hfC%TJ&xM]VL pLDʲˌvǾ23sqîjJ.9Or.^kH b, ُ߹6N+*BLƨp]lioA5O<9q AҰ^̶߰mӝ>ƊXQ62>1^?$lZեPw6G]Ij/*X.jDޔȳ$ Lɉ@f5yP<4vuyȕ\#;氩G 'F{̓S}6tRGN$95-N=Yؠ8;2fYaa[x{T ~航nF1uՅ+Yn"SkdNŗ(L4}dJ_}&ZB@Âfj$pmqZi6v{}"ͯa7۵#9w:dmӨ-k%aã?m5s|6t/ړ]fxS;I33 "z~aБ|U43.'(VXu.YHE xFC66zs36iՇܸ'S:R̙5ȫ)qj\̒krhzq4Yݕ23Y"^7NZZ!6ԝ( vIf&#\QR5L|9skta]6kX<7r=A5F[ƣ~B#}CZ8uZ7TjO2MOk@4 KWTk[vaP<]5 3<T#~'Gj??OFݦ)PS*`&[GءزІj밊uv\# }xۤ7[GY8EL'X ՟,?3׌\6x{RUk5g\Z'#*M}k55>m49.FNC@!j9ԧsI*/iY]gĠ%8$m, h]fڧM̒GM('J϶>O-,`abdlL(l"J -YbHhlG 2Mc$U \F6eOc3e1EQ5g|f0?|6zϋi%8vȘ{ceJwf F2C㩡uE+YEIPv'f`7+P&X[2JtOӖ7ϳU B" j L݁|m*FlqmwiC%o7es:UƯXiHnۑ"%'i>mEٙ6KOh4gDL1І;v;N<ՙ<9Sµ[?;cueB @D~ywͫP7~hTpHY![82)a [΁ݐMSArGf-Qلm]nh<8_'iR!$3RYDܿݡiDf2ޱ)L>3}m>`_ l4<ݾ3xy"j,zL!'3S*C~}&7 :ވhbr73ee cL}7d cLxu9w2^3E (BxA@}v?q@ i=WG|%u-t.lS8SL95VxE80k<*=>RCWY-ZQdܡ%Mjx='1U%Ț[H x`=* 0 Mӳo>;$=uaufd7}QgTkÚ:}# q 6KZ*mFP!! *eGV BA16<lFNf!:y6[9%`uF}sb,jW_i+Wt9s@M6otڱJv'Fea5*Zt[{7SNm^/q ڝԑELvJ8@xQavܭ߳Mӽ:^|+0̋Kcor0i63h?LNo5p8!~eLb ɢ:Uv-'h_1H=tKl:moIJ݇7J'H-**VnDޏ3Bp.k5۶nk%L *H_DJ!,`Fu[3aC'p$;vFg*T6$kV[8̺$YRC_;#<3c7T (*{ygzZ9ZDel$_[s$zM\r.NVlq xe(}kڻl[)~IFkm4\n8HoHjK@*q?0e~2g_DgKIu-J%= 6JjQZ(onjLl`A%g+h^lC3C]lt eCw^άg@Zc+8b:vgP˵Dd,[ю%3fA#o9+wVt]l~aG]=cnîC13*kuOk4Iޡ l:cqbZ{,+\XLrףng s4t2ǥMx6q-e<艛,C~YjblHj}W9,P60 ȝooŤ&)jw}g w@mut@Q}צw:w>"TS! 9*=zc:­GCf] So̖lI\6Z6k#vHmڙ#;~yb9[I޴j݅ƣyإ$" 3{PUӅX͞_H̫6#wCk hi_bn{K5tel㙤Y{M])ce˨v.2 fOw -kXPyBȂȌ*cdz! ^5R.$LGnZKjJcV䛔jn4g{^O@vMTEOnY3dq8ꔔE~fJZON&~Xʿ*3v0~({" lhW 4h@ds7\v;tKMD*Am%5qF&y{;Wrʮ"x6XOs~-mzP'CRә"%;ƻ悧U:Z4cJAPs/$@AI "ɑMUӣP,[AݗxF`NtTib6BxY#R+6"L Vh v&V-k1E Njl#2z.?RTC&5uYM:Z'#__wU*?v➎KfoUr,]W/~U/5$!ߢb$7(ܟ*oʊ"sw@i9&Y./%s!{w1vzś'0u?@?\KzVJLk'o._޸M֫Zv]Ekrճ5zGv][r/IMHmkK0;_*j)S|˘oy+Z;RUJϋ޴!W^O7ӣwFuڴU?]_ kD1_u(B껷tZ:}]pe&Vē<$+߮$tܿ;^NQ,w)w}rgUWƾ?̲iQy^%w_%8̵^Jd-eU^HF.wB^ݻ\,M{I_^wB.wr V_nO]:X!, 7,SZLԟNq}K߿S$MVŗWI3|ږ/IkZW_􌦵z=F6/$˗kN߫Է7u.CMW1oWUz̨z7F!LY]j:[5ɭՒ-+5Kn~Wݯ]? l??14Z޸lNf*6n?!1;]Wޫא_^h(M1u-s ߤ-˗+FBC:!O3^/~1W!-u|Uk_7#N~!_J?Mt)8}߭b+]WxYD(`dBP WgoHvk*lYw _Hzpk_j!ׯUU >Uj6h ǦRa=GɯbZu$F?u_OdNȽr@__5zkUbRz]}n_j.'DnM]I9h!|N^&|GgL~^-/j,]Eh˒\M˿E˹.4~EZ$UީK);^N\T+DW>~,O]kuk~E͜*~{]\ֵjQ\M﻾x/uʻݯ~ff񤒑:u0V~7Iޣ$$wAOhի"<ۗEdW{o% ~<>[G]F}־Uz &BVb5x >Cu tG3~B\o꿦}2J_ BuH%ݯ;PQU]/_P8w\Ů#L)"{/z`"fUydm-=VIn{]TדRMZ19'_UhauZ|޻u_]^EOj[~$wzW~߬Mk)s/U^MIO˫ֻ%YP+U{}\NTׯpl/~ש?{>yO>צRZvzI.؅5ZMjMVIĽiv/>שđ{ޥ]%ZvSIJ͒U2+j#+^#]kR˫_+-c#'~M:Yr2q~޿/__2k2z)t͞WM?F\D'SkпU{: 跋 B зA 7) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.235045 SABnzbd-4.3.2/tests/data/par2file/basic_16k.par20000644000000000000000000000063014625637207020331 0ustar00runnerstaffPAR2PKTZ5`oݞ@Kki"s MV*KYPAR 2.0FileDescS!3d.Eab{ȭ˴Y+'kywF6Erss_feed_test.xmlPAR2PKTd#IP S/Ii"s MV*KYPAR 2.0IFSCS!3d.EabES,^/.PAR2PKT\=;j&i"s MV*KYPAR 2.0MainS!3d.EabPAR2PKTLs~)UՈ-8Sj/zi"s MV*KYPAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2438726 SABnzbd-4.3.2/tests/data/test_passworded{{secret}}/passworded-file.rar0000644000000000000000000000045514625637207025500 0ustar00runnerstaffRar! )FL]<Ff testfile.bin0 TƚmJ&lԬw8NKzLNx>T  d[2@GD^F 5A-qe<FfMy_Test_Download.bin0 TƚmJ@[ISJ@WLNx>T  dd@E&9BqaAWAR8p Yɩ{\auB!wVQ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2408655 SABnzbd-4.3.2/tests/data/sorting/SINGLE_sort_s23e06_480i-SABnzbd/abc.mov0000644000000000000000000000014514625637207024312 0ustar00runnerstaff7~=@B.Op q@ 1eś;&GLv#x]Uo3K ^96!{:~Djꡕ1ekr ~, ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2414424 SABnzbd-4.3.2/tests/data/sorting/sea_sort_s02_4k_uhd-SABnzbd/E07.data0000644000000000000000000000015314625637207024172 0ustar00runnerstaff^/̷kկ>}$g0uH\=)Nde'mQdy(.-k&_H[Oh:vqS"˹@EGB%̴r././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2413864 SABnzbd-4.3.2/tests/data/sorting/sea_sort_s02_4k_uhd-SABnzbd/E06.data0000644000000000000000000000015214625637207024170 0ustar00runnerstaff:S・>!^&d;Sr@jդѨ Tc!Ju NnV/mb= wd&ǭ:⇸: TJ/mK` x././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2410395 SABnzbd-4.3.2/tests/data/sorting/sea_sort_s01_4k_uhd-SABnzbd/S01E02.data0000644000000000000000000000014614625637207024452 0ustar00runnerstaff[$"Ov?oOВs tB-!zG ]CVC7TpTtO\[z^5J ۷ Bۣ ڽL././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2411094 SABnzbd-4.3.2/tests/data/sorting/sea_sort_s01_4k_uhd-SABnzbd/S01E03.data0000644000000000000000000000014714625637207024454 0ustar00runnerstaff9nshK_KYoZEiVش-g{ | `6өȋT~g3xsŶ·{HS )}U{././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2412176 SABnzbd-4.3.2/tests/data/sorting/sea_sort_s01_4k_uhd-SABnzbd/S01E05.data0000644000000000000000000000015114625637207024451 0ustar00runnerstaffZN8i=I:̀:t-eg]*{5ְ7+%5ұ6_֦?R"l=q(JKo@t|NIL././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.240975 SABnzbd-4.3.2/tests/data/sorting/sea_sort_s01_4k_uhd-SABnzbd/S01E01.data0000644000000000000000000000014514625637207024450 0ustar00runnerstaff7~=@B.Op q@ C ߌw o~L)C ߌw o~L)„frnch_german_dem.rarPAR2PKTd]|BPso.tfKʉPAR 2.0IFSCujzݖ.;(9O`-_{PAR2PKT\/N 6lo.tfKʉPAR 2.0MainuPAR2PKTL'jCYuOF o.tfKʉPAR 2.0CreatorQuickPar 0.9././@PaxHeader0000000000000000000000000000014700000000000010217 xustar0075 path=SABnzbd-4.3.2/tests/data/test_win_unicode/frènch_german_demö.rar 28 mtime=1716993671.2439692 SABnzbd-4.3.2/tests/data/test_win_unicode/fr?nch_german_dem?.rar0000644000000000000000000000020414625637207024016 0ustar00runnerstaffRar! y6  aJfrènch_german_demö.bin  Z>%3r=HpwVQ././@PaxHeader0000000000000000000000000000014700000000000010217 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol002+04.par2 27 mtime=1716993671.246373 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol002+04.par20000644000000000000000000036356014625637207021405 0ustar00runnerstaffPAR2PKTxU.fXOC(ԍ̯'(m?6SSPAR 2.0RecvSlicD |v9nu[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx{=2 ,bnMCm?6SSPAR 2.0RecvSlicZw cP\o&tbtizC3@]eIM7PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxAK!=&$ROjܩm?6SSPAR 2.0RecvSlicIV5lDOG3aYPmʥ(fBcɺgu_2Y?SPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxI\i A~a]m?6SSPAR 2.0RecvSlicV<@{aeL2 x1/yK,SfdndNJ&1PAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000015000000000000010211 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol126+73.par2 28 mtime=1716993671.2486768 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol126+73.par20000644000000000000000000110725014625637207021413 0ustar00runnerstaffPAR2PKTxX=XXYY c>m?6SSPAR 2.0RecvSlic~K9)v DDkSbvW[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxƞ}.76zD <\m?6SSPAR 2.0RecvSlic`9lR~f^kGNc4^ Ej!b'D*nPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxIszwZq m?6SSPAR 2.0RecvSlicj{ګO欳|6K1rNAm>:AGPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxL_lvcCaAm?6SSPAR 2.0RecvSlicM,aZ`'#'HÏkn#9OsƀOCp DPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx(J3s索_+m?6SSPAR 2.0RecvSlicGE.O|f;bR=Oŵao0uVRu+=̃FPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx؃ŏ_,/m?6SSPAR 2.0RecvSlic??Ҙғ9-꟫0O7|J< z/$ C~PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTx#mGERbGɩm?6SSPAR 2.0RecvSlic`=6"j̼v0لyMB" CQou7mt@n$Y~xPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx߆[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxPxk=V/m?6SSPAR 2.0RecvSlicμfq褺mśoNL`0wS)&Χude2kw7Kim ;=PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx31a2s)m?6SSPAR 2.0RecvSlicE>Z[,pɃ2RUA5Ds߃y| a2PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxi@ @`*m?6SSPAR 2.0RecvSlicޮ Hce1 uauJf䑎se{bCSPAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxF"1u am?6SSPAR 2.0RecvSlicK'+z4fO2sQς=|CaLtj71 (poѶ؝YPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTx/j!/ qm?6SSPAR 2.0RecvSlicO\,|(Gf$_;nh3c{Hpzli'?#XPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxպ l-0|m?6SSPAR 2.0RecvSlicՒ]+DUk4E> ڊ"sL ѿT XxdZ=PAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxTEb>i I^<٪m?6SSPAR 2.0RecvSlic G+7X# ƙx9ݓk©٤)m'`{XߡS +PAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTxxRUةm?6SSPAR 2.0RecvSlic3ҙ$|/:~&\yn>@FnBVYGPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxR}B5vJ-CKm?6SSPAR 2.0RecvSlic[JuEZy{N4D (/ @VպEf˱PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxd%h lL)˩m?6SSPAR 2.0RecvSlic9`aVRg 6ꧯ41`LHɞݵPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxK?Yw L:m?6SSPAR 2.0RecvSlic5 Gd0+Gc'4׊TwU$ቭ+tgC1#"PAR2PKTm8>g"9v.S&PAR2PKTx;:}H/[`mթm?6SSPAR 2.0RecvSlic+ߏyJ`{ĜeBy2B)Fg:˖SMM& #PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx#kí_t#tũm?6SSPAR 2.0RecvSlic4"Dڍ:B_brAh Ub-Pg[Db߷tPAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxp\r3/Em?6SSPAR 2.0RecvSlicJAg#(c2|Kw8X+&ːJulb~UPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxhns!U]w.4GHDm?6SSPAR 2.0RecvSlicԬvUݶ=17 >b/#)Є91d=L]`PAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxKҷN,ʨm?6SSPAR 2.0RecvSlic/FN⼥5 :}qL]&|زyɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTx%\2e80m?6SSPAR 2.0RecvSlic}.Z^0Oy%Ed؈Ȍs{r@5 <:ogPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTxѨ,{zXr5rm?6SSPAR 2.0RecvSlic~ -n%P\Up`Yɗpc0]5-1&O3W PAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx{L7V7Xm?6SSPAR 2.0RecvSlicDzYI-j6JwZͰxInK߭'ΛhP h,#&PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTx$뾊 X)Ctam?6SSPAR 2.0RecvSlic^ Ѵi(#βP\eoηIGp3Ôe&PAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxYqUb=0(fm?6SSPAR 2.0RecvSlic'8=eO`]:jdmzt+%{[L {W"PCPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKTxLxo$U.vm?6SSPAR 2.0RecvSlichU#51Ϻy+%N*sf0CԷ钘^<PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx8Lj/)m?6SSPAR 2.0RecvSlic͛#o6Zvk4D+b^tgDuњYvf4{ȸPAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx]{2ꅪOc>m?6SSPAR 2.0RecvSlicyEq(]2\ 1 ư0='@LҠ\nKgPAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxrpk Pm?6SSPAR 2.0RecvSlic3.9kFclv(n8UF&zۗ+P ,HNGPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxgU F%%cm?6SSPAR 2.0RecvSlicbQ`Wf؇mЅG" k?;NJWYBPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxG*>nX-䲩m?6SSPAR 2.0RecvSlicBr=$?Y5嚎Gcf̅J`OX5n!IPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxz . Q&Hթm?6SSPAR 2.0RecvSlicM[lL xA ơ 5͞tD,3xx1M3PAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTx#xkm?6SSPAR 2.0RecvSlicK2 "`F9Ei%:{8WWW3^PAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTxwTQt6\2m?6SSPAR 2.0RecvSlic&Eh?]:_ @ nl}وUI Cۼ˃PAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxIʰ2\#8!B$\m?6SSPAR 2.0RecvSlic,>Ș4&H]ƻwۧR0Fi\ PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx|QBnaEm?6SSPAR 2.0RecvSlic=M︎i`њ3|#<of@|a {PAR2PKTm8>g"9v.S&PAR2PKTxѬDah6t?m?6SSPAR 2.0RecvSlic c#؎$նqxqN3L͙ Rc@cmNZ C[/B>y+aP2P)kPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx-EʠlN<7'Bm?6SSPAR 2.0RecvSlicO;c(qɋӨ4[YW 4 5hܳP.|PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx_s &W5'm?6SSPAR 2.0RecvSlicfF t"G}X6q>xU2d6#=@d FL"=什r5PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTx˸Q\VEm>m?6SSPAR 2.0RecvSlicr^FL]]_cIJ&uΧ^ >r">PAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTx%b2p@2Mũm?6SSPAR 2.0RecvSlic4+a}BC&22! 6 )scȚ5o`JXPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxSg(.m?6SSPAR 2.0RecvSlicrYgm eeG+O"oEOɈ {|MuV>DPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTx1 j)c, VbWm?6SSPAR 2.0RecvSlicK)]kT~q?$, ׌u˫9 "OPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx7/jVөm?6SSPAR 2.0RecvSlicqL;YnT6'ˎRt8WT:PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTxOugBRO ]m?6SSPAR 2.0RecvSlic):^(.:񖱪B< , }+kL"O-2zKV{PAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx`uf$ cXbҏm?6SSPAR 2.0RecvSlicl^ S~HG01L[dPPAR2PKTm8>g"9v.S&PAR2PKTx%nhKFsDm?6SSPAR 2.0RecvSlica*juy_,ժF E"A7Pr7DqJrL큁ÓuPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx?bWIncåm?6SSPAR 2.0RecvSlic#mrn:lK"sxn3AE3}BlvXDž3^HDnPAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx>KSKJsUotm?6SSPAR 2.0RecvSlic 61p[M{aXfW&@e8xug*0x~PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTx$QDӇ9>rm?6SSPAR 2.0RecvSlic y [!oU]p` ?-I[;B㟎SPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTx1&1Iɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxsg`Qsm?6SSPAR 2.0RecvSliceޢ=|e`cK^˘>! S_C(ANѯ<يPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx74F4Zdݰm?6SSPAR 2.0RecvSlicIH9v.S&PAR2PKTxkұoI;m?6SSPAR 2.0RecvSlichqVg}ܼ :TZ.)% fm3'Oœ.)<PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxnbz%$pG9Gm?6SSPAR 2.0RecvSlicp2P^$ɯL%(jAUK!YG 0!n w%PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx'PBՃ 數6m?6SSPAR 2.0RecvSliclKmhvS*HkɠD2'$ΞTK75sUt:PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxkx1e䰍+m?6SSPAR 2.0RecvSlicqw<FQG, B/uhǫF9v.S&PAR2PKTx̋ʄ~C\+ɩm?6SSPAR 2.0RecvSlic\>bT-($xxbyk$\чk>1=|vPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxQ{ (H*Xm?6SSPAR 2.0RecvSlic~,70'{Jwci@rgmgQh݉KȻ־`=X4qPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTx3ԛo *Rm?6SSPAR 2.0RecvSlic~3zti|j2 =4S@iԚKWa;Xykr0PAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxGl:uU|m?6SSPAR 2.0RecvSlic?[ŀ$3a=tcO8ih a\<ⶓO #NfPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTxh^-rN[m?6SSPAR 2.0RecvSlic-Ԩ6B@{rti.a%L;eX8ieVyvPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxēc}+6ŵ1@m?6SSPAR 2.0RecvSlic_zWtX**X~og"t Fͺ'<7-bNٗYjJ\e PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxtޙ (Ǧ{m?6SSPAR 2.0RecvSlic{2@rs;UHsB6@ gʣ^ J̜ܕ#ɀ PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxF;>6F5[Pm?6SSPAR 2.0RecvSlic`v=duax*qr ,TkQ/\X/){CZ5팋PAR2PKTm8>g"9v.S&PAR2PKTx39T7 M"m?6SSPAR 2.0RecvSlic7:~hsKe)^H3yʧ~Yxeõ#PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx,?_ZZ",(m?6SSPAR 2.0RecvSlic9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000014600000000000010216 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol014+16.par2 26 mtime=1716993671.24686 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol014+16.par20000644000000000000000000063020014625637207021377 0ustar00runnerstaffPAR2PKTxfٛĄpm?6SSPAR 2.0RecvSlicls9.L rA[G_lW&#/* " QnaŚ PKX/kYB.uPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx=A35W:m?6SSPAR 2.0RecvSlicVU$m&DZ޼aӝLp"(Bɐ1GkPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx_g㈞ܵkm?6SSPAR 2.0RecvSlic4^iғp~SWA>ՎnsU _CAhE NnPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx|RQrR'AKR/m?6SSPAR 2.0RecvSlic ef^?) 6a67t *?nrG'ݚ"̻qT CPAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTx{s*7\m?6SSPAR 2.0RecvSlic+X=#a.n#O~bॷ6\H,BEpUf/&1> ǔPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTx:-:{d>m?6SSPAR 2.0RecvSliceV|7M9ެ&~J"0HH9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTxJaǀ5.ةm?6SSPAR 2.0RecvSlice~ibJПl $|@lCT%o[{g[7PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTx'Ց}0rlm?6SSPAR 2.0RecvSlic/ *`otسc3~TE\~NbWjs3q)bOoPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx/Wv 4m?6SSPAR 2.0RecvSlicdN rKIWoJTIh-yΓ(bn\PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKTx\ Vn@! @m?6SSPAR 2.0RecvSlicFR i6$Ah=7dﺉe~5cC&ɯ NfE}dwKPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxenz&[8~ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTx =G" wUt"m?6SSPAR 2.0RecvSlicJ+@3OƇg ^0\ͻ-4#0Ls@PAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx-m"0L1Ymsm?6SSPAR 2.0RecvSlicLEc|w^^_vpf!8~"5w왞|]Ws#A}ϭuW%PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxR3,9e]90m?6SSPAR 2.0RecvSlicvgG(5WzOZMc@0[NK}3(Ff09)3 f3;PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxP@F審m?6SSPAR 2.0RecvSlicx5ti~9v.S&PAR2PKTx/lۘAm?6SSPAR 2.0RecvSlicu974KM9o:\T8A OL$)^tW;f! ?!;PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000013500000000000010214 xustar0066 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.par2 27 mtime=1716993671.244634 SABnzbd-4.3.2/tests/data/unicode_rar/?????.par20000644000000000000000000012104014625637207020126 0ustar00runnerstaffPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000015000000000000010211 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol000+02.par2 28 mtime=1716993671.2453036 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol000+02.par20000644000000000000000000024231014625637207021366 0ustar00runnerstaffPAR2PKTx"|?eYթm?6SSPAR 2.0RecvSlic2?l.E9(+ ŒŨnTK~ "m?pzbuPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx®ZW_ӂm?6SSPAR 2.0RecvSlicq ʜΥQd$֫M0CSg*9tA4_PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000014700000000000010217 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol062+64.par2 27 mtime=1716993671.248264 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol062+64.par20000644000000000000000000110516014625637207021410 0ustar00runnerstaffPAR2PKTxaiٷKb'ᑕ+m?6SSPAR 2.0RecvSlic>щ%9/K }ҍ\%im$R}{'>ϙD>PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxLӸ06Ph}C琩m?6SSPAR 2.0RecvSlic?e-v00s!ޞnj%̹]i^ F. h .l4wSPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTx?-e#Q=skwm?6SSPAR 2.0RecvSlic@~%B\zfP~qnvMg(Zś< ]X FPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx"h R8_m?6SSPAR 2.0RecvSlicA eBxTyl6Kw~|] JB9v.S&PAR2PKTxi[ٿ~%ʩm?6SSPAR 2.0RecvSlicDLa+8H!{FX;T 1E }rPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx-%d뼾$!Dm?6SSPAR 2.0RecvSlicEHR坳Zrk}[Y:]WMn-BHl7yU!FPAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx"bt!vm?6SSPAR 2.0RecvSlicF$8L{anXJT ZCo'B46?,޴"{ב"gPAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx8hqqMm?6SSPAR 2.0RecvSlicG $0n9^QqϢ;h_ x F{ehd/'PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTx2-!]nSm?6SSPAR 2.0RecvSlicH$}<q -j-_5wFu>o/7M]xLC"PAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxu5ί p"Km?6SSPAR 2.0RecvSlicIxztXH28Jl\}C̘ l- lgfOPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx AQJm?6SSPAR 2.0RecvSlicJ}p^(H +):4=l.Op bÀJ+{XU ^ PAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTx#Ki5Om?6SSPAR 2.0RecvSlicKc>n8vT&]YQ͜)H-DlPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx<{=ƃ  m?6SSPAR 2.0RecvSlicMA݇̚8I> W DfXQ VuPf?MPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxko(W}%Cm?6SSPAR 2.0RecvSlicNL"L4ɀ6 iWA粨y}"Oo!I4^PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTxKΎW[Z9v.S&PAR2PKTx'hz ¯²m?6SSPAR 2.0RecvSlicPAUZXJʔs/f|\l(οѼoi {H PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxo*S!Im?6SSPAR 2.0RecvSlicQĔkmOEH`B{_֛f7tpN$Oʢ~PAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTx+KN)~^m?6SSPAR 2.0RecvSlicR[N~/DL `?rSD*ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTx=VtmN5m?6SSPAR 2.0RecvSlicSȍx寧-c;Nl")^z'^F^/fNisPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTxw讪Er ym?6SSPAR 2.0RecvSlicTX{Q?odFu6=xV %׫Cl ֶPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx׍Wp*m?6SSPAR 2.0RecvSlicU_?K#}wetdzAǯ"a;w}|ՖFˤЊPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxLUF"1+Kaom?6SSPAR 2.0RecvSlicV׀kLS8~e`Bo1ש8O5(oPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx[! fZةm?6SSPAR 2.0RecvSlicWnݼNZ8͝g"9v.S&PAR2PKTxiaI-E*m?6SSPAR 2.0RecvSlicXHGVE&`Jiӊ_N['GVz?nhPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx(IYm]N}m?6SSPAR 2.0RecvSlicYE4WM}""07 v}Er1}ň7Vӈ^(]Ё&]!O2H"PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxĢ9m?6SSPAR 2.0RecvSlicZj'Ev%衒V1/rW{Mh/] o2<UÒ\PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxq|E/U`j3m?6SSPAR 2.0RecvSlic[ٶc Y%|[5"z3Ac\+X7žy_b66:yPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxWfEq]Y= m?6SSPAR 2.0RecvSlic\H>ELXQr2ҺӟnoTlVhPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTxĎd&_ Im?6SSPAR 2.0RecvSlic]{Q_+#7`.ljuE/|u>iw:ɤ׆j@5PAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxI@vgYqF/TUm?6SSPAR 2.0RecvSlic^'si!*="t Ո{ R6o*IZPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTxA9ȞλN[m?6SSPAR 2.0RecvSlic_$?[pv‹ UrPe1[.9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxK$=s ?JOs{+Υm?6SSPAR 2.0RecvSlic`F@i桁WwK'h*4 =e-&~<2?P'PAR2PKTm8>g"9v.S&PAR2PKTx dN7*zm?6SSPAR 2.0RecvSlicaE/jbu 4` ;i90s,vqkl5Mc&wPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxn}?. c~;m?6SSPAR 2.0RecvSlicbޣXhel["9+觀 @i⿺ȓ0M02oqaPAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx Sle3蓩m?6SSPAR 2.0RecvSlicc:Zodן b8"}fNª#r؂6Sz7PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTx52?zp{4@ Km?6SSPAR 2.0RecvSlicd;Ͱ8E@bF"Xa v"r|HS6nPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxA%i 6- m?6SSPAR 2.0RecvSlice,ϧ\K:@'!xb.HSO uѿPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx>r9Om?6SSPAR 2.0RecvSlicfO= @Ƞ Fһ#;2˶eó[{(*s&,Wtq PAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxQ\!-䀨m?6SSPAR 2.0RecvSlicghƃ 鋪nb \"3ڐ7*h,xAwr UuIYPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTxi`sj1ZZG,:h;pm?6SSPAR 2.0RecvSlich9 34Ȿ+gnqDGa'mDvj 9-3 Q%PAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxxB3&b ﵩm?6SSPAR 2.0RecvSliciGj:`:n,k;=@?2ܨg`pf:F޴:<4xPAR2PKTm8>g"9v.S&PAR2PKTxz~tia?m)Em?6SSPAR 2.0RecvSlicj4WW)J TV$2m )ߋ|W&lg7UclyskPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTxRm\XA']2m?6SSPAR 2.0RecvSlickpہr:i6Wxtd#V"* VtELPAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx].ݱ }8SUm?6SSPAR 2.0RecvSliclH"IJ ΠʶY@jvV4ylF [xh2 tPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxe 1m?6SSPAR 2.0RecvSlicm]`bkvD,MIssU.#7bs{PAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTx.%yd Yqm?6SSPAR 2.0RecvSlicnK;!%Df]{$6s_v>mDd 񥙥]̅ PAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxkzQo{1 m?6SSPAR 2.0RecvSlicoxWCUۦ8c"BV2(U0ķԂNsPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxW n!R٤Xm?6SSPAR 2.0RecvSlicpLXϱ,-i vc[ h0A#Nj8;otpriB+K(PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTx^_Rd&؉m?6SSPAR 2.0RecvSlicqN@f$B#9up=?sn"\kGzuwYGʁPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx5jfcɘdm?6SSPAR 2.0RecvSlicrcV&F7<@;:lj9\R'0$ @voPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKTxi+ 8Y~m?6SSPAR 2.0RecvSlicsOY*P' g[ƨ,14!jY&P6PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx9cZkCWw2ym?6SSPAR 2.0RecvSlict\P |'T}K-[A:FJ\fq3`GىDS3PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxh.x[ 2ym?6SSPAR 2.0RecvSlicu.-9D̚0Ɣ-b `FE@}P|b`֊CE3mclClPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTx19܅/s-4-ܩm?6SSPAR 2.0RecvSlicvcv$hW /^@)1O,h~a-qJPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxF锝Of3 9+©m?6SSPAR 2.0RecvSlicwLLZlh s0Vn cjB#7bT0v JwPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxjD,g{zL44m?6SSPAR 2.0RecvSlicxXB;]W| 3Z5O૊2%;8PAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTx .L\Vxšm?6SSPAR 2.0RecvSlicy 0;Dpѭ'=:#&K hG3Y—W~XiOPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTx{9iVjt0m?6SSPAR 2.0RecvSlicz^` f;l W1L3:4@l$NP@220@PAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxebO=|ĩm?6SSPAR 2.0RecvSlic{N#8:o8*c-v chC;i? ֺAu+Z?|CEPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKTx6VB-WWi]m?6SSPAR 2.0RecvSlic|Hu3 d1pFpy 說$a4ot0b6܀PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTx6IJPHsm?6SSPAR 2.0RecvSlic}jѻjk/g,qc'9`$d8yo8N{pڲ>(88%PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000014300000000000010213 xustar0071 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.part3.rar 28 mtime=1716993671.2448869 SABnzbd-4.3.2/tests/data/unicode_rar/?????.part3.rar0000644000000000000000000005000014625637207021073 0ustar00runnerstaffRar!= QviD s$ $我喜欢编程_My_Test_Download.bin  dl+QO+% NIQviD s$ $我喜欢编程_My_Test_Download.bin  dl+GQ&././@PaxHeader0000000000000000000000000000014200000000000010212 xustar0071 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.part2.rar 27 mtime=1716993671.244794 SABnzbd-4.3.2/tests/data/unicode_rar/?????.part2.rar0000644000000000000000000005000014625637207021072 0ustar00runnerstaffRar!d QviD s$ $我喜欢编程_My_Test_Download.bin  dl+QO+% NIQviD s$ $我喜欢编程_My_Test_Download.bin  dl+GQ&././@PaxHeader0000000000000000000000000000014200000000000010212 xustar0071 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.part1.rar 27 mtime=1716993671.244717 SABnzbd-4.3.2/tests/data/unicode_rar/?????.part1.rar0000644000000000000000000005000014625637207021071 0ustar00runnerstaffRar!a D /G$我喜欢编程_My_Test_Download.bin  dl+QONID /G$我喜欢编程_My_Test_Download.bin  dl+GQ&././@PaxHeader0000000000000000000000000000014200000000000010212 xustar0071 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.part5.rar 27 mtime=1716993671.245071 SABnzbd-4.3.2/tests/data/unicode_rar/?????.part5.rar0000644000000000000000000005000014625637207021075 0ustar00runnerstaffRar! QviD s$ $我喜欢编程_My_Test_Download.bin  dl+QO+% NIQviD s$ $我喜欢编程_My_Test_Download.bin  dl+GQ&././@PaxHeader0000000000000000000000000000014300000000000010213 xustar0071 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.part4.rar 28 mtime=1716993671.2449675 SABnzbd-4.3.2/tests/data/unicode_rar/?????.part4.rar0000644000000000000000000005000014625637207021074 0ustar00runnerstaffRar!~ QviD s$ $我喜欢编程_My_Test_Download.bin  dl+QO+% NIQviD s$ $我喜欢编程_My_Test_Download.bin  dl+GQ&././@PaxHeader0000000000000000000000000000014300000000000010213 xustar0071 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.part6.rar 28 mtime=1716993671.2451434 SABnzbd-4.3.2/tests/data/unicode_rar/?????.part6.rar0000644000000000000000000000224714625637207021110 0ustar00runnerstaffRar!j gD aJ$我喜欢编程_My_Test_Download.bin  dl+wVQ././@PaxHeader0000000000000000000000000000014600000000000010216 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol030+32.par2 26 mtime=1716993671.24797 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol030+32.par20000644000000000000000000075467014625637207021415 0ustar00runnerstaffPAR2PKTx SՍGN.m?6SSPAR 2.0RecvSlic6/QKVn|5Wr:@hMzh&,Jp HAPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxV+Tԩm?6SSPAR 2.0RecvSlicHϲS*_)rd_0-j'VYO}YqB8PAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxHٲ= L O|m?6SSPAR 2.0RecvSlic n[sM[W3 N*T45#M{ J!SYeJAsPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTxLqPX?rǩm?6SSPAR 2.0RecvSlic!ӽ@U8Cl78Qhu8x[J׫Wi=8ܛкC,PAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTx'y!G$ӝm?6SSPAR 2.0RecvSlic"Ty1ޢ b[vG'&m75mZNRzNw3צ#lYPAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx$G{ Wx2LK˩m?6SSPAR 2.0RecvSlic#'^uxp;P2bٗޮT"ie|'H`W"Ld2SK6}G`PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTxjt^-=8Ұgm?6SSPAR 2.0RecvSlic$!8J:(Fit[ n ȌnWìqlL !PAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxi:@PG_ũm?6SSPAR 2.0RecvSlic%Nx[)ScB&-$bLA_ïz֭rO0x[PAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx`XcmG|m?6SSPAR 2.0RecvSlic&P3…rX޻\x5,8PD]^񫙲[^S5bYoNxI`PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx>% (,m?6SSPAR 2.0RecvSlic'Z & (\o`^R3R$`nq 5lJ4}KpqB< PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTxSCӹ'0 $n5}m?6SSPAR 2.0RecvSlic(FieE?Z :?p=IDo:]Vdw9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxwrzB`W|m?6SSPAR 2.0RecvSlic)]_ˊ)a>ژv, IA2Pw«f~j)ߊ[PPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTx13GY0Pm?6SSPAR 2.0RecvSlic*,P tFW3ד^c]+ڻB3]uz?V1PAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTx~v6sX%2wom?6SSPAR 2.0RecvSlic+Fƭ]s@~D=s%h3d EqnDDm |PAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxA,M̢Dm?6SSPAR 2.0RecvSlic,M/3ϫK {x 델)s|Z}u;b3nxaPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKTxR_^kf:'ʀݩm?6SSPAR 2.0RecvSlic-?_!q4qS( YvgαfUx"xw߾Ƙh*lcPAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx-e&{} Im?6SSPAR 2.0RecvSlic.Kyjnfj_gu;,s%WQn q^tĝŪB1^ܯPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKTxA~f* Ʃm?6SSPAR 2.0RecvSlic/b'n sTO?-&\eR{JN jj:O]PAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTxyOpPQ֩m?6SSPAR 2.0RecvSlic0yqysڐGr?B:Vy 'Sb\s@")9-ґkPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTx-~k&em?6SSPAR 2.0RecvSlic1Ju!ö& xCezW ܎0=f46f/s "MQ^#>lPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTxEX72MF m?6SSPAR 2.0RecvSlic2~I* +7L!݈nH$opHPv -6%PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx%N d-m?6SSPAR 2.0RecvSlic3JmW9*;j>bvzħۋ ns~Qד$YLsg:PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKTx!H$Pdgmk>m?6SSPAR 2.0RecvSlic4J 7 Wc7[- ]cb\i !zV.#{z rPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTx=uP1Ւ+= m?6SSPAR 2.0RecvSlic5Ѹ(:#RځZwZʺ.i^%J㋦jy:L`FPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxXF9vBl$.m?6SSPAR 2.0RecvSlic61L4.ހDPӵ'4#, ,B>NPAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxV~>8Whm?6SSPAR 2.0RecvSlic7X-WiIN0shv>f 1o;| ephS98gxPAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTxHRܸ,.XH/;m?6SSPAR 2.0RecvSlic8 !X||/"OF^7Nݶ*EnUqPAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxaňG^m?6SSPAR 2.0RecvSlic9_43s,4|1ۉaܙ3tf0 WKx'ډvzhPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTxaLA˩m?6SSPAR 2.0RecvSlic:ޑn`rv2*k ާj-=̛әxs5pcPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKTxzv7m?6SSPAR 2.0RecvSlic;in{? n\S[+2/ 3]3_9v.S&PAR2PKTx”%"}_ Am?6SSPAR 2.0RecvSlic<aXNe1KQ4N!őF vGgA|,}] PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKTx j" m$m?6SSPAR 2.0RecvSlic=w}=ČQ_HF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000015000000000000010211 xustar0076 path=SABnzbd-4.3.2/tests/data/unicode_rar/我喜欢编程.vol006+08.par2 28 mtime=1716993671.2466147 SABnzbd-4.3.2/tests/data/unicode_rar/?????.vol006+08.par20000644000000000000000000050541014625637207021405 0ustar00runnerstaffPAR2PKTx]3,[f&[%N-m?6SSPAR 2.0RecvSlici䞴/|ݱTPyMPx5T9e!KX&6NPAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxwSJWX:Gm?6SSPAR 2.0RecvSlic˲+#&=T'WKH@GM{&cqnvfReLM78PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxEC \}aAaXm?6SSPAR 2.0RecvSlicZ}ɃA+CKD{d/k ~#/*AQ/ZXf:PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx l` mM49v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTxh6Hbx[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTxƑ|b9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTx;bfVZ ;өm?6SSPAR 2.0RecvSlic {itY['p͆gT\V-~֚o̔@Wj/d\[3PAR2PKTeS&eSڮRm?6SSPAR 2.0Main414p/O[%mFkdsk>[nVWGbOPlpŕTvB'OP桭Z1sVrPAR2PKT`r2s]{f٩m?6SSPAR 2.0FileDesc14p/O[%mF T (qb\aܺ?w 2P我喜欢编程.part3.rarPAR2PKT&AiE<>ɢҩm?6SSPAR 2.0FileDesckdsk>[tB W+-4zҴtB W+-4zҧ我喜欢编程.part6.rarPAR2PKTY=-)Q m?6SSPAR 2.0FileDescnVWGbOPlq!' *y 9@A&nahEiP我喜欢编程.part2.rarPAR2PKTn_:p= TaJm?6SSPAR 2.0FileDescpŕTf+꠾G%#oěm33#P我喜欢编程.part1.rarPAR2PKT@SAi#I^m?6SSPAR 2.0FileDescvB'OP桭Z1ћdfuaZe djrP我喜欢编程.part5.rarPAR2PKTx B:v>m?6SSPAR 2.0RecvSlic `YntH=23ԙ Ϛ|Q0s-# ?PAR2PKTU9%G1yR۲Jp'm?6SSPAR 2.0FileDescsVr%-HcԈ8TAȾ8g AP我喜欢编程.part4.rarPAR2PKTR~ZA sm?6SSPAR 2.0IFSC14p/O[%mF!BTCU8mW D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTk[۩%5K /Km?6SSPAR 2.0IFSCkdsk>[c3x4 E{7ֺ D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+q&=Dp3M-,PAR2PKTm8>g"9v.S&PAR2PKT!FMx ;-m?6SSPAR 2.0IFSCpŕTBbT.--e| Ϩ}@ &A>F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+fx~/,d+#.{_̍+s$ ھ߆Wr >9v.S&PAR2PKTޙJsq(+|ڇ+=m?6SSPAR 2.0IFSCvB'OP桭Z1#Ǧr|I$#?ח,y D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTtS٬d `guܩm?6SSPAR 2.0IFSCsVrTjxҾ慄 D pJNDPgF 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+F 9obQ+Q9Kd]z^pnUշo"Ir >9v.S&PAR2PKTh^/gdgsXm?6SSPAR 2.0CreatorCreated by par2cmdline version 0.8.1.././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4451437 SABnzbd-4.3.2/sabnzbd/bpsmeter.py0000644000000000000000000004642614625637243016055 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.bpsmeter - bpsmeter """ import time import logging import re from typing import List, Dict, Optional import sabnzbd from sabnzbd.constants import BYTES_FILE_NAME, KIBI from sabnzbd.misc import to_units import sabnzbd.cfg as cfg DAY = float(24 * 60 * 60) WEEK = DAY * 7 DAYS = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) BPS_LIST_MAX = 275 RE_DAY = re.compile(r"^\s*(\d+)[^:]*") RE_HHMM = re.compile(r"(\d+):(\d+)\s*$") def tomorrow(t: float) -> float: """Return timestamp for tomorrow (midnight)""" now = time.localtime(t) ntime = (now[0], now[1], now[2], 0, 0, 0, now[6], now[7], now[8]) return time.mktime(ntime) + DAY def this_week(t: float) -> float: """Return timestamp for start of this week (monday)""" while 1: tm = time.localtime(t) if tm.tm_wday == 0: break t -= DAY monday = (tm.tm_year, tm.tm_mon, tm.tm_mday, 0, 0, 0, 0, 0, tm.tm_isdst) return time.mktime(monday) def next_week(t: float) -> float: """Return timestamp for start of next week (monday)""" return this_week(t) + WEEK def this_month(t: float) -> float: """Return timestamp for start of next month""" now = time.localtime(t) ntime = (now[0], now[1], 1, 0, 0, 0, 0, 0, now[8]) return time.mktime(ntime) def last_month_day(tm: time.struct_time) -> int: """Return last day of this month""" year, month = tm[:2] day = DAYS[month] # This simple formula for leap years is good enough if day == 28 and (year % 4) == 0: day = 29 return day def next_month(t: float) -> float: """Return timestamp for start of next month""" now = time.localtime(t) month = now.tm_mon + 1 year = now.tm_year if month > 12: month = 1 year += 1 ntime = (year, month, 1, 0, 0, 0, 0, 0, now[8]) return time.mktime(ntime) class BPSMeter: __slots__ = ( "start_time", "log_time", "speed_log_time", "last_update", "bps", "bps_list", "server_bps", "cached_amount", "sum_cached_amount", "day_total", "week_total", "month_total", "grand_total", "timeline_total", "article_stats_tried", "article_stats_failed", "delayed_assembler", "day_label", "end_of_day", "end_of_week", "end_of_month", "q_day", "q_period", "quota", "left", "have_quota", "q_time", "q_hour", "q_minute", "quota_enabled", ) def __init__(self): t = time.time() self.start_time = t self.log_time = t self.speed_log_time = t self.last_update = t self.bps = 0.0 self.bps_list: List[int] = [] self.server_bps: Dict[str, float] = {} self.cached_amount: Dict[str, int] = {} self.sum_cached_amount: int = 0 self.day_total: Dict[str, int] = {} self.week_total: Dict[str, int] = {} self.month_total: Dict[str, int] = {} self.grand_total: Dict[str, int] = {} self.timeline_total: Dict[str, Dict[str, int]] = {} self.article_stats_tried: Dict[str, Dict[str, int]] = {} self.article_stats_failed: Dict[str, Dict[str, int]] = {} self.delayed_assembler: int = 0 self.day_label: str = time.strftime("%Y-%m-%d") self.end_of_day: float = tomorrow(t) # Time that current day will end self.end_of_week: float = next_week(t) # Time that current day will end self.end_of_month: float = next_month(t) # Time that current month will end self.q_day = 1 # Day of quota reset self.q_period = "m" # Daily/Weekly/Monthly quota = d/w/m self.quota = 0.0 # Quota self.left = 0.0 # Remaining quota self.have_quota = False # Flag for quota active self.q_time = 0 # Next reset time for quota self.q_hour = 0 # Quota reset hour self.q_minute = 0 # Quota reset minute self.quota_enabled: bool = True # Scheduled quota enable/disable def save(self): """Save admin to disk""" sabnzbd.filesystem.save_admin( ( self.last_update, self.grand_total, self.day_total, self.week_total, self.month_total, self.end_of_day, self.end_of_week, self.end_of_month, self.quota, self.left, self.q_time, self.timeline_total, self.article_stats_tried, self.article_stats_failed, ), BYTES_FILE_NAME, ) def defaults(self): """Get the latest data from the database and assign to a fake server""" logging.debug("Setting default BPS meter values") with sabnzbd.database.HistoryDB() as history_db: grand, month, week = history_db.get_history_size() self.grand_total = {} self.month_total = {} self.week_total = {} self.day_total = {} if grand: self.grand_total["x"] = grand if month: self.month_total["x"] = month if week: self.week_total["x"] = week self.quota = self.left = cfg.quota_size.get_float() def read(self): """Read admin from disk, return True when pause is needed""" res = False quota = self.left = cfg.quota_size.get_float() # Quota for this period self.have_quota = bool(cfg.quota_size()) data = sabnzbd.filesystem.load_admin(BYTES_FILE_NAME) try: ( self.last_update, self.grand_total, self.day_total, self.week_total, self.month_total, self.end_of_day, self.end_of_week, self.end_of_month, self.quota, self.left, self.q_time, self.timeline_total, ) = data[:12] # Article statistics were only added in 3.2.x if len(data) > 12: self.article_stats_tried, self.article_stats_failed = data[12:14] # Clean the data, it could have invalid values in older versions for server in self.timeline_total: for data_data in self.timeline_total[server]: if not isinstance(self.timeline_total[server][data_data], int): self.timeline_total[server][data_data] = 0 # Trigger quota actions if abs(quota - self.quota) > 0.5: self.change_quota() res = self.reset_quota() except: self.defaults() return res def init_server_stats(self, server: str = None): """Initialize counters for "server" """ if server not in self.cached_amount: self.cached_amount[server] = 0 self.server_bps[server] = 0.0 if server not in self.day_total: self.day_total[server] = 0 if server not in self.week_total: self.week_total[server] = 0 if server not in self.month_total: self.month_total[server] = 0 if server not in self.month_total: self.month_total[server] = 0 if server not in self.grand_total: self.grand_total[server] = 0 if server not in self.timeline_total: self.timeline_total[server] = {} if self.day_label not in self.timeline_total[server]: self.timeline_total[server][self.day_label] = 0 if server not in self.server_bps: self.server_bps[server] = 0.0 if server not in self.article_stats_tried: self.article_stats_tried[server] = {} self.article_stats_failed[server] = {} if self.day_label not in self.article_stats_tried[server]: self.article_stats_tried[server][self.day_label] = 0 self.article_stats_failed[server][self.day_label] = 0 def update(self, server: Optional[str] = None, amount: int = 0): """Update counters for "server" with "amount" bytes""" # Add amount to temporary storage if server: self.cached_amount[server] += amount self.sum_cached_amount += amount return t = time.time() if t > self.end_of_day: # Current day passed, get new end of day self.day_label = time.strftime("%Y-%m-%d") self.end_of_day = tomorrow(t) - 1.0 self.day_total = {} # Reset delayed counters so they don't go too high self.delayed_assembler = 0 # Check end of week and end of month if t > self.end_of_week: self.week_total = {} self.end_of_week = next_week(t) - 1.0 if t > self.end_of_month: self.month_total = {} self.end_of_month = next_month(t) - 1.0 # Need to reset all counters for server in sabnzbd.Downloader.servers[:]: self.init_server_stats(server.id) # Add amounts that have been stored temporarily to statistics for srv in self.cached_amount: if self.cached_amount[srv]: self.day_total[srv] += self.cached_amount[srv] self.week_total[srv] += self.cached_amount[srv] self.month_total[srv] += self.cached_amount[srv] self.grand_total[srv] += self.cached_amount[srv] self.timeline_total[srv][self.day_label] += self.cached_amount[srv] # Update server bps try: self.server_bps[srv] = ( self.server_bps[srv] * (self.last_update - self.start_time) + self.cached_amount[srv] ) / (t - self.start_time) except ZeroDivisionError: self.server_bps[srv] = 0.0 # Reset for next time self.cached_amount[srv] = 0 # Quota check if self.have_quota and self.quota_enabled: self.left -= self.sum_cached_amount if self.left <= 0.0: if not sabnzbd.Downloader.paused: sabnzbd.Downloader.pause() logging.warning(T("Quota spent, pausing downloading")) # Speedometer try: self.bps = (self.bps * (self.last_update - self.start_time) + self.sum_cached_amount) / ( t - self.start_time ) except ZeroDivisionError: self.bps = 0.0 self.sum_cached_amount = 0 self.last_update = t check_time = t - 5.0 if self.start_time < check_time: self.start_time = check_time if self.bps < 0.01: self.reset() elif self.log_time < check_time: logging.debug("Speed: %sB/s", to_units(self.bps)) self.log_time = t if self.speed_log_time < (t - 1.0): self.add_empty_time() self.bps_list.append(int(self.bps / KIBI)) self.speed_log_time = t def register_server_article_tried(self, server: str): """Keep track how many articles were tried for each server""" self.article_stats_tried[server][self.day_label] += 1 def register_server_article_failed(self, server: str): """Keep track how many articles failed for each server""" self.article_stats_failed[server][self.day_label] += 1 def reset(self): t = time.time() self.start_time = t self.log_time = t self.last_update = t # Reset general BPS and the for all servers self.bps = 0.0 for server in self.server_bps: self.server_bps[server] = 0.0 def add_empty_time(self): # Extra zeros, but never more than the maximum! nr_diffs = min(int(time.time() - self.speed_log_time), BPS_LIST_MAX) if nr_diffs > 1: self.bps_list.extend([0] * nr_diffs) # Always trim the list to the max-length if len(self.bps_list) > BPS_LIST_MAX: self.bps_list = self.bps_list[len(self.bps_list) - BPS_LIST_MAX :] def get_sums(self): """return tuple of grand, month, week, day totals""" return ( sum(self.grand_total.values()), sum(self.month_total.values()), sum(self.week_total.values()), sum(self.day_total.values()), ) def amounts(self, server: str): """Return grand, month, week, day and article totals for specified server""" return ( self.grand_total.get(server, 0), self.month_total.get(server, 0), self.week_total.get(server, 0), self.day_total.get(server, 0), self.timeline_total.get(server, {}), self.article_stats_tried.get(server, {}), self.article_stats_failed.get(server, {}), ) def clear_server(self, server: str): """Clean counters for specified server""" if server in self.day_total: del self.day_total[server] if server in self.week_total: del self.week_total[server] if server in self.month_total: del self.month_total[server] if server in self.grand_total: del self.grand_total[server] if server in self.timeline_total: del self.timeline_total[server] if server in self.article_stats_tried: del self.article_stats_tried[server] if server in self.article_stats_failed: del self.article_stats_failed[server] self.init_server_stats(server) self.save() def get_bps_list(self): refresh_rate = int(cfg.refresh_rate()) if cfg.refresh_rate() else 1 self.add_empty_time() # We record every second, but display at the user's refresh-rate return self.bps_list[::refresh_rate] def reset_quota(self, force: bool = False): """Check if it's time to reset the quota, optionally resuming Return True, when still paused or should be paused """ if force or (self.have_quota and time.time() > (self.q_time - 50)): self.quota = self.left = cfg.quota_size.get_float() logging.info("Quota was reset to %s", self.quota) if cfg.quota_resume(): logging.info("Auto-resume due to quota reset") sabnzbd.Downloader.resume() self.next_reset() return False else: return True def next_reset(self, t: Optional[float] = None): """Determine next reset time""" t = t or time.time() tm = time.localtime(t) if self.q_period == "d": nx = (tm[0], tm[1], tm[2], self.q_hour, self.q_minute, 0, 0, 0, tm[8]) if (tm.tm_hour * 60 + tm.tm_min) >= (self.q_hour * 60 + self.q_minute): # If today's moment has passed, it will happen tomorrow t = time.mktime(nx) + 24 * 3600 tm = time.localtime(t) elif self.q_period == "w": if self.q_day < tm.tm_wday + 1 or ( self.q_day == tm.tm_wday + 1 and (tm.tm_hour * 60 + tm.tm_min) >= (self.q_hour * 60 + self.q_minute) ): tm = time.localtime(next_week(t)) dif = abs(self.q_day - tm.tm_wday - 1) t = time.mktime(tm) + dif * 24 * 3600 tm = time.localtime(t) elif self.q_period == "m": if self.q_day < tm.tm_mday or ( self.q_day == tm.tm_mday and (tm.tm_hour * 60 + tm.tm_min) >= (self.q_hour * 60 + self.q_minute) ): tm = time.localtime(next_month(t)) day = min(last_month_day(tm), self.q_day) tm = (tm[0], tm[1], day, self.q_hour, self.q_minute, 0, 0, 0, tm[8]) else: return tm = (tm[0], tm[1], tm[2], self.q_hour, self.q_minute, 0, 0, 0, tm[8]) self.q_time = time.mktime(tm) logging.debug("Will reset quota at %s", tm) def change_quota(self, allow_resume: bool = True): """Update quota, potentially pausing downloader""" if not self.have_quota and self.quota < 0.5: # Never set, use last period's size per = cfg.quota_period() sums = self.get_sums() if per == "d": self.left = sums[3] elif per == "w": self.left = sums[2] elif per == "m": self.left = sums[1] self.have_quota = bool(cfg.quota_size()) if self.have_quota: quota = cfg.quota_size.get_float() if self.quota: # Quota change, recalculate amount left self.left = quota - (self.quota - self.left) else: # If previously no quota, self.left holds this period's usage self.left = quota - self.left self.quota = quota else: self.quota = self.left = 0 self.update() self.next_reset() if self.left > 0.5 and allow_resume: self.resume() def get_quota(self): """If quota active, return check-function, hour, minute""" if self.have_quota: self.q_period = cfg.quota_period()[0].lower() self.q_day = 1 self.q_hour = self.q_minute = 0 # Pattern = # The and part can both be optional txt = cfg.quota_day().lower() if m := RE_DAY.search(txt): self.q_day = int(m.group(1)) if m := RE_HHMM.search(txt): self.q_hour = int(m.group(1)) self.q_minute = int(m.group(2)) if self.q_period == "w": self.q_day = max(1, self.q_day) self.q_day = min(7, self.q_day) elif self.q_period == "m": self.q_day = max(1, self.q_day) self.q_day = min(31, self.q_day) else: self.q_day = 1 self.change_quota(allow_resume=False) return quota_handler, self.q_hour, self.q_minute else: return None, 0, 0 def set_status(self, status: bool, action: bool = True): """Disable/enable quota management""" self.quota_enabled = status if action and not status: self.resume() @staticmethod def resume(): """Resume downloading""" if cfg.quota_resume() and sabnzbd.Downloader.paused: sabnzbd.Downloader.resume() def quota_handler(): """To be called from scheduler""" logging.debug("Checking quota") sabnzbd.BPSMeter.reset_quota() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4453058 SABnzbd-4.3.2/sabnzbd/postproc.py0000644000000000000000000014233414625637243016100 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.postproc - threaded post-processing of jobs """ import os import logging import functools import subprocess import time import re import gc import queue from typing import List, Optional, Tuple import sabnzbd from sabnzbd.newsunpack import ( unpacker, par2_repair, external_processing, sfv_check, build_filelists, rar_sort, is_sfv_file, ) from threading import Thread from sabnzbd.misc import ( on_cleanup_list, is_sample, helpful_warning, history_updated, change_queue_complete_action, run_script, is_none, ) from sabnzbd.filesystem import ( real_path, get_unique_dir, move_to_path, make_script_path, long_path, clip_path, renamer, remove_dir, globber, globber_full, set_permissions, cleanup_empty_directories, fix_unix_encoding, sanitize_and_trim_path, sanitize_files, remove_file, listdir_full, setname_from_path, create_all_dirs, get_unique_filename, get_ext, get_filename, directory_is_writable, check_filesystem_capabilities, ) from sabnzbd.nzbstuff import NzbObject from sabnzbd.sorting import Sorter from sabnzbd.constants import ( REPAIR_PRIORITY, FORCE_PRIORITY, POSTPROC_QUEUE_FILE_NAME, POSTPROC_QUEUE_VERSION, JOB_ADMIN, Status, VERIFIED_FILE, IGNORED_MOVIE_FOLDERS, ) from sabnzbd.nzbparser import process_single_nzb import sabnzbd.emailer as emailer import sabnzbd.config as config import sabnzbd.cfg as cfg import sabnzbd.database as database import sabnzbd.notifier as notifier import sabnzbd.utils.rarfile as rarfile import sabnzbd.utils.rarvolinfo as rarvolinfo import sabnzbd.utils.checkdir import sabnzbd.deobfuscate_filenames as deobfuscate MAX_FAST_JOB_COUNT = 3 class PostProcessor(Thread): """PostProcessor thread, designed as Singleton""" def __init__(self): """Initialize PostProcessor thread""" super().__init__() # This history queue is simply used to log what active items to display in the web_ui self.history_queue: List[NzbObject] = [] self.load() # Fast-queue for jobs already finished by DirectUnpack self.fast_queue: queue.Queue[Optional[NzbObject]] = queue.Queue() # Regular queue for jobs that might need more attention self.slow_queue: queue.Queue[Optional[NzbObject]] = queue.Queue() # Load all old jobs for nzo in self.history_queue: self.process(nzo) # So we can always cancel external processes self.external_process: Optional[subprocess.Popen] = None # Counter to not only process fast-jobs self.__fast_job_count = 0 # State variables self.__stop = False self.__busy = False self.paused = False def save(self): """Save postproc queue""" logging.info("Saving postproc queue") sabnzbd.filesystem.save_admin((POSTPROC_QUEUE_VERSION, self.history_queue), POSTPROC_QUEUE_FILE_NAME) def load(self): """Save postproc queue""" logging.info("Loading postproc queue") data = sabnzbd.filesystem.load_admin(POSTPROC_QUEUE_FILE_NAME) if data is None: return try: version, history_queue = data if POSTPROC_QUEUE_VERSION != version: logging.warning(T("Old queue detected, use Status->Repair to convert the queue")) elif isinstance(history_queue, list): self.history_queue = [nzo for nzo in history_queue if os.path.exists(nzo.download_path)] except: logging.info("Corrupt %s file, discarding", POSTPROC_QUEUE_FILE_NAME) logging.info("Traceback: ", exc_info=True) def delete(self, nzo_id: str, del_files: bool = False): """Remove a job from the post processor queue""" for nzo in self.history_queue: if nzo.nzo_id == nzo_id: if nzo.status in (Status.FAILED, Status.COMPLETED): nzo.to_be_removed = True elif nzo.status in (Status.DOWNLOADING, Status.QUEUED): self.remove(nzo) nzo.purge_data(delete_all_data=del_files) logging.info("Removed job %s from postproc queue", nzo.final_name) nzo.work_name = "" # Mark as deleted job break def process(self, nzo: NzbObject): """Push on finished job in the queue""" # Make sure we return the status "Waiting" nzo.status = Status.QUEUED if nzo not in self.history_queue: self.history_queue.append(nzo) # Fast-track if it has DirectUnpacked jobs or if it's still going if nzo.direct_unpacker and (nzo.direct_unpacker.success_sets or not nzo.direct_unpacker.killed): self.fast_queue.put(nzo) else: self.slow_queue.put(nzo) self.save() history_updated() def remove(self, nzo: NzbObject): """Remove given nzo from the queue""" try: self.history_queue.remove(nzo) except: pass self.save() history_updated() def stop(self): """Stop thread after finishing running job""" self.__stop = True self.slow_queue.put(None) self.fast_queue.put(None) def cancel_pp(self, nzo_ids: List[str]) -> Optional[bool]: """Abort Direct Unpack and change the status, so that the PP is canceled""" result = None for nzo in self.history_queue: if nzo.nzo_id in nzo_ids: nzo.abort_direct_unpacker() if nzo.pp_active: nzo.pp_active = False try: # Try to kill any external running process self.external_process.kill() logging.info("Killed external process %s", self.external_process.args[0]) except: pass result = True return result return result def empty(self) -> bool: """Return True if pp queue is empty""" return self.slow_queue.empty() and self.fast_queue.empty() and not self.__busy def get_queue( self, search: Optional[str] = None, categories: Optional[List[str]] = None, statuses: Optional[List[str]] = None, nzo_ids: Optional[List[str]] = None, ) -> List[NzbObject]: """Return list of NZOs that still need to be processed. Optionally filtered by the search terms""" re_search = None if isinstance(search, str): # Replace * with .* and ' ' with . search_text = search.strip().replace("*", ".*").replace(" ", ".*") + ".*?" try: re_search = re.compile(search_text, re.I) except: logging.error(T("Failed to compile regex for search term: %s"), search_text) # Need a copy to prevent race conditions filtered_queue = [] for nzo in self.history_queue[:]: if not nzo.work_name: continue if re_search and not re_search.search(nzo.final_name): continue if categories and nzo.cat not in categories: continue if statuses and nzo.status not in statuses: continue if nzo_ids and nzo.nzo_id not in nzo_ids: continue filtered_queue.append(nzo) return filtered_queue def get_path(self, nzo_id: str) -> Optional[str]: """Return download path for given nzo_id or None when not found""" for nzo in self.history_queue: if nzo.nzo_id == nzo_id: return nzo.download_path return None def run(self): """Postprocessor loop""" # First we do a dircheck complete_dir = sabnzbd.cfg.complete_dir.get_path() if sabnzbd.utils.checkdir.isFAT(complete_dir): helpful_warning( T("Completed Download Folder %s is on FAT file system, limiting maximum file size to 4GB") % complete_dir ) else: logging.debug("Completed Download Folder %s is not on FAT", complete_dir) if directory_is_writable(sabnzbd.cfg.download_dir.get_path()): check_filesystem_capabilities(sabnzbd.cfg.download_dir.get_path()) if directory_is_writable(sabnzbd.cfg.complete_dir.get_path()): check_filesystem_capabilities(sabnzbd.cfg.complete_dir.get_path()) # Do an extra purge of the history on startup to ensure timely removal on systems that # aren't on 24/7 and typically don't benefit from the daily scheduled call at midnight database.scheduled_history_purge() # Check for Apprise notification script # We don't have a much better place to do this, since there's no notifier-thread # TODO: Remove in 4.4 if sabnzbd.cfg.nscript_script() == "sabnzbd-notify.py": helpful_warning( "NZB-Notify has been integrated into SABnzbd. You can now use the " "Apprise section to configure the same notifications." ) # Start looping check_eoq = False while not self.__stop: self.__busy = False if self.paused: time.sleep(5) continue # Set NzbObject object to None so references from this thread do not keep the # object alive until the next job is added to post-processing (see #1628) nzo = None # Something in the fast queue? try: # Every few fast-jobs we should check allow a # slow job so that they don't wait forever if self.__fast_job_count >= MAX_FAST_JOB_COUNT and self.slow_queue.qsize(): raise queue.Empty nzo = self.fast_queue.get(timeout=2) self.__fast_job_count += 1 except queue.Empty: # Try the slow queue try: nzo = self.slow_queue.get(timeout=2) # Reset fast-counter self.__fast_job_count = 0 except queue.Empty: # Check for empty queue if check_eoq: check_eoq = False handle_empty_queue() # No fast or slow jobs, better luck next loop! continue # Stop job if not nzo: continue # Job was already deleted. if not nzo.work_name: check_eoq = True continue # Flag NZO as being processed nzo.pp_active = True # Pause downloader, if users wants that if cfg.pause_on_post_processing(): sabnzbd.Downloader.wait_for_postproc() self.__busy = True process_job(nzo) if nzo.to_be_removed: with database.HistoryDB() as history_db: history_db.remove(nzo.nzo_id) nzo.purge_data() # Processing done nzo.pp_active = False self.remove(nzo) self.external_process = None check_eoq = True # Allow download to proceed sabnzbd.Downloader.resume_from_postproc() def process_job(nzo: NzbObject) -> bool: """Process one job""" start = time.time() # keep track of whether we can continue all_ok = True # keep track of par problems par_error = False # keep track of any unpacking errors unpack_error = False # Signal empty download, for when 'empty_postproc' is enabled empty = False nzb_list = [] one_folder = False newfiles = [] # These need to be initialized in case of a crash workdir_complete = "" tmp_workdir_complete = None script_log = "" script_line = "" # Get the job flags, repair/unpack can be changed during the steps, so we use local copy nzo.save_attribs() flag_repair, flag_unpack = nzo.repair, nzo.unpack # Normalize PP, just to be sure if nzo.delete: flag_unpack = True if flag_unpack: flag_repair = True # Get the NZB name filename = nzo.final_name # Download-processes can mark job as failed, skip all steps if nzo.fail_msg: all_ok = False par_error = True unpack_error = 1 try: # If no files are present (except __admin__), fail the job if all_ok and len(globber(nzo.download_path)) < 2: if nzo.precheck: _, ratio = nzo.check_availability_ratio() emsg = T("Download might fail, only %s of required %s available") % (ratio, cfg.req_completion_rate()) else: emsg = T("Download failed - Not on your server(s)") empty = True emsg += " - https://sabnzbd.org/not-complete" nzo.fail_msg = emsg nzo.set_unpack_info("Download", emsg) nzo.status = Status.FAILED # do not run unpacking or parity verification flag_repair = flag_unpack = False all_ok = cfg.empty_postproc() and empty if not all_ok: par_error = True unpack_error = 1 script = nzo.script logging.info( "Starting Post-Processing on %s => Repair:%s, Unpack:%s, Delete:%s, Script:%s, Cat:%s", filename, flag_repair, flag_unpack, nzo.delete, script, nzo.cat, ) # Set complete dir to workdir in case we need to abort workdir_complete = nzo.download_path # Send post-processing notification notifier.send_notification(T("Post-processing"), nzo.final_name, "pp", nzo.cat) # Par processing, if enabled if all_ok and flag_repair: par_error, re_add = parring(nzo) if re_add: # Try to get more par files return False # If we don't need extra par2, we can disconnect if not sabnzbd.NzbQueue.actives(grabs=False) and cfg.autodisconnect(): # This was the last job, close server connections sabnzbd.Downloader.disconnect() # Sanitize the resulting files sanitize_files(folder=nzo.download_path) # Check if user allows unsafe post-processing if flag_repair and cfg.safe_postproc(): all_ok = all_ok and not par_error if all_ok: # Fix encodings fix_unix_encoding(nzo.download_path) # Use dirs generated by direct-unpacker if nzo.direct_unpacker and nzo.direct_unpacker.unpack_dir_info: ( tmp_workdir_complete, workdir_complete, file_sorter, one_folder, marker_file, ) = nzo.direct_unpacker.unpack_dir_info else: # Generate extraction path tmp_workdir_complete, workdir_complete, file_sorter, one_folder, marker_file = prepare_extraction_path( nzo ) # Run Stage 2: Unpack if flag_unpack: # Set the current nzo status to "Extracting...". Used in History nzo.status = Status.EXTRACTING logging.info("Running unpacker on %s", filename) unpack_error, newfiles = unpacker(nzo, tmp_workdir_complete, one_folder) logging.info("Unpacked files %s", newfiles) # Sanitize the resulting files newfiles = sanitize_files(filelist=newfiles) logging.info("Finished unpack_magic on %s", filename) if cfg.safe_postproc(): all_ok = all_ok and not unpack_error if all_ok: # Move any (left-over) files to destination nzo.status = Status.MOVING nzo.set_action_line(T("Moving"), "...") for root, _, files in os.walk(nzo.download_path): if not root.endswith(JOB_ADMIN): for file in files: path = os.path.join(root, file) new_path = path.replace(nzo.download_path, tmp_workdir_complete) ok, new_path = move_to_path(path, new_path) if new_path: newfiles.append(new_path) if not ok: nzo.set_unpack_info("Unpack", T("Failed moving %s to %s") % (path, new_path)) all_ok = False break # Set permissions right set_permissions(tmp_workdir_complete) if all_ok and marker_file: del_marker(os.path.join(tmp_workdir_complete, marker_file)) remove_from_list(marker_file, newfiles) if all_ok: # Remove files matching the cleanup list cleanup_list(tmp_workdir_complete, skip_nzb=True) # Check if this is an NZB-only download, if so redirect to queue # except when PP was Download-only if flag_repair: nzb_list = nzb_redirect(tmp_workdir_complete, nzo.final_name, nzo.pp, script, nzo.cat, nzo.priority) else: nzb_list = None if nzb_list: nzo.set_unpack_info("Download", T("Sent %s to queue") % nzb_list) cleanup_empty_directories(tmp_workdir_complete) else: # Full cleanup including nzb's cleanup_list(tmp_workdir_complete, skip_nzb=False) script_ret = 0 script_error = False if not nzb_list: # Give destination its final name if cfg.folder_rename() and tmp_workdir_complete and not one_folder: if not all_ok: # Rename failed folders so they are easy to recognize workdir_complete = tmp_workdir_complete.replace("_UNPACK_", "_FAILED_") workdir_complete = get_unique_dir(workdir_complete, create_dir=False) try: newfiles = rename_and_collapse_folder(tmp_workdir_complete, workdir_complete, newfiles) except: logging.error( T('Error renaming "%s" to "%s"'), clip_path(tmp_workdir_complete), clip_path(workdir_complete), ) logging.info("Traceback: ", exc_info=True) # Better disable sorting because filenames are all off now file_sorter.sorter_active = False if empty: job_result = -1 else: job_result = int(par_error) + int(bool(unpack_error)) * 2 if cfg.ignore_samples(): remove_samples(workdir_complete) # TV/Movie/Date Renaming code part 2 - rename and move files to parent folder if all_ok and file_sorter.sorter_active: if newfiles: workdir_complete, ok = file_sorter.rename(newfiles, workdir_complete) if not ok: nzo.set_unpack_info("Unpack", T("Failed to move files")) nzo.fail_msg = T("Failed to move files") all_ok = False # Run further post-processing if (all_ok or not cfg.safe_postproc()) and not nzb_list: # Use par2 files to deobfuscate unpacked file names # Only if we also run cleanup, so not to process the "regular" par2 files if nzo.delete and cfg.process_unpacked_par2(): newfiles = deobfuscate.recover_par2_names(newfiles) if cfg.deobfuscate_final_filenames(): # Deobfuscate the filenames logging.info("Running deobfuscate") deobfuscate.deobfuscate(nzo, newfiles, nzo.final_name) # Run the user script if script_path := make_script_path(script): # Set the current nzo status to "Ext Script...". Used in History nzo.status = Status.RUNNING nzo.set_action_line(T("Running script"), script) nzo.set_unpack_info("Script", T("Running user script %s") % script, unique=True) script_log, script_ret = external_processing( script_path, nzo, clip_path(workdir_complete), nzo.final_name, job_result ) # Format output depending on return status script_line = get_last_line(script_log) if script_ret: if script_line: script_line = "Exit(%s): %s " % (script_ret, script_line) else: script_line = T("Script exit code is %s") % script_ret elif not script_line: script_line = T("Ran %s") % script nzo.set_unpack_info("Script", script_line, unique=True) # Maybe bad script result should fail job if script_ret and cfg.script_can_fail(): script_error = True all_ok = False nzo.fail_msg = script_line # Email the results if not nzb_list and cfg.email_endjob(): if cfg.email_endjob() == 1 or (cfg.email_endjob() == 2 and (unpack_error or par_error or script_error)): emailer.endjob( nzo.final_name, nzo.cat, all_ok, workdir_complete, nzo.bytes_downloaded, nzo.fail_msg, nzo.unpack_info, script, script_log, script_ret, ) if script_log and len(script_log.rstrip().split("\n")) > 1: # Can do this only now, otherwise it would show up in the email nzo.set_unpack_info( "Script", '%s (%s)' % (script_line, nzo.nzo_id, T("More")), unique=True, ) # Cleanup again, including NZB files if all_ok and os.path.isdir(workdir_complete): cleanup_list(workdir_complete, False) # Force error for empty result all_ok = all_ok and not empty # See if we need to start an alternative or remove the duplicates sabnzbd.NzbQueue.handle_duplicate_alternatives(nzo, all_ok) except: logging.error(T("Post Processing Failed for %s (%s)"), filename, T("see logfile")) logging.info("Traceback: ", exc_info=True) nzo.fail_msg = T("Post-processing was aborted") notifier.send_notification(T("Download Failed"), filename, "failed", nzo.cat) nzo.status = Status.FAILED par_error = True all_ok = False if cfg.email_endjob(): emailer.endjob( nzo.final_name, nzo.cat, all_ok, clip_path(workdir_complete), nzo.bytes_downloaded, nzo.fail_msg, nzo.unpack_info, "", "", 0, ) workdir_notifcation_action = workdir_complete if all_ok: # If the folder only contains one file OR folder, have that as the path # Be aware that series/generic/date sorting may move a single file into a folder containing other files workdir_complete = one_file_or_folder(workdir_complete) workdir_complete = os.path.normpath(workdir_complete) # Clean up the NZO data try: nzo.purge_data(delete_all_data=all_ok) except: logging.error(T("Cleanup of %s failed."), nzo.final_name) logging.info("Traceback: ", exc_info=True) # Use automatic retry link on par2 errors and encrypted/bad RARs if par_error or unpack_error in (2, 3): try_alt_nzb(nzo) # Check if it was aborted if not nzo.pp_active: nzo.fail_msg = T("Post-processing was aborted") all_ok = False # Show final status in history if all_ok: notifier.send_notification( T("Download Completed"), filename, "complete", nzo.cat, {"open_folder": clip_path(workdir_notifcation_action)}, ) nzo.status = Status.COMPLETED nzo.fail_msg = "" else: notifier.send_notification(T("Download Failed"), filename, "failed", nzo.cat) nzo.status = Status.FAILED # Log the overall time taken for postprocessing postproc_time = int(time.time() - start) with database.HistoryDB() as history_db: # Add the nzo to the database. Only the path, script and time taken is passed # Other information is obtained from the nzo history_db.add_history_db(nzo, workdir_complete, postproc_time, script_log, script_line) # Purge items history_db.auto_history_purge() history_updated() return True def prepare_extraction_path(nzo: NzbObject) -> Tuple[str, str, Sorter, bool, Optional[str]]: """Based on the information that we have, generate the extraction path and create the directory. Separated so it can be called from DirectUnpacker """ create_job_dir = True marker_file = None # Determine category directory catdir = config.get_category(nzo.cat).dir() if not catdir: # Fall back to Default if undefined at category-level catdir = config.get_category().dir() # Check whether the creation of job directories has been disabled if catdir.endswith("*"): catdir = catdir[:-1] create_job_dir = False complete_dir = long_path(real_path(cfg.complete_dir.get_path(), catdir)) # Initialize the sorter and let it construct a path for the Complete directory file_sorter = Sorter( nzo, nzo.final_name, complete_dir, nzo.cat, ) if file_sorter.sorter_active: complete_dir = file_sorter.get_final_path() # Sorting overrides the per-category job directory creation setting create_job_dir = True complete_dir = sanitize_and_trim_path(complete_dir) if not create_job_dir: workdir_complete = create_all_dirs(complete_dir, apply_permissions=True) else: workdir_complete = get_unique_dir(os.path.join(complete_dir, nzo.final_name), create_dir=True) marker_file = set_marker(workdir_complete) if not workdir_complete or not os.path.exists(workdir_complete): logging.error(T("Cannot create final folder %s") % os.path.join(complete_dir, nzo.final_name)) raise IOError if create_job_dir and cfg.folder_rename(): prefixed_path = prefix(workdir_complete, "_UNPACK_") tmp_workdir_complete = get_unique_dir(prefix(workdir_complete, "_UNPACK_"), create_dir=False) try: renamer(workdir_complete, tmp_workdir_complete) except: pass # On failure, just use the original name # Is the unique path different? Then we also need to modify the final path if prefixed_path != tmp_workdir_complete: # The unique path adds an "extension" workdir_complete = workdir_complete + get_ext(tmp_workdir_complete) else: tmp_workdir_complete = workdir_complete return tmp_workdir_complete, workdir_complete, file_sorter, not create_job_dir, marker_file def parring(nzo: NzbObject) -> Tuple[bool, bool]: """Perform par processing. Returns: (par_error, re_add)""" logging.info("Starting verification and repair of %s", nzo.final_name) par_error = False re_add = False # Get verification status of sets verified = sabnzbd.filesystem.load_data(VERIFIED_FILE, nzo.admin_path, remove=False) or {} logging.debug("Verified sets: %s", verified) # If all were verified successfully, we skip the rest of the checks if verified and all(verified.values()): logging.info("Skipping verification and repair, all sets previously verified: %s", verified) return par_error, re_add if nzo.extrapars: # Need to make a copy because it can change during iteration for setname in list(nzo.extrapars): # We do not care about repairing samples if cfg.ignore_samples() and is_sample(setname.lower()): logging.info("Skipping verification and repair of %s because it looks like a sample", setname) continue # Skip sets that were already tried if not verified.get(setname, False): logging.info("Running verification and repair on set %s", setname) need_re_add, res = par2_repair(nzo, setname) re_add = re_add or need_re_add verified[setname] = res # Update the general repair-state par_error = par_error or not res else: logging.info("Skipping verification and repair of %s as it was previously verified", setname) # Skip other checks and RAR-rename if there was a par2 problem if not par_error: # If there's no RAR's, they might be super-obfuscated # This can happen even if par2 is present, it is always performed # so that in the next section the try_rar_check can be used if no # par2 check was performed in the previous part _, rars, _, _ = build_filelists(nzo.download_path, check_rar=False) if not rars: # Returns number of renamed RAR's rar_renamer(nzo) # Try non-par2 checks if no par2 was available (empty) and they were not tried before ("" set to True) if not any(verified.values()): # No par2-sets found, skipped if already tried before logging.info("No par2 sets for %s", nzo.final_name) nzo.set_unpack_info("Repair", T("[%s] No par2 sets") % nzo.final_name) # Try SFV-based verification and rename sfv_check_result = None if cfg.sfv_check() and not verified.get("", False): sfv_check_result = try_sfv_check(nzo) par_error = sfv_check_result is False # If no luck with SFV, do RAR-check if sfv_check_result is None and cfg.enable_unrar(): # Check for RAR's with a sensible extension _, rars, _, _ = build_filelists(nzo.download_path, check_rar=False) if rars: par_error = not try_rar_check(nzo, rars) # Save that we already tried SFV/RAR-verification verified[""] = not par_error if re_add: logging.info("Re-added %s to queue", nzo.final_name) # need to reset the status so the processing happens again if nzo.priority != FORCE_PRIORITY: nzo.priority = REPAIR_PRIORITY nzo.status = Status.FETCHING nzo.fail_msg = "" sabnzbd.NzbQueue.add(nzo) sabnzbd.Downloader.resume_from_postproc() logging.debug("Verified sets: %s", verified) sabnzbd.filesystem.save_data(verified, VERIFIED_FILE, nzo.admin_path) logging.info("Verification and repair finished for %s", nzo.final_name) return par_error, re_add def try_sfv_check(nzo: NzbObject) -> Optional[bool]: """Attempt to verify set using SFV file Return None if no SFV-sets, True/False based on verification """ # Get list of SFV names sfvs = globber_full(nzo.download_path, "*.sfv") # If no files named *.sfv, lets search for obfuscated SFV files if not sfvs: files = globber_full(nzo.download_path, "*") for file in files: if is_sfv_file(file): logging.debug("Found and will use obfuscated SFV file: %s", file) sfvs.append(file) if not sfvs: # still no SFV, so: return None result = sfv_check(sfvs, nzo) if not result: print_sfv = [os.path.basename(sfv) for sfv in sfvs] fail_msg = T('Some files failed to verify against "%s"') % "; ".join(print_sfv) nzo.set_unpack_info("Repair", fail_msg) nzo.status = Status.FAILED nzo.fail_msg = fail_msg return False # Success nzo.set_unpack_info("Repair", T("Verified successfully using SFV files")) return True def try_rar_check(nzo: NzbObject, rars: List[str]) -> bool: """Attempt to verify set using the RARs Return True if verified, False when failed When setname is '', all RAR files will be used, otherwise only the matching one If no RAR's are found, returns True """ # Sort for better processing rars.sort(key=functools.cmp_to_key(rar_sort)) # Test if rars: setname = setname_from_path(rars[0]) nzo.status = Status.VERIFYING nzo.set_unpack_info("Repair", T("Trying RAR-based verification"), setname) nzo.set_action_line(T("Trying RAR-based verification"), "...") try: # Requires de-unicode for RarFile to work! zf = rarfile.RarFile(rars[0]) # Skip if it's encrypted if zf.needs_password(): msg = T("[%s] RAR-based verification failed: %s") % (setname, T("Passworded")) nzo.set_unpack_info("Repair", msg) return True # Will throw exception if something is wrong zf.testrar() # Success! msg = T("RAR files verified successfully") nzo.set_unpack_info("Repair", msg, setname) logging.info(msg) return True except rarfile.Error as e: nzo.fail_msg = T("RAR files failed to verify") msg = T("[%s] RAR-based verification failed: %s") % (setname, e) nzo.set_unpack_info("Repair", msg, setname) logging.info(msg) return False else: # No rar-files, so just continue return True def rar_renamer(nzo: NzbObject) -> int: """Deobfuscate rar file names: Use header and content information to give RAR-files decent names""" nzo.status = Status.VERIFYING nzo.set_unpack_info("Repair", T("Trying RAR renamer")) nzo.set_action_line(T("Trying RAR renamer"), "...") renamed_files = 0 # This is the most important datastructure (in case of mixed obfuscated rarsets) rarvolnr = {} # rarvolnr will contain per rar vol number the rarfilenames and their respective contents (and maybe other characteristics, like filesizes). # for example: rarvolnr[6]['somerandomfilename.rar']={'readme.txt', 'linux.iso'}, # which means 'somerandomfilename.rar' has rarvolnumber 6, and contents 'readme.txt' and 'linux.iso' # if we find a rarfile with rarvolnumber 7, and 'linux.iso' in it, we have a match! # The volume number and real extension of a (obfuscated) rar file # so volnrext['dfakjldfalkjdfl.blabla'] = (14, 'part014.rar') or (2, 'r000') # Not really needed, but handy to avoid a second lookup at the renaming volnrext = {} # Scan rar files in workdir, but not subdirs workdir_files = os.listdir(nzo.download_path) for file_to_check in workdir_files: file_to_check = os.path.join(nzo.download_path, file_to_check) # We only want files: if not os.path.isfile(file_to_check): continue if rarfile.is_rarfile(file_to_check): # if a rar file is fully encrypted, rarfile.RarFile() will return an empty list: if not rarfile.RarFile(file_to_check, single_file_check=True).filelist(): logging.info( "Download %s contains a fully encrypted & obfuscated rar-file: %s.", nzo.final_name, file_to_check, ) # bail out return renamed_files # The function will check if it's a RAR-file # We do a sanity-check for the returned number rar_vol, new_extension = rarvolinfo.get_rar_extension(file_to_check) if 0 < rar_vol < 1000: logging.debug("Detected volume-number %s from RAR-header: %s ", rar_vol, file_to_check) volnrext[file_to_check] = (rar_vol, new_extension) # The files inside rar file rar_contents = rarfile.RarFile( os.path.join(nzo.download_path, file_to_check), single_file_check=True ).filelist() try: rarvolnr[rar_vol] except: # does not yet exist, so create: rarvolnr[rar_vol] = {} rarvolnr[rar_vol][file_to_check] = rar_contents # store them for matching (if needed) else: logging.debug("No RAR-volume-number found in %s", file_to_check) logging.debug("Deobfuscate: rarvolnr is: %s", rarvolnr) logging.debug("Deobfuscate: volnrext is: %s", volnrext) # Could be that there are no rar-files, we stop if not len(rarvolnr): return renamed_files # this can probably done with a max-key-lambda oneliner, but ... how? numberofrarsets = 0 for mykey in rarvolnr.keys(): numberofrarsets = max(numberofrarsets, len(rarvolnr[mykey])) logging.debug("Number of rarset is %s", numberofrarsets) if numberofrarsets == 1: # Just one obfuscated rarset ... that's easy logging.debug("Deobfuscate: Just one obfuscated rarset") for filename in volnrext: new_rar_name = "%s.%s" % (nzo.final_name, volnrext[filename][1]) new_rar_name = os.path.join(nzo.download_path, new_rar_name) new_rar_name = get_unique_filename(new_rar_name) logging.debug("Deobfuscate: Renaming %s to %s" % (filename, new_rar_name)) renamer(filename, new_rar_name) renamed_files += 1 return renamed_files # numberofrarsets bigger than 1, so a mixed rar set, so we need pre-checking # Sanity check of the rar set # Get the highest rar part number (that's the upper limit): highest_rar = sorted(rarvolnr.keys())[-1] # A staircase check: number of rarsets should no go up, but stay the same or go down how_many_previous = 1000 # 1000 rarset mixed ... should be enough ... typical is 1, 2 or maybe 3 # Start at part001.rar and go the highest for rar_set_number in range(1, highest_rar + 1): try: how_many_here = len(rarvolnr[rar_set_number]) except: # rarset does not exist at all logging.warning("rarset %s is missing completely, so I can't deobfuscate.", rar_set_number) return 0 # OK, it exists, now let's check it's not higher if how_many_here > how_many_previous: # this should not happen: higher number of rarset than previous number of rarset logging.warning("no staircase! rarset %s is higher than previous, so I can't deobfuscate.", rar_set_number) return 0 how_many_previous = how_many_here # OK, that looked OK (a declining staircase), so we can safely proceed # More than one obfuscated rarset, so we must do matching based of files inside the rar files # Assign (random) rar set names, first come first serve basis rarsetname = {} # in which rar set it should be, so rar set 'A', or 'B', or ... mychar = "A" # First things first: Assigning a rarsetname to the rar file which have volume number 1 for base_obfuscated_filename in rarvolnr[1]: rarsetname[base_obfuscated_filename] = mychar + "--" + nzo.final_name mychar = chr(ord(mychar) + 1) logging.debug("Deobfuscate: rarsetname %s", rarsetname) # Do the matching, layer by layer (read: rarvolnumber) # So, all rar files with rarvolnr 1, find the contents (files inside the rar), # and match with rarfiles with rarvolnr 2, and put them in the correct rarset. # And so on, until the highest rarvolnr minus 1 matched against highest rarvolnr for n in range(1, len(rarvolnr)): logging.debug("Deobfuscate: Finding matches between rar sets %s and %s" % (n, n + 1)) for base_obfuscated_filename in rarvolnr[n]: matchcounter = 0 for next_obfuscated_filename in rarvolnr[n + 1]: # set() method with intersection (less strict): set(rarvolnr[n][base_obfuscated_filename]).intersection(set(rarvolnr[n+1][next_obfuscated_filename])) # check if the last filename inside the existing rar matches with the first filename in the following rar if rarvolnr[n][base_obfuscated_filename][-1] == rarvolnr[n + 1][next_obfuscated_filename][0]: try: rarsetname[next_obfuscated_filename] = rarsetname[base_obfuscated_filename] matchcounter += 1 except KeyError: logging.warning(T("No matching earlier rar file for %s"), next_obfuscated_filename) if matchcounter > 1: logging.info("Deobfuscate: more than one match, so risk on false positive matching.") # Do the renaming: for filename in rarsetname: new_rar_name = "%s.%s" % (rarsetname[filename], volnrext[filename][1]) new_rar_name = os.path.join(nzo.download_path, new_rar_name) new_rar_name = get_unique_filename(new_rar_name) logging.debug("Deobfuscate: Renaming %s to %s" % (filename, new_rar_name)) renamer(filename, new_rar_name) renamed_files += 1 # Done: The obfuscated rar files have now been renamed to regular formatted filenames return renamed_files def handle_empty_queue(): """Check if empty queue calls for action""" if not sabnzbd.NzbQueue.actives(): sabnzbd.save_state() notifier.send_notification( "SABnzbd", T("Queue finished"), "queue_done", actions={"open_complete": cfg.complete_dir.get_clipped_path()}, ) # Perform end-of-queue script if not is_none(cfg.end_queue_script()): logging.info("Queue has finished, launching script: %s ", cfg.end_queue_script()) run_script(cfg.end_queue_script()) # Perform end-of-queue action when one is set if sabnzbd.QUEUECOMPLETEACTION: logging.info("Queue has finished, launching action: %s ", sabnzbd.QUEUECOMPLETEACTION) Thread(target=sabnzbd.QUEUECOMPLETEACTION).start() change_queue_complete_action(cfg.queue_complete(), new=False) # Trigger garbage collection and release of memory logging.debug("Triggering garbage collection and release of memory") gc.collect() if sabnzbd.LIBC: sabnzbd.LIBC.malloc_trim(0) def cleanup_list(wdir: str, skip_nzb: bool): """Remove all files whose extension matches the cleanup list, optionally ignoring the nzb extension """ if cfg.cleanup_list(): try: with os.scandir(wdir) as files: for entry in files: if entry.is_dir(): cleanup_list(entry.path, skip_nzb) cleanup_empty_directories(entry.path) else: if on_cleanup_list(entry.name, skip_nzb): try: logging.info("Removing unwanted file %s", entry.path) remove_file(entry.path) except: logging.error(T("Removing %s failed"), clip_path(entry.path)) logging.info("Traceback: ", exc_info=True) except: logging.info("Traceback: ", exc_info=True) def prefix(path: str, pre: str) -> str: """Apply prefix to last part of path '/my/path' and 'hi_' will give '/my/hi_path' """ p, d = os.path.split(path) return os.path.join(p, pre + d) def nzb_redirect(wdir, nzbname, pp, script, cat, priority): """Check if this job contains only NZB files, if so send to queue and remove if on clean-up list Returns list of processed NZB's """ files = listdir_full(wdir) for nzb_file in files: if get_ext(nzb_file) != ".nzb": return None # For multiple NZBs, cannot use the current job name if len(files) != 1: nzbname = None # Process all NZB files for nzb_file in files: process_single_nzb( get_filename(nzb_file), nzb_file, pp=pp, script=script, cat=cat, priority=priority, dup_check=False, nzbname=nzbname, ) return files def one_file_or_folder(folder: str) -> str: """If the dir only contains one file or folder, join that file/folder onto the path""" if os.path.exists(folder) and os.path.isdir(folder): try: cont = os.listdir(folder) if len(cont) == 1: folder = os.path.join(folder, cont[0]) folder = one_file_or_folder(folder) except OSError: # Can occur on paths it doesn't like, for example "C:" pass return folder TAG_RE = re.compile(r"<[^>]+>") def get_last_line(txt: str) -> str: """Return last non-empty line of a text, trim to 150 max""" # First we remove HTML code in a basic way txt = TAG_RE.sub(" ", txt) # Then we get the last line lines = txt.split("\n") n = len(lines) - 1 while n >= 0 and not lines[n].strip("\r\t "): n = n - 1 line = lines[n].strip("\r\t ") if len(line) >= 150: line = line[:147] + "..." return line def remove_samples(path: str): """Remove all files that match the sample pattern Skip deleting if it matches all files or there is only 1 file """ files_to_delete = [] nr_files = 0 for root, _dirs, files in os.walk(path): for file_to_match in files: nr_files += 1 if is_sample(file_to_match): files_to_delete.append(os.path.join(root, file_to_match)) # Make sure we skip false-positives if len(files_to_delete) < nr_files: for path in files_to_delete: try: logging.info("Removing unwanted sample file %s", path) remove_file(path) except: logging.error(T("Removing %s failed"), clip_path(path)) logging.info("Traceback: ", exc_info=True) else: logging.info("Skipping sample-removal, false-positive") def rename_and_collapse_folder(oldpath: str, newpath: str, files: List[str]) -> List[str]: """Rename folder, collapsing when there's just a single subfolder oldpath --> newpath OR oldpath/subfolder --> newpath Modify list of filenames accordingly """ orgpath = oldpath items = globber(oldpath) if len(items) == 1: folder = items[0] folder_path = os.path.join(oldpath, folder) if os.path.isdir(folder_path) and folder.lower() not in IGNORED_MOVIE_FOLDERS: logging.info("Collapsing %s", os.path.join(newpath, folder)) oldpath = folder_path oldpath = os.path.normpath(oldpath) newpath = os.path.normpath(newpath) files = [os.path.normpath(f).replace(oldpath, newpath) for f in files] renamer(oldpath, newpath) try: remove_dir(orgpath) except: pass return files def set_marker(folder: str) -> Optional[str]: """Set marker file and return name""" if name := cfg.marker_file(): path = os.path.join(folder, name) logging.debug("Create marker file %s", path) try: fp = open(path, "w") fp.close() except: logging.info("Cannot create marker file %s", path) logging.info("Traceback: ", exc_info=True) name = None return name def del_marker(path: str): """Remove marker file""" if path and os.path.exists(path): logging.debug("Removing marker file %s", path) try: remove_file(path) except: logging.info("Cannot remove marker file %s", path) logging.info("Traceback: ", exc_info=True) def remove_from_list(name: Optional[str], lst: List[str]): if name: for n in range(len(lst)): if lst[n].endswith(name): logging.debug("Popping %s", lst[n]) lst.pop(n) return def try_alt_nzb(nzo: NzbObject): """Try to get a new NZB if available""" url = nzo.nzo_info.get("failure") if url and cfg.new_nzb_on_failure(): sabnzbd.urlgrabber.add_url(url, nzo.pp, nzo.script, nzo.cat, nzo.priority) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.445397 SABnzbd-4.3.2/sabnzbd/lang.py0000644000000000000000000001740014625637243015143 0ustar00runnerstaff#!/usr/bin/python3 -OO # -*- coding: utf-8 -*- # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.lang - Language support """ # This module should be the first non-standard import to # be done at the top of the application's main file. # This will ensure that the default language is available # and the special functions are active. # This module cannot import any application modules!! # # Required keywords for pygettext.py: -k T -k TT # # The following pseudo-builtins are provided. # T() Unicode translation # TT() Dummy translation, use to mark table entries for POT scanning import gettext import builtins import glob import os import locale __all__ = ["set_locale_info", "set_language", "list_languages", "is_rtl"] _DOMAIN = "" # Holds translation domain _LOCALEDIR = "" # Holds path to the translation base folder def set_locale_info(domain, localedir): """Setup the domain and localedir for translations""" global _DOMAIN, _LOCALEDIR _DOMAIN = domain _LOCALEDIR = localedir def set_language(language=None): """Activate language, empty language will set default texts.""" if not language: language = "" lng = gettext.translation(_DOMAIN, _LOCALEDIR, [language], fallback=True) builtins.__dict__["T"] = lng.gettext builtins.__dict__["TT"] = lambda x: str(x) # Use in text tables def list_languages(): """Return sorted list of (lang-code, lang-string) pairs, representing the available languages. When any language file is found, the default tuple ('en', 'English') will be included. Otherwise an empty list is returned. """ # Find all the MO files. lst = [] for path in glob.glob(os.path.join(_LOCALEDIR, "*")): if os.path.isdir(path) and not path.endswith("en"): lngname = os.path.basename(path) lng = locale.normalize(lngname) # Example: 'pt_BR.ISO8859-1' lng_short = lng[: lng.find("_")] lng_full = lng[: lng.find(".")] # First try full language string, e.g. 'pt_BR' language = LanguageTable.get(lng_full, (lng_full, lng_full)) if language[0] == lng_full: # Full language string not defined: try short form, e.g. 'pt' language = LanguageTable.get(lng_short, (lng_short, lng_short)) lng = lng_short else: lng = lng_full language = language[1] lst.append((lng, language)) lst.append(("en", "English")) lst.sort() return lst def is_rtl(lang): """returns True if given lang is a right-to-left language. Default: False.""" try: return LanguageTable.get(lang, "en")[3] except: return False # English name, native name, code page, right-to-left LanguageTable = { "aa": ("Afar", "Afaraf", 0, False), "af": ("Afrikaans", "Afrikaans", 0, False), "ak": ("Akan", "Akan", 0, False), "sq": ("Albanian", "Shqip", 0, False), "an": ("Aragonese", "Aragonés", 0, False), "ae": ("Avestan", "Avesta", 0, False), "ay": ("Aymara", "Aymararu", 0, False), "bm": ("Bambara", "Bamanankan", 0, False), "eu": ("Basque", "Euskara", 0, False), "bi": ("Bislama", "Bislama", 0, False), "bs": ("Bosnian", "Bosanskijezik", 0, False), "br": ("Breton", "Brezhoneg", 0, False), "ca": ("Catalan", "Català", 0, False), "ch": ("Chamorro", "Chamoru", 0, False), "kw": ("Cornish", "Kernewek", 0, False), "co": ("Corsican", "Corsu", 0, False), "hr": ("Croatian", "Hrvatski", 0, False), "cs": ("Czech", "Cesky, ceština", 0, False), "da": ("Danish", "Dansk", 0, False), "nl": ("Dutch", "Nederlands", 0, False), "en": ("English", "English", 0, False), "eo": ("Esperanto", "Esperanto", 0, False), "et": ("Estonian", "Eesti", 0, False), "fo": ("Faroese", "Føroyskt", 0, False), "fj": ("Fijian", "Vosa Vakaviti", 0, False), "fi": ("Finnish", "Suomi", 0, False), "fr": ("French", "Français", 0, False), "gl": ("Galician", "Galego", 0, False), "de": ("German", "Deutsch", 0, False), "he": ("Hebrew", "עִבְרִית‎", 1255, True), "hz": ("Herero", "Otjiherero", 0, False), "ho": ("Hiri Motu", "Hiri Motu", 0, False), "hu": ("Hungarian", "Magyar", 0, False), "id": ("Indonesian", "Bahasa Indonesia", 0, False), "ga": ("Irish", "Gaeilge", 0, False), "io": ("Ido", "Ido", 0, False), "is": ("Icelandic", "Íslenska", 0, False), "it": ("Italian", "Italiano", 0, False), "jv": ("Javanese", "BasaJawa", 0, False), "rw": ("Kinyarwanda", "Ikinyarwanda", 0, False), "kg": ("Kongo", "KiKongo", 0, False), "kj": ("Kwanyama", "Kuanyama", 0, False), "la": ("Latin", "Lingua latina", 0, False), "lb": ("Luxembourgish", "Lëtzebuergesch", 0, False), "lg": ("Luganda", "Luganda", 0, False), "li": ("Limburgish", "Limburgs", 0, False), "ln": ("Lingala", "Lingála", 0, False), "lt": ("Lithuanian", "Lietuviukalba", 0, False), "lv": ("Latvian", "Latviešuvaloda", 0, False), "gv": ("Manx", "Gaelg", 0, False), "mg": ("Malagasy", "Malagasy fiteny", 0, False), "mt": ("Maltese", "Malti", 0, False), "nb": ("Norwegian Bokmål", "Norsk bokmål", 0, False), "nn": ("Norwegian Nynorsk", "Norsk nynorsk", 0, False), "no": ("Norwegian", "Norsk", 0, False), "oc": ("Occitan", "Occitan", 0, False), "om": ("Oromo", "Afaan Oromoo", 0, False), "pl": ("Polish", "Polski", 0, False), "pt": ("Portuguese", "Português", 0, False), "pt_BR": ("Portuguese Brazilian", "Português Brasileiro", 0, False), "rm": ("Romansh", "Rumantsch grischun", 0, False), "rn": ("Kirundi", "kiRundi", 0, False), "ro": ("Romanian", "Româna", 1250, False), "sc": ("Sardinian", "Sardu", 0, False), "se": ("Northern Sami", "Davvisámegiella", 0, False), "sm": ("Samoan", "Gagana fa'a Samoa", 0, False), "gd": ("Gaelic", "Gàidhlig", 0, False), "ru": ("Russian", "русский язык", 1251, False), "sr": ("Serbian", "српски", 1251, False), "sn": ("Shona", "Chi Shona", 0, False), "sk": ("Slovak", "Slovencina", 0, False), "sl": ("Slovene", "Slovenšcina", 0, False), "st": ("Southern Sotho", "Sesotho", 0, False), "es": ("Spanish Castilian", "Español, castellano", 0, False), "su": ("Sundanese", "Basa Sunda", 0, False), "sw": ("Swahili", "Kiswahili", 0, False), "ss": ("Swati", "SiSwati", 0, False), "sv": ("Swedish", "Svenska", 0, False), "tn": ("Tswana", "Setswana", 0, False), "to": ("Tonga (Tonga Islands)", "faka Tonga", 0, False), "tr": ("Turkish", "Türkçe", 0, False), "ts": ("Tsonga", "Xitsonga", 0, False), "tw": ("Twi", "Twi", 0, False), "ty": ("Tahitian", "Reo Tahiti", 0, False), "wa": ("Walloon", "Walon", 0, False), "cy": ("Welsh", "Cymraeg", 0, False), "wo": ("Wolof", "Wollof", 0, False), "fy": ("Western Frisian", "Frysk", 0, False), "xh": ("Xhosa", "isi Xhosa", 0, False), "yo": ("Yoruba", "Yorùbá", 0, False), "zu": ("Zulu", "isi Zulu", 0, False), "zh_CN": ("SimpChinese", "简体中文", 936, False), } # Setup a safe null-translation set_language() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4454803 SABnzbd-4.3.2/sabnzbd/decoder.py0000644000000000000000000002727414625637243015641 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.decoder - article decoder """ import logging import hashlib import binascii from io import BytesIO from zlib import crc32 import sabnzbd from sabnzbd.constants import SABCTOOLS_VERSION_REQUIRED from sabnzbd.encoding import ubtou from sabnzbd.nzbstuff import Article from sabnzbd.misc import match_str # Check for correct SABCTools version SABCTOOLS_VERSION = None SABCTOOLS_SIMD = None SABCTOOLS_OPENSSL_LINKED = None try: import sabctools SABCTOOLS_ENABLED = True SABCTOOLS_VERSION = sabctools.__version__ SABCTOOLS_SIMD = sabctools.simd SABCTOOLS_OPENSSL_LINKED = sabctools.openssl_linked # Verify version to at least match minor version if SABCTOOLS_VERSION[:3] != SABCTOOLS_VERSION_REQUIRED[:3]: raise ImportError except: SABCTOOLS_ENABLED = False class BadData(Exception): def __init__(self, data: bytes): super().__init__() self.data = data class BadYenc(Exception): pass class BadUu(Exception): pass def decode(article: Article, data_view: memoryview): decoded_data = None nzo = article.nzf.nzo art_id = article.article # Keeping track article_success = False try: if nzo.precheck: raise BadYenc if sabnzbd.LOG_ALL: logging.debug("Decoding %s", art_id) if article.nzf.type == "uu": decoded_data = decode_uu(article, bytes(data_view)) else: decoded_data = decode_yenc(article, data_view) article_success = True except MemoryError: logging.warning(T("Decoder failure: Out of memory")) logging.info("Cache: %d, %d, %d", *sabnzbd.ArticleCache.cache_info()) logging.info("Traceback: ", exc_info=True) sabnzbd.Downloader.pause() # This article should be fetched again sabnzbd.NzbQueue.reset_try_lists(article) return except BadData as error: # Continue to the next one if we found new server if search_new_server(article): return # Store data, maybe par2 can still fix it decoded_data = error.data except BadUu: logging.info("Badly formed uu article in %s", art_id) # Try the next server if search_new_server(article): return except (BadYenc, ValueError): # Handles precheck and badly formed articles if nzo.precheck and data_view and data_view[:4] == b"223 ": # STAT was used, so we only get a status code article_success = True else: # Try uu-decoding if not nzo.precheck and article.nzf.type != "yenc": try: decoded_data = decode_uu(article, bytes(data_view)) logging.debug("Found uu-encoded article %s in job %s", art_id, nzo.final_name) article_success = True except: pass # Only bother with further checks if uu-decoding didn't work out if not article_success: # Convert the first 2000 bytes of raw socket data to article lines, # and examine the headers (for precheck) or body (for download). for line in bytes(data_view[:2000]).split(b"\r\n"): lline = line.lower() if lline.startswith(b"message-id:"): article_success = True # Look for DMCA clues (while skipping "X-" headers) if not lline.startswith(b"x-") and match_str(lline, (b"dmca", b"removed", b"cancel", b"blocked")): article_success = False logging.info("Article removed from server (%s)", art_id) break # Pre-check, proper article found so just register if nzo.precheck and article_success and sabnzbd.LOG_ALL: logging.debug("Server %s has article %s", article.fetcher, art_id) elif not article_success: # If not pre-check, this must be a bad article if not nzo.precheck: logging.info("Badly formed yEnc article %s", art_id) # Continue to the next one if we found new server if search_new_server(article): return except: logging.warning(T("Unknown Error while decoding %s"), art_id) logging.info("Traceback: ", exc_info=True) # Continue to the next one if we found new server if search_new_server(article): return if decoded_data: # If the data needs to be written to disk due to full cache, this will be slow # Causing the decoder-queue to fill up and delay the downloader sabnzbd.ArticleCache.save_article(article, decoded_data) article.decoded = True elif not nzo.precheck: # Nothing to save article.on_disk = True sabnzbd.NzbQueue.register_article(article, article_success) def decode_yenc(article: Article, data_view: memoryview) -> bytearray: # Let SABCTools do all the heavy lifting ( decoded_data, yenc_filename, article.file_size, article.data_begin, article.data_size, crc_correct, ) = sabctools.yenc_decode(data_view) nzf = article.nzf # Assume it is yenc nzf.type = "yenc" # Only set the name if it was found and not obfuscated if not nzf.filename_checked and yenc_filename: # Set the md5-of-16k if this is the first article if article.lowest_partnum: nzf.md5of16k = hashlib.md5(decoded_data[:16384]).digest() # Try the rename, even if it's not the first article # For example when the first article was missing nzf.nzo.verify_nzf_filename(nzf, yenc_filename) # CRC check if crc_correct is None: logging.info("CRC Error in %s", article.article) raise BadData(decoded_data) article.crc32 = crc_correct return decoded_data def decode_uu(article: Article, raw_data: bytes) -> bytes: """Try to uu-decode an article. The raw_data may or may not contain headers. If there are headers, they will be separated from the body by at least one empty line. In case of no headers, the first line seems to always be the nntp response code (220/222) directly followed by the msg body.""" if not raw_data: logging.debug("No data to decode") raise BadUu # Line up the raw_data raw_data = raw_data.split(b"\r\n") # Index of the uu payload start in raw_data uu_start = 0 # Limit the number of lines to check for the onset of uu data limit = min(len(raw_data), 32) - 1 if limit < 3: logging.debug("Article too short to contain valid uu-encoded data") raise BadUu # Try to find an empty line separating the body from headers or response # code and set the expected payload start to the next line. try: uu_start = raw_data[:limit].index(b"") + 1 except ValueError: # No empty line, look for a response code instead if raw_data[0].startswith(b"220 ") or raw_data[0].startswith(b"222 "): uu_start = 1 else: # Invalid data? logging.debug("Failed to locate start of uu payload") raise BadUu def is_uu_junk(line: bytes) -> bool: """Determine if the line is empty or contains known junk data""" return (not line) or line == b"-- " or line.startswith(b"Posted via ") # Check the uu 'begin' line if article.lowest_partnum: try: # Make sure the line after the uu_start one isn't empty as well or # detection of the 'begin' line won't work. For articles other than # lowest_partnum, filtering out empty lines (and other junk) can # wait until the actual decoding step. for index in range(uu_start, limit): if is_uu_junk(raw_data[index]): uu_start = index + 1 else: # Bingo break else: # Search reached the limit raise IndexError uu_begin_data = raw_data[uu_start].split(b" ") # Filename may contain spaces uu_filename = ubtou(b" ".join(uu_begin_data[2:]).strip()) # Sanity check the 'begin' line if ( len(uu_begin_data) < 3 or uu_begin_data[0].lower() != b"begin" or (not int(uu_begin_data[1], 8)) or (not uu_filename) ): raise ValueError # Consider this enough proof to set the type, avoiding further # futile attempts at decoding articles in this nzf as yenc. article.nzf.type = "uu" # Bump the pointer for the payload to the next line uu_start += 1 except Exception: logging.debug("Missing or invalid uu 'begin' line: %s", raw_data[uu_start] if uu_start < limit else None) raise BadUu # Do the actual decoding with BytesIO() as decoded_data: for line in raw_data[uu_start:]: # Ignore junk if is_uu_junk(line): continue # End of the article if line in (b"`", b"end", b"."): break # Remove dot stuffing if line.startswith(b".."): line = line[1:] try: decoded_line = binascii.a2b_uu(line) except binascii.Error as msg: try: # Workaround for broken uuencoders by Fredrik Lundh nbytes = (((line[0] - 32) & 63) * 4 + 5) // 3 decoded_line = binascii.a2b_uu(line[:nbytes]) except Exception as msg2: logging.info( "Error while uu-decoding %s: %s (line: %s; workaround: %s)", article.article, msg, line, msg2 ) raise BadData(decoded_data.getvalue()) # Store the decoded data decoded_data.write(decoded_line) # Set the type to uu; the latter is still needed in # case the lowest_partnum article was damaged or slow to download. article.nzf.type = "uu" if article.lowest_partnum: decoded_data.seek(0) article.nzf.md5of16k = hashlib.md5(decoded_data.read(16384)).digest() # Handle the filename if not article.nzf.filename_checked and uu_filename: article.nzf.nzo.verify_nzf_filename(article.nzf, uu_filename) data = decoded_data.getvalue() article.crc32 = crc32(data) return data def search_new_server(article: Article) -> bool: """Shorthand for searching new server or else increasing bad_articles""" # Continue to the next one if we found new server if not article.search_new_server(): # Increase bad articles if no new server was found article.nzf.nzo.increase_bad_articles_counter("bad_articles") return False return True ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4455607 SABnzbd-4.3.2/sabnzbd/skintext.py0000644000000000000000000015212714625637243016101 0ustar00runnerstaff#!/usr/bin/python3 -OO # -*- coding: UTF-8 -*- # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.skintext - Language strings used in the templates """ SKIN_TEXT = { # Special texts "stage-download": TT("Download"), #: Queue status "download" "stage-repair": TT("Repair"), #: PP phase "repair" "stage-filejoin": TT("Join files"), #: PP phase "filejoin" "stage-unpack": TT("Unpack"), #: PP phase "unpack" "stage-deobfuscate": TT("Deobfuscate"), #: PP phase "deobfuscate" "stage-script": TT("Script"), #: PP phase "script" "stage-rss": TT("RSS"), #: PP RSS feed of the NZB "stage-source": TT("Source"), #: PP Source of the NZB (path or URL) "stage-servers": TT("Servers"), #: PP Distribution over servers "post-Completed": TT("Completed"), #: PP status "post-Failed": TT("Failed"), #: PP status "post-Queued": TT("Waiting"), #: Queue and PP status "post-Paused": TT("Paused"), #: PP status "post-Repairing": TT("Repairing..."), #: PP status "post-Extracting": TT("Extracting..."), #: PP status "post-Moving": TT("Moving..."), #: PP status "post-Running": TT("Running script..."), #: PP status "post-Fetching": TT("Fetching extra blocks..."), #: PP status "post-QuickCheck": TT("Quick Check..."), #: PP status "post-Verifying": TT("Verifying..."), #: PP status "post-Checking": TT("Checking"), #: PP status "sch-disable_server": TT("disable server"), #: #: Config->Scheduler "sch-enable_server": TT("enable server"), #: #: Config->Scheduler "sch-speedlimit": TT("Speedlimit"), #: #: Config->Scheduler "sch-pause_all": TT("Pause All"), #: #: Config->Scheduler "sch-pause_post": TT("Pause post-processing"), #: #: Config->Scheduler "sch-resume_post": TT("Resume post-processing"), #: #: Config->Scheduler "sch-scan_folder": TT("Scan watched folder"), #: #: Config->Scheduler "sch-rss_scan": TT("Read RSS feeds"), #: #: Config->Scheduler "sch-remove_failed": TT("Remove failed jobs"), #: Config->Scheduler "sch-remove_completed": TT("Remove completed jobs"), #: Config->Scheduler "sch-pause_all_low": TT("Pause low priority jobs"), #: Config->Scheduler "sch-pause_all_normal": TT("Pause normal priority jobs"), #: Config->Scheduler "sch-pause_all_high": TT("Pause high priority jobs"), #: Config->Scheduler "sch-resume_all_low": TT("Resume low priority jobs"), #: Config->Scheduler "sch-resume_all_normal": TT("Resume normal priority jobs"), #: Config->Scheduler "sch-resume_all_high": TT("Resume high priority jobs"), #: Config->Scheduler "sch-enable_quota": TT("Enable quota management"), #: Config->Scheduler "sch-disable_quota": TT("Disable quota management"), #: Config->Scheduler "sch-pause_cat": TT("Pause jobs with category"), #: Config->Scheduler "sch-resume_cat": TT("Resume jobs with category"), #: Config->Scheduler "prowl-off": TT("Off"), #: Prowl priority "prowl-very-low": TT("Very Low"), #: Prowl priority "prowl-moderate": TT("Moderate"), #: Prowl priority "prowl-normal": TT("Normal"), #: Prowl priority "prowl-high": TT("High"), #: Prowl priority "prowl-emergency": TT("Emergency"), #: Prowl priority "pushover-off": TT("Off"), #: Prowl priority "pushover-low": TT("Low"), #: Prowl priority "pushover-high": TT("High"), #: Prowl priority # General texts "default": TT("Default"), #: Default value, used in dropdown menus "none": TT("None"), #: No value, used in dropdown menus "hour": TT("hour"), #: One hour "hours": TT("hours"), #: Multiple hours "minute": TT("min"), #: One minute "minutes": TT("mins"), #: Multiple minutes "second": TT("sec"), #: One second "seconds": TT("seconds"), #: Multiple seconds "day": TT("day"), "days": TT("days"), "week": TT("week"), "month": TT("Month"), "year": TT("Year"), "monday": TT("Monday"), "tuesday": TT("Tuesday"), "wednesday": TT("Wednesday"), "thursday": TT("Thursday"), "friday": TT("Friday"), "saturday": TT("Saturday"), "sunday": TT("Sunday"), "day-of-month": TT("Day of month"), "thisWeek": TT("This week"), "thisMonth": TT("This month"), "selectedDates": TT("Selected date range"), "today": TT("Today"), "total": TT("Total"), "on": TT("on"), "off": TT("off"), "parameters": TT("Parameters"), #: Config: startup parameters of SABnzbd "pythonVersion": TT("Python Version"), "notAvailable": TT("Not available"), "empty": TT("Empty"), "homePage": TT("Home page"), #: Home page of the SABnzbd project "source": TT("Source"), #: Where to find the SABnzbd sourcecode "or": TT("or"), "host": TT("Host"), "cancel": TT("Cancel"), "login": TT("Log in"), "logout": TT("Log out"), "rememberme": TT("Remember me"), # General template elements "button-save": TT("Save"), #: "Save" button "button-saving": TT("Saving.."), "button-failed": TT("Failed"), "confirm": TT("Are you sure?"), #: Used in confirmation popups # Header "menu-home": TT("Home"), #: Main menu item "menu-queue": TT("Queue"), #: Main menu item "menu-history": TT("History"), #: Main menu item "menu-config": TT("Config"), #: Main menu item "menu-cons": TT("Status"), #: Main menu item "menu-help": TT("Help"), #: Main menu item "menu-wiki": TT("Wiki"), #: Main menu item "menu-forums": TT("Forum"), #: Main menu item "menu-live-chat": TT("Live Chat"), #: Main menu item "menu-issues": TT("Issues"), #: Main menu item "menu-donate": TT("Support the project, Donate!"), #: Main menu item "cmenu-general": TT("General"), #: Main menu item "cmenu-folders": TT("Folders"), #: Main menu item "cmenu-switches": TT("Switches"), #: Main menu item "cmenu-servers": TT("Servers"), #: Main menu item "cmenu-scheduling": TT("Scheduling"), #: Main menu item "cmenu-rss": TT("RSS"), #: Main menu item "cmenu-notif": TT("Notifications"), #: Main menu item "cmenu-email": TT("Email"), #: Main menu item "cmenu-cat": TT("Categories"), #: Main menu item "cmenu-sorting": TT("Sorting"), #: Main menu item "cmenu-special": TT("Special"), #: Main menu item "cmenu-search": TT("Search"), #: Main menu item # Main page "shutdownOK?": TT("Are you sure you want to shutdown SABnzbd?"), "link-pause": TT("Pause"), #: Pause downloading "link-resume": TT("Resume"), #: Resume downloading "button-add": TT("Add"), #: Add NZB to queue (button) "add": TT("Add"), #: Add NZB to queue (header) "category": TT("Category"), #: Job category "script": TT("Script"), "priority": TT("Priority"), "pp-none": TT("Download"), #: Post processing pick list "pp-repair": TT("+Repair"), #: Post processing pick list "pp-unpack": TT("+Unpack"), #: Post processing pick list "pp-delete": TT("+Delete"), #: Post processing pick list "pr-force": TT("Force"), #: Priority pick list "pr-normal": TT("Normal"), #: Priority pick list "pr-high": TT("High"), #: Priority pick list "pr-low": TT("Low"), #: Priority pick list "pr-paused": TT("Paused"), #: Priority pick list "pr-stop": TT("Stop"), #: Priority pick list "enterURL": TT("Enter URL"), #: Add NZB Dialog # Queue page "shutdownPc": TT("Shutdown PC"), #: Queue page end-of-queue action "standbyPc": TT("Standby PC"), #: Queue page end-of-queue action "hibernatePc": TT("Hibernate PC"), #: Queue page end-of-queue action "shutdownSab": TT("Shutdown SABnzbd"), #: Queue page end-of-queue action "pauseFor": TT("Pause for"), #: Queue page button or entry box "mode": TT("Processing"), #: Queue page table column header "name": TT("Name"), #: Queue page table column header "button-retry": TT("Retry"), #: Queue page button "eoq-scripts": TT("Scripts"), #: Queue page table, script selection menu "purgeQueue": TT("Purge Queue"), #: Queue page button "purgeQueueConf": TT("Delete all items from the queue?"), #: Confirmation popup "confirm-delete": TT("Are you sure you want to remove these jobs?"), #: Delete confirmation popup "purgeNZBs": TT("Purge NZBs"), #: Queue page button "purgeNZBs-Files": TT("Purge NZBs & Delete Files"), #: Queue page button "removeNZB": TT("Remove NZB"), #: Queue page button "removeNZB-Files": TT("Remove NZB & Delete Files"), #: Queue page button "permanently-delete": TT("Permanently delete (skip archive)"), #: Checkbox if job should be added to Archive "missingArt": TT("Missing articles"), #: Caption for missing articles in Queue "quota-left": TT("Quota left"), #: Remaining quota (displayed in Queue) "manual": TT("manual"), #: Manual reset of quota "link-resetQuota": TT("Reset Quota now"), # History page "archive": TT("Archive"), "purgeHist": TT("Purge History"), #: History page button "hideDetails": TT("Hide details"), #: Button/link hiding History job details "showDetails": TT("Show details"), #: Button/link showing History job details "showFailedHis": TT("Show Failed"), #: Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! "showAllHis": TT("Show All"), #: Button or link showing all History jobs "showArchive": TT("Show Archive"), #: Button showing all archived jobs "size": TT("Size"), #: History table header "status": TT("Status"), #: History table header "purgeFailed": TT("Purge Failed NZBs"), #: Button to delete all failed jobs in History "purgeFailed-Files": TT( "Purge Failed NZBs & Delete Files" ), #: Button to delete all failed jobs in History, including files "purgeCompl": TT("Purge Completed NZBs"), #: Button to delete all completed jobs in History "purgePage": TT("Purge NZBs on the current page"), #: Button to delete jobs on current page in History "opt-extra-NZB": TT("Optional Supplemental NZB"), #: Button to add NZB to failed job in History "msg-path": TT("Path"), #: Path as displayed in History details "link-retryAll": TT("Retry all failed jobs"), #: Retry all failed jobs in History # Connections page "link-forceDisc": TT("Force Disconnect"), #: Status page button "explain-forceDisc": TT( "Disconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue." ), #: Status page button text "askTestEmail": TT("This will send a test email to your account."), "link-showLog": TT("Show Logging"), #: Status page button "link-testEmail": TT("Test Email"), #: Status page button "logging": TT("Logging"), #: Status page selection menu "log-errWarn": TT("Errors/Warning"), #: Status page table header "log-info": TT("+ Info"), #: Status page logging selection value "log-debug": TT("+ Debug"), #: Status page logging selection value "connections": TT("Connections"), #: Status page tab header "article-id": TT("Article identifier"), #: Status page, article identifier "file-set": TT("File set"), #: Status page, par-set that article belongs to "warning": TT("Warning"), #: Status page, table column header, actual message "warnings": TT("Warnings"), #: Footer: indicator of warnings "enabled": TT("Enabled"), #: Status page, indicator that server is enabled # Dashboard "dashboard-connectionError": TT("Connection failed!"), "dashboard-localIP4": TT("Local IPv4 address"), "dashboard-publicIP4": TT("Public IPv4 address"), "dashboard-IP6": TT("IPv6 address"), "dashboard-NameserverDNS": TT("Nameserver / DNS Lookup"), "dashboard-delayed": TT("Download speed limited by"), "dashboard-delayed-disk": TT("Disk speed"), "dashboard-loadavg": TT("System load"), "dashboard-systemPerformance": TT("System Performance (Pystone)"), #: Do not translate Pystone "dashboard-downloadDirSpeed": TT("Download folder speed"), "dashboard-completeDirSpeed": TT("Complete folder speed"), "dashboard-internetBandwidth": TT("Internet Bandwidth"), "dashboard-repeatTest": TT("Repeat test"), "dashboard-testDownload": TT("Test download"), "dashboard-testDownload-explain": TT( "Adds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup." ), # Configuration "confgFile": TT("Config File"), "cache": TT("Used cache"), #: Main config page, how much cache is in use "explain-Restart": TT( "This will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards." ), "explain-needNewLogin": TT("
If authentication is enabled, you will need to login again."), "button-advanced": TT("Advanced"), "button-restart": TT("Restart"), "explain-orphans": TT( "There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue." ), "explain-Repair": TT( 'The "Repair" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order.' ), "confirmWithoutSavingPrompt": TT("Changes have not been saved, and will be lost."), "explain-sessionExpire": TT("When your IP address changes or SABnzbd is restarted the session will expire."), "opt-enable_7zip": TT("Enable 7zip"), "explain-getpar2turbo": TT("Speed up repairs by installing par2cmdline-turbo, it is available for many platforms."), "version": TT("Version"), "uptime": TT("Uptime"), "backup": TT("Backup"), #: Indicates that server is Backup server in Status page "readwiki": TT("Read the Wiki Help on this!"), "restarting-sab": TT("Restarting SABnzbd..."), # Config->General "restartRequired": TT("Changes will require a SABnzbd restart!"), "webServer": TT("SABnzbd Web Server"), "opt-host": TT("SABnzbd Host"), "explain-host": TT("Host SABnzbd should listen on."), "opt-port": TT("SABnzbd Port"), "explain-port": TT("Port SABnzbd should listen on."), "opt-web_dir": TT("Web Interface Theme"), "explain-web_dir": TT("Choose a theme."), "opt-web_username": TT("SABnzbd Username"), "explain-web_username": TT("Optional authentication username."), "opt-web_password": TT("SABnzbd Password"), "explain-web_password": TT("Optional authentication password."), "checkSafety": TT( "If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface." ), "security": TT("Security"), "opt-enable_https": TT("Enable HTTPS"), "explain-enable_https": TT("Enable accessing the interface from a HTTPS address."), "explain-enable_https_warning": TT( "Modern web browsers and other clients will not accept self-signed certificates and will give a warning and/or won't connect at all." ), "opt-https_port": TT("HTTPS Port"), "explain-https_port": TT("If empty, the standard port will only listen to HTTPS."), "opt-https_cert": TT("HTTPS Certificate"), "explain-https_cert": TT("File name or path to HTTPS Certificate."), "explain-new-cert": TT("Generate new self-signed certificate and key. Requires SABnzbd restart!"), "opt-https_key": TT("HTTPS Key"), "explain-https_key": TT("File name or path to HTTPS Key."), "opt-https_chain": TT("HTTPS Chain Certifcates"), "explain-https_chain": TT("File name or path to HTTPS Chain."), "tuning": TT("Tuning"), "opt-rss_rate": TT("RSS Checking Interval"), "explain-rss_rate": TT("Checking interval (in minutes, at least 15). Not active when you use the Scheduler!"), "opt-bandwidth_max": TT("Maximum line speed"), "opt-bandwidth_perc": TT("Percentage of line speed"), "explain-bandwidth_perc": TT("Which percentage of the linespeed should SABnzbd use, e.g. 50"), "opt-cache_limitstr": TT("Article Cache Limit"), "explain-cache_limitstr": TT( 'Cache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: "64M" or "128M"' ), "create-backup": TT("Create backup"), "explain-create_backup": TT( "Create a backup of the configuration file and databases in the Backup Folder.
" "If the Backup Folder is not set, the backup will be created in the Completed Download Folder.
" "Recurring backups can be configured on the Scheduling page." ), "opt-cleanup_list": TT("Cleanup List"), "explain-cleanup_list": TT( "List of file extensions that should be deleted after download.
For example: nfo or nfo, sfv" ), "opt-history_retention": TT("History Retention"), "history_retention-all": TT("Keep all jobs"), "history_retention-number-archive": TT("Move jobs to the archive if the history exceeds specified number of jobs"), "history_retention-number-delete": TT("Delete jobs if the history and archive exceeds specified number of jobs"), "history_retention-days-archive": TT("Move jobs to the archive after specified number of days"), "history_retention-days-delete": TT("Delete jobs from the history and archive after specified number of days"), "history_retention-archive": TT("Move all completed jobs to archive"), "history_retention-none": TT("Delete all completed jobs"), "history_retention-limit": TT("Jobs"), "button-saveChanges": TT("Save Changes"), "button-restoreDefaults": TT("Restore Defaults"), "explain-restoreDefaults": TT("Reset"), "opt-language": TT("Language"), "explain-language": TT("Select a web interface language."), "explain-ask-language": TT( "Help us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:" ), # Link to sabnzbd.org follows this text "opt-apikey": TT("API Key"), "explain-apikey": TT("This key will give 3rd party programs full access to SABnzbd."), "opt-nzbkey": TT("NZB Key"), "explain-nzbkey": TT("This key will allow 3rd party programs to add NZBs to SABnzbd."), "button-apikey": TT("Generate New Key"), "explain-qr-code": TT("API Key QR Code"), #: Explanation for QR code of APIKEY "opt-inet_exposure": TT("External internet access"), "explain-inet_exposure": TT("You can set access rights for systems outside your local network."), "inet-local": TT("No access"), # Selection value for external access "inet-nzb": TT("Add NZB files "), # Selection value for external access "inet-api": TT("API (no Config)"), # Selection value for external access "inet-fullapi": TT("Full API"), # Selection value for external access "inet-ui": TT("Full Web interface"), # Selection value for external access "inet-external_login": TT("Only external access requires login"), # Selection value for external access # Config->Folders "explain-folderConfig": TT( "NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders." ), "userFolders": TT("User Folders"), "browse-folder": TT("Browse"), "opt-download_dir": TT("Temporary Download Folder"), "explain-download_dir": TT( "Location to store unprocessed downloads.
Can only be changed when queue is empty." ), "opt-download_free": TT("Minimum Free Space for Temporary Download Folder"), "explain-download_free": TT( 'Auto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"' ), "opt-complete_dir": TT("Completed Download Folder"), "explain-complete_dir": TT( "Location to store finished, fully processed downloads.
Can be overruled by user-defined categories." ), "explain-complete_dir-sorting": TT("Use Sorting to automatically organize and rename your completed downloads."), "opt-complete_free": TT("Minimum Free Space for Completed Download Folder"), "explain-complete_free": TT("Will not work if a category folder is on a different disk."), "opt-fulldisk_autoresume": TT("Auto resume"), "explain-fulldisk_autoresume": TT( "Downloading will automatically resume if the minimum free space is available again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." ), "opt-permissions": TT("Permissions for completed downloads"), "explain-permissions": TT( 'Set permissions pattern for completed files/folders.
In octal notation. For example: "755" or "777"' ), "opt-dirscan_dir": TT("Watched Folder"), "explain-dirscan_dir": TT("Folder to monitor for .nzb files."), "opt-dirscan_speed": TT("Watched Folder Scan Speed"), "explain-dirscan_speed": TT("Number of seconds between scans for .nzb files."), "opt-script_dir": TT("Scripts Folder"), "explain-script_dir": TT("Folder containing user scripts."), "opt-email_dir": TT("Email Templates Folder"), "explain-email_dir": TT("Folder containing user-defined email templates."), "opt-password_file": TT("Password file"), "explain-password_file": TT("File containing all passwords to be tried on encrypted RAR files."), "systemFolders": TT("System Folders"), "hiddenFolders": TT("Hidden Folders"), "opt-admin_dir": TT("Administrative Folder"), "explain-admin_dir1": TT( "Location for queue admin and history database.
Can only be changed when queue is empty." ), "opt-backup_dir": TT("Backup Folder"), "explain-backup_dir": TT( "Location where the backups of the configuration file and databases are stored.
" "If left empty, the backup will be created in the Completed Download Folder." ), "explain-admin_dir2": TT("Data will not be moved. Requires SABnzbd restart!"), "opt-log_dir": TT("Log Folder"), "explain-log_dir": TT("Location of log files for SABnzbd.
Requires SABnzbd restart!"), "purge_log_files": TT("Purge Logs"), "opt-nzb_backup_dir": TT(".nzb Backup Folder"), "explain-nzb_backup_dir": TT("Location where .nzb files will be stored."), "base-folder": TT("Default Base Folder"), # Config->Switches "opt-enable_all_par": TT("Download all par2 files"), "explain-enable_all_par": TT("This prevents multiple repair runs by downloading all par2 files when needed."), "opt-enable_recursive": TT("Enable recursive unpacking"), "explain-enable_recursive": TT("Unpack archives (rar, zip, 7z) within archives."), "opt-flat_unpack": TT("Ignore any folders inside archives"), "explain-flat_unpack": TT("All files will go into a single folder."), "opt-top_only": TT("Only Get Articles for Top of Queue"), "explain-top_only": TT("Enable for less memory usage. Disable to prevent slow jobs from blocking the queue."), "opt-safe_postproc": TT("Post-Process Only Verified Jobs"), "explain-safe_postproc": TT( "Only unpack and run scripts on jobs that passed the verification stage. If turned off, all jobs will be marked as Completed even if they are incomplete." ), "opt-pause_on_pwrar": TT("Action when encrypted RAR is downloaded"), "explain-pause_on_pwrar": TT('In case of "Pause", you\'ll need to set a password and resume the job.'), "opt-no_dupes": TT("Identical download detection"), "explain-no_dupes": TT("Detect identical downloads based on name or NZB contents."), "opt-no_smart_dupes": TT("Smart duplicate detection"), "explain-no_smart_dupes": TT("Detect duplicates based on analysis of the filename."), "opt-dupes_propercheck": TT("Allow proper releases"), "explain-dupes_propercheck": TT( "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in the download name." ), "nodupes-off": TT("Off"), #: Three way switch for duplicates "nodupes-ignore": TT("Discard"), #: Four way switch for duplicates "nodupes-pause": TT("Pause"), #: Four way switch for duplicates "nodupes-tag": TT("Tag job"), #: Four way switch for duplicates "fail-to-history": TT("Fail job (move to History)"), #: Four way switch for duplicates "abort": TT("Abort post-processing"), "opt-action_on_unwanted_extensions": TT("Action when unwanted extension detected"), "explain-action_on_unwanted_extensions": TT("Action when an unwanted extension is detected"), "opt-unwanted_extensions": TT("Unwanted extensions"), "unwanted_extensions_blacklist": TT("Blacklist"), "unwanted_extensions_whitelist": TT("Whitelist"), "explain-unwanted_extensions": TT( "Select a mode and list all (un)wanted extensions. For example: exe or exe, com" ), "opt-sfv_check": TT("Enable SFV-based checks"), "explain-sfv_check": TT("Do an extra verification based on SFV files."), "opt-script_can_fail": TT("User script can flag job as failed"), "explain-script_can_fail": TT( "When the user script returns a non-zero exit code, the job will be flagged as failed." ), "opt-folder_rename": TT("Enable folder rename"), "explain-folder_rename": TT( "Use temporary names during post processing. Disable when your system doesn't handle that properly." ), "opt-pre_script": TT("Pre-queue user script"), "explain-pre_script": TT("Used before an NZB enters the queue."), "opt-end_queue_script": TT("On queue finish script"), "explain-end_queue_script": TT("Executed after the queue finishes downloading."), "opt-par_option": TT("Extra PAR2 Parameters"), "opt-nice": TT("Nice Parameters"), "opt-ionice": TT("IONice Parameters"), "opt-win_process_prio": TT("External process priority"), "win_process_prio-high": TT("High"), "win_process_prio-normal": TT("Normal"), "win_process_prio-low": TT("Low"), "win_process_prio-idle": TT("Idle"), "opt-auto_disconnect": TT("Disconnect on Empty Queue"), "explain-auto_disconnect": TT("Disconnect from Usenet server(s) when queue is empty or paused."), "opt-auto_sort": TT("Automatically sort queue"), "explain-auto_sort": TT("Automatically sort jobs in the queue when a new job is added."), "explain-auto_sort_remaining": TT("The queue will resort every 30 seconds if % downloaded is selected."), "opt-direct_unpack": TT("Direct Unpack"), "explain-direct_unpack": TT( "Jobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair." ), "opt-propagation_delay": TT("Propagation delay"), "explain-propagation_delay": TT( "Posts will be paused untill they are at least this age. Setting job priority to Force will skip the delay." ), "opt-check_new_rel": TT("Check for New Release"), "also-test": TT("Also test releases"), #: Pick list for weekly test for new releases "opt-replace_spaces": TT("Replace Spaces in Foldername"), "explain-replace_spaces": TT("Replace spaces with underscores in folder names."), "opt-replace_underscores": TT("Replace underscores in folder name"), "explain-replace_underscores": TT("Replace underscores with dots in folder names."), "opt-replace_dots": TT("Replace dots in Foldername"), "explain-replace_dots": TT("Replace dots with spaces in folder names."), "opt-sanitize_safe": TT("Make Windows compatible"), "explain-sanitize_safe": TT("For servers: make sure names are compatible with Windows."), "opt-auto_browser": TT("Launch Browser on Startup"), "explain-auto_browser": TT("Launch the default web browser when starting SABnzbd."), "opt-pause_on_post_processing": TT("Pause Downloading During Post-Processing"), "explain-pause_on_post_processing": TT( "Pauses downloading at the start of post processing and resumes when finished." ), "opt-ignore_samples": TT("Ignore Samples"), "explain-ignore_samples": TT("Filter out sample files (e.g. video samples)."), "igsam-del": TT("Delete after download"), "opt-deobfuscate_final_filenames": TT("Deobfuscate final filenames"), "explain-deobfuscate_final_filenames": TT( "If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name." ), "explain-deobfuscate_final_filenames-ext": TT( "Additionally, attempts to set the correct file extension based on the file signature if the extension is not present or meaningless." ), "opt-enable_https_verification": TT("HTTPS certificate verification"), "explain-enable_https_verification": TT( "Verify certificates when connecting to indexers and RSS-sources using HTTPS." ), "opt-socks5_proxy_url": TT("SOCKS5 Proxy"), "explain-socks5_proxy_url": TT("Use the specified SOCKS5 proxy for all outgoing connections."), "swtag-server": TT("Server"), "swtag-queue": TT("Queue"), "swtag-pp": TT("Post processing"), "swtag-naming": TT("Naming"), "swtag-quota": TT("Quota"), "opt-quota_size": TT("Size"), #: Size of the download quota "explain-quota_size": TT("How much can be downloaded this month (K/M/G)"), "opt-quota_day": TT("Reset day"), #: Reset day of the download quota "explain-quota_day": TT( "On which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)" ), "opt-quota_resume": TT("Auto resume"), #: Auto-resume download on the reset day "explain-quota_resume": TT("Should downloading resume after the quota is reset?"), "opt-quota_period": TT("Quota period"), #: Does the quota get reset every day, week or month? "explain-quota_period": TT("Does the quota get reset each day, week or month?"), "opt-pre_check": TT("Check before download"), "explain-pre_check": TT("Try to predict successful completion before actual download (slower!)"), "opt-ssl_ciphers": TT("SSL Ciphers"), "explain-ssl_ciphers": TT("Increase performance by forcing a lower SSL encryption strength."), "opt-max_art_tries": TT("Maximum retries"), "explain-max_art_tries": TT("Maximum number of retries per server"), "opt-fail_hopeless_jobs": TT("Abort jobs that cannot be completed"), "explain-fail_hopeless_jobs": TT( "When during download it becomes clear that too much data is missing, abort the job" ), # Config->Server "addServer": TT("Add Server"), #: Caption "srv-displayname": TT("Server description"), #: User defined name for server "srv-host": TT("Host"), #: Server hostname or IP "srv-port": TT("Port"), #: Server port "srv-username": TT("Username"), #: Server username "srv-password": TT("Password"), #: Server password "srv-timeout": TT("Timeout"), #: Server timeout "srv-connections": TT("Connections"), #: Server: amount of connections "srv-expire_date": TT("Account expiration date"), "srv-explain-expire_date": TT("Warn 5 days in advance of account expiration date."), "srv-explain-quota": TT( "Quota for this account, counted from the time it is set. In bytes, optionally follow with K,M,G.
Warn when it reaches 0, checked every few minutes." ), "srv-retention": TT("Retention time"), #: Server's retention time in days "srv-ssl": TT("SSL"), #: Server SSL tickbox "explain-ssl": TT("Secure connection to server"), #: Server SSL tickbox "opt-ssl_verify": TT("Certificate verification"), "explain-ssl_verify": TT( "Minimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname." ), "ssl_verify-disabled": TT("Disabled"), "ssl_verify-normal": TT("Minimal"), "ssl_verify-strict": TT("Strict"), "srv-priority": TT("Priority"), #: Server priority "explain-svrprio": TT("0 is highest priority, 100 is the lowest priority"), #: Explain server priority "srv-required": TT("Required"), #: Server required tickbox "explain-required": TT( "In case of connection failures, the download queue will be paused for a few minutes instead of skipping this server" ), #: Explain server required tickbox "srv-optional": TT("Optional"), #: Server optional tickbox "explain-optional": TT( "For unreliable servers, will be ignored longer in case of failures" ), #: Explain server optional tickbox "srv-enable": TT("Enable"), #: Enable server tickbox "button-addServer": TT("Add Server"), #: Button: Add server "button-delServer": TT("Remove Server"), #: Button: Remove server "button-testServer": TT("Test Server"), #: Button: Test server "button-clrServer": TT("Clear Counters"), #: Button: Clear server's byte counters "srv-testing": TT("Testing server details..."), "srv-bandwidth": TT("Bandwidth"), "srv-notes": TT("Personal notes"), "srv-article-availability": TT("Article availability"), "srv-articles-tried": TT( "%f% available of %d requested articles" ), #: Server article availability, %f=percentage, %d=number of articles # Config->Scheduling "addSchedule": TT("Add Schedule"), #:Config->Scheduling "sch-frequency": TT("Frequency"), #:Config->Scheduling "sch-action": TT("Action"), #:Config->Scheduling "sch-arguments": TT("Arguments"), #:Config->Scheduling "button-addSchedule": TT("Add Schedule"), #:Config->Scheduling "currentSchedules": TT("Current Schedules"), #:Config->Scheduling "sch-resume": TT("Resume"), #:Config->Scheduling "sch-pause": TT("Pause"), #:Config->Scheduling "sch-shutdown": TT("Shutdown"), #:Config->Scheduling "sch-restart": TT("Restart"), #:Config->Scheduling "sch-create_backup": TT("Create backup"), #:Config->Scheduling # Config->RSS "explain-RSS": TT( 'The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".' ), "feed": TT("Feed"), #: Config->RSS, tab header "addMultipleFeeds": TT("Seperate multiple URLs by a comma"), #: Config->RSS, placeholder (cannot be too long) "button-preFeed": TT("Read Feed"), #: Config->RSS button "button-forceFeed": TT("Force Download"), #: Config->RSS button "button-evalFeed": TT("Apply filters"), "rss-edit": TT("Edit"), #: Config->RSS edit button "rss-nextscan": TT("Next scan at"), #: Config->RSS when will be the next RSS scan "rss-order": TT("Order"), #: Config->RSS table column header "rss-type": TT("Type"), #: Config->RSS table column header "rss-filter": TT("Filter"), #: Config->RSS table column header "rss-accept": TT("Accept"), #: Config->RSS filter-type selection menu "rss-reject": TT("Reject"), #: Config->RSS filter-type selection menu "rss-must": TT("Requires"), #: Config->RSS filter-type selection menu "rss-mustcat": TT("RequiresCat"), #: Config->RSS filter-type selection menu "rss-atleast": TT("At least"), #: Config->RSS filter-type selection menu "rss-atmost": TT("At most"), #: Config->RSS filter-type selection menu "rss-from": TT("From SxxEyy"), #: Config->RSS filter-type selection menu "From Season/Episode" "rss-from-show": TT("From Show SxxEyy"), #: Config->RSS filter-type selection menu "From Show Season/Episode" "rss-matched": TT("Matched"), #: Config->RSS section header "rss-notMatched": TT("Not Matched"), #: Config->RSS section header "rss-done": TT("Downloaded"), #: Config->RSS section header "rss-added": TT("Added NZB"), #: Config->RSS after adding to queue "link-download": TT("Download"), #: Config->RSS button "download item" "button-rssNow": TT("Read All Feeds Now"), #: Config->RSS button # Config->Notifications "defaultNotifiesAll": TT( "If only the Default category is selected, notifications are enabled for jobs in all categories." ), "opt-email_endjob": TT("Email Notification On Job Completion"), "email-never": TT("Never"), #: When to send email "email-always": TT("Always"), #: When to send email "email-errorOnly": TT("Error-only"), #: When to send email "opt-email_full": TT("Disk Full Notifications"), "explain-email_full": TT("Send email when disk is full and SABnzbd is paused."), "opt-email_rss": TT("Send RSS notifications"), "explain-email_rss": TT("Send email when an RSS feed adds jobs to the queue."), "opt-email_server": TT("SMTP Server"), "explain-email_server": TT("Set your ISP's server for outgoing email."), "opt-email_to": TT("Email Recipient"), "explain-email_to": TT("Email address to send the email to."), "opt-email_from": TT("Email Sender"), "explain-email_from": TT("Who should we say sent the email?"), "opt-email_account": TT("OPTIONAL Account Username"), "explain-email_account": TT("For authenticated email, account name."), "opt-email_pwd": TT("OPTIONAL Account Password"), "explain-email_pwd": TT("For authenticated email, password."), "notifications-notesent": TT("Notification Sent!"), "opt-ntfosd_enable": TT("Enable NotifyOSD"), #: Don't translate "NotifyOSD" "opt-ncenter_enable": TT("Notification Center"), "opt-acenter_enable": TT("Enable Windows Notifications"), "testNotify": TT("Test Notification"), "section-NC": TT("Notification Center"), #: Header for macOS Notfication Center section "section-AC": TT("Windows Notifications"), "section-OSD": TT("NotifyOSD"), #: Header for Ubuntu's NotifyOSD notifications section "section-Prowl": TT("Prowl"), #: Header for Prowl notification section "opt-prowl_enable": TT("Enable Prowl notifications"), #: Prowl settings "explain-prowl_enable": TT("Requires a Prowl account"), #: Prowl settings "opt-prowl_apikey": TT("API key for Prowl"), #: Prowl settings "explain-prowl_apikey": TT("Personal API key for Prowl (required)"), #: Prowl settings "section-Pushover": TT("Pushover"), #: Header for Pushover notification section "opt-pushover_enable": TT("Enable Pushover notifications"), #: Pushover settings "explain-pushover_enable": TT("Requires a Pushover account"), #: Pushoversettings "opt-pushover_token": TT("Application Token"), #: Pushover settings "explain-pushover_token": TT("Application token (required)"), #: Pushover settings "opt-pushover_userkey": TT("User Key"), #: Pushover settings "explain-pushover_userkey": TT("User Key (required)"), #: Pushover settings "opt-pushover_device": TT("Device(s)"), #: Pushover settings "explain-pushover_device": TT("Device(s) to which message should be sent"), #: Pushover settings "opt-pushover_emergency_retry": TT("Emergency retry"), #: Pushover settings "explain-pushover_emergency_retry": TT( "How often (in seconds) the same notification will be sent" ), #: Pushover settings "opt-pushover_emergency_expire": TT("Emergency expire"), #: Pushover settings "explain-pushover_emergency_expire": TT( "How many seconds your notification will continue to be retried" ), #: Pushover settings "section-Pushbullet": TT("Pushbullet"), #: Header for Pushbullet notification section "opt-pushbullet_enable": TT("Enable Pushbullet notifications"), #: Pushbullet settings "explain-pushbullet_enable": TT("Requires a Pushbullet account"), #: Pushbulletsettings "opt-pushbullet_apikey": TT("Personal API key"), #: Pushbullet settings "explain-pushbullet_apikey": TT("Your personal Pushbullet API key (required)"), #: Pushbullet settings "opt-pushbullet_device": TT("Device"), #: Pushbullet settings "explain-pushbullet_device": TT("Device to which message should be sent"), #: Pushbullet settings "opt-apprise_enable": TT("Enable Apprise notifications"), #: Apprise settings "explain-apprise_enable": TT( "Send notifications using Apprise to almost any notification service" ), #: Apprise settings "opt-apprise_urls": TT("Default Apprise URLs"), #: Apprise settings "explain-apprise_urls": TT("Use a comma and/or space to identify more than one URL."), #: Apprise settings "explain-apprise_extra_urls": TT( "Override the default URLs for specific notification types below, if desired." ), #: Apprise settings "section-NScript": TT("Notification Script"), #: Header for Notification Script notification section "opt-nscript_enable": TT("Enable notification script"), #: Notification Script settings "opt-nscript_script": TT("Script"), #: Notification Script settings "opt-nscript_parameters": TT("Parameters"), #: Notification Script settings "explain-nscript_enable": TT("Executes a custom script"), #: Notification Scriptsettings "explain-nscript_script": TT("Which script should we execute for notification?"), #: Notification Scriptsettings # Config->Cat "explain-catTags": TT( 'Indexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to "Indexer Categories / Groups" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki.' ), "explain-catTags2": TT("Ending the path with an asterisk * will prevent creation of job folders."), "explain-relFolder": TT("Relative folders are based on"), "catFolderPath": TT("Folder/Path"), "catTags": TT("Indexer Categories / Groups"), # Config->Sorting "sort-legenda": TT("Pattern Key"), "button-clear": TT("Clear"), "movieSort": TT("Movie Sorting"), "seriesSort": TT("Series Sorting"), "presetSort": TT("Presets"), "affectedCat": TT("Affected Categories"), "sort-meaning": TT("Meaning"), "sort-pattern": TT("Pattern"), "sort-result": TT("Result"), "sort-title": TT("Title"), "movie-sp-name": TT("Movie Name"), "movie-dot-name": TT("Movie.Name"), "movie-us-name": TT("Movie_Name"), "show-sp-name": TT("Show Name"), "show-dot-name": TT("Show.Name"), "show-us-name": TT("Show_Name"), "show-seasonNum": TT("Season Number"), "show-epNum": TT("Episode Number"), "ep-name": TT("Episode Name"), "ep-sp-name": TT("Episode Name"), "ep-dot-name": TT("Episode.Name"), "ep-us-name": TT("Episode_Name"), "extension": TT("Extension"), "partNumber": TT("Part Number"), "decade": TT("Decade"), "orgFilename": TT("Original Filename"), "orgJobname": TT("Original Job Name"), "lowercase": TT("Lower Case"), "TEXT": TT("TEXT"), "text": TT("text"), "sort-File": TT("file"), "sortString": TT("Sort String"), "multiPartLabel": TT("Multi-part Label"), "button-showFolder": TT("Show folder"), "button-seasonFolder": TT("Season folder"), "button-inFolders": TT("In folders"), "button-noFolders": TT("No folders"), "button-FileLikeFolder": TT("Job Name as Filename"), "button-Series": TT("Series"), "case-adjusted": TT("case-adjusted"), #: Note for title expression in Sorting that does case adjustment "sortResult": TT("Processed Result"), "sort-guessitMeaning": TT("Any property"), "sort-guessitProperty": TT("property"), "guessit-sp-property": TT("GuessIt Property"), "guessit-dot-property": TT("GuessIt.Property"), "guessit-us-property": TT("GuessIt_Property"), "sort-minimum-size": TT("Minimum Filesize"), "guessit-type": TT("Affected Job Types"), "guessit-type-all": TT("All"), "guessit-type-tv": TT("Series"), "guessit-type-date": TT("Series with air dates"), "guessit-type-movie": TT("Movies"), "guessit-type-other": TT("Other / Unknown"), "explain-sorting": TT( "

Use Sorters to automatically organize your completed downloads. For example, put all episodes from a series " "in a season-specific folder. Or, put movies in a folder named after the movie.

" "

Sorters are tried in order of appearance and can be reordered by dragging and dropping.
" "The first active sorter that matches both the affected category and job type is applied.

" "

More options are available when Advanced Settings is checked.
" "Detailed information can be found on the Wiki.

" ), "add-sorter": TT("Add Sorter"), "remove-sorter": TT("Remove Sorter"), "sort-test-data": TT("Test Data"), "sort-quick-add": TT("Quick start"), "sort-quick-add-series": TT( 'Move and rename all episodes in the "tv" category to a show-specific folder' ), #: Do not translate "tv"! "sort-quick-add-movies": TT( 'Move and rename all movies in the "movies" category to a movie-specific folder' ), #: Do not translate "movies"! # Config->Special "explain-special": TT( "Rarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
" "Don't change these without checking the Wiki first, as some have serious side-effects.
" "The default values are between parentheses." ), "sptag-boolean": TT("Switches"), "sptag-entries": TT("Values"), # NZO "nzoDetails": TT("Edit NZB Details"), #: Job details page "nzo-delete": TT("Delete"), #: Job details page, delete button "nzo-filename": TT("Filename"), #: Job details page, filename column header "nzo-age": TT("Age"), #: Job details page, file age column header # Glitter skin "Glitter-addNZB": TT("Add NZB"), "Glitter-pause5m": TT("Pause for 5 minutes"), "Glitter-pause15m": TT("Pause for 15 minutes"), "Glitter-pause30m": TT("Pause for 30 minutes"), "Glitter-pause1h": TT("Pause for 1 hour"), "Glitter-pause3h": TT("Pause for 3 hours"), "Glitter-pause6h": TT("Pause for 6 hours"), "Glitter-setMaxLinespeed": TT("You must set a maximum bandwidth before you can set a bandwidth limit"), "Glitter-left": TT("left"), "Glitter-free": TT("Free Space"), "Glitter-freeTemp": TT("Temp Folder"), "Glitter-search": TT("Search"), "Glitter-multiOperations": TT("Multi-Operations"), "Glitter-multiSelect": TT("Hold shift key to select a range"), "Glitter-checkAll": TT("Check all"), "Glitter-restartSab": TT("Restart SABnzbd"), "Glitter-onFinish": TT("On queue finish"), "Glitter-statusInterfaceOptions": TT("Status and interface options"), "Glitter-dragAndDrop": TT("Or drag and drop files in the window!"), "Glitter-today": TT("Today"), "Glitter-thisMonth": TT("This month"), "Glitter-total": TT("Total"), "Glitter-lostConnection": TT("Lost connection to SABnzbd.."), "Glitter-afterRestart": TT("In case of SABnzbd restart this screen will disappear automatically!"), "Glitter-disabled": TT("Disabled"), "Glitter-warning": TT("WARNING:"), "Glitter-error": TT("ERROR:"), "Glitter-fetch": TT("Fetch"), "Glitter-interfaceOptions": TT("Web Interface"), "Glitter-interfaceRefresh": TT("Refresh rate"), "Glitter-useGlobalOptions": TT("Use global interface settings"), "Glitter-queueItemLimit": TT("Queue item limit"), "Glitter-historyItemLimit": TT("History item limit"), "Glitter-dateFormat": TT("Date format"), "Glitter-showExtraQueueColumn": TT("Extra queue columns"), "Glitter-showExtraHistoryColumn": TT("Extra history columns"), "Glitter-page": TT("page"), "Glitter-loading": TT("Loading"), "Glitter-articles": TT("articles"), "Glitter-rename": TT("Rename"), "Glitter-repairQueue": TT("Queue repair"), "Glitter-showActiveConnections": TT("Show active connections"), "Glitter-unblockServer": TT("Unblock"), "Glitter-orphanedJobs": TT("Orphaned jobs"), "Glitter-backToQueue": TT("Send back to queue"), "Glitter-purgeOrphaned": TT("Delete All"), "Glitter-retryAllOrphaned": TT("Retry all"), "Glitter-deleteJobAndFolders": TT("Remove NZB & Delete Files"), "Glitter-addFromURL": TT("Fetch NZB from URL"), "Glitter-addFromFile": TT("Upload NZB"), "Glitter-chooseFile": TT("Browse"), "Glitter-addnzbFilename": TT("Optionally specify a filename"), "Glitter-submit": TT("Submit"), "Glitter-removeSelected": TT("Remove all selected files"), "Glitter-toggleCompletedFiles": TT("Hide/show completed files"), "Glitter-top": TT("Top"), "Glitter-bottom": TT("Bottom"), "Glitter-retryJob": TT("Retry"), "Glitter-retryNoChecks": TT( "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be completed' are disabled." ), "Glitter-more": TT("More"), "Glitter-scriptLog": TT("View Script Log"), "Glitter-clearHistory": TT("Purge History"), "Glitter-confirmAbortDirectUnpack": TT("Renaming the job will abort Direct Unpack."), "Glitter-updateAvailable": TT("Update Available!"), "Glitter-noLocalStorage": TT( "LocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!" ), #: Don't translate LocalStorage "Glitter-glitterTips": TT("Glitter has some (new) features you might like!"), "Glitter-custom": TT("Custom"), "Glitter-displayCompact": TT("Compact layout"), "Glitter-displayFullWidth": TT("Always use full screen width"), "Glitter-displayTabbed": TT("Tabbed layout
(separate queue and history)"), "Glitter-speed": TT("Speed"), "Glitter-confirmDeleteQueue": TT("Confirm Queue Deletions"), "Glitter-confirmDeleteHistory": TT("Confirm History Deletions"), "Glitter-keyboardShortcuts": TT("Keyboard shortcuts"), "Glitter-keyboardShortcuts-arrows": TT("Shift+Arrow key: Browse Queue and History pages"), "Glitter-pausePrompt": TT("How long or untill when do you want to pause? (in English!)"), "Glitter-pausePromptFail": TT("Sorry, we could not interpret that. Try again."), "Glitter-pauseFor": TT("Pause for..."), "Glitter-refresh": TT("Refresh"), "Glitter-logText": TT( "All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings." ), "Glitter-sortRemaining": TT("Sort by % downloaded Most→Least"), "Glitter-sortAgeAsc": TT("Sort by Age Oldest→Newest"), "Glitter-sortAgeDesc": TT("Sort by Age Newest→Oldest"), "Glitter-sortNameAsc": TT("Sort by Name A→Z"), "Glitter-sortNameDesc": TT("Sort by Name Z→A"), "Glitter-sortSizeAsc": TT("Sort by Size Smallest→Largest"), "Glitter-sortSizeDesc": TT("Sort by Size Largest→Smallest"), "Glitter-notification-uploading": TT("Uploading"), # Notification window "Glitter-notification-disconnect": TT("Forcing disconnect"), # Notification window "Glitter-notification-removing1": TT("Removing job"), # Notification window "Glitter-notification-removing": TT("Removing jobs"), # Notification window "Glitter-notification-shutdown": TT("Shutting down"), # Notification window # Wizard "wizard-quickstart": TT("SABnzbd Quick-Start Wizard"), "wizard-version": TT("SABnzbd Version"), "wizard-previous": TT("Previous"), #: Button to go to previous Wizard page "wizard-next": TT("Next"), #: Button to go to next Wizard page "wizard-server": TT("Server Details"), "wizard-explain-server": TT("Please enter in the details of your primary usenet provider."), "wizard-server-con-explain": TT("The number of connections allowed by your provider"), "wizard-server-con-eg": TT("E.g. 8 or 20"), #: Wizard: examples of amount of connections "wizard-server-ssl-explain": TT("Select only if your provider allows SSL connections."), "wizard-server-text": TT("Click to test the entered details."), "wizard-example": TT("E.g."), #: Abbreviation for "for example" "wizard-button-testServer": TT("Test Server"), #: Wizard step "wizard-complete": TT("Setup is now complete!"), #: Wizard step "wizard-tip1": TT("SABnzbd will now be running in the background."), #: Wizard tip "wizard-tip2": TT("Closing any browser windows/tabs will NOT close SABnzbd."), #: Wizard tip "wizard-tip4": TT( "It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background." ), #: Wizard tip "wizard-tip-wiki": TT( "Further help can be found on our" ), #: Will be appended with a wiki-link, adjust word order accordingly "wizard-goto": TT("Go to SABnzbd"), #: Wizard step "wizard-exit": TT("Exit SABnzbd"), #: Wizard EXIT button on first page "wizard-start": TT("Start Wizard"), #: Wizard START button on first page "restore-backup": TT("Restore backup"), # Special "yourRights": TT( """ SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. """ ), } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4456534 SABnzbd-4.3.2/sabnzbd/misc.py0000644000000000000000000014352014625637243015160 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.misc - misc classes """ import os import platform import ssl import sys import logging import functools import urllib.request import urllib.parse import re import subprocess import socket import time import datetime import inspect import queue import ctypes import html import ipaddress import socks from threading import Thread from collections.abc import Iterable from typing import Union, Tuple, Any, AnyStr, Optional, List, Dict, Collection import sabnzbd import sabnzbd.getipaddress from sabnzbd.constants import ( DEFAULT_PRIORITY, MEBI, DEF_ARTICLE_CACHE_DEFAULT, DEF_ARTICLE_CACHE_MAX, REPAIR_REQUEST, GUESSIT_SORT_TYPES, ) import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.decorators import cache_maintainer from sabnzbd.encoding import ubtou, platform_btou from sabnzbd.filesystem import userxbit, make_script_path, remove_file if sabnzbd.WIN32: try: import winreg import win32process import win32con # Define scheduling priorities WIN_SCHED_PRIOS = { 1: win32process.IDLE_PRIORITY_CLASS, 2: win32process.BELOW_NORMAL_PRIORITY_CLASS, 3: win32process.NORMAL_PRIORITY_CLASS, 4: win32process.ABOVE_NORMAL_PRIORITY_CLASS, } except ImportError: pass if sabnzbd.MACOS: from sabnzbd.utils import sleepless TAB_UNITS = ("", "K", "M", "G", "T", "P") RE_UNITS = re.compile(r"(\d+\.*\d*)\s*([KMGTP]?)", re.I) RE_VERSION = re.compile(r"(\d+)\.(\d+)\.(\d+)([a-zA-Z]*)(\d*)") RE_SAMPLE = re.compile(r"((^|[\W_])(sample|proof))", re.I) # something-sample or something-proof RE_IP4 = re.compile(r"inet\s+(addr:\s*)?(\d+\.\d+\.\d+\.\d+)") RE_IP6 = re.compile(r"inet6\s+(addr:\s*)?([0-9a-f:]+)", re.I) # Check if strings are defined for AM and PM HAVE_AMPM = bool(time.strftime("%p")) def helpful_warning(msg, *args, **kwargs): """Wrapper to ignore helpful warnings if desired""" if cfg.helpful_warnings(): msg = "%s\n%s" % (msg, T("To prevent all helpful warnings, disable Special setting 'helpful_warnings'.")) return logging.warning(msg, *args, **kwargs) return logging.info(msg, *args, **kwargs) def duplicate_warning(*args, **kwargs): """Wrapper to ignore duplicate warnings if desired""" if cfg.warn_dupl_jobs(): return logging.warning(*args, **kwargs) return logging.info(*args, **kwargs) def time_format(fmt): """Return time-format string adjusted for 12/24 hour clock setting""" if cfg.ampm() and HAVE_AMPM: return fmt.replace("%H:%M:%S", "%I:%M:%S %p").replace("%H:%M", "%I:%M %p") else: return fmt def format_time_left(totalseconds: int, short_format: bool = False) -> str: """Calculate the time left in the format [DD:]HH:MM:SS or [DD:][HH:]MM:SS (short_format)""" if totalseconds > 0: try: minutes, seconds = divmod(totalseconds, 60) hours, minutes = divmod(minutes, 60) days, hours = divmod(hours, 24) if seconds < 10: seconds = "0%s" % seconds if hours > 0 or not short_format: if minutes < 10: minutes = "0%s" % minutes if days > 0: if hours < 10: hours = "0%s" % hours return "%s:%s:%s:%s" % (days, hours, minutes, seconds) else: return "%s:%s:%s" % (hours, minutes, seconds) else: return "%s:%s" % (minutes, seconds) except: pass if short_format: return "0:00" return "0:00:00" def calc_age(date: datetime.datetime, trans: bool = False) -> str: """Calculate the age difference between now and date. Value is returned as either days, hours, or minutes. When 'trans' is True, time symbols will be translated. """ if trans: d = T("d") # : Single letter abbreviation of day h = T("h") # : Single letter abbreviation of hour m = T("m") # : Single letter abbreviation of minute else: d = "d" h = "h" m = "m" try: # Return time difference in human-readable format date_diff = datetime.datetime.now() - date if date_diff.days: return "%d%s" % (date_diff.days, d) elif int(date_diff.seconds / 3600): return "%d%s" % (date_diff.seconds / 3600, h) else: return "%d%s" % (date_diff.seconds / 60, m) except: return "-" def safe_lower(txt: Any) -> str: """Return lowercased string. Return '' for None""" if txt: return txt.lower() else: return "" def is_none(inp: Any) -> bool: """Check for 'not X' but also if it's maybe the string 'None'""" return not inp or (isinstance(inp, str) and inp.lower() == "none") def clean_comma_separated_list(inp: Any) -> List[str]: """Return a list of stripped values from a string or list, empty ones removed""" result_ids = [] if isinstance(inp, str): inp = inp.split(",") if isinstance(inp, Iterable): for inp_id in inp: if new_id := inp_id.strip(): result_ids.append(new_id) return result_ids def cmp(x, y): """ Replacement for built-in function cmp that was removed in Python 3 Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y. """ return (x > y) - (x < y) class MultiAddQueue(queue.Queue): def put_multiple(self, multiple_items: Collection): """Take advantage of the dequeue used by Queue that has a very fast extend method to add multiple items at once. See: https://github.com/sabnzbd/sabnzbd/discussions/2704""" with self.not_full: self.queue.extend(multiple_items) self.unfinished_tasks += len(multiple_items) self.not_empty.notify() def cat_pp_script_sanitizer( cat: Optional[str] = None, pp: Optional[Union[int, str]] = None, script: Optional[str] = None, ) -> Tuple[Optional[Union[int, str]], Optional[str], Optional[str]]: """Basic sanitizer from outside input to a bit more predictable values""" # Cannot use "not pp" because pp can also be 0 if pp in ("", "-1"): pp = None # Check for valid script is performed in NzbObject init if not script or script.lower() == "default": script = None if not cat or cat.lower() in ("default", "*"): cat = None return cat, pp, script def name_to_cat(fname, cat=None): """Retrieve category from file name, but only if "cat" is None.""" if cat is None and fname.startswith("{{"): n = fname.find("}}") if n > 2: cat = fname[2:n].strip() fname = fname[n + 2 :].strip() logging.debug("Job %s has category %s", fname, cat) return fname, cat def cat_to_opts(cat, pp=None, script=None, priority=None) -> Tuple[str, int, str, int]: """Derive options from category, if options not already defined. Specified options have priority over category-options. If no valid category is given, special category '*' will supply default values """ def_cat = config.get_category() cat = safe_lower(cat) if cat in ("", "none", "default"): cat = "*" my_cat = config.get_category(cat) # Ignore the input category if we don't know it if my_cat == def_cat: cat = "*" if pp is None: pp = my_cat.pp() if pp == "": pp = def_cat.pp() if not script: script = my_cat.script() if safe_lower(script) in ("", "default"): script = def_cat.script() if priority is None or priority == "" or priority == DEFAULT_PRIORITY: priority = my_cat.priority() if priority == DEFAULT_PRIORITY: priority = def_cat.priority() logging.debug("Parsing category %s to attributes: pp=%s script=%s prio=%s", cat, pp, script, priority) return cat, pp, script, priority def pp_to_opts(pp: Optional[int]) -> Tuple[bool, bool, bool]: """Convert numeric processing options to (repair, unpack, delete)""" # Convert the pp to an int pp = sabnzbd.interface.int_conv(pp) if pp == 0: return False, False, False if pp == 1: return True, False, False if pp == 2: return True, True, False return True, True, True def opts_to_pp(repair: bool, unpack: bool, delete: bool) -> int: """Convert (repair, unpack, delete) to numeric process options""" if delete: return 3 if unpack: return 2 if repair: return 1 return 0 def sort_to_opts(sort_type: str) -> int: """Convert a guessed sort_type to its integer equivalent""" for k, v in GUESSIT_SORT_TYPES.items(): if v == sort_type: return k else: logging.debug("Invalid sort_type %s, pretending a match to 0 ('all')", sort_type) return 0 _wildcard_to_regex = { "\\": r"\\", "^": r"\^", "$": r"\$", ".": r"\.", "[": r"\[", "]": r"\]", "(": r"\(", ")": r"\)", "+": r"\+", "?": r".", "|": r"\|", "{": r"\{", "}": r"\}", "*": r".*", } def wildcard_to_re(text): """Convert plain wildcard string (with '*' and '?') to regex.""" return "".join([_wildcard_to_regex.get(ch, ch) for ch in text]) def convert_filter(text): """Return compiled regex. If string starts with re: it's a real regex else quote all regex specials, replace '*' by '.*' """ text = text.strip().lower() if text.startswith("re:"): txt = text[3:].strip() else: txt = wildcard_to_re(text) try: return re.compile(txt, re.I) except: logging.debug("Could not compile regex: %s", text) return None def cat_convert(cat): """Convert indexer's category/group-name to user categories. If no match found, but indexer-cat equals user-cat, then return user-cat If no match found, but the indexer-cat starts with the user-cat, return user-cat If no match found, return None """ if not is_none(cat): cats = config.get_ordered_categories() raw_cats = config.get_categories() for ucat in cats: try: # Ordered cat-list has tags only as string indexer = raw_cats[ucat["name"]].newzbin() if not isinstance(indexer, list): indexer = [indexer] except: indexer = [] for name in indexer: if re.search("^%s$" % wildcard_to_re(name), cat, re.I): if "." in name: logging.debug('Convert group "%s" to user-cat "%s"', cat, ucat["name"]) else: logging.debug('Convert index site category "%s" to user-cat "%s"', cat, ucat["name"]) return ucat["name"] # Try to find full match between user category and indexer category for ucat in cats: if cat.lower() == ucat["name"].lower(): logging.debug('Convert index site category "%s" to user-cat "%s"', cat, ucat["name"]) return ucat["name"] # Try to find partial match between user category and indexer category for ucat in cats: if cat.lower().startswith(ucat["name"].lower()): logging.debug('Convert index site category "%s" to user-cat "%s"', cat, ucat["name"]) return ucat["name"] return None _SERVICE_KEY = "SYSTEM\\CurrentControlSet\\services\\" _SERVICE_PARM = "CommandLine" def get_serv_parms(service): """Get the service command line parameters from Registry""" service_parms = [] try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, _SERVICE_KEY + service) for n in range(winreg.QueryInfoKey(key)[1]): name, service_parms, _val_type = winreg.EnumValue(key, n) if name == _SERVICE_PARM: break winreg.CloseKey(key) except OSError: pass # Always add the base program service_parms.insert(0, os.path.normpath(os.path.abspath(sys.argv[0]))) return service_parms def set_serv_parms(service, args): """Set the service command line parameters in Registry""" serv = [] for arg in args: serv.append(arg[0]) if arg[1]: serv.append(arg[1]) try: key = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, _SERVICE_KEY + service) winreg.SetValueEx(key, _SERVICE_PARM, None, winreg.REG_MULTI_SZ, serv) winreg.CloseKey(key) except OSError: return False return True def get_from_url(url: str) -> Optional[str]: """Retrieve URL and return content""" try: req = urllib.request.Request(url) req.add_header("User-Agent", "SABnzbd/%s" % sabnzbd.__version__) with urllib.request.urlopen(req) as response: return ubtou(response.read()) except: return None def convert_version(text): """Convert version string to numerical value and a testversion indicator""" version = 0 test = True if m := RE_VERSION.search(ubtou(text)): version = int(m.group(1)) * 1000000 + int(m.group(2)) * 10000 + int(m.group(3)) * 100 try: if m.group(4).lower() == "rc": version = version + 80 elif m.group(4).lower() == "beta": version = version + 40 version = version + int(m.group(5)) except: version = version + 99 test = False return version, test def check_latest_version(): """Do an online check for the latest version Perform an online version check Syntax of online version file: The latter two lines are only present when an alpha/beta/rc is available. Formula for the version numbers (line 1 and 3). ..[rc|beta|alpha] The value for a final version is assumed to be 99. The value for the beta/rc version is 1..98, with RC getting a boost of 80 and Beta of 40. This is done to signal alpha/beta/rc users of availability of the final version (which is implicitly 99). People will only be informed to upgrade to a higher alpha/beta/rc version, if they are already using an alpha/beta/rc. RC's are valued higher than Beta's, which are valued higher than Alpha's. """ if not cfg.version_check(): return current, testver = convert_version(sabnzbd.__version__) if not current: logging.debug("Unsupported release number (%s), will not check", sabnzbd.__version__) return # Fetch version info data = get_from_url("https://sabnzbd.org/latest.txt") if not data: logging.info("Cannot retrieve version information from sabnzbd.org") logging.debug("Traceback: ", exc_info=True) return version_data = data.split() try: latest_label = version_data[0] url = version_data[1] except: latest_label = "" url = "" try: latest_testlabel = version_data[2] url_beta = version_data[3] except: latest_testlabel = "" url_beta = "" latest = convert_version(latest_label)[0] latest_test = convert_version(latest_testlabel)[0] logging.debug( "Checked for a new release, cur=%s, latest=%s (on %s), latest_test=%s (on %s)", current, latest, url, latest_test, url_beta, ) if latest_test and cfg.version_check() > 1: # User always wants to see the latest test release latest = latest_test latest_label = latest_testlabel url = url_beta notify_version = None if current < latest: # This is a test version, but user hasn't seen the # "Final" of this one yet, so show the Final # Or this one is behind, show latest final sabnzbd.NEW_VERSION = (latest_label, url) notify_version = latest_label elif testver and current < latest_test: # This is a test version beyond the latest Final, so show latest Alpha/Beta/RC sabnzbd.NEW_VERSION = (latest_testlabel, url_beta) notify_version = latest_testlabel if notify_version: sabnzbd.notifier.send_notification(T("Update Available!"), "SABnzbd %s" % notify_version, "other") def upload_file_to_sabnzbd(url, fp): """Function for uploading nzbs to a running SABnzbd instance""" try: fp = urllib.parse.quote_plus(fp) url = "%s&mode=addlocalfile&name=%s" % (url, fp) # Add local API-key if it wasn't already in the registered URL apikey = cfg.api_key() if apikey and "apikey" not in url: url = "%s&apikey=%s" % (url, apikey) if "apikey" not in url: # Use alternative login method username = cfg.username() password = cfg.password() if username and password: url = "%s&ma_username=%s&ma_password=%s" % (url, username, password) get_from_url(url) except: logging.error(T("Failed to upload file: %s"), fp) logging.info("Traceback: ", exc_info=True) def from_units(val: str) -> float: """Convert K/M/G/T/P notation to float Does not support negative numbers""" val = str(val).strip().upper() if val == "-1": return float(val) if m := RE_UNITS.search(val): if m.group(2): val = float(m.group(1)) unit = m.group(2) n = 0 while unit != TAB_UNITS[n]: val = val * 1024.0 n = n + 1 else: val = m.group(1) try: return float(val) except: return 0.0 else: return 0.0 def to_units(val: Union[int, float], postfix="") -> str: """Convert number to K/M/G/T/P notation Show single decimal for M and higher Also supports negative numbers """ if not isinstance(val, (int, float)): return "" if val < 0: sign = "-" else: sign = "" # Determine what form we are at val = abs(val) n = 0 while (val > 1023) and (n < 5): val = val / 1024 n = n + 1 if n > 1: decimals = 1 else: decimals = 0 return ("%%s%%.%sf %%s%%s" % decimals) % (sign, val, TAB_UNITS[n], postfix) def caller_name(skip=2): """Get a name of a caller in the format module.method Originally used: https://gist.github.com/techtonik/2151727 Adapted for speed by using sys calls directly """ # Only do the tracing on Debug (function is always called) if cfg.log_level() != 2: return "N/A" parentframe = sys._getframe(skip) function_name = parentframe.f_code.co_name # Module name is not available in the binaries, we can use the filename instead if hasattr(sys, "frozen"): module_name = inspect.getfile(parentframe) else: module_name = inspect.getmodule(parentframe).__name__ # For decorated functions we have to go deeper if function_name in ("call_func", "wrap") and skip == 2: return caller_name(4) return ".".join([module_name, function_name]) def exit_sab(value: int): """Leave the program after flushing stderr/stdout""" try: sys.stderr.flush() sys.stdout.flush() except AttributeError: # Not supported on Windows binaries pass # Cannot use sys.exit as it will not work inside the macOS-runner-thread os._exit(value) def split_host(srv): """Split host:port notation, allowing for IPV6""" if not srv: return None, None # IPV6 literal (with no port) if srv[-1] == "]": return srv, None out = srv.rsplit(":", 1) if len(out) == 1: # No port port = None else: try: port = int(out[1]) except ValueError: return srv, None return out[0], port def get_cache_limit(): """Depending on OS, calculate cache limits. In ArticleCache it will make sure we stay within system limits for 32/64 bit """ # Calculate, if possible try: if sabnzbd.WIN32: # Windows mem_bytes = get_windows_memory() elif sabnzbd.MACOS: # macOS mem_bytes = get_macos_memory() else: # Linux mem_bytes = os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES") # Use 1/4th of available memory mem_bytes = mem_bytes / 4 # We don't want to set a value that's too high if mem_bytes > from_units(DEF_ARTICLE_CACHE_MAX): return DEF_ARTICLE_CACHE_MAX # We make sure it's at least a valid value if mem_bytes > from_units("32M"): return to_units(mem_bytes) except: pass # Always at least minimum on Windows/macOS if sabnzbd.WIN32 and sabnzbd.MACOS: return DEF_ARTICLE_CACHE_DEFAULT # If failed, leave empty for Linux so user needs to decide return "" def get_windows_memory(): """Use ctypes to extract available memory""" class MEMORYSTATUSEX(ctypes.Structure): _fields_ = [ ("dwLength", ctypes.c_ulong), ("dwMemoryLoad", ctypes.c_ulong), ("ullTotalPhys", ctypes.c_ulonglong), ("ullAvailPhys", ctypes.c_ulonglong), ("ullTotalPageFile", ctypes.c_ulonglong), ("ullAvailPageFile", ctypes.c_ulonglong), ("ullTotalVirtual", ctypes.c_ulonglong), ("ullAvailVirtual", ctypes.c_ulonglong), ("sullAvailExtendedVirtual", ctypes.c_ulonglong), ] def __init__(self): # have to initialize this to the size of MEMORYSTATUSEX self.dwLength = ctypes.sizeof(self) super(MEMORYSTATUSEX, self).__init__() stat = MEMORYSTATUSEX() ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat)) return stat.ullTotalPhys def get_macos_memory(): """Use system-call to extract total memory on macOS""" system_output = run_command(["sysctl", "hw.memsize"]) return float(system_output.split()[1]) @cache_maintainer(clear_time=3600) @functools.lru_cache(maxsize=None) def get_cpu_name(): """Find the CPU name (which needs a different method per OS), and return it If none found, return platform.platform()""" cputype = None try: if sabnzbd.WIN32: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Hardware\Description\System\CentralProcessor\0") cputype = winreg.QueryValueEx(key, "ProcessorNameString")[0] winreg.CloseKey(key) elif sabnzbd.MACOS: cputype = subprocess.check_output(["sysctl", "-n", "machdep.cpu.brand_string"]).strip() else: with open("/proc/cpuinfo") as fp: for myline in fp.readlines(): if myline.startswith("model name"): # Typical line: # model name : Intel(R) Xeon(R) CPU E5335 @ 2.00GHz cputype = myline.split(":", 1)[1] # get everything after the first ":" break # we're done cputype = platform_btou(cputype) except: # An exception, maybe due to a subprocess call gone wrong pass if cputype: # OK, found. Remove unwanted spaces: cputype = " ".join(cputype.split()) else: try: # Not found, so let's fall back to platform() cputype = platform.platform() except: # Can fail on special platforms (like Snapcraft or embedded) pass logging.debug("CPU model = %s", cputype) return cputype def on_cleanup_list(filename: str, skip_nzb: bool = False) -> bool: """Return True if a filename matches the clean-up list""" cleanup_list = cfg.cleanup_list() if cleanup_list: name, ext = os.path.splitext(filename) ext = ext.strip().lower() name = name.strip() for cleanup_ext in cleanup_list: cleanup_ext = "." + cleanup_ext if (cleanup_ext == ext or (ext == "" and cleanup_ext == name)) and not (skip_nzb and cleanup_ext == ".nzb"): return True return False def memory_usage(): try: # Probably only works on Linux because it uses /proc//statm with open("/proc/%d/statm" % os.getpid()) as t: v = t.read().split() virt = int(_PAGE_SIZE * int(v[0]) / MEBI) res = int(_PAGE_SIZE * int(v[1]) / MEBI) return "V=%sM R=%sM" % (virt, res) except IOError: pass except: logging.debug("Error retrieving memory usage") logging.info("Traceback: ", exc_info=True) try: _PAGE_SIZE = os.sysconf("SC_PAGE_SIZE") except: _PAGE_SIZE = 0 _HAVE_STATM = _PAGE_SIZE and memory_usage() def loadavg(): """Return 1, 5 and 15 minute load average of host or "" if not supported""" p = "" if not sabnzbd.WIN32 and not sabnzbd.MACOS: try: p = "%.2f | %.2f | %.2f" % os.getloadavg() except: pass if _HAVE_STATM: p = "%s | %s" % (p, memory_usage()) return p def format_time_string(seconds: float) -> str: """Return a formatted and translated time string""" def unit(single, n): # Seconds and minutes are special due to historical reasons if single == "minute" or (single == "second" and n == 1): single = single[:3] if n == 1: return T(single) return T(single + "s") # Format the string, size by size seconds = int_conv(seconds) completestr = [] days = seconds // 86400 if days >= 1: completestr.append("%s %s" % (days, unit("day", days))) seconds -= days * 86400 hours = seconds // 3600 if hours >= 1: completestr.append("%s %s" % (hours, unit("hour", hours))) seconds -= hours * 3600 minutes = seconds // 60 if minutes >= 1: completestr.append("%s %s" % (minutes, unit("minute", minutes))) seconds -= minutes * 60 if seconds > 0: completestr.append("%s %s" % (seconds, unit("second", seconds))) # Zero or invalid integer if not completestr: completestr.append("0 %s" % unit("second", 0)) return " ".join(completestr) def int_conv(value: Any, default: Any = 0) -> int: """Safe conversion to int (can handle None) Returns 0 or requested default value""" try: return int(value) except: return default def create_https_certificates(ssl_cert, ssl_key): """Create self-signed HTTPS certificates and store in paths 'ssl_cert' and 'ssl_key'""" try: from sabnzbd.utils.certgen import generate_key, generate_local_cert private_key = generate_key(key_size=2048, output_file=ssl_key) generate_local_cert(private_key, days_valid=3560, output_file=ssl_cert, LN="SABnzbd", ON="SABnzbd") logging.info("Self-signed certificates generated successfully") except: logging.error(T("Error creating SSL key and certificate")) logging.info("Traceback: ", exc_info=True) return False return True def get_all_passwords(nzo) -> List[str]: """Get all passwords, from the NZB, meta and password file. In case a working password is already known, try it first.""" passwords = [] if nzo.correct_password: passwords.append(nzo.correct_password) if nzo.password: logging.info("Found a password that was set by the user: %s", nzo.password) passwords.append(nzo.password.strip()) # Note that we get a reference to the list, so adding to it updates the original list! meta_passwords = nzo.meta.get("password", []) pw = nzo.nzo_info.get("password") if pw and pw not in meta_passwords: meta_passwords.append(pw) if meta_passwords: passwords.extend(meta_passwords) logging.info("Read %s passwords from meta data in NZB: %s", len(meta_passwords), meta_passwords) pw_file = cfg.password_file.get_path() if pw_file: try: with open(pw_file, "r") as pwf: lines = pwf.read().split("\n") # Remove empty lines and space-only passwords and remove surrounding spaces pws = [pw.strip("\r\n ") for pw in lines if pw.strip("\r\n ")] logging.debug("Read these passwords from file: %s", pws) passwords.extend(pws) logging.info("Read %s passwords from file %s", len(pws), pw_file) # Check size if len(pws) > 30: helpful_warning( T( "Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords." ) ) except: logging.warning(T("Failed to read the password file %s"), pw_file) logging.info("Traceback: ", exc_info=True) if nzo.password: # If an explicit password was set, add a retry without password, just in case. passwords.append("") elif not passwords or nzo.encrypted < 1: # If we're not sure about encryption, start with empty password # and make sure we have at least the empty password passwords.insert(0, "") unique_passwords = [] for password in passwords: if password not in unique_passwords: unique_passwords.append(password) return unique_passwords def is_sample(filename: str) -> bool: """Try to determine if filename is (most likely) a sample""" return bool(re.search(RE_SAMPLE, filename)) def find_on_path(targets): """Search the PATH for a program and return full path""" if sabnzbd.WIN32: paths = os.getenv("PATH").split(";") else: paths = os.getenv("PATH").split(":") if isinstance(targets, str): targets = (targets,) for path in paths: for target in targets: target_path = os.path.abspath(os.path.join(path, target)) if os.path.isfile(target_path) and os.access(target_path, os.X_OK): return target_path return None def strip_ipv4_mapped_notation(ip: str) -> str: """Convert an IP address in IPv4-mapped IPv6 notation (e.g. ::ffff:192.168.0.10) to its regular IPv4 form. Any value of ip that doesn't use the relevant notation is returned unchanged. CherryPy may report remote IP addresses in this notation. While the ipaddress module should be able to handle that, the latter has issues with the is_private/is_loopback properties for these addresses. See https://bugs.python.org/issue33433""" try: # Keep the original if ipv4_mapped is None ip = ipaddress.ip_address(ip).ipv4_mapped or ip except (AttributeError, ValueError): pass return str(ip) def ip_in_subnet(ip: str, subnet: str) -> bool: """Determine whether ip is part of subnet. For the latter, the standard form with a prefix or netmask (e.g. "192.168.1.0/24" or "10.42.0.0/255.255.0.0") is expected. Input in SABnzbd's old cfg.local_ranges() settings style (e.g. "192.168.1."), intended for use with str.startswith(), is also accepted and internally converted to address/prefix form.""" if not ip or not subnet: return False try: if subnet.find("/") < 0 and subnet.find("::") < 0: # The subnet doesn't include a prefix or netmask, or represent a single (compressed) # IPv6 address; try converting from the older local_ranges settings style. # Take the IP version of the subnet into account IP_LEN, IP_BITS, IP_SEP = (8, 16, ":") if subnet.find(":") >= 0 else (4, 8, ".") subnet = subnet.rstrip(IP_SEP).split(IP_SEP) prefix = IP_BITS * len(subnet) # Append as many zeros as needed subnet.extend(["0"] * (IP_LEN - len(subnet))) # Store in address/prefix form subnet = "%s/%s" % (IP_SEP.join(subnet), prefix) ip = strip_ipv4_mapped_notation(ip) return ipaddress.ip_address(ip) in ipaddress.ip_network(subnet, strict=True) except Exception: # Probably an invalid range return False def is_ipv4_addr(ip: str) -> bool: """Determine if the ip is an IPv4 address""" try: return ipaddress.ip_address(ip).version == 4 except ValueError: return False def is_ipv6_addr(ip: str) -> bool: """Determine if the ip is an IPv6 address; square brackets ([2001::1]) are OK""" try: return ipaddress.ip_address(ip.strip("[]")).version == 6 except (ValueError, AttributeError): return False def is_loopback_addr(ip: str) -> bool: """Determine if the ip is an IPv4 or IPv6 local loopback address""" try: if ip.find(".") < 0: ip = ip.strip("[]") ip = strip_ipv4_mapped_notation(ip) return ipaddress.ip_address(ip).is_loopback except (ValueError, AttributeError): return False def is_localhost(value: str) -> bool: """Determine if the input is some variety of 'localhost'""" return (value == "localhost") or is_loopback_addr(value) def is_lan_addr(ip: str) -> bool: """Determine if the ip is a local area network address""" try: ip = strip_ipv4_mapped_notation(ip) return ( # The ipaddress module considers these private, see https://bugs.python.org/issue38655 not ip in ("0.0.0.0", "255.255.255.255") and not ip_in_subnet(ip, "::/128") # Also catch (partially) exploded forms of "::" and ipaddress.ip_address(ip).is_private and not is_loopback_addr(ip) ) except ValueError: return False def is_local_addr(ip: str) -> bool: """Determine if an IP address is to be considered local, i.e. it's part of a subnet in local_ranges, if defined, or in private address space reserved for local area networks.""" if local_ranges := cfg.local_ranges(): return any(ip_in_subnet(ip, local_range) for local_range in local_ranges) else: return is_lan_addr(ip) def ip_extract() -> List[str]: """Return list of IP addresses of this system""" ips = [] program = find_on_path("ip") if program: program = [program, "a"] else: program = find_on_path("ifconfig") if program: program = [program] if sabnzbd.WIN32 or not program: try: info = socket.getaddrinfo(socket.gethostname(), None) except: # Hostname does not resolve, use localhost info = socket.getaddrinfo("localhost", None) for item in info: ips.append(item[4][0]) else: output = run_command(program) for line in output.split("\n"): m = RE_IP4.search(line) if not (m and m.group(2)): m = RE_IP6.search(line) if m and m.group(2): ips.append(m.group(2)) return ips def get_base_url(url: str) -> str: """Return only the true root domain for the favicon, so api.oznzb.com -> oznzb.com But also api.althub.co.za -> althub.co.za """ url_host = urllib.parse.urlparse(url).hostname if url_host: url_split = url_host.split(".") # Exception for localhost and IPv6 addresses if len(url_split) < 3: return url_host return ".".join(len(url_split[-2]) < 4 and url_split[-3:] or url_split[-2:]) else: return "" def match_str(text: AnyStr, matches: Tuple[AnyStr, ...]) -> Optional[AnyStr]: """Return first matching element of list 'matches' in 'text', otherwise None""" text = text.lower() for match in matches: if match.lower() in text: return match return None def recursive_html_escape(input_dict_or_list: Union[Dict[str, Any], List], exclude_items: Tuple[str, ...] = ()): """Recursively update the input_dict in-place with html-safe values""" if isinstance(input_dict_or_list, (dict, list)): if isinstance(input_dict_or_list, dict): iterator = input_dict_or_list.items() else: # For lists we use enumerate iterator = enumerate(input_dict_or_list) for key, value in iterator: # Ignore any keys that are not safe to convert if key not in exclude_items: # We ignore any other than str if isinstance(value, str): input_dict_or_list[key] = html.escape(value, quote=True) if isinstance(value, (dict, list)): recursive_html_escape(value, exclude_items=exclude_items) else: raise ValueError("Expected dict or str, got %s" % type(input_dict_or_list)) def list2cmdline_unrar(lst: List[str]) -> str: """convert list to a unrar.exe-compatible command string Unrar uses "" instead of \" to escape the double quote""" nlst = [] for arg in lst: if not arg: nlst.append('""') else: if isinstance(arg, str): arg = arg.replace('"', '""') nlst.append('"%s"' % arg) return " ".join(nlst) def build_and_run_command(command: List[str], windows_unrar_command: bool = False, text_mode: bool = True, **kwargs): """Builds and then runs command with necessary flags and optional IONice and Nice commands. Optional Popen arguments can be supplied. On Windows we need to run our own list2cmdline for Unrar. Returns the Popen-instance. """ # command[0] should be set, and thus not None if not command[0]: logging.error(T("[%s] The command in build_command is undefined."), caller_name()) raise IOError if not sabnzbd.WIN32: if command[0].endswith(".py"): with open(command[0], "r") as script_file: if not userxbit(command[0]): # Inform user that Python scripts need x-bit and then stop logging.error(T('Python script "%s" does not have execute (+x) permission set'), command[0]) raise IOError elif script_file.read(2) != "#!": # No shebang (#!) defined, add default python command.insert(0, sys.executable if sys.executable else "python") if sabnzbd.newsunpack.IONICE_COMMAND and cfg.ionice(): ionice = cfg.ionice().split() command = ionice + command command.insert(0, sabnzbd.newsunpack.IONICE_COMMAND) if sabnzbd.newsunpack.NICE_COMMAND and cfg.nice(): nice = cfg.nice().split() command = nice + command command.insert(0, sabnzbd.newsunpack.NICE_COMMAND) creationflags = 0 startupinfo = None else: # For Windows we always need to add python interpreter if command[0].endswith(".py"): command.insert(0, "python.exe") if windows_unrar_command: command = list2cmdline_unrar(command) # On some Windows platforms we need to suppress a quick pop-up of the command window startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags = win32process.STARTF_USESHOWWINDOW startupinfo.wShowWindow = win32con.SW_HIDE creationflags = WIN_SCHED_PRIOS[cfg.win_process_prio()] # Set the basic Popen arguments popen_kwargs = { "stdout": subprocess.PIPE, "stderr": subprocess.STDOUT, "bufsize": 0, "startupinfo": startupinfo, "creationflags": creationflags, } # In text mode we ignore errors if text_mode: # We default to utf8, and hope for the best popen_kwargs.update({"text": True, "encoding": "utf8", "errors": "replace"}) # Update with the supplied ones popen_kwargs.update(kwargs) # Run the command logging.info("[%s] Running external command: %s", caller_name(), command) logging.debug("Popen arguments: %s", popen_kwargs) return subprocess.Popen(command, **popen_kwargs) def run_command(cmd: List[str], **kwargs): """Run simple external command and return output as a string.""" with build_and_run_command(cmd, **kwargs) as p: txt = p.stdout.read() p.wait() return txt def run_script(script: str): """Run a user script""" if script_path := make_script_path(script): try: script_output = run_command([script_path], env=sabnzbd.newsunpack.create_env()) logging.info("Output of script %s: \n%s", script, script_output) except: logging.info("Failed script %s, Traceback: ", script, exc_info=True) def set_socks5_proxy(): if cfg.socks5_proxy_url(): proxy = urllib.parse.urlparse(cfg.socks5_proxy_url()) logging.info("Using Socks5 proxy %s:%s", proxy.hostname, proxy.port) socks.set_default_proxy( socks.SOCKS5, proxy.hostname, proxy.port, True, # use remote DNS, default proxy.username, proxy.password, ) socket.socket = socks.socksocket def set_https_verification(value): """Set HTTPS-verification state while returning current setting False = disable verification """ prev = ssl._create_default_https_context == ssl.create_default_context if value: ssl._create_default_https_context = ssl.create_default_context else: ssl._create_default_https_context = ssl._create_unverified_context return prev def request_repair(): """Request a full repair on next restart""" path = os.path.join(cfg.admin_dir.get_path(), REPAIR_REQUEST) try: with open(path, "w") as f: f.write("\n") except: pass def check_repair_request(): """Return True if repair request found, remove afterwards""" path = os.path.join(cfg.admin_dir.get_path(), REPAIR_REQUEST) if os.path.exists(path): try: remove_file(path) except: pass return True return False def system_shutdown(): """Shutdown system after halting download and saving bookkeeping""" logging.info("Performing system shutdown") # Do not use regular shutdown, as we should be able to still send system-shutdown Thread(target=sabnzbd.halt).start() while sabnzbd.__INITIALIZED__: time.sleep(1.0) if sabnzbd.WIN32: sabnzbd.powersup.win_shutdown() elif sabnzbd.MACOS: sabnzbd.powersup.osx_shutdown() else: sabnzbd.powersup.linux_shutdown() def system_hibernate(): """Hibernate system""" logging.info("Performing system hybernation") if sabnzbd.WIN32: sabnzbd.powersup.win_hibernate() elif sabnzbd.MACOS: sabnzbd.powersup.osx_hibernate() else: sabnzbd.powersup.linux_hibernate() def system_standby(): """Standby system""" logging.info("Performing system standby") if sabnzbd.WIN32: sabnzbd.powersup.win_standby() elif sabnzbd.MACOS: sabnzbd.powersup.osx_standby() else: sabnzbd.powersup.linux_standby() def change_queue_complete_action(action: str, new: bool = True): """Action or script to be performed once the queue has been completed""" function = None if new or cfg.queue_complete_pers(): if action == "shutdown_pc": function = system_shutdown elif action == "hibernate_pc": function = system_hibernate elif action == "standby_pc": function = system_standby elif action == "shutdown_program": function = sabnzbd.shutdown_program else: action = None else: action = None if new: cfg.queue_complete.set(action or "") config.save_config() sabnzbd.QUEUECOMPLETE = action sabnzbd.QUEUECOMPLETEACTION = function def keep_awake(): """If we still have work to do, keep Windows/macOS system awake""" if sabnzbd.KERNEL32 or sabnzbd.FOUNDATION: if sabnzbd.cfg.keep_awake(): ES_CONTINUOUS = 0x80000000 ES_SYSTEM_REQUIRED = 0x00000001 if (not sabnzbd.Downloader.no_active_jobs() and not sabnzbd.NzbQueue.is_empty()) or ( not sabnzbd.PostProcessor.paused and not sabnzbd.PostProcessor.empty() ): if sabnzbd.KERNEL32: # Set ES_SYSTEM_REQUIRED until the next call sabnzbd.KERNEL32.SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) else: sleepless.keep_awake("SABnzbd is busy downloading and/or post-processing") else: if sabnzbd.KERNEL32: # Allow the regular state again sabnzbd.KERNEL32.SetThreadExecutionState(ES_CONTINUOUS) else: sleepless.allow_sleep() def history_updated(): """To make sure we always have a fresh history""" sabnzbd.LAST_HISTORY_UPDATE += 1 # Never go over the limit if sabnzbd.LAST_HISTORY_UPDATE + 1 >= sys.maxsize: sabnzbd.LAST_HISTORY_UPDATE = 1 def convert_sorter_settings(): """Convert older tv/movie/date sorter settings to the new universal sorter The old settings used: -enable_tv_sorting = OptionBool("misc", "enable_tv_sorting", False) -tv_sort_string = OptionStr("misc", "tv_sort_string") -tv_categories = OptionList("misc", "tv_categories", ["tv"]) -enable_movie_sorting = OptionBool("misc", "enable_movie_sorting", False) -movie_sort_string = OptionStr("misc", "movie_sort_string") -movie_sort_extra = OptionStr("misc", "movie_sort_extra", "-cd%1", strip=False) -movie_categories = OptionList("misc", "movie_categories", ["movies"]) -enable_date_sorting = OptionBool("misc", "enable_date_sorting", False) -date_sort_string = OptionStr("misc", "date_sort_string") -date_categories = OptionList("misc", "date_categories", ["tv"]) -movie_rename_limit = OptionStr("misc", "movie_rename_limit", "100M") -episode_rename_limit = OptionStr("misc", "episode_rename_limit", "20M") The new settings define a sorter as follows (cf. class config.ConfigSorter): name: str { name: str order: int min_size: Union[str|int] = "50M" multipart_label: Optional[str] = "" sort_string: str sort_cats: List[str] sort_type: List[int] is_active: bool = 1 } With the old settings, sorting was tried in a fixed order (series first, movies last); that order is retained by the conversion code. We only convert enabled sorters.""" # Keep track of order order = 0 if cfg.enable_tv_sorting() and cfg.tv_sort_string() and cfg.tv_categories(): # Define a new sorter based on the old configuration tv_sorter = {} tv_sorter["order"] = order tv_sorter["min_size"] = cfg.episode_rename_limit() tv_sorter["multipart_label"] = "" # Previously only available for movie sorting tv_sorter["sort_string"] = cfg.tv_sort_string() tv_sorter["sort_cats"] = cfg.tv_categories() tv_sorter["sort_type"] = [sort_to_opts("tv")] tv_sorter["is_active"] = int(cfg.enable_tv_sorting()) # Configure the new sorter logging.debug("Converted old series sorter config to '%s': %s", T("Series Sorting"), tv_sorter) config.ConfigSorter(T("Series Sorting"), tv_sorter) order += 1 if cfg.enable_date_sorting() and cfg.date_sort_string() and cfg.date_categories(): date_sorter = {} date_sorter["order"] = order date_sorter["min_size"] = cfg.episode_rename_limit() date_sorter["multipart_label"] = "" # Previously only available for movie sorting date_sorter["sort_string"] = cfg.date_sort_string() date_sorter["sort_cats"] = cfg.date_categories() date_sorter["sort_type"] = [sort_to_opts("date")] date_sorter["is_active"] = int(cfg.enable_date_sorting()) # Configure the new sorter logging.debug("Converted old date sorter config to '%s': %s", T("Date Sorting"), date_sorter) config.ConfigSorter(T("Date Sorting"), date_sorter) order += 1 if cfg.enable_movie_sorting() and cfg.movie_sort_string() and cfg.movie_categories(): movie_sorter = {} movie_sorter["order"] = order movie_sorter["min_size"] = cfg.movie_rename_limit() movie_sorter["multipart_label"] = cfg.movie_sort_extra() movie_sorter["sort_string"] = cfg.movie_sort_string() movie_sorter["sort_cats"] = cfg.movie_categories() movie_sorter["sort_type"] = [sort_to_opts("movie")] movie_sorter["is_active"] = int(cfg.enable_movie_sorting()) # Configure the new sorter logging.debug("Converted old movie sorter config to '%s': %s", T("Movie Sorting"), movie_sorter) config.ConfigSorter(T("Movie Sorting"), movie_sorter) def convert_history_retention(): """Convert single-option to the split history retention setting""" if "d" in cfg.history_retention(): days_to_keep = int_conv(cfg.history_retention().strip()[:-1]) cfg.history_retention_option.set("days-delete") cfg.history_retention_number.set(days_to_keep) else: to_keep = int_conv(sabnzbd.cfg.history_retention()) if to_keep > 0: cfg.history_retention_option.set("number-delete") cfg.history_retention_number.set(to_keep) elif to_keep < 0: cfg.history_retention_option.set("all-delete") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4457424 SABnzbd-4.3.2/sabnzbd/urlgrabber.py0000644000000000000000000004275014625637243016357 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.urlgrabber - Queue for grabbing NZB files from websites """ import os import sys import time import logging import queue import urllib.request import urllib.parse import urllib.error from http.client import IncompleteRead, HTTPResponse from mailbox import Message from threading import Thread import base64 from typing import Tuple, Optional, Union, List, Dict, Any import sabnzbd from sabnzbd.constants import DEF_TIMEOUT, FUTURE_Q_FOLDER, VALID_NZB_FILES, Status, VALID_ARCHIVES, DuplicateStatus import sabnzbd.misc as misc import sabnzbd.filesystem import sabnzbd.cfg as cfg import sabnzbd.emailer as emailer import sabnzbd.notifier as notifier from sabnzbd.encoding import ubtou, utob from sabnzbd.nzbparser import AddNzbFileResult from sabnzbd.nzbstuff import NzbObject, NzbRejected, NzbRejectToHistory class URLGrabber(Thread): def __init__(self): super().__init__() self.queue: queue.Queue[Tuple[Optional[str], Optional[NzbObject]]] = queue.Queue() self.shutdown = False def add(self, url: str, future_nzo: NzbObject, when: Optional[int] = None): """Add an URL to the URLGrabber queue, 'when' is seconds from now""" if future_nzo and when: # Always increase counter future_nzo.url_tries += 1 # Too many tries? Cancel if future_nzo.url_tries > cfg.max_url_retries(): self.fail_to_history(future_nzo, url, T("Maximum retries")) return future_nzo.url_wait = time.time() + when self.queue.put((url, future_nzo)) def stop(self): self.shutdown = True self.queue.put((None, None)) def run(self): # Read all URL's to grab from the queue for url_nzo_tup in sabnzbd.NzbQueue.get_urls(): self.queue.put(url_nzo_tup) # Start fetching while not self.shutdown: # Set NzbObject object to None so reference from this thread # does not keep the object alive in the future (see #1628) future_nzo = None url, future_nzo = self.queue.get() if not url: # stop signal, go test self.shutdown continue if future_nzo: # Re-queue when too early and still active if future_nzo.url_wait and future_nzo.url_wait > time.time(): self.add(url, future_nzo) time.sleep(1.0) continue # Paused if future_nzo.status == Status.PAUSED: self.add(url, future_nzo) time.sleep(1.0) continue url = url.replace(" ", "") try: if future_nzo: # If nzo entry deleted, give up try: deleted = future_nzo.removed_from_queue except AttributeError: deleted = True if deleted: logging.debug("Dropping URL %s, job entry missing", url) continue filename = None nzo_info = future_nzo.nzo_info wait = 0 retry = True fetch_request = None logging.info("Grabbing URL %s", url) try: fetch_request = _build_request(url) except (urllib.error.HTTPError, Exception) as e: # Cannot list exceptions here, because of unpredictability over platforms error0 = str(sys.exc_info()[0]).lower() error1 = str(sys.exc_info()[1]).lower() logging.debug('Error "%s" trying to get the url %s', error1, url) if "certificate_verify_failed" in error1 or "certificateerror" in error0: msg = T("Server %s uses an untrusted HTTPS certificate") % "" msg += " - https://sabnzbd.org/certificate-errors" retry = False elif "nodename nor servname provided" in error1: msg = T("Server name does not resolve") retry = False elif "401" in error1 or "unauthorized" in error1: msg = T("Unauthorized access") retry = False elif "404" in error1: msg = T("File not on server") retry = False elif hasattr(e, "headers") and "retry-after" in e.headers: # Catch if the server send retry (e.headers is case-INsensitive) wait = misc.int_conv(e.headers["retry-after"]) if fetch_request: for hdr in fetch_request.headers: try: item = hdr.lower() value = fetch_request.headers[hdr] except: continue # Skip empty values if not value: continue if item in ("category_id", "x-dnzb-category"): # Use indexer category in case no specific one was set if value and future_nzo.cat in (None, "*"): if indexer_cat := misc.cat_convert(value): future_nzo.cat = indexer_cat elif item == "x-dnzb-moreinfo": nzo_info["more_info"] = value elif item == "x-dnzb-name": filename = value if not filename.endswith(".nzb"): filename += ".nzb" elif item == "x-dnzb-propername": nzo_info["propername"] = value elif item == "x-dnzb-episodename": nzo_info["episodename"] = value elif item == "x-dnzb-year": nzo_info["year"] = value elif item == "x-dnzb-failure": nzo_info["failure"] = value elif item == "x-dnzb-details": nzo_info["details"] = value elif item == "x-dnzb-password": nzo_info["password"] = value elif item == "retry-after": wait = misc.int_conv(value) elif item == "content-disposition": # Get filename from Content-Disposition header if not filename and "filename" in value: filename = filename_from_content_disposition(value) if wait: # For sites that have a rate-limiting attribute msg = "" retry = True fetch_request = None elif retry: fetch_request, msg, retry, wait, data = _analyse(fetch_request, future_nzo) if not fetch_request: if retry: logging.info("Retry URL %s", url) self.add(url, future_nzo, wait) else: self.fail_to_history(future_nzo, url, msg) continue if not filename: filename = os.path.basename(urllib.parse.unquote(url)) # URL was redirected, maybe the redirect has better filename? # Check if the original URL has extension if ( url != fetch_request.geturl() and sabnzbd.filesystem.get_ext(filename) not in VALID_NZB_FILES + VALID_ARCHIVES ): filename = os.path.basename(urllib.parse.unquote(fetch_request.geturl())) elif "&nzbname=" in filename: # Sometimes the filename contains the full URL, duh! filename = filename[filename.find("&nzbname=") + 9 :] # process data if not data: try: data = fetch_request.read() except (IncompleteRead, IOError): self.fail_to_history(future_nzo, url, T("Server could not complete request")) fetch_request.close() continue fetch_request.close() if b" 0: emailer.badfetch_mail(msg, url) # Parse category to make sure script is set correctly after a grab nzo.cat, _, nzo.script, _ = misc.cat_to_opts(nzo.cat, script=nzo.script) # Add to history and run script if desired sabnzbd.NzbQueue.fail_to_history(nzo) def _build_request(url: str) -> HTTPResponse: # Detect basic auth # Adapted from python-feedparser user_passwd = None u = urllib.parse.urlparse(url) if u.username is not None or u.password is not None: if u.username and u.password: user_passwd = "%s:%s" % (u.username, u.password) host_port = u.hostname if u.port: host_port += ":" + str(u.port) url = urllib.parse.urlunparse(u._replace(netloc=host_port)) # Start request req = urllib.request.Request(url) # Add headers req.add_header("User-Agent", "SABnzbd/%s" % sabnzbd.__version__) req.add_header("Accept-encoding", "gzip") if user_passwd: req.add_header("Authorization", "Basic " + ubtou(base64.b64encode(utob(user_passwd))).strip()) return urllib.request.urlopen(req) def _analyse(fetch_request: HTTPResponse, future_nzo: NzbObject): """Analyze response of indexer returns fetch_request|None, error-message|None, retry, wait-seconds, data """ data = None if not fetch_request or fetch_request.getcode() != 200: if fetch_request: msg = fetch_request.msg else: msg = "" # Increasing wait-time in steps for standard errors when = DEF_TIMEOUT * (future_nzo.url_tries + 1) logging.debug("No usable response from indexer, retry after %s sec", when) return None, msg, True, when, data return fetch_request, fetch_request.msg, False, 0, data def filename_from_content_disposition(content_disposition: str) -> Optional[str]: """ Extract and validate filename from a Content-Disposition header. Origin: https://github.com/httpie/httpie/blob/4c8633c6e51f388523ab4fa649040934402a4fc9/httpie/downloads.py#L98 :param content_disposition: Content-Disposition value :type content_disposition: str :return: the filename if present and valid, otherwise `None` :example: filename_from_content_disposition('attachment; filename=jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz') should return: 'jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz' """ if filename := Message(f"Content-Disposition: attachment; {content_disposition}").get_filename(): # Basic sanitation if filename := os.path.basename(filename).lstrip(".").strip(): return filename def add_url( url: str, pp: Optional[Union[int, str]] = None, script: Optional[str] = None, cat: Optional[str] = None, priority: Optional[Union[int, str]] = None, nzbname: Optional[str] = None, password: Optional[str] = None, nzo_info: Optional[Dict[str, Any]] = None, dup_check: bool = True, ) -> Tuple[AddNzbFileResult, List[str]]: """Add NZB based on a URL, attributes optional""" if not url.lower().startswith("http"): return AddNzbFileResult.NO_FILES_FOUND, [] # Base conversion of input cat, pp, script = misc.cat_pp_script_sanitizer(cat, pp, script) # Generate the placeholder logging.debug("Creating placeholder NZO for %s", url) msg = T("Trying to fetch NZB from %s") % url result: AddNzbFileResult = AddNzbFileResult.OK future_nzo = None nzo_ids = [] try: future_nzo = NzbObject( filename=msg, pp=pp, script=script, futuretype=True, cat=cat, url=url, priority=priority, password=password, nzbname=nzbname, status=Status.GRABBING, nzo_info=nzo_info, dup_check=dup_check, ) except NzbRejected: # Rejected as duplicate result = AddNzbFileResult.ERROR except NzbRejectToHistory as err: # Duplicate directed to history sabnzbd.NzbQueue.fail_to_history(err.nzo) nzo_ids.append(err.nzo.nzo_id) # Success if future_nzo: nzo_ids.append(sabnzbd.NzbQueue.add(future_nzo)) sabnzbd.URLGrabber.add(url, future_nzo) return result, nzo_ids ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4458442 SABnzbd-4.3.2/sabnzbd/rss.py0000644000000000000000000006613414625637243015041 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.rss - rss client functionality """ import re import logging import time import datetime import threading import urllib.parse import sabnzbd from sabnzbd.constants import RSS_FILE_NAME, DEFAULT_PRIORITY from sabnzbd.decorators import synchronized import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.misc import ( cat_convert, convert_filter, cat_to_opts, match_str, from_units, int_conv, get_base_url, helpful_warning, ) import sabnzbd.emailer as emailer import feedparser ############################################################################## # Wrapper functions ############################################################################## def notdefault(item): """Return True if not 'Default|''|*'""" return bool(item) and str(item).lower() not in ("default", "*", "", str(DEFAULT_PRIORITY)) def remove_obsolete(jobs, new_jobs): """Expire G/B links that are not in new_jobs (mark them 'X') Expired links older than 3 days are removed from 'jobs' """ now = time.time() limit = now - 259200 # 3days (3x24x3600) for old in list(jobs): tm = jobs[old]["time"] if old not in new_jobs: if jobs[old].get("status", " ")[0] in ("G", "B"): jobs[old]["status"] = "X" if jobs[old]["status"] == "X" and tm < limit: logging.debug("Purging link %s", old) del jobs[old] RSS_LOCK = threading.RLock() _RE_SP = re.compile(r"s*(\d+)[ex](\d+)", re.I) _RE_SIZE1 = re.compile(r"Size:\s*(\d+\.\d+\s*[KMG]?)B\W*", re.I) _RE_SIZE2 = re.compile(r"\W*(\d+\.\d+\s*[KMG]?)B\W*", re.I) class RSSReader: def __init__(self): self.jobs = {} self.next_run = time.time() self.shutdown = False try: self.jobs = sabnzbd.filesystem.load_admin(RSS_FILE_NAME) if self.jobs: for feed in self.jobs: remove_obsolete(self.jobs[feed], list(self.jobs[feed])) except: logging.warning(T("Cannot read %s"), RSS_FILE_NAME) logging.info("Traceback: ", exc_info=True) # Storage needs to be dict if not self.jobs: self.jobs = {} # jobs is a NAME-indexed dictionary # Each element is link-indexed dictionary # Each element is another dictionary: # status : 'D', 'G', 'B', 'X' (downloaded, good-match, bad-match, obsolete) # '*' added means: from the initial batch # '-' added to 'D' means downloaded, but not displayed anymore # title : Title # url : URL # cat : category # orgcat : category as read from feed # pp : pp # script : script # prio : priority # time : timestamp (used for time-based clean-up) # size : size in bytes # age : age in datetime format as specified by feed # season : season number (if applicable) # episode : episode number (if applicable) # Patch feedparser patch_feedparser() def stop(self): self.shutdown = True @synchronized(RSS_LOCK) def run_feed(self, feed=None, download=False, ignoreFirst=False, force=False, readout=True): """Run the query for one URI and apply filters""" self.shutdown = False if not feed: return "No such feed" newlinks = [] new_downloads = [] # Preparations, get options try: feeds = config.get_rss()[feed] except KeyError: logging.error(T('Incorrect RSS feed description "%s"'), feed) logging.info("Traceback: ", exc_info=True) return T('Incorrect RSS feed description "%s"') % feed uris = feeds.uri() defCat = feeds.cat() if not notdefault(defCat) or defCat not in sabnzbd.api.list_cats(default=False): defCat = None defPP = feeds.pp() if not notdefault(defPP): defPP = None defScript = feeds.script() if not notdefault(defScript): defScript = None defPrio = feeds.priority() if not notdefault(defPrio): defPrio = None # Preparations, convert filters to regex's regexes = [] reTypes = [] reCats = [] rePPs = [] rePrios = [] reScripts = [] reEnabled = [] for feed_filter in feeds.filters(): reCat = feed_filter[0] if defCat in ("", "*"): reCat = None reCats.append(reCat) rePPs.append(feed_filter[1]) reScripts.append(feed_filter[2]) reTypes.append(feed_filter[3]) if feed_filter[3] in ("<", ">", "F", "S"): regexes.append(feed_filter[4]) else: regexes.append(convert_filter(feed_filter[4])) rePrios.append(feed_filter[5]) reEnabled.append(feed_filter[6] != "0") regcount = len(regexes) # Set first if this is the very first scan of this URI first = (feed not in self.jobs) and ignoreFirst # Add SABnzbd's custom User Agent feedparser.USER_AGENT = "SABnzbd/%s" % sabnzbd.__version__ # Read the RSS feed msg = "" entries = [] if readout: all_entries = [] for uri in uris: # Reset parsing message for each feed msg = "" feed_parsed = {} uri = uri.replace(" ", "%20").replace("feed://", "http://") logging.debug("Running feedparser on %s", uri) try: feed_parsed = feedparser.parse(uri) except Exception as feedparser_exc: # Feedparser 5 would catch all errors, while 6 just throws them back at us feed_parsed["bozo_exception"] = feedparser_exc logging.debug("Finished parsing %s", uri) status = feed_parsed.get("status", 999) if status in (401, 402, 403): msg = T("Do not have valid authentication for feed %s") % uri elif 500 <= status <= 599: msg = T("Server side error (server code %s); could not get %s on %s") % (status, feed, uri) entries = feed_parsed.get("entries", []) if not entries and "feed" in feed_parsed and "error" in feed_parsed["feed"]: msg = T("Failed to retrieve RSS from %s: %s") % (uri, feed_parsed["feed"]["error"]) # Exception was thrown if "bozo_exception" in feed_parsed and not entries: msg = str(feed_parsed["bozo_exception"]) if "CERTIFICATE_VERIFY_FAILED" in msg: msg = T("Server %s uses an untrusted HTTPS certificate") % get_base_url(uri) msg += " - https://sabnzbd.org/certificate-errors" elif "href" in feed_parsed and feed_parsed["href"] != uri and "login" in feed_parsed["href"]: # Redirect to login page! msg = T("Do not have valid authentication for feed %s") % uri else: msg = T("Failed to retrieve RSS from %s: %s") % (uri, msg) if msg: # We need to escape any "%20" that could be in the warning due to the URL's helpful_warning(urllib.parse.unquote(msg)) elif not entries: msg = T("RSS Feed %s was empty") % uri logging.info(msg) all_entries.extend(entries) entries = all_entries # In case of a new feed if feed not in self.jobs: self.jobs[feed] = {} jobs = self.jobs[feed] # Error in readout or now new readout if readout: if not entries: return msg else: entries = jobs # Filter out valid new links for entry in entries: if self.shutdown: return if readout: try: link, infourl, category, size, age, season, episode = _get_link(entry) except (AttributeError, IndexError): logging.info(T("Incompatible feed") + " " + uri) logging.info("Traceback: ", exc_info=True) return T("Incompatible feed") title = entry.title # If there's multiple feeds, remove the duplicates based on title and size if len(uris) > 1: skip_job = False for job_link, job in jobs.items(): # Allow 5% size deviation because indexers might have small differences for same release if ( job.get("title") == title and link != job_link and (job.get("size") * 0.95) < size < (job.get("size") * 1.05) ): logging.info("Ignoring job %s from other feed", title) skip_job = True break if skip_job: continue else: link = entry infourl = jobs[link].get("infourl", "") category = jobs[link].get("orgcat", "") if category in ("", "*"): category = None title = jobs[link].get("title", "") size = jobs[link].get("size", 0) age = jobs[link].get("age") season = jobs[link].get("season", 0) episode = jobs[link].get("episode", 0) if link: # Make sure spaces are quoted in the URL link = link.strip().replace(" ", "%20") newlinks.append(link) if link in jobs: jobstat = jobs[link].get("status", " ")[0] else: jobstat = "N" if jobstat in "NGB" or (jobstat == "X" and readout): # Match this title against all filters logging.debug("Trying title %s", title) result = False myCat = defCat myPP = defPP myScript = defScript myPrio = defPrio n = 0 if ("F" in reTypes or "S" in reTypes) and (not season or not episode): show_analysis = sabnzbd.sorting.BasicAnalyzer(title) season = show_analysis.info.get("season") episode = show_analysis.info.get("episode") # Match against all filters until an positive or negative match logging.debug("Size %s", size) for n in range(regcount): if reEnabled[n]: if category and reTypes[n] == "C": found = re.search(regexes[n], category) if not found: logging.debug("Filter rejected on rule %d", n) result = False break elif reTypes[n] == "<" and size and from_units(regexes[n]) < size: # "Size at most" : too large logging.debug("Filter rejected on rule %d", n) result = False break elif reTypes[n] == ">" and size and from_units(regexes[n]) > size: # "Size at least" : too small logging.debug("Filter rejected on rule %d", n) result = False break elif reTypes[n] == "F" and not ep_match(season, episode, regexes[n]): # "Starting from SxxEyy", too early episode logging.debug("Filter requirement match on rule %d", n) result = False break elif reTypes[n] == "S" and ep_match(season, episode, regexes[n], title): logging.debug("Filter matched on rule %d", n) result = True break else: if regexes[n]: found = re.search(regexes[n], title) else: found = False if reTypes[n] == "M" and not found: logging.debug("Filter rejected on rule %d", n) result = False break if found and reTypes[n] == "A": logging.debug("Filter matched on rule %d", n) result = True break if found and reTypes[n] == "R": logging.debug("Filter rejected on rule %d", n) result = False break if len(reCats): if not result and defCat: # Apply Feed-category on non-matched items myCat = defCat elif result and notdefault(reCats[n]): # Use the matched info myCat = reCats[n] elif category and not defCat: # No result and no Feed-category myCat = cat_convert(category) if myCat: myCat, catPP, catScript, catPrio = cat_to_opts(myCat) else: myCat = catPP = catScript = catPrio = None if notdefault(rePPs[n]): myPP = rePPs[n] elif not (reCats[n] or category): myPP = catPP if notdefault(reScripts[n]): myScript = reScripts[n] elif not (notdefault(reCats[n]) or category): myScript = catScript if rePrios[n] not in (str(DEFAULT_PRIORITY), ""): myPrio = rePrios[n] elif not ((rePrios[n] != str(DEFAULT_PRIORITY)) or category): myPrio = catPrio act = download and not first if link in jobs: act = act and not jobs[link].get("status", "").endswith("*") act = act or force star = first or jobs[link].get("status", "").endswith("*") else: star = first if result: _HandleLink( feed, jobs, link, infourl, title, size, age, season, episode, "G", category, myCat, myPP, myScript, act, star, priority=myPrio, rule=n, ) if act: new_downloads.append(title) else: _HandleLink( feed, jobs, link, infourl, title, size, age, season, episode, "B", category, myCat, myPP, myScript, False, star, priority=myPrio, rule=n, ) # Send email if wanted and not "forced" if new_downloads and cfg.email_rss() and not force: emailer.rss_mail(feed, new_downloads) remove_obsolete(jobs, newlinks) return msg def run(self): """Run all the URI's and filters""" if not sabnzbd.PAUSED_ALL: active = False if self.next_run < time.time(): self.next_run = time.time() + cfg.rss_rate() * 60 feeds = config.get_rss() try: for feed in feeds: if feeds[feed].enable(): logging.info('Starting scheduled RSS read-out for "%s"', feed) active = True self.run_feed(feed, download=True, ignoreFirst=True) # Wait 15 seconds, else sites may get irritated for _ in range(15): if self.shutdown: return else: time.sleep(1.0) except (KeyError, RuntimeError): # Feed must have been deleted logging.info("RSS read-out crashed, feed must have been deleted or edited") logging.debug("Traceback: ", exc_info=True) pass if active: self.save() logging.info("Finished scheduled RSS read-outs") @synchronized(RSS_LOCK) def show_result(self, feed): if feed in self.jobs: try: return self.jobs[feed] except: return {} else: return {} @synchronized(RSS_LOCK) def save(self): sabnzbd.filesystem.save_admin(self.jobs, RSS_FILE_NAME) @synchronized(RSS_LOCK) def delete(self, feed): if feed in self.jobs: del self.jobs[feed] @synchronized(RSS_LOCK) def rename(self, old_feed, new_feed): if old_feed in self.jobs: old_data = self.jobs.pop(old_feed) self.jobs[new_feed] = old_data @synchronized(RSS_LOCK) def flag_downloaded(self, feed, fid): if feed in self.jobs: lst = self.jobs[feed] for link in lst: if lst[link].get("url", "") == fid: lst[link]["status"] = "D" lst[link]["time_downloaded"] = time.localtime() @synchronized(RSS_LOCK) def lookup_url(self, feed, url): if url and feed in self.jobs: lst = self.jobs[feed] for link in lst: if lst[link].get("url") == url: return lst[link] return None @synchronized(RSS_LOCK) def clear_feed(self, feed): # Remove any previous references to this feed name, and start fresh if feed in self.jobs: del self.jobs[feed] @synchronized(RSS_LOCK) def clear_downloaded(self, feed): # Mark downloaded jobs, so that they won't be displayed any more. if feed in self.jobs: for item in self.jobs[feed]: if self.jobs[feed][item]["status"] == "D": self.jobs[feed][item]["status"] = "D-" def patch_feedparser(): """Apply options that work for SABnzbd Add additional parsing of attributes """ feedparser.SANITIZE_HTML = 0 feedparser.RESOLVE_RELATIVE_URIS = 0 # Support both feedparser 5 and 6 try: feedparser_mixin = feedparser._FeedParserMixin feedparser_parse_date = feedparser._parse_date except AttributeError: feedparser_mixin = feedparser.mixin._FeedParserMixin feedparser_parse_date = feedparser.datetimes._parse_date # Add our own namespace feedparser_mixin.namespaces["http://www.newznab.com/DTD/2010/feeds/attributes/"] = "newznab" # Add parsers for the namespace def _start_newznab_attr(self, attrsD): # Support both feedparser 5 and 6 try: context = self._getContext() except AttributeError: context = self._get_context() # Add the dict if "newznab" not in context: context["newznab"] = {} # Don't crash when it fails try: # Add keys context["newznab"][attrsD["name"]] = attrsD["value"] # Try to get date-object if attrsD["name"] == "usenetdate": context["newznab"][attrsD["name"] + "_parsed"] = feedparser_parse_date(attrsD["value"]) except KeyError: pass feedparser_mixin._start_newznab_attr = _start_newznab_attr feedparser_mixin._start_nZEDb_attr = _start_newznab_attr feedparser_mixin._start_nzedb_attr = _start_newznab_attr feedparser_mixin._start_nntmux_attr = _start_newznab_attr def _HandleLink( feed, jobs, link, infourl, title, size, age, season, episode, flag, orgcat, cat, pp, script, download, star, priority=DEFAULT_PRIORITY, rule=0, ): """Process one link""" if script == "": script = None if pp == "": pp = None jobs[link] = {} jobs[link]["title"] = title jobs[link]["url"] = link jobs[link]["infourl"] = infourl jobs[link]["cat"] = cat jobs[link]["pp"] = pp jobs[link]["script"] = script jobs[link]["prio"] = str(priority) jobs[link]["orgcat"] = orgcat jobs[link]["size"] = size jobs[link]["age"] = age jobs[link]["time"] = time.time() jobs[link]["rule"] = str(rule) jobs[link]["season"] = season jobs[link]["episode"] = episode if special_rss_site(link): nzbname = None else: nzbname = title if download: jobs[link]["status"] = "D" jobs[link]["time_downloaded"] = time.localtime() logging.info("Adding %s (%s) to queue", link, title) sabnzbd.urlgrabber.add_url( link, pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname, nzo_info={"RSS": feed}, ) else: if star: jobs[link]["status"] = flag + "*" else: jobs[link]["status"] = flag def _get_link(entry): """Retrieve the post link from this entry Returns (link, category, size) """ size = 0 age = datetime.datetime.now() # Try standard link and enclosures first link = entry.link if not link: link = entry.links[0].href if "enclosures" in entry: try: link = entry.enclosures[0]["href"] size = int(entry.enclosures[0]["length"]) except: pass # GUID usually has URL to result on page infourl = None if entry.get("id") and entry.id != link and entry.id.lower().startswith("http"): infourl = entry.id if size == 0: # Try to find size in Description try: desc = entry.description.replace("\n", " ").replace(" ", " ") m = _RE_SIZE1.search(desc) or _RE_SIZE2.search(desc) if m: size = from_units(m.group(1)) except: pass # Try newznab attribute first, this is the correct one try: # Convert it to format that calc_age understands age = datetime.datetime(*entry["newznab"]["usenetdate_parsed"][:6]) except: # Date from feed (usually lags behind) try: # Convert it to format that calc_age understands age = datetime.datetime(*entry.published_parsed[:6]) except: pass finally: # We need to convert it to local timezone, feedparser always returns UTC age = age - datetime.timedelta(seconds=time.timezone) # Maybe the newznab also provided SxxExx info try: season = re.findall(r"\d+", entry["newznab"]["season"])[0] episode = re.findall(r"\d+", entry["newznab"]["episode"])[0] except (KeyError, IndexError): season = episode = 0 if link and link.lower().startswith("http"): try: category = entry.cattext except AttributeError: try: category = entry.category except AttributeError: try: # nzb.su category = entry.tags[0]["term"] except (AttributeError, IndexError, KeyError): try: category = entry.description except AttributeError: category = "" return link, infourl, category, size, age, season, episode else: logging.warning(T("Empty RSS entry found (%s)"), link) return None, None, "", 0, None, 0, 0 def special_rss_site(url): """Return True if url describes an RSS site with odd titles""" return cfg.rss_filenames() or match_str(url, cfg.rss_odd_titles()) def ep_match(season, episode, expr, title=None): """Return True if season, episode is at or above expected Optionally `title` can be matched """ if m := _RE_SP.search(expr): # Make sure they are all integers for comparison req_season = int(m.group(1)) req_episode = int(m.group(2)) season = int_conv(season) episode = int_conv(episode) if season > req_season or (season == req_season and episode >= req_episode): if title: show = expr[: m.start()].replace(".", " ").replace("_", " ").strip() show = show.replace(" ", "[._ ]+") return bool(re.search(show, title, re.I)) else: return True else: return False else: return True ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.445921 SABnzbd-4.3.2/sabnzbd/cfg.py0000644000000000000000000010477014625637243014770 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.cfg - Configuration Parameters """ import logging import os import re import argparse import socket import ipaddress from typing import List, Tuple, Union import sabnzbd from sabnzbd.config import ( OptionBool, OptionNumber, OptionPassword, OptionDir, OptionStr, OptionList, create_api_key, ) from sabnzbd.constants import ( DEF_HOST, DEF_PORT, DEF_STD_WEB_DIR, DEF_ADMIN_DIR, DEF_DOWNLOAD_DIR, DEF_NZBBACK_DIR, DEF_SCANRATE, DEF_COMPLETE_DIR, DEF_FOLDER_MAX, DEF_STD_WEB_COLOR, DEF_HTTPS_CERT_FILE, DEF_HTTPS_KEY_FILE, ) from sabnzbd.filesystem import same_directory, real_path, is_valid_script, is_network_path # Validators currently only are made for string/list-of-strings # and return those on success or an error message. ValidateResult = Union[Tuple[None, str], Tuple[None, List[str]], Tuple[str, None]] ############################################################################## # Default Validation handlers ############################################################################## class ErrorCatchingArgumentParser(argparse.ArgumentParser): def error(self, status=0, message=None): # Need to override so it doesn't raise SystemExit if status: raise ValueError def clean_nice_ionice_parameters(value: str) -> ValidateResult: """Verify that the passed parameters are not exploits""" if value: parser = ErrorCatchingArgumentParser() # Nice parameters parser.add_argument("-n", "--adjustment", type=int) # Ionice parameters, not supporting -p parser.add_argument("--classdata", type=int) parser.add_argument("-c", "--class", type=int) parser.add_argument("-t", "--ignore", action="store_true") try: parser.parse_args(value.split()) except ValueError: # Also log at start-up if invalid parameter was set in the ini msg = "%s: %s" % (T("Incorrect parameter"), value) logging.error(msg) return msg, None return None, value def all_lowercase(value: Union[str, List]) -> Tuple[None, Union[str, List]]: """Lowercase and strip everything!""" if isinstance(value, list): return None, [item.lower().strip() for item in value] return None, value.lower().strip() def lower_case_ext(value: Union[str, List]) -> Tuple[None, Union[str, List]]: """Generate lower case extension(s), without dot""" if isinstance(value, list): return None, [item.lower().strip(" .") for item in value] return None, value.lower().strip(" .") def validate_single_tag(value: List[str]) -> Tuple[None, List[str]]: """Don't split single indexer tags like "TV > HD" into ['TV', '>', 'HD'] """ if len(value) == 3: if value[1] == ">": return None, [" ".join(value)] return None, value def validate_strip_right_slash(value: str) -> Tuple[None, str]: """Strips the right slash""" if value: return None, value.rstrip("/") return None, value RE_VAL = re.compile(r"[^@ ]+@[^.@ ]+\.[^.@ ]") def validate_email(value: Union[List, str]) -> ValidateResult: if email_endjob() or email_full() or email_rss(): if isinstance(value, list): values = value else: values = [value] for addr in values: if not (addr and RE_VAL.match(addr)): return T("%s is not a valid email address") % addr, None return None, value def validate_server(value: str) -> ValidateResult: """Check if server non-empty""" if value == "" and (email_endjob() or email_full() or email_rss()): return T("Server address required"), None else: return None, value def validate_host(value: str) -> ValidateResult: """Check if host is valid: an IP address, or a name/FQDN that resolves to an IP address""" # easy: value is a plain IPv4 or IPv6 address: try: ipaddress.ip_address(value) # valid host, so return it return None, value except: pass # we don't want a plain number. As socket.getaddrinfo("100", ...) allows that, we have to pre-check try: int(value) # plain int as input, which is not allowed return T("Invalid server address."), None except: pass # not a plain IPv4 nor IPv6 address, so let's check if it's a name that resolves to IPv4 try: socket.getaddrinfo(value, None, socket.AF_INET) # all good logging.debug("Valid host name") return None, value except: pass # ... and if not: does it resolve to IPv6 ... ? try: socket.getaddrinfo(value, None, socket.AF_INET6) # all good logging.debug("Valid host name") return None, value except: logging.debug("No valid host name") pass # if we get here, it is not valid host, so return None return T("Invalid server address."), None def validate_script(value: str) -> ValidateResult: """Check if value is a valid script""" if not sabnzbd.__INITIALIZED__ or (value and is_valid_script(value)): return None, value elif sabnzbd.misc.is_none(value): return None, "None" return T("%s is not a valid script") % value, None def validate_permissions(value: str) -> ValidateResult: """Check the permissions for correct input""" # Octal verification if not value: return None, value try: oct_value = int(value, 8) # Block setting it to 0 if not oct_value: raise ValueError except ValueError: return T("%s is not a correct octal value") % value, None # Check if we at least have user-permissions if oct_value < int("700", 8): sabnzbd.misc.helpful_warning( T("Permissions setting of %s might deny SABnzbd access to the files and folders it creates."), value ) return None, value def validate_safedir(root: str, value: str, default: str) -> ValidateResult: """Allow only when queues are empty and not a network-path""" if not sabnzbd.__INITIALIZED__ or (sabnzbd.PostProcessor.empty() and sabnzbd.NzbQueue.is_empty()): # We allow it, but send a warning if is_network_path(real_path(root, value)): sabnzbd.misc.helpful_warning(T('Network path "%s" should not be used here'), value) return validate_default_if_empty(root, value, default) else: return T("Queue not empty, cannot change folder."), None def validate_download_vs_complete_dir(root: str, value: str, default: str): """Make sure download_dir and complete_dir are not identical or that download_dir is not a subfolder of complete_dir""" # Check what new value we are trying to set if default == DEF_COMPLETE_DIR: check_download_dir = download_dir.get_path() check_complete_dir = real_path(root, value) elif default == DEF_DOWNLOAD_DIR: check_download_dir = real_path(root, value) check_complete_dir = complete_dir.get_path() else: raise ValueError("Validator can only be used for download_dir/complete_dir") if same_directory(check_download_dir, check_complete_dir): return ( T("The Completed Download Folder cannot be the same or a subfolder of the Temporary Download Folder"), None, ) elif default == DEF_COMPLETE_DIR: # The complete_dir allows UNC return validate_default_if_empty(root, value, default) else: return validate_safedir(root, value, default) def validate_scriptdir_not_appdir(root: str, value: str, default: str) -> Tuple[None, str]: """Warn users to not use the Program Files folder for their scripts""" # Need to add seperator so /mnt/sabnzbd and /mnt/sabnzbd-data are not detected as equal if value and same_directory(sabnzbd.DIR_PROG, os.path.join(root, value)): # Warn, but do not block sabnzbd.misc.helpful_warning( T( "Do not use a folder in the application folder as your Scripts Folder, it might be emptied during updates." ) ) return None, value def validate_default_if_empty(root: str, value: str, default: str) -> Tuple[None, str]: """If value is empty, return default""" if value: return None, value else: return None, default ############################################################################## # Special settings ############################################################################## # This should be here so it's initialized first when the config is read helpful_warnings = OptionBool("misc", "helpful_warnings", True) queue_complete = OptionStr("misc", "queue_complete") queue_complete_pers = OptionBool("misc", "queue_complete_pers", False) bandwidth_perc = OptionNumber("misc", "bandwidth_perc", 100, minval=0, maxval=100) refresh_rate = OptionNumber("misc", "refresh_rate", 0) interface_settings = OptionStr("misc", "interface_settings") log_level = OptionNumber("logging", "log_level", 1, minval=-1, maxval=2) log_size = OptionNumber("logging", "max_log_size", 5242880) log_backups = OptionNumber("logging", "log_backups", 5, minval=1, maxval=1024) queue_limit = OptionNumber("misc", "queue_limit", 20, minval=0) configlock = OptionBool("misc", "config_lock", False) ############################################################################## # One time trackers ############################################################################## fixed_ports = OptionBool("misc", "fixed_ports", False, public=False) notified_new_skin = OptionNumber("misc", "notified_new_skin", 0) direct_unpack_tested = OptionBool("misc", "direct_unpack_tested", False, public=False) sorters_converted = OptionBool("misc", "sorters_converted", False, public=False) ############################################################################## # Config - General ############################################################################## version_check = OptionNumber("misc", "check_new_rel", 1) autobrowser = OptionBool("misc", "auto_browser", True) language = OptionStr("misc", "language", "en") enable_https_verification = OptionBool("misc", "enable_https_verification", True) cherryhost = OptionStr("misc", "host", DEF_HOST, validation=validate_host) cherryport = OptionStr("misc", "port", DEF_PORT) https_port = OptionStr("misc", "https_port") username = OptionStr("misc", "username") password = OptionPassword("misc", "password") bandwidth_max = OptionStr("misc", "bandwidth_max") cache_limit = OptionStr("misc", "cache_limit") web_dir = OptionStr("misc", "web_dir", DEF_STD_WEB_DIR) web_color = OptionStr("misc", "web_color", DEF_STD_WEB_COLOR) https_cert = OptionDir("misc", "https_cert", DEF_HTTPS_CERT_FILE, create=False) https_key = OptionDir("misc", "https_key", DEF_HTTPS_KEY_FILE, create=False) https_chain = OptionDir("misc", "https_chain", create=False) enable_https = OptionBool("misc", "enable_https", False) # 0=local-only, 1=nzb, 2=api, 3=full_api, 4=webui, 5=webui with login for external inet_exposure = OptionNumber("misc", "inet_exposure", 0, protect=True) api_key = OptionStr("misc", "api_key", create_api_key()) nzb_key = OptionStr("misc", "nzb_key", create_api_key()) socks5_proxy_url = OptionStr("misc", "socks5_proxy_url") ############################################################################## # Config - Folders ############################################################################## permissions = OptionStr("misc", "permissions", validation=validate_permissions) download_dir = OptionDir( "misc", "download_dir", DEF_DOWNLOAD_DIR, create=False, # Flag is modified and directory is created during initialize! apply_permissions=True, validation=validate_download_vs_complete_dir, ) download_free = OptionStr("misc", "download_free") complete_dir = OptionDir( "misc", "complete_dir", DEF_COMPLETE_DIR, create=False, # Flag is modified and directory is created during initialize! apply_permissions=True, validation=validate_download_vs_complete_dir, ) complete_free = OptionStr("misc", "complete_free") fulldisk_autoresume = OptionBool("misc", "fulldisk_autoresume", False) script_dir = OptionDir("misc", "script_dir", writable=False, validation=validate_scriptdir_not_appdir) nzb_backup_dir = OptionDir("misc", "nzb_backup_dir", DEF_NZBBACK_DIR) admin_dir = OptionDir("misc", "admin_dir", DEF_ADMIN_DIR, validation=validate_safedir) backup_dir = OptionDir("misc", "backup_dir") dirscan_dir = OptionDir("misc", "dirscan_dir", writable=False) dirscan_speed = OptionNumber("misc", "dirscan_speed", DEF_SCANRATE, minval=0, maxval=3600) password_file = OptionDir("misc", "password_file", "", create=False) log_dir = OptionDir("misc", "log_dir", "logs", validation=validate_default_if_empty) ############################################################################## # Config - Switches ############################################################################## max_art_tries = OptionNumber("misc", "max_art_tries", 3, minval=2) top_only = OptionBool("misc", "top_only", False) sfv_check = OptionBool("misc", "sfv_check", True) script_can_fail = OptionBool("misc", "script_can_fail", False) enable_recursive = OptionBool("misc", "enable_recursive", True) flat_unpack = OptionBool("misc", "flat_unpack", False) par_option = OptionStr("misc", "par_option") pre_check = OptionBool("misc", "pre_check", False) nice = OptionStr("misc", "nice", validation=clean_nice_ionice_parameters) win_process_prio = OptionNumber("misc", "win_process_prio", 3) ionice = OptionStr("misc", "ionice", validation=clean_nice_ionice_parameters) fail_hopeless_jobs = OptionBool("misc", "fail_hopeless_jobs", True) fast_fail = OptionBool("misc", "fast_fail", True) autodisconnect = OptionBool("misc", "auto_disconnect", True) pre_script = OptionStr("misc", "pre_script", "None", validation=validate_script) end_queue_script = OptionStr("misc", "end_queue_script", "None", validation=validate_script) no_dupes = OptionNumber("misc", "no_dupes", 0) no_series_dupes = OptionNumber("misc", "no_series_dupes", 0) # Kept for converting to no_smart_dupes no_smart_dupes = OptionNumber("misc", "no_smart_dupes", 0) dupes_propercheck = OptionBool("misc", "dupes_propercheck", True) pause_on_pwrar = OptionNumber("misc", "pause_on_pwrar", 1) ignore_samples = OptionBool("misc", "ignore_samples", False) deobfuscate_final_filenames = OptionBool("misc", "deobfuscate_final_filenames", True) auto_sort = OptionStr("misc", "auto_sort") direct_unpack = OptionBool("misc", "direct_unpack", False) propagation_delay = OptionNumber("misc", "propagation_delay", 0, minval=0) folder_rename = OptionBool("misc", "folder_rename", True) replace_spaces = OptionBool("misc", "replace_spaces", False) replace_underscores = OptionBool("misc", "replace_underscores", False) replace_dots = OptionBool("misc", "replace_dots", False) safe_postproc = OptionBool("misc", "safe_postproc", True) pause_on_post_processing = OptionBool("misc", "pause_on_post_processing", False) enable_all_par = OptionBool("misc", "enable_all_par", False) sanitize_safe = OptionBool("misc", "sanitize_safe", False) cleanup_list = OptionList("misc", "cleanup_list", validation=lower_case_ext) unwanted_extensions = OptionList("misc", "unwanted_extensions", validation=lower_case_ext) action_on_unwanted_extensions = OptionNumber("misc", "action_on_unwanted_extensions", 0) unwanted_extensions_mode = OptionNumber("misc", "unwanted_extensions_mode", 0) new_nzb_on_failure = OptionBool("misc", "new_nzb_on_failure", False) history_retention = OptionStr("misc", "history_retention", "0") # Kept for converting to split option history_retention_option = OptionStr("misc", "history_retention_option", "all") history_retention_number = OptionNumber("misc", "history_retention_number", minval=1) quota_size = OptionStr("misc", "quota_size") quota_day = OptionStr("misc", "quota_day") quota_resume = OptionBool("misc", "quota_resume", False) quota_period = OptionStr("misc", "quota_period", "m") ############################################################################## # Config - Sorting (OLD SORTER) ############################################################################## enable_tv_sorting = OptionBool("misc", "enable_tv_sorting", False, public=False) tv_sort_string = OptionStr("misc", "tv_sort_string", public=False) tv_categories = OptionList("misc", "tv_categories", ["tv"], public=False) enable_movie_sorting = OptionBool("misc", "enable_movie_sorting", False, public=False) movie_sort_string = OptionStr("misc", "movie_sort_string", public=False) movie_sort_extra = OptionStr("misc", "movie_sort_extra", "-cd%1", strip=False, public=False) movie_categories = OptionList("misc", "movie_categories", ["movies"], public=False) enable_date_sorting = OptionBool("misc", "enable_date_sorting", False, public=False) date_sort_string = OptionStr("misc", "date_sort_string", public=False) date_categories = OptionList("misc", "date_categories", ["tv"], public=False) ############################################################################## # Config - Scheduling and RSS ############################################################################## schedules = OptionList("misc", "schedlines") rss_rate = OptionNumber("misc", "rss_rate", 60, minval=15, maxval=24 * 60) ############################################################################## # Config - Specials ############################################################################## # Bool switches ampm = OptionBool("misc", "ampm", False) start_paused = OptionBool("misc", "start_paused", False) preserve_paused_state = OptionBool("misc", "preserve_paused_state", False) enable_par_cleanup = OptionBool("misc", "enable_par_cleanup", True) process_unpacked_par2 = OptionBool("misc", "process_unpacked_par2", True) enable_multipar = OptionBool("misc", "enable_multipar", True) enable_unrar = OptionBool("misc", "enable_unrar", True) enable_7zip = OptionBool("misc", "enable_7zip", True) enable_filejoin = OptionBool("misc", "enable_filejoin", True) enable_tsjoin = OptionBool("misc", "enable_tsjoin", True) overwrite_files = OptionBool("misc", "overwrite_files", False) ignore_unrar_dates = OptionBool("misc", "ignore_unrar_dates", False) backup_for_duplicates = OptionBool("misc", "backup_for_duplicates", False) empty_postproc = OptionBool("misc", "empty_postproc", False) wait_for_dfolder = OptionBool("misc", "wait_for_dfolder", False) rss_filenames = OptionBool("misc", "rss_filenames", False) api_logging = OptionBool("misc", "api_logging", True) html_login = OptionBool("misc", "html_login", True) disable_archive = OptionBool("misc", "disable_archive", False) warn_dupl_jobs = OptionBool("misc", "warn_dupl_jobs", False) keep_awake = OptionBool("misc", "keep_awake", True) tray_icon = OptionBool("misc", "tray_icon", True) allow_incomplete_nzb = OptionBool("misc", "allow_incomplete_nzb", False) enable_broadcast = OptionBool("misc", "enable_broadcast", True) ipv6_hosting = OptionBool("misc", "ipv6_hosting", False) ipv6_staging = OptionBool("misc", "ipv6_staging", False) api_warnings = OptionBool("misc", "api_warnings", True, protect=True) no_penalties = OptionBool("misc", "no_penalties", False) x_frame_options = OptionBool("misc", "x_frame_options", True) allow_old_ssl_tls = OptionBool("misc", "allow_old_ssl_tls", False) enable_season_sorting = OptionBool("misc", "enable_season_sorting", True) verify_xff_header = OptionBool("misc", "verify_xff_header", False) # Text values rss_odd_titles = OptionList("misc", "rss_odd_titles", ["nzbindex.nl/", "nzbindex.com/", "nzbclub.com/"]) quick_check_ext_ignore = OptionList("misc", "quick_check_ext_ignore", ["nfo", "sfv", "srr"], validation=lower_case_ext) req_completion_rate = OptionNumber("misc", "req_completion_rate", 100.2, minval=100, maxval=200) selftest_host = OptionStr("misc", "selftest_host", "self-test.sabnzbd.org") movie_rename_limit = OptionStr("misc", "movie_rename_limit", "100M") episode_rename_limit = OptionStr("misc", "episode_rename_limit", "20M") size_limit = OptionStr("misc", "size_limit", "0") direct_unpack_threads = OptionNumber("misc", "direct_unpack_threads", 3, minval=1) history_limit = OptionNumber("misc", "history_limit", 10, minval=0) wait_ext_drive = OptionNumber("misc", "wait_ext_drive", 5, minval=1, maxval=60) max_foldername_length = OptionNumber("misc", "max_foldername_length", DEF_FOLDER_MAX, minval=20, maxval=65000) marker_file = OptionStr("misc", "nomedia_marker") ipv6_servers = OptionBool("misc", "ipv6_servers", True) url_base = OptionStr("misc", "url_base", "/sabnzbd", validation=validate_strip_right_slash) host_whitelist = OptionList("misc", "host_whitelist", validation=all_lowercase) local_ranges = OptionList("misc", "local_ranges", protect=True) max_url_retries = OptionNumber("misc", "max_url_retries", 10, minval=1) downloader_sleep_time = OptionNumber("misc", "downloader_sleep_time", 10, minval=0) receive_threads = OptionNumber("misc", "receive_threads", 2, minval=1) switchinterval = OptionNumber("misc", "switchinterval", 0.005, minval=0.001) ssdp_broadcast_interval = OptionNumber("misc", "ssdp_broadcast_interval", 15, minval=1, maxval=600) ext_rename_ignore = OptionList("misc", "ext_rename_ignore", validation=lower_case_ext) ############################################################################## # Config - Notifications ############################################################################## # [email] email_server = OptionStr("misc", "email_server", validation=validate_server) email_to = OptionList("misc", "email_to", validation=validate_email) email_from = OptionStr("misc", "email_from", validation=validate_email) email_account = OptionStr("misc", "email_account") email_pwd = OptionPassword("misc", "email_pwd") email_endjob = OptionNumber("misc", "email_endjob", 0, 0, 2) email_full = OptionBool("misc", "email_full", False) email_dir = OptionDir("misc", "email_dir") email_rss = OptionBool("misc", "email_rss", False) email_cats = OptionList("misc", "email_cats", ["*"]) # [ncenter] ncenter_enable = OptionBool("ncenter", "ncenter_enable", sabnzbd.MACOS) ncenter_cats = OptionList("ncenter", "ncenter_cats", ["*"]) ncenter_prio_startup = OptionBool("ncenter", "ncenter_prio_startup", False) ncenter_prio_download = OptionBool("ncenter", "ncenter_prio_download", False) ncenter_prio_pause_resume = OptionBool("ncenter", "ncenter_prio_pause_resume", False) ncenter_prio_pp = OptionBool("ncenter", "ncenter_prio_pp", False) ncenter_prio_complete = OptionBool("ncenter", "ncenter_prio_complete", True) ncenter_prio_failed = OptionBool("ncenter", "ncenter_prio_failed", True) ncenter_prio_disk_full = OptionBool("ncenter", "ncenter_prio_disk_full", True) ncenter_prio_new_login = OptionBool("ncenter", "ncenter_prio_new_login", False) ncenter_prio_warning = OptionBool("ncenter", "ncenter_prio_warning", False) ncenter_prio_error = OptionBool("ncenter", "ncenter_prio_error", False) ncenter_prio_queue_done = OptionBool("ncenter", "ncenter_prio_queue_done", False) ncenter_prio_other = OptionBool("ncenter", "ncenter_prio_other", True) # [acenter] acenter_enable = OptionBool("acenter", "acenter_enable", sabnzbd.WIN32) acenter_cats = OptionList("acenter", "acenter_cats", ["*"]) acenter_prio_startup = OptionBool("acenter", "acenter_prio_startup", False) acenter_prio_download = OptionBool("acenter", "acenter_prio_download", False) acenter_prio_pause_resume = OptionBool("acenter", "acenter_prio_pause_resume", False) acenter_prio_pp = OptionBool("acenter", "acenter_prio_pp", False) acenter_prio_complete = OptionBool("acenter", "acenter_prio_complete", True) acenter_prio_failed = OptionBool("acenter", "acenter_prio_failed", True) acenter_prio_disk_full = OptionBool("acenter", "acenter_prio_disk_full", True) acenter_prio_new_login = OptionBool("acenter", "acenter_prio_new_login", False) acenter_prio_warning = OptionBool("acenter", "acenter_prio_warning", False) acenter_prio_error = OptionBool("acenter", "acenter_prio_error", False) acenter_prio_queue_done = OptionBool("acenter", "acenter_prio_queue_done", False) acenter_prio_other = OptionBool("acenter", "acenter_prio_other", True) # [ntfosd] ntfosd_enable = OptionBool("ntfosd", "ntfosd_enable", not sabnzbd.WIN32 and not sabnzbd.MACOS) ntfosd_cats = OptionList("ntfosd", "ntfosd_cats", ["*"]) ntfosd_prio_startup = OptionBool("ntfosd", "ntfosd_prio_startup", False) ntfosd_prio_download = OptionBool("ntfosd", "ntfosd_prio_download", False) ntfosd_prio_pause_resume = OptionBool("ntfosd", "ntfosd_prio_pause_resume", False) ntfosd_prio_pp = OptionBool("ntfosd", "ntfosd_prio_pp", False) ntfosd_prio_complete = OptionBool("ntfosd", "ntfosd_prio_complete", True) ntfosd_prio_failed = OptionBool("ntfosd", "ntfosd_prio_failed", True) ntfosd_prio_disk_full = OptionBool("ntfosd", "ntfosd_prio_disk_full", True) ntfosd_prio_new_login = OptionBool("ntfosd", "ntfosd_prio_new_login", False) ntfosd_prio_warning = OptionBool("ntfosd", "ntfosd_prio_warning", False) ntfosd_prio_error = OptionBool("ntfosd", "ntfosd_prio_error", False) ntfosd_prio_queue_done = OptionBool("ntfosd", "ntfosd_prio_queue_done", False) ntfosd_prio_other = OptionBool("ntfosd", "ntfosd_prio_other", True) # [prowl] prowl_enable = OptionBool("prowl", "prowl_enable", False) prowl_cats = OptionList("prowl", "prowl_cats", ["*"]) prowl_apikey = OptionStr("prowl", "prowl_apikey") prowl_prio_startup = OptionNumber("prowl", "prowl_prio_startup", -3) prowl_prio_download = OptionNumber("prowl", "prowl_prio_download", -3) prowl_prio_pause_resume = OptionNumber("prowl", "prowl_prio_pause_resume", -3) prowl_prio_pp = OptionNumber("prowl", "prowl_prio_pp", -3) prowl_prio_complete = OptionNumber("prowl", "prowl_prio_complete", 0) prowl_prio_failed = OptionNumber("prowl", "prowl_prio_failed", 1) prowl_prio_disk_full = OptionNumber("prowl", "prowl_prio_disk_full", 1) prowl_prio_new_login = OptionNumber("prowl", "prowl_prio_new_login", -3) prowl_prio_warning = OptionNumber("prowl", "prowl_prio_warning", -3) prowl_prio_error = OptionNumber("prowl", "prowl_prio_error", -3) prowl_prio_queue_done = OptionNumber("prowl", "prowl_prio_queue_done", -3) prowl_prio_other = OptionNumber("prowl", "prowl_prio_other", 0) # [pushover] pushover_token = OptionStr("pushover", "pushover_token") pushover_userkey = OptionStr("pushover", "pushover_userkey") pushover_device = OptionStr("pushover", "pushover_device") pushover_emergency_expire = OptionNumber("pushover", "pushover_emergency_expire", 3600) pushover_emergency_retry = OptionNumber("pushover", "pushover_emergency_retry", 60) pushover_enable = OptionBool("pushover", "pushover_enable") pushover_cats = OptionList("pushover", "pushover_cats", ["*"]) pushover_prio_startup = OptionNumber("pushover", "pushover_prio_startup", -3) pushover_prio_download = OptionNumber("pushover", "pushover_prio_download", -2) pushover_prio_pause_resume = OptionNumber("pushover", "pushover_prio_pause_resume", -2) pushover_prio_pp = OptionNumber("pushover", "pushover_prio_pp", -3) pushover_prio_complete = OptionNumber("pushover", "pushover_prio_complete", -1) pushover_prio_failed = OptionNumber("pushover", "pushover_prio_failed", -1) pushover_prio_disk_full = OptionNumber("pushover", "pushover_prio_disk_full", 1) pushover_prio_new_login = OptionNumber("pushover", "pushover_prio_new_login", -3) pushover_prio_warning = OptionNumber("pushover", "pushover_prio_warning", 1) pushover_prio_error = OptionNumber("pushover", "pushover_prio_error", 1) pushover_prio_queue_done = OptionNumber("pushover", "pushover_prio_queue_done", -3) pushover_prio_other = OptionNumber("pushover", "pushover_prio_other", -1) # [pushbullet] pushbullet_enable = OptionBool("pushbullet", "pushbullet_enable") pushbullet_cats = OptionList("pushbullet", "pushbullet_cats", ["*"]) pushbullet_apikey = OptionStr("pushbullet", "pushbullet_apikey") pushbullet_device = OptionStr("pushbullet", "pushbullet_device") pushbullet_prio_startup = OptionBool("pushbullet", "pushbullet_prio_startup", False) pushbullet_prio_download = OptionBool("pushbullet", "pushbullet_prio_download", False) pushbullet_prio_pause_resume = OptionBool("pushbullet", "pushbullet_prio_pause_resume", False) pushbullet_prio_pp = OptionBool("pushbullet", "pushbullet_prio_pp", False) pushbullet_prio_complete = OptionBool("pushbullet", "pushbullet_prio_complete", True) pushbullet_prio_failed = OptionBool("pushbullet", "pushbullet_prio_failed", True) pushbullet_prio_disk_full = OptionBool("pushbullet", "pushbullet_prio_disk_full", True) pushbullet_prio_new_login = OptionBool("pushbullet", "pushbullet_prio_new_login", False) pushbullet_prio_warning = OptionBool("pushbullet", "pushbullet_prio_warning", False) pushbullet_prio_error = OptionBool("pushbullet", "pushbullet_prio_error", False) pushbullet_prio_queue_done = OptionBool("pushbullet", "pushbullet_prio_queue_done", False) pushbullet_prio_other = OptionBool("pushbullet", "pushbullet_prio_other", True) # [apprise] apprise_enable = OptionBool("apprise", "apprise_enable") apprise_cats = OptionList("apprise", "apprise_cats", ["*"]) apprise_urls = OptionStr("apprise", "apprise_urls") apprise_target_startup = OptionStr("apprise", "apprise_target_startup") apprise_target_startup_enable = OptionBool("apprise", "apprise_target_startup_enable", False) apprise_target_download = OptionStr("apprise", "apprise_target_download") apprise_target_download_enable = OptionBool("apprise", "apprise_target_download_enable", False) apprise_target_pause_resume = OptionStr("apprise", "apprise_target_pause_resume") apprise_target_pause_resume_enable = OptionBool("apprise", "apprise_target_pause_resume_enable", False) apprise_target_pp = OptionStr("apprise", "apprise_target_pp") apprise_target_pp_enable = OptionBool("apprise", "apprise_target_pp_enable", False) apprise_target_complete = OptionStr("apprise", "apprise_target_complete") apprise_target_complete_enable = OptionBool("apprise", "apprise_target_complete_enable", True) apprise_target_failed = OptionStr("apprise", "apprise_target_failed") apprise_target_failed_enable = OptionBool("apprise", "apprise_target_failed_enable", True) apprise_target_disk_full = OptionStr("apprise", "apprise_target_disk_full") apprise_target_disk_full_enable = OptionBool("apprise", "apprise_target_disk_full_enable", False) apprise_target_new_login = OptionStr("apprise", "apprise_target_new_login") apprise_target_new_login_enable = OptionBool("apprise", "apprise_target_new_login_enable", True) apprise_target_warning = OptionStr("apprise", "apprise_target_warning") apprise_target_warning_enable = OptionBool("apprise", "apprise_target_warning_enable", False) apprise_target_error = OptionStr("apprise", "apprise_target_error") apprise_target_error_enable = OptionBool("apprise", "apprise_target_error_enable", False) apprise_target_queue_done = OptionStr("apprise", "apprise_target_queue_done") apprise_target_query_done_enable = OptionBool("apprise", "apprise_target_queue_done_enable", False) apprise_target_other = OptionStr("apprise", "apprise_target_other") apprise_target_other_enable = OptionBool("apprise", "apprise_target_other_enable", True) # [nscript] nscript_enable = OptionBool("nscript", "nscript_enable") nscript_cats = OptionList("nscript", "nscript_cats", ["*"]) nscript_script = OptionStr("nscript", "nscript_script", validation=validate_script) nscript_parameters = OptionStr("nscript", "nscript_parameters") nscript_prio_startup = OptionBool("nscript", "nscript_prio_startup", False) nscript_prio_download = OptionBool("nscript", "nscript_prio_download", False) nscript_prio_pause_resume = OptionBool("nscript", "nscript_prio_pause_resume", False) nscript_prio_pp = OptionBool("nscript", "nscript_prio_pp", False) nscript_prio_complete = OptionBool("nscript", "nscript_prio_complete", True) nscript_prio_failed = OptionBool("nscript", "nscript_prio_failed", True) nscript_prio_disk_full = OptionBool("nscript", "nscript_prio_disk_full", True) nscript_prio_new_login = OptionBool("nscript", "nscript_prio_new_login", False) nscript_prio_warning = OptionBool("nscript", "nscript_prio_warning", False) nscript_prio_error = OptionBool("nscript", "nscript_prio_error", False) nscript_prio_queue_done = OptionBool("nscript", "nscript_prio_queue_done", False) nscript_prio_other = OptionBool("nscript", "nscript_prio_other", True) ############################################################################## # Set root folders for Folder config-items ############################################################################## def set_root_folders(home, lcldata): email_dir.set_root(home) download_dir.set_root(home) complete_dir.set_root(home) script_dir.set_root(home) nzb_backup_dir.set_root(lcldata) admin_dir.set_root(lcldata) backup_dir.set_root(home) dirscan_dir.set_root(home) log_dir.set_root(lcldata) password_file.set_root(home) def set_root_folders2(): https_cert.set_root(admin_dir.get_path()) https_key.set_root(admin_dir.get_path()) https_chain.set_root(admin_dir.get_path()) ############################################################################## # Callbacks for settings ############################################################################## def new_limit(): """Callback for article cache changes""" sabnzbd.ArticleCache.new_limit(cache_limit.get_int()) def guard_restart(): """Callback for config options requiring a restart""" sabnzbd.RESTART_REQ = True def guard_top_only(): """Callback for change of top_only option""" sabnzbd.NzbQueue.set_top_only(top_only()) def guard_pause_on_pp(): """Callback for change of pause-download-on-pp""" if pause_on_post_processing(): pass # Not safe to idle downloader, because we don't know # if post-processing is active now else: sabnzbd.Downloader.resume_from_postproc() def guard_quota_size(): """Callback for change of quota_size""" sabnzbd.BPSMeter.change_quota() def guard_quota_dp(): """Callback for change of quota_day or quota_period""" sabnzbd.Scheduler.restart() def guard_language(): """Callback for change of the interface language""" sabnzbd.lang.set_language(language()) sabnzbd.api.clear_trans_cache() def guard_https_ver(): """Callback for change of https verification""" sabnzbd.misc.set_https_verification(enable_https_verification()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4460115 SABnzbd-4.3.2/sabnzbd/internetspeed.py0000644000000000000000000001147414625637243017100 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.internetspeed - Measure internet bandwidth using sabctools routines """ import sys import logging import socket import ssl import time import threading from typing import Dict import sabctools import sabnzbd from sabnzbd.happyeyeballs import happyeyeballs, family_type TEST_HOSTNAME = "sabnzbd.org" TEST_PORT = 443 TEST_FILE = "/tests/internetspeed/100MB.bin" TEST_FILE_SIZE = 100 * 1024 * 1024 TEST_REQUEST = f"GET {TEST_FILE} HTTP/1.1\nHost: {TEST_HOSTNAME}\nUser-Agent: SABnzbd/{sabnzbd.__version__}\n\n" SOCKET_TIMEOUT = 3 BUFFER_SIZE = 5 * 1024 * 1024 # Each connection will allocate its own buffer, so mind the memory usage! NR_CONNECTIONS = 5 TIME_LIMIT = 3 def internetspeed_worker(secure_sock: ssl.SSLSocket, socket_speed: Dict[ssl.SSLSocket, float]): """Worker to perform the requests in parallel""" secure_sock.sendall(TEST_REQUEST.encode()) empty_buffer = memoryview(sabctools.bytearray_malloc(BUFFER_SIZE)) start_time = time.perf_counter() diff_time = 0 data_received = 0 while diff_time < TIME_LIMIT: if data_received < TEST_FILE_SIZE: try: if new_bytes := sabctools.unlocked_ssl_recv_into(secure_sock, empty_buffer): # Update the speed after every loop diff_time = time.perf_counter() - start_time data_received += new_bytes socket_speed[secure_sock] = data_received / diff_time else: break except ssl.SSLWantReadError: time.sleep(0) else: break try: secure_sock.close() except socket.error: # In case socket was closed unexpectedly already pass def internetspeed_interal(test_time_limit: int = TIME_LIMIT, family: int = socket.AF_UNSPEC) -> float: """Measure internet speed from a test-download using our optimized SSL-code""" context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) socket_speed = {} try: addrinfo = happyeyeballs(TEST_HOSTNAME, TEST_PORT, SOCKET_TIMEOUT, family) for _ in range(NR_CONNECTIONS): sock = socket.socket(addrinfo.family, addrinfo.type) sock.settimeout(SOCKET_TIMEOUT) sock.connect(addrinfo.sockaddr) secure_sock = context.wrap_socket(sock, server_hostname=TEST_HOSTNAME) secure_sock.setblocking(False) socket_speed[secure_sock] = 0 for secure_sock in socket_speed: threading.Thread(target=internetspeed_worker, args=(secure_sock, socket_speed), daemon=True).start() except Exception: logging.info("Internet Bandwidth connection failure", exc_info=True) return 0.0 # We let the workers finish time.sleep(test_time_limit + 0.5) speed = sum(socket_speed.values()) / 1024 / 1024 logging.debug("Internet Bandwidth (%s) = %.2f MB/s - %.2f Mbps", family_type(family), speed, speed * 8.05) return speed def internetspeed() -> float: # Internet bandwidth if not sabnzbd.cfg.ipv6_staging(): # no special IPv6 wishes, so straight Internet speed test (ipv4 / ipv6 agnostic) return round(internetspeed_interal(), 2) else: internetspeed_ipv4 = round(internetspeed_interal(family=socket.AF_INET), 1) internetspeed_ipv6 = round(internetspeed_interal(family=socket.AF_INET6), 1) if internetspeed_ipv4 > 0 and internetspeed_ipv6 > 0: # both working, so let's see if it's about the same speed (good), there is a big difference (bad) if 0.5 > (internetspeed_ipv4 / internetspeed_ipv6) > 2: sabnzbd.misc.helpful_warning( T( "Internet Bandwidth of IPv4 significantly different from IPv6: %f MB/s versus %f MB/s", internetspeed_ipv4, internetspeed_ipv6, ) ) return max(internetspeed_ipv4, internetspeed_ipv6) if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) internetspeed() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4462225 SABnzbd-4.3.2/sabnzbd/config.py0000644000000000000000000012527714625637243015503 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.config - Configuration Support """ import logging import os import re import shutil import threading import time import uuid import io import zipfile from typing import List, Dict, Any, Callable, Optional, Union, Tuple from urllib.parse import urlparse import configobj import sabnzbd from sabnzbd.constants import ( CONFIG_VERSION, NORMAL_PRIORITY, DEFAULT_PRIORITY, CONFIG_BACKUP_FILES, CONFIG_BACKUP_HTTPS, DEF_INI_FILE, DEF_SORTER_RENAME_SIZE, ) from sabnzbd.decorators import synchronized from sabnzbd.filesystem import clip_path, real_path, create_real_path, renamer, remove_file, is_writable CONFIG_LOCK = threading.RLock() CFG_OBJ: configobj.ConfigObj # Holds INI structure # during re-write this variable is global # to allow direct access to INI structure CFG_MODIFIED = False # Signals a change in option dictionary # Should be reset after saving to settings file RE_PARAMFINDER = re.compile(r"""'.*?'|".*?"|[^'",\s][^,]*""") class Option: """Basic option class, basic fields""" def __init__( self, section: str, keyword: str, default_val: Any = None, add: bool = True, public: bool = True, protect: bool = False, ): """Basic option `section` : single section for this option `keyword` : keyword in the section `default_val` : value returned when no value has been set `callback` : procedure to call when value is successfully changed `public` : if this value should be shown in API calls `protect` : do not allow setting via the API (specifically set_dict) """ self.__section = section self.__keyword: str = keyword self.__default_val: Any = default_val self.__value: Any = None self.__callback: Optional[Callable] = None self.__public: bool = public self.__protect = protect # Add myself to the config dictionary if add: add_to_database(section, keyword, self) def get(self) -> Any: """Retrieve value field""" if self.__value is not None: return self.__value else: return self.__default_val def get_string(self) -> str: return str(self.get()) def get_dict(self, for_public_api: bool = False) -> Dict[str, Any]: """Return value as a dictionary. Will not show non-public options if needed for the API""" if not self.__public and for_public_api: return {} return {self.__keyword: self.get()} def set_dict(self, values: Dict[str, Any]): """Set value based on dictionary""" if not self.__protect: try: self.set(values["value"]) except KeyError: pass def set(self, value: Any): """Set new value, no validation""" global CFG_MODIFIED if value is not None: if isinstance(value, list) or isinstance(value, dict) or value != self.__value: self.__value = value CFG_MODIFIED = True if self.__callback: self.__callback() @property def section(self) -> Any: return self.__section @property def keyword(self) -> Any: return self.__keyword @property def default(self) -> Any: return self.__default_val def callback(self, callback: Callable): """Set callback function""" self.__callback = callback class OptionNumber(Option): """Numeric option class, int/float is determined from default value.""" def __init__( self, section: str, keyword: str, default_val: float = 0, minval: Optional[float] = None, maxval: Optional[float] = None, validation: Optional[Callable] = None, add: bool = True, public: bool = True, protect: bool = False, ): self.__minval: Optional[float] = minval self.__maxval: Optional[float] = maxval self.__validation: Optional[Callable] = validation self.__int: bool = isinstance(default_val, int) super().__init__(section, keyword, default_val, add=add, public=public, protect=protect) def set(self, value: Any): """set new value, limited by range""" if value is not None: try: if self.__int: value = int(value) else: value = float(value) except ValueError: value = super().default if self.__validation: _, val = self.__validation(value) super().set(val) else: if self.__maxval is not None and value > self.__maxval: value = self.__maxval elif self.__minval is not None and value < self.__minval: value = self.__minval super().set(value) def __call__(self) -> Union[int, float]: """get() replacement""" return self.get() class OptionBool(Option): """Boolean option class, always returns 0 or 1.""" def __init__( self, section: str, keyword: str, default_val: bool = False, add: bool = True, public: bool = True, protect: bool = False, ): super().__init__(section, keyword, int(default_val), add=add, public=public, protect=protect) def set(self, value: Any): # Store the value as integer, easier to parse when reading the config. super().set(sabnzbd.misc.int_conv(value)) def __call__(self) -> int: """get() replacement""" return int(self.get()) class OptionDir(Option): """Directory option class""" def __init__( self, section: str, keyword: str, default_val: str = "", apply_permissions: bool = False, create: bool = True, validation: Optional[Callable] = None, writable: bool = True, add: bool = True, public: bool = True, protect: bool = False, ): self.__validation: Optional[Callable] = validation self.__root: str = "" # Base directory for relative paths self.__apply_permissions: bool = apply_permissions self.__create: bool = create self.__writable: bool = writable super().__init__(section, keyword, default_val, add=add, public=public, protect=protect) def create_path(self, path: Optional[str] = None): if not path: path = self.get() return create_real_path(self.keyword, self.__root, path, self.__apply_permissions, self.__writable) def get(self) -> str: """Return value, corrected for platform""" p = super().get() if sabnzbd.WIN32: return p.replace("/", "\\") if "/" in p else p else: return p.replace("\\", "/") if "\\" in p else p def get_path(self) -> str: """Return full absolute path, create it if necessary""" path = "" if value := self.get(): path = real_path(self.__root, value) if self.__create and not os.path.exists(path): _, path, _ = self.create_path(value) return path def get_clipped_path(self) -> str: """Return clipped full absolute path""" return clip_path(self.get_path()) def test_path(self) -> bool: """Return True if path exists""" if value := self.get(): return os.path.exists(real_path(self.__root, value)) else: return False def set_root(self, root: str): """Set new root, is assumed to be valid""" self.__root = root def set(self, value: str, create: bool = False) -> Optional[str]: """Set new dir value, validate and create if needed Return None when directory is accepted Return error-string when not accepted, value will not be changed 'create' means try to create (but don't set permanent create flag) """ error = None if value is not None and (value != self.get() or create): value = value.strip() if self.__validation: error, value = self.__validation(self.__root, value, super().default) if not error: if value and (self.__create or create): _, path, error = self.create_path(value) if not error: super().set(value) return error def set_create(self, value: bool): """Set auto-creation value""" self.__create = value def __call__(self) -> str: """get() replacement""" return self.get() class OptionList(Option): """List option class""" def __init__( self, section: str, keyword: str, default_val: Union[str, List, None] = None, validation: Optional[Callable] = None, add: bool = True, public: bool = True, protect: bool = False, ): self.__validation: Optional[Callable] = validation if default_val is None: default_val = [] super().__init__(section, keyword, default_val, add=add, public=public, protect=protect) def set(self, value: Union[str, List]) -> Optional[str]: """Set the list given a comma-separated string or a list""" error = None if value is not None: if not isinstance(value, list): if '"' not in value and "," not in value: value = value.split() else: value = RE_PARAMFINDER.findall(value) if self.__validation: error, value = self.__validation(value) if not error: super().set(value) return error def get_string(self) -> str: """Return the list as a comma-separated string""" return ", ".join(self.get()) def default_string(self) -> str: """Return the default list as a comma-separated string""" return ", ".join(self.default) def __call__(self) -> List[str]: """get() replacement""" return self.get() class OptionStr(Option): """String class.""" def __init__( self, section: str, keyword: str, default_val: str = "", validation: Optional[Callable] = None, add: bool = True, strip: bool = True, public: bool = True, protect: bool = False, ): self.__validation: Optional[Callable] = validation self.__strip: bool = strip super().__init__(section, keyword, default_val, add=add, public=public, protect=protect) def get_float(self) -> float: """Return value converted to a float, allowing KMGT notation""" return sabnzbd.misc.from_units(self.get()) def get_int(self) -> int: """Return value converted to an int, allowing KMGT notation""" return int(self.get_float()) def set(self, value: Any) -> Optional[str]: """Set stripped value""" error = None if isinstance(value, str) and self.__strip: value = value.strip() if self.__validation: error, val = self.__validation(value) super().set(val) else: super().set(value) return error def __call__(self) -> str: """get() replacement""" return self.get() class OptionPassword(Option): """Password class.""" def __init__(self, section: str, keyword: str, default_val: str = "", add: bool = True): self.get_string = self.get_stars super().__init__(section, keyword, default_val, add=add) def get(self) -> Optional[str]: """Return decoded password""" return decode_password(super().get(), self.keyword) def get_stars(self) -> Optional[str]: """Return non-descript asterisk string""" if self.get(): return "*" * 10 return "" def get_dict(self, for_public_api: bool = False) -> Dict[str, str]: """Return value a dictionary""" if for_public_api: return {self.keyword: self.get_stars()} else: return {self.keyword: self.get()} def set(self, pw: str): """Set password, encode it""" if (pw is not None and pw == "") or (pw and pw.strip("*")): super().set(encode_password(pw)) def __call__(self) -> str: """get() replacement""" return self.get() class ConfigServer: """Class defining a single server""" def __init__(self, name, values): self.__name = clean_section_name(name) name = "servers," + self.__name self.displayname = OptionStr(name, "displayname", add=False) self.host = OptionStr(name, "host", validation=sabnzbd.cfg.all_lowercase, add=False) self.port = OptionNumber(name, "port", 119, 0, 2**16 - 1, add=False) self.timeout = OptionNumber(name, "timeout", 60, 20, 240, add=False) self.username = OptionStr(name, "username", add=False) self.password = OptionPassword(name, "password", add=False) self.connections = OptionNumber(name, "connections", 1, 0, 500, add=False) self.ssl = OptionBool(name, "ssl", False, add=False) # 0=No, 1=Normal, 2=Strict (hostname verification) self.ssl_verify = OptionNumber(name, "ssl_verify", 2, add=False) self.ssl_ciphers = OptionStr(name, "ssl_ciphers", add=False) self.enable = OptionBool(name, "enable", True, add=False) self.required = OptionBool(name, "required", False, add=False) self.optional = OptionBool(name, "optional", False, add=False) self.retention = OptionNumber(name, "retention", 0, add=False) self.expire_date = OptionStr(name, "expire_date", add=False) self.quota = OptionStr(name, "quota", add=False) self.usage_at_start = OptionNumber(name, "usage_at_start", add=False) self.priority = OptionNumber(name, "priority", 0, 0, 99, add=False) self.notes = OptionStr(name, "notes", add=False) self.set_dict(values) add_to_database("servers", self.__name, self) def set_dict(self, values: Dict[str, Any]): """Set one or more fields, passed as dictionary""" # Replace usage_at_start value with most recent statistics if the user changes the quota value # Only when we are updating it from the Config if sabnzbd.WEBUI_READY and values.get("quota", "") != self.quota(): values["usage_at_start"] = sabnzbd.BPSMeter.grand_total.get(self.__name, 0) # Store all values for kw in ( "displayname", "host", "port", "timeout", "username", "password", "connections", "ssl", "ssl_verify", "ssl_ciphers", "enable", "required", "optional", "retention", "expire_date", "quota", "usage_at_start", "priority", "notes", ): try: value = values[kw] getattr(self, kw).set(value) except KeyError: continue if not self.displayname(): self.displayname.set(self.__name) def get_dict(self, for_public_api: bool = False) -> Dict[str, Any]: """Return a dictionary with all attributes""" output_dict = {} output_dict["name"] = self.__name output_dict["displayname"] = self.displayname() output_dict["host"] = self.host() output_dict["port"] = self.port() output_dict["timeout"] = self.timeout() output_dict["username"] = self.username() if for_public_api: output_dict["password"] = self.password.get_stars() else: output_dict["password"] = self.password() output_dict["connections"] = self.connections() output_dict["ssl"] = self.ssl() output_dict["ssl_verify"] = self.ssl_verify() output_dict["ssl_ciphers"] = self.ssl_ciphers() output_dict["enable"] = self.enable() output_dict["required"] = self.required() output_dict["optional"] = self.optional() output_dict["retention"] = self.retention() output_dict["expire_date"] = self.expire_date() output_dict["quota"] = self.quota() output_dict["usage_at_start"] = self.usage_at_start() output_dict["priority"] = self.priority() output_dict["notes"] = self.notes() return output_dict def delete(self): """Remove from database""" delete_from_database("servers", self.__name) def rename(self, name: str): """Give server new display name""" self.displayname.set(name) class ConfigCat: """Class defining a single category""" def __init__(self, name: str, values: Dict[str, Any]): self.__name = clean_section_name(name) name = "categories," + self.__name self.order = OptionNumber(name, "order", 0, 0, 100, add=False) self.pp = OptionStr(name, "pp", add=False) self.script = OptionStr(name, "script", "Default", add=False) self.dir = OptionDir(name, "dir", add=False, create=False) self.newzbin = OptionList(name, "newzbin", add=False, validation=sabnzbd.cfg.validate_single_tag) self.priority = OptionNumber(name, "priority", DEFAULT_PRIORITY, add=False) self.set_dict(values) add_to_database("categories", self.__name, self) def set_dict(self, values: Dict[str, Any]): """Set one or more fields, passed as dictionary""" for kw in ("order", "pp", "script", "dir", "newzbin", "priority"): try: value = values[kw] getattr(self, kw).set(value) except KeyError: continue def get_dict(self, for_public_api: bool = False) -> Dict[str, Any]: """Return a dictionary with all attributes""" output_dict = {} output_dict["name"] = self.__name output_dict["order"] = self.order() output_dict["pp"] = self.pp() output_dict["script"] = self.script() output_dict["dir"] = self.dir() output_dict["newzbin"] = self.newzbin.get_string() output_dict["priority"] = self.priority() return output_dict def delete(self): """Remove from database""" delete_from_database("categories", self.__name) class ConfigSorter: """Class defining a single Sorter""" def __init__(self, name, values): self.__name = clean_section_name(name) name = "sorters," + self.__name self.order = OptionNumber(name, "order", len(get_sorters()), 0, 100, add=False) self.min_size = OptionStr(name, "min_size", DEF_SORTER_RENAME_SIZE, add=False) self.multipart_label = OptionStr(name, "multipart_label", add=False) self.sort_string = OptionStr(name, "sort_string", add=False) self.sort_cats = OptionList(name, "sort_cats", add=False) self.sort_type = OptionList(name, "sort_type", add=False) self.is_active = OptionBool(name, "is_active", add=False) self.set_dict(values) add_to_database("sorters", self.__name, self) def set_dict(self, values: Dict[str, Any]): """Set one or more fields, passed as dictionary""" for kw in ("order", "min_size", "multipart_label", "sort_string", "sort_cats", "sort_type", "is_active"): try: value = values[kw] getattr(self, kw).set(value) except KeyError: continue def get_dict(self, for_public_api: bool = False) -> Dict[str, Any]: """Return a dictionary with all attributes""" output_dict = {} output_dict["name"] = self.__name output_dict["order"] = self.order() output_dict["min_size"] = self.min_size() output_dict["multipart_label"] = self.multipart_label() output_dict["sort_string"] = self.sort_string() output_dict["sort_cats"] = self.sort_cats() output_dict["sort_type"] = [int(num) for num in self.sort_type()] output_dict["is_active"] = self.is_active() return output_dict def delete(self): """Remove from database""" delete_from_database("sorters", self.__name) def rename(self, new_name: str): """Update the name and the saved entries""" delete_from_database("sorters", self.__name) self.__name = new_name add_to_database("sorters", self.__name, self) class OptionFilters(Option): """Filter list class""" def __init__(self, section, keyword, add=True): super().__init__(section, keyword, add=add) self.set([]) def move(self, current: int, new: int): """Move filter from position 'current' to 'new'""" lst = self.get() try: item = lst.pop(current) lst.insert(new, item) except IndexError: return self.set(lst) def update(self, pos: int, value: Tuple): """Update filter 'pos' definition, value is a list Append if 'pos' outside list """ lst = self.get() try: lst[pos] = value except IndexError: lst.append(value) self.set(lst) def delete(self, pos: int): """Remove filter 'pos'""" lst = self.get() try: lst.pop(pos) except IndexError: return self.set(lst) def get_dict(self, for_public_api: bool = False) -> Dict[str, str]: """Return filter list as a dictionary with keys 'filter[0-9]+'""" output_dict = {} for n, rss_filter in enumerate(self.get()): output_dict[f"filter{n}"] = rss_filter return output_dict def set_dict(self, values: Dict[str, Any]): """Create filter list from dictionary with keys 'filter[0-9]+'""" filters = [] # We don't know how many filters there are, so just assume all values are filters for n in range(len(values)): kw = f"filter{n}" if kw in values: filters.append(values[kw]) if filters: self.set(filters) def __call__(self) -> List[List[str]]: """get() replacement""" return self.get() class ConfigRSS: """Class defining a single Feed definition""" def __init__(self, name, values): self.__name = clean_section_name(name) name = "rss," + self.__name self.uri = OptionList(name, "uri", add=False) self.cat = OptionStr(name, "cat", add=False) self.pp = OptionStr(name, "pp", add=False) self.script = OptionStr(name, "script", add=False) self.enable = OptionBool(name, "enable", add=False) self.priority = OptionNumber(name, "priority", DEFAULT_PRIORITY, DEFAULT_PRIORITY, 2, add=False) self.filters = OptionFilters(name, "filters", add=False) self.filters.set([["", "", "", "A", "*", DEFAULT_PRIORITY, "1"]]) self.set_dict(values) add_to_database("rss", self.__name, self) def set_dict(self, values: Dict[str, Any]): """Set one or more fields, passed as dictionary""" for kw in ("uri", "cat", "pp", "script", "priority", "enable"): try: value = values[kw] getattr(self, kw).set(value) except KeyError: continue self.filters.set_dict(values) def get_dict(self, for_public_api: bool = False) -> Dict[str, Any]: """Return a dictionary with all attributes""" output_dict = {} output_dict["name"] = self.__name output_dict["uri"] = self.uri() output_dict["cat"] = self.cat() output_dict["pp"] = self.pp() output_dict["script"] = self.script() output_dict["enable"] = self.enable() output_dict["priority"] = self.priority() filters = self.filters.get_dict() for kw in filters: output_dict[kw] = filters[kw] return output_dict def delete(self): """Remove from database""" delete_from_database("rss", self.__name) def rename(self, new_name: str) -> str: """Update the name and the saved entries""" # Sanitize the name before using it new_name = clean_section_name(new_name) delete_from_database("rss", self.__name) sabnzbd.RSSReader.rename(self.__name, new_name) self.__name = new_name add_to_database("rss", self.__name, self) return self.__name # Add typing to the options database-dict AllConfigTypes = Union[ Option, OptionStr, OptionPassword, OptionNumber, OptionBool, OptionList, OptionDir, ConfigCat, ConfigSorter, ConfigRSS, ConfigServer, ] CFG_DATABASE: Dict[str, Dict[str, AllConfigTypes]] = {} @synchronized(CONFIG_LOCK) def add_to_database(section: str, keyword: str, obj: AllConfigTypes): """add object as section/keyword to INI database""" global CFG_DATABASE if section not in CFG_DATABASE: CFG_DATABASE[section] = {} CFG_DATABASE[section][keyword] = obj @synchronized(CONFIG_LOCK) def delete_from_database(section, keyword): """Remove section/keyword from INI database""" global CFG_DATABASE, CFG_OBJ, CFG_MODIFIED del CFG_DATABASE[section][keyword] try: del CFG_OBJ[section][keyword] except KeyError: pass CFG_MODIFIED = True @synchronized(CONFIG_LOCK) def get_dconfig(section, keyword, nested=False): """Return a config values dictionary, Single item or slices based on 'section', 'keyword' """ data = {} if not section: for section in CFG_DATABASE.keys(): res, conf = get_dconfig(section, None, True) data.update(conf) elif not keyword: try: sect = CFG_DATABASE[section] except KeyError: return False, {} if section == "categories": data[section] = get_ordered_categories() elif section == "sorters": data[section] = get_ordered_sorters() elif section in ("servers", "rss"): data[section] = [] for keyword in sect.keys(): res, conf = get_dconfig(section, keyword, True) data[section].append(conf) else: data[section] = {} for keyword in sect.keys(): res, conf = get_dconfig(section, keyword, True) data[section].update(conf) else: try: item = CFG_DATABASE[section][keyword] except KeyError: return False, {} data = item.get_dict(for_public_api=True) if not nested: if section in ("sorters", "servers", "categories", "rss"): data = {section: [data]} else: data = {section: data} return True, data @synchronized(CONFIG_LOCK) def get_config(section: str, keyword: str) -> Optional[AllConfigTypes]: """Return a config object, based on 'section', 'keyword'""" try: return CFG_DATABASE[section][keyword] except KeyError: logging.debug("Missing configuration item %s,%s", section, keyword) return None @synchronized(CONFIG_LOCK) def set_config(kwargs): """Set a config item, using values in dictionary""" try: item = CFG_DATABASE[kwargs.get("section")][kwargs.get("keyword")] except KeyError: return False item.set_dict(kwargs) return True @synchronized(CONFIG_LOCK) def delete(section: str, keyword: str): """Delete specific config item""" try: CFG_DATABASE[section][keyword].delete() except KeyError: return ############################################################################## # INI file support # # This does input and output of configuration to an INI file. # It translates this data structure to the config database. ############################################################################## @synchronized(CONFIG_LOCK) def read_config(path): """Read the complete INI file and check its version number if OK, pass values to config-database """ return _read_config(path) def _read_config(path, try_backup=False): """Read the complete INI file and check its version number if OK, pass values to config-database """ global CFG_OBJ, CFG_DATABASE, CFG_MODIFIED if try_backup or not os.path.exists(path): # Not found, try backup try: shutil.copyfile(path + ".bak", path) try_backup = True except IOError: pass if not os.path.exists(path): # No file found, create default INI file try: if not sabnzbd.WIN32: prev = os.umask(0o77) with open(path, "w") as fp: fp.write("__version__=%s\n[misc]\n[logging]\n" % CONFIG_VERSION) if not sabnzbd.WIN32: os.umask(prev) except IOError: return False, "Cannot create INI file %s" % path try: # Let configobj open the file CFG_OBJ = configobj.ConfigObj(infile=path, default_encoding="utf-8", encoding="utf-8") except (IOError, configobj.ConfigObjError, UnicodeEncodeError) as strerror: if try_backup: # No luck! return False, '"%s" is not a valid configuration file
Error message: %s' % (path, strerror) else: # Try backup file return _read_config(path, True) try: version = sabnzbd.misc.int_conv(CFG_OBJ["__version__"]) if version > int(CONFIG_VERSION): return False, "Incorrect version number %s in %s" % (version, path) except (KeyError, ValueError): pass CFG_OBJ.filename = path CFG_OBJ.encoding = "utf-8" CFG_OBJ["__encoding__"] = "utf-8" CFG_OBJ["__version__"] = str(CONFIG_VERSION) # Use CFG data to set values for all static options for section in CFG_DATABASE: if section not in ("sorters", "servers", "categories", "rss"): for option in CFG_DATABASE[section]: config_option = CFG_DATABASE[section][option] try: config_option.set(CFG_OBJ[config_option.section][config_option.keyword]) except KeyError: pass # Define the special settings if "categories" in CFG_OBJ: for cat in CFG_OBJ["categories"]: ConfigCat(cat, CFG_OBJ["categories"][cat]) if "rss" in CFG_OBJ: for rss_feed in CFG_OBJ["rss"]: ConfigRSS(rss_feed, CFG_OBJ["rss"][rss_feed]) if "servers" in CFG_OBJ: for server in CFG_OBJ["servers"]: ConfigServer(server, CFG_OBJ["servers"][server]) if "sorters" in CFG_OBJ: for sorter in CFG_OBJ["sorters"]: ConfigSorter(sorter, CFG_OBJ["sorters"][sorter]) CFG_MODIFIED = False return True, "" @synchronized(CONFIG_LOCK) def save_config(force=False): """Update Setup file with current option values""" global CFG_OBJ, CFG_DATABASE, CFG_MODIFIED if not (CFG_MODIFIED or force): return True if sabnzbd.cfg.configlock(): logging.warning(T("Configuration locked, cannot save settings")) return False for section in CFG_DATABASE: if section in ("sorters", "servers", "categories", "rss"): if section not in CFG_OBJ: CFG_OBJ[section] = {} for subsection in CFG_DATABASE[section]: if subsection not in CFG_OBJ[section]: CFG_OBJ[section][subsection] = {} CFG_OBJ[section][subsection] = CFG_DATABASE[section][subsection].get_dict() else: for option in CFG_DATABASE[section]: config_option = CFG_DATABASE[section][option] if config_option.section not in CFG_OBJ: CFG_OBJ[config_option.section] = {} CFG_OBJ[config_option.section][config_option.keyword] = CFG_DATABASE[section][option]() res = False filename = CFG_OBJ.filename bakname = filename + ".bak" # Check if file is writable if not is_writable(filename): logging.error(T("Cannot write to INI file %s"), filename) return res # copy current file to backup try: shutil.copyfile(filename, bakname) shutil.copymode(filename, bakname) except: # Something wrong with the backup, logging.error(T("Cannot create backup file for %s"), bakname) logging.info("Traceback: ", exc_info=True) return res # Write new config file try: logging.info("Writing settings to INI file %s", filename) CFG_OBJ.write() shutil.copymode(bakname, filename) CFG_MODIFIED = False res = True except: logging.error(T("Cannot write to INI file %s"), filename) logging.info("Traceback: ", exc_info=True) try: remove_file(filename) except: pass # Restore INI file from backup renamer(bakname, filename) return res def create_config_backup() -> Union[str, bool]: """Put config data in a zip file, returns path on success""" admin_path = sabnzbd.cfg.admin_dir.get_path() output_filename = "sabnzbd_backup_%s_%s.zip" % (sabnzbd.__version__, time.strftime("%Y.%m.%d_%H.%M.%S")) # Check if there is a backup folder set, use complete otherwise if sabnzbd.cfg.backup_dir(): backup_dir = sabnzbd.cfg.backup_dir.get_path() else: backup_dir = sabnzbd.cfg.complete_dir.get_path() complete_path = os.path.join(backup_dir, output_filename) logging.debug("Backing up %s + %s in %s", admin_path, CFG_OBJ.filename, complete_path) try: with open(complete_path, "wb") as zip_buffer: with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_ref: for filename in CONFIG_BACKUP_FILES: full_path = os.path.join(admin_path, filename) if os.path.isfile(full_path): with open(full_path, "rb") as data: zip_ref.writestr(filename, data.read()) for filename, setting in CONFIG_BACKUP_HTTPS.items(): full_path = getattr(sabnzbd.cfg, setting).get_path() # Only accept HTTPS config files that were successfully loaded by cherrypy on # startup to protect against last-minute breaking config changes as well as # inclusion of unrelated files in the backup through manipulated settings. if full_path and os.path.isfile(full_path) and full_path in sabnzbd.CONFIG_BACKUP_HTTPS_OK: logging.debug("Adding %s file %s to backup", setting, full_path) with open(full_path, "rb") as data: # Add the https cert/key/chain files with a fixed relative filename, # regardless of where they are actually stored on the filesystem zip_ref.writestr(filename, data.read()) with open(CFG_OBJ.filename, "rb") as data: zip_ref.writestr(DEF_INI_FILE, data.read()) return clip_path(complete_path) except: logging.info("Failed to create backup: ", exc_info=True) return False def validate_config_backup(config_backup_data: bytes) -> bool: """Check that the zip file contains a sabnzbd.ini""" try: with io.BytesIO(config_backup_data) as backup_ref: with zipfile.ZipFile(backup_ref, "r") as zip_ref: # Will throw KeyError if not present zip_ref.getinfo(DEF_INI_FILE) return True except: return False def restore_config_backup(config_backup_data: bytes): """Restore configuration files from zip file""" global CFG_MODIFIED try: with io.BytesIO(config_backup_data) as backup_ref: with zipfile.ZipFile(backup_ref, "r") as zip_ref: # Write config file first and read it logging.debug("Writing backup of config-file to %s", CFG_OBJ.filename) with open(CFG_OBJ.filename, "wb") as destination_ref: destination_ref.write(zip_ref.read(DEF_INI_FILE)) logging.debug("Loading settings from backup config-file") read_config(CFG_OBJ.filename) # Write the rest of the admin files that we want to recover adminpath = sabnzbd.cfg.admin_dir.get_path() for filename in CONFIG_BACKUP_FILES + list(CONFIG_BACKUP_HTTPS.keys()): try: zip_ref.getinfo(filename) destination_file = os.path.join(adminpath, filename) logging.debug("Writing backup of %s to %s", filename, destination_file) with open(destination_file, "wb") as destination_ref: destination_ref.write(zip_ref.read(filename)) # For HTTPS config files, point the associated setting to the restored file if setting := CONFIG_BACKUP_HTTPS.get(filename): logging.debug("Setting value of %s to restored file %s", setting, filename) getattr(sabnzbd.cfg, setting).set(filename) CFG_MODIFIED = True except KeyError: # File not in archive pass save_config() except: logging.warning(T("Could not restore backup")) logging.info("Traceback: ", exc_info=True) @synchronized(CONFIG_LOCK) def get_servers() -> Dict[str, ConfigServer]: global CFG_DATABASE try: return CFG_DATABASE["servers"] except KeyError: return {} @synchronized(CONFIG_LOCK) def get_sorters() -> Dict[str, ConfigSorter]: global CFG_DATABASE try: return CFG_DATABASE["sorters"] except KeyError: return {} def get_ordered_sorters() -> List[Dict]: """Return sorters as an ordered list""" database_sorters = get_sorters() sorters = [database_sorters[sorter].get_dict() for sorter in database_sorters.keys()] sorters.sort(key=lambda sorter: sorter["order"]) return sorters @synchronized(CONFIG_LOCK) def get_categories() -> Dict[str, ConfigCat]: """Return link to categories section. This section will always contain special category '*' """ global CFG_DATABASE if "categories" not in CFG_DATABASE: CFG_DATABASE["categories"] = {} cats = CFG_DATABASE["categories"] # Add Default categories if "*" not in cats: ConfigCat("*", {"order": 0, "pp": "3", "script": "None", "priority": NORMAL_PRIORITY}) # Add some category suggestions ConfigCat("movies", {"order": 1}) ConfigCat("tv", {"order": 2}) ConfigCat("audio", {"order": 3}) ConfigCat("software", {"order": 4}) # Save config for future use save_config(True) return cats def get_category(cat: str = "*") -> ConfigCat: """Get one specific category or if not found the default one""" cats = get_categories() try: return cats[cat] except KeyError: return cats["*"] def get_ordered_categories() -> List[Dict]: """Return list-copy of categories section that's ordered by user's ordering including Default-category """ database_cats = get_categories() # Transform to list and sort categories = [] for cat in database_cats.keys(): if cat != "*": categories.append(database_cats[cat].get_dict()) # Sort and add default * category categories.sort(key=lambda cat: cat["order"]) categories.insert(0, database_cats["*"].get_dict()) return categories @synchronized(CONFIG_LOCK) def get_rss() -> Dict[str, ConfigRSS]: global CFG_DATABASE try: # We have to remove non-separator commas by detecting if they are valid URL's for feed_key in CFG_DATABASE["rss"]: feed = CFG_DATABASE["rss"][feed_key] # Only modify if we have to, to prevent repeated config-saving have_new_uri = False # Create a new corrected list new_feed_uris = [] for feed_uri in feed.uri(): if new_feed_uris and not urlparse(feed_uri).scheme and urlparse(new_feed_uris[-1]).scheme: # Current one has no scheme but previous one does, append to previous new_feed_uris[-1] += "," + feed_uri have_new_uri = True continue # Add full working URL new_feed_uris.append(feed_uri) # Set new list if have_new_uri: feed.uri.set(new_feed_uris) return CFG_DATABASE["rss"] except KeyError: return {} def get_filename(): global CFG_OBJ return CFG_OBJ.filename def clean_section_name(section: str) -> str: """Make a section name suitable to be used in the INI, since it can't have starting "[" or a trailing "]". Unfortuantly, ConfigObj doesn't do this for us.""" new_section_name = section.strip("[]") if not new_section_name: raise ValueError("Invalid section name %s, nothing left after cleaning" % section) return new_section_name __PW_PREFIX = "!!!encoded!!!" def encode_password(pw): """Encode password in hexadecimal if needed""" enc = False if pw: encPW = __PW_PREFIX for c in pw: cnum = ord(c) if c == "#" or cnum < 33 or cnum > 126: enc = True encPW += "%2x" % cnum if enc: return encPW return pw def decode_password(pw: str, name: str) -> str: """Decode hexadecimal encoded password but only decode when prefixed """ decPW = "" if pw and pw.startswith(__PW_PREFIX): for n in range(len(__PW_PREFIX), len(pw), 2): try: ch = chr(int(pw[n] + pw[n + 1], 16)) except ValueError: logging.error(T("Incorrectly encoded password %s"), name) return "" decPW += ch return decPW else: return pw def create_api_key(): """Return a new randomized API_KEY""" return uuid.uuid4().hex ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4463196 SABnzbd-4.3.2/sabnzbd/version.py0000644000000000000000000000057714625637243015716 0ustar00runnerstaff# This file will be patched by setup.py # The __version__ should be set to the branch name # Leave __baseline__ set to unknown to enable setting commit-hash # (e.g. "develop" or "1.2.x") # You MUST use double quotes (so " and not ') # Do not forget to update the appdata file for every major release! __version__ = "4.3.2" __baseline__ = "8a42abd1e78b0c29081a4d717c5b457f7bb3a473" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.446394 SABnzbd-4.3.2/sabnzbd/encoding.py0000644000000000000000000000627214625637243016015 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.encoding - Unicode/byte translation functions """ import locale import chardet from xml.sax.saxutils import escape from typing import AnyStr CODEPAGE = locale.getpreferredencoding() def utob(str_in: AnyStr) -> bytes: """Shorthand for converting UTF-8 string to bytes""" if isinstance(str_in, bytes): return str_in return str_in.encode("utf-8") def ubtou(str_in: AnyStr) -> str: """Shorthand for converting unicode bytes to UTF-8 string""" if isinstance(str_in, str): return str_in return str_in.decode("utf-8") def platform_btou(str_in: AnyStr) -> str: """Return Unicode string, if not already Unicode, decode with locale encoding. NOTE: Used for POpen because universal_newlines/text parameter doesn't always work! We cannot use encoding-parameter because it's Python 3.7+ """ if isinstance(str_in, bytes): try: return ubtou(str_in) except UnicodeDecodeError: return str_in.decode(CODEPAGE, errors="replace").replace("?", "!") else: return str_in def correct_unknown_encoding(str_or_bytes_in: AnyStr) -> str: """Files created on Windows but unpacked/repaired on linux can result in invalid filenames. Try to fix this encoding by going to bytes and then back to unicode again. Last resort we use chardet package """ # If already string, back to bytes if not isinstance(str_or_bytes_in, bytes): str_or_bytes_in = str_or_bytes_in.encode("utf-8", "surrogateescape") # Try simple bytes-to-string try: return ubtou(str_or_bytes_in) except UnicodeDecodeError: try: # Try using 8-bit ASCII, if came from Windows return str_or_bytes_in.decode("ISO-8859-1") except ValueError: # Last resort we use the slow chardet package return str_or_bytes_in.decode(chardet.detect(str_or_bytes_in)["encoding"]) def correct_cherrypy_encoding(inputstring: str) -> str: """convert inputstring with separate, individual chars (1-255) to valid string (with UTF8 encoding)""" try: return inputstring.encode("raw_unicode_escape").decode("utf8") except: # not possible to convert to UTF8, so don't change anything: return inputstring def xml_name(input_value) -> str: """Prepare name for use in HTML/XML context""" if input_value is not None: return escape(str(input_value)) return "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4464736 SABnzbd-4.3.2/sabnzbd/downloader.py0000644000000000000000000013177214625637243016371 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.downloader - download engine """ import select import logging from threading import Thread, RLock, current_thread import socket import sys import ssl import time from datetime import date from typing import List, Dict, Optional, Union, Set import sabnzbd from sabnzbd.decorators import synchronized, NzbQueueLocker, DOWNLOADER_CV, DOWNLOADER_LOCK from sabnzbd.newswrapper import NewsWrapper, NNTPPermanentError import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.misc import from_units, helpful_warning, int_conv, MultiAddQueue from sabnzbd.happyeyeballs import happyeyeballs, AddrInfo from sabnzbd.constants import SOFT_QUEUE_LIMIT # Timeout penalty in minutes for each cause _PENALTY_UNKNOWN = 3 # Unknown cause _PENALTY_502 = 5 # Unknown 502 _PENALTY_TIMEOUT = 10 # Server doesn't give an answer (multiple times) _PENALTY_SHARE = 10 # Account sharing detected _PENALTY_TOOMANY = 10 # Too many connections _PENALTY_PERM = 10 # Permanent error, like bad username/password _PENALTY_SHORT = 1 # Minimal penalty when no_penalties is set _PENALTY_VERYSHORT = 0.1 # Error 400 without cause clues # Wait this many seconds between checking idle servers for new articles or busy threads for timeout _SERVER_CHECK_DELAY = 0.5 # Wait this many seconds between updates of the BPSMeter _BPSMETER_UPDATE_DELAY = 0.05 # How many articles should be prefetched when checking the next articles? _ARTICLE_PREFETCH = 20 # Minimum expected size of TCP receive buffer _DEFAULT_CHUNK_SIZE = 32768 TIMER_LOCK = RLock() class Server: # Pre-define attributes to save memory and improve get/set performance __slots__ = ( "id", "newid", "restart", "displayname", "host", "port", "timeout", "threads", "priority", "ssl", "ssl_verify", "ssl_ciphers", "ssl_context", "required", "optional", "retention", "username", "password", "busy_threads", "next_busy_threads_check", "idle_threads", "next_article_search", "active", "bad_cons", "errormsg", "warning", "addrinfo", "ssl_info", "request", "have_body", "have_stat", "article_queue", ) def __init__( self, server_id, displayname, host, port, timeout, threads, priority, use_ssl, ssl_verify, ssl_ciphers, username=None, password=None, required=False, optional=False, retention=0, ): self.id: str = server_id self.newid: Optional[str] = None self.restart: bool = False self.displayname: str = displayname self.host: str = host self.port: int = port self.timeout: int = timeout self.threads: int = threads self.priority: int = priority self.ssl: bool = use_ssl self.ssl_verify: int = ssl_verify self.ssl_ciphers: str = ssl_ciphers self.ssl_context: Optional[ssl.SSLContext] = None self.required: bool = required self.optional: bool = optional self.retention: int = retention self.username: Optional[str] = username self.password: Optional[str] = password self.busy_threads: Set[NewsWrapper] = set() self.next_busy_threads_check: float = 0 self.idle_threads: Set[NewsWrapper] = set() self.next_article_search: float = 0 self.active: bool = True self.bad_cons: int = 0 self.errormsg: str = "" self.warning: str = "" self.addrinfo: Union[AddrInfo, None, bool] = None # Will hold fasted address information self.ssl_info: str = "" # Will hold the type and cipher of SSL connection self.request: bool = False # True if a getaddrinfo() request is pending self.have_body: bool = True # Assume server has "BODY", until proven otherwise self.have_stat: bool = True # Assume server has "STAT", until proven otherwise self.article_queue: List[sabnzbd.nzbstuff.Article] = [] # Skip during server testing if threads: # Initialize threads for i in range(threads): self.idle_threads.add(NewsWrapper(self, i + 1)) # Tell the BPSMeter about this server sabnzbd.BPSMeter.init_server_stats(self.id) def deactivate(self): """Deactivate server and reset queued articles""" self.active = False self.reset_article_queue() def stop(self): """Remove all connections from server""" for nw in self.idle_threads: sabnzbd.Downloader.remove_socket(nw) nw.hard_reset() self.idle_threads = set() @synchronized(DOWNLOADER_LOCK) def get_article(self): """Get article from pre-fetched and pre-fetch new ones if necessary. Articles that are too old for this server are immediately marked as tried""" if self.article_queue: return self.article_queue.pop(0) if self.next_article_search < time.time(): # Pre-fetch new articles self.article_queue = sabnzbd.NzbQueue.get_articles(self, sabnzbd.Downloader.servers, _ARTICLE_PREFETCH) if self.article_queue: article = self.article_queue.pop(0) # Mark expired articles as tried on this server if self.retention and article.nzf.nzo.avg_stamp < time.time() - self.retention: sabnzbd.Downloader.decode(article) while self.article_queue: sabnzbd.Downloader.decode(self.article_queue.pop()) else: return article else: # No available articles, skip this server for a short time self.next_article_search = time.time() + _SERVER_CHECK_DELAY return None def reset_article_queue(self): logging.debug("Resetting article queue for %s", self) for article in self.article_queue: sabnzbd.NzbQueue.reset_try_lists(article, remove_fetcher_from_trylist=False) self.article_queue = [] def request_addrinfo(self): """Launch async request to resolve server address and perform Happy Eyeballs. In some situations this can be slow and result in delayed starts and timeouts on connections. Because of this, the results will be cached in the server object.""" if not self.request: self.request = True Thread(target=self.request_addrinfo_blocking).start() def request_addrinfo_blocking(self): """Blocking attempt to run getaddrinfo() and Happy Eyeballs for specified server""" logging.debug("Retrieving server address information for %s", self.host) # Disable IPV6 if desired family = socket.AF_UNSPEC if not cfg.ipv6_servers(): family = socket.AF_INET self.addrinfo = happyeyeballs(self.host, self.port, self.timeout, family) if not self.addrinfo: self.bad_cons += self.threads # Notify next call to maybe_block_server self.addrinfo = False else: self.bad_cons = 0 self.request = False sabnzbd.Downloader.wakeup() def __repr__(self): return "" % (self.host, self.port) class Downloader(Thread): """Singleton Downloader Thread""" # Improves get/set performance, even though it's inherited from Thread # Due to the huge number of get-calls in run(), it can actually make a difference __slots__ = ( "paused", "bandwidth_limit", "bandwidth_perc", "sleep_time", "paused_for_postproc", "shutdown", "server_restarts", "force_disconnect", "read_fds", "servers", "timers", "last_max_chunk_size", "max_chunk_size", ) def __init__(self, paused=False): super().__init__() logging.debug("Initializing downloader") # Used for scheduled pausing self.paused: bool = paused # Used for reducing speed, should always be int and not float self.bandwidth_limit: int = 0 self.bandwidth_perc: int = 0 cfg.bandwidth_perc.callback(self.speed_set) cfg.bandwidth_max.callback(self.speed_set) self.speed_set() # Used to see if we can add a slowdown to the Downloader-loop self.sleep_time: float = 0.0 self.sleep_time_set() cfg.downloader_sleep_time.callback(self.sleep_time_set) # Sleep check variables self.last_max_chunk_size: int = 0 self.max_chunk_size: int = _DEFAULT_CHUNK_SIZE self.paused_for_postproc: bool = False self.shutdown: bool = False # A user might change server parms again before server restart is ready. # Keep a counter to prevent multiple restarts self.server_restarts: int = 0 self.force_disconnect: bool = False self.read_fds: Dict[int, NewsWrapper] = {} self.servers: List[Server] = [] self.timers: Dict[str, List[float]] = {} for server in config.get_servers(): self.init_server(None, server) def init_server(self, oldserver: Optional[str], newserver: str): """Setup or re-setup single server When oldserver is defined and in use, delay startup. Note that the server names are "host:port" strings! """ create = False servers = config.get_servers() if newserver in servers: srv = servers[newserver] enabled = srv.enable() displayname = srv.displayname() host = srv.host() port = srv.port() timeout = srv.timeout() threads = srv.connections() priority = srv.priority() ssl = srv.ssl() ssl_verify = srv.ssl_verify() ssl_ciphers = srv.ssl_ciphers() username = srv.username() password = srv.password() required = srv.required() optional = srv.optional() retention = int(srv.retention() * 24 * 3600) # days ==> seconds create = True if oldserver: for server in self.servers: if server.id == oldserver: # Server exists, do re-init later create = False server.newid = newserver server.restart = True server.reset_article_queue() self.server_restarts += 1 break if create and enabled and host and port and threads: self.servers.append( Server( newserver, displayname, host, port, timeout, threads, priority, ssl, ssl_verify, ssl_ciphers, username, password, required, optional, retention, ) ) # Sort the servers for performance self.servers.sort(key=lambda svr: "%02d%s" % (svr.priority, svr.displayname.lower())) @synchronized(DOWNLOADER_LOCK) def add_socket(self, fileno: int, nw: NewsWrapper): """Add a socket ready to be used to the list to be watched""" self.read_fds[fileno] = nw @synchronized(DOWNLOADER_LOCK) def remove_socket(self, nw: NewsWrapper): """Remove a socket to be watched""" if nw.nntp: self.read_fds.pop(nw.nntp.fileno, None) @NzbQueueLocker def set_paused_state(self, state: bool): """Set downloader to new paused state if it is changed""" if self.paused != state: if cfg.preserve_paused_state(): cfg.start_paused.set(state) self.paused = state @NzbQueueLocker def resume(self): # Do not notify when SABnzbd is still starting if self.paused and sabnzbd.WEB_DIR: logging.info("Resuming") sabnzbd.notifier.send_notification("SABnzbd", T("Resuming"), "pause_resume") if cfg.preserve_paused_state(): cfg.start_paused.set(False) self.paused = False @NzbQueueLocker def pause(self): """Pause the downloader, optionally saving admin""" if not self.paused: self.paused = True logging.info("Pausing") sabnzbd.notifier.send_notification("SABnzbd", T("Paused"), "pause_resume") if cfg.preserve_paused_state(): cfg.start_paused.set(True) if self.no_active_jobs(): sabnzbd.BPSMeter.reset() if cfg.autodisconnect(): self.disconnect() def wait_for_postproc(self): logging.info("Waiting for post-processing to finish") self.paused_for_postproc = True @NzbQueueLocker def resume_from_postproc(self): logging.info("Post-processing finished, resuming download") self.paused_for_postproc = False @NzbQueueLocker def disconnect(self): logging.info("Forcing disconnect") self.force_disconnect = True def limit_speed(self, value: Union[str, int]): """Set the actual download speed in Bytes/sec When 'value' ends with a '%' sign or is within 1-100, it is interpreted as a percentage of the maximum bandwidth When no '%' is found, it is interpreted as an absolute speed (including KMGT notation). """ if value: mx = cfg.bandwidth_max.get_int() if "%" in str(value) or (0 < from_units(value) < 101): limit = value.strip(" %") self.bandwidth_perc = int_conv(limit) if mx: self.bandwidth_limit = int(mx * self.bandwidth_perc / 100) else: helpful_warning(T("You must set a maximum bandwidth before you can set a bandwidth limit")) else: self.bandwidth_limit = int(from_units(value)) if mx: self.bandwidth_perc = int(self.bandwidth_limit / mx * 100) else: self.bandwidth_perc = 100 else: self.speed_set() logging.info("Speed limit set to %s B/s", self.bandwidth_limit) def speed_set(self): perc = cfg.bandwidth_perc() limit = cfg.bandwidth_max.get_int() if limit and perc: self.bandwidth_perc = int(perc) self.bandwidth_limit = int(limit * perc / 100) else: self.bandwidth_perc = 0 self.bandwidth_limit = 0 def sleep_time_set(self): self.sleep_time = cfg.downloader_sleep_time() * 0.0001 logging.debug("Sleep time: %f seconds", self.sleep_time) def no_active_jobs(self) -> bool: """Is the queue paused or is it paused but are there still forced items?""" return self.paused and not sabnzbd.NzbQueue.has_forced_jobs() def highest_server(self, me: Server): """Return True when this server has the highest priority of the active ones 0 is the highest priority, servers are sorted by priority. """ for server in self.servers: if server.priority == me.priority: return True if server.active: return False def maybe_block_server(self, server: Server): # Was it resolving problem? if server.addrinfo is False: # Warn about resolving issues errormsg = T("Cannot connect to server %s [%s]") % (server.host, T("Server name does not resolve")) if server.errormsg != errormsg: server.errormsg = errormsg logging.warning(errormsg) if not server.required: logging.warning(T("Server %s will be ignored for %s minutes"), server.host, _PENALTY_TIMEOUT) # Not fully the same as the code below for optional servers server.bad_cons = 0 if server.required: sabnzbd.Scheduler.plan_required_server_resume() else: server.deactivate() self.plan_server(server, _PENALTY_TIMEOUT) # Optional and active server had too many problems. # Disable it now and send a re-enable plan to the scheduler if server.optional and server.active and (server.bad_cons / server.threads) > 3: # Deactivate server server.bad_cons = 0 server.deactivate() logging.warning(T("Server %s will be ignored for %s minutes"), server.host, _PENALTY_TIMEOUT) self.plan_server(server, _PENALTY_TIMEOUT) # Remove all connections to server for nw in server.idle_threads | server.busy_threads: self.__reset_nw(nw, "Forcing disconnect", warn=False, wait=False, retry_article=False) # Make sure server address resolution is refreshed server.addrinfo = None @staticmethod def decode(article, data_view: Optional[memoryview] = None): """Decode article""" # Article was requested and fetched, update article stats for the server sabnzbd.BPSMeter.register_server_article_tried(article.fetcher.id) # Handle broken articles directly if not data_view: if not article.search_new_server(): sabnzbd.NzbQueue.register_article(article, success=False) article.nzf.nzo.increase_bad_articles_counter("missing_articles") return # Decode and send to article cache sabnzbd.decoder.decode(article, data_view) def run(self): # Warn if there are servers defined, but none are valid if config.get_servers() and not self.servers: logging.warning(T("There are no active servers!")) # Kick BPS-Meter to check quota BPSMeter = sabnzbd.BPSMeter BPSMeter.update() next_bpsmeter_update = 0 # Check server expiration dates check_server_expiration() # Initialize queue and threads process_nw_queue = MultiAddQueue() for _ in range(cfg.receive_threads()): # Started as daemon, so we don't need any shutdown logic in the worker # The Downloader code will make sure shutdown is handled gracefully Thread(target=self.process_nw_worker, args=(self.read_fds, process_nw_queue), daemon=True).start() # Catch all errors, just in case try: while 1: now = time.time() # Set Article to None so references from this # thread do not keep the parent objects alive (see #1628) article = None for server in self.servers: # Skip this server if there's no point searching for new stuff to do if server.addrinfo and not server.busy_threads and server.next_article_search > now: continue if server.next_busy_threads_check < now: server.next_busy_threads_check = now + _SERVER_CHECK_DELAY for nw in server.busy_threads.copy(): if (nw.nntp and nw.nntp.error_msg) or (nw.timeout and now > nw.timeout): if nw.nntp and nw.nntp.error_msg: # Already showed error self.__reset_nw(nw) else: self.__reset_nw(nw, "Timed out", warn=True) server.bad_cons += 1 self.maybe_block_server(server) if server.restart: if not server.busy_threads: server.stop() self.servers.remove(server) if newid := server.newid: self.init_server(None, newid) self.server_restarts -= 1 # Have to leave this loop, because we removed element break else: # Restart pending, don't add new articles continue if ( not server.idle_threads or self.no_active_jobs() or self.shutdown or self.paused_for_postproc or not server.active ): continue for nw in server.idle_threads.copy(): if nw.timeout: if now < nw.timeout: continue else: nw.timeout = None if not server.addrinfo: # Only request info if there's stuff in the queue if not sabnzbd.NzbQueue.is_empty(): self.maybe_block_server(server) server.request_addrinfo() break nw.article = server.get_article() if not nw.article: break server.idle_threads.remove(nw) server.busy_threads.add(nw) if nw.connected: self.__request_article(nw) else: try: logging.info("%s@%s: Initiating connection", nw.thrdnum, server.host) nw.init_connect() except: logging.error( T("Failed to initialize %s@%s with reason: %s"), nw.thrdnum, server.host, sys.exc_info()[1], ) self.__reset_nw(nw, "Failed to initialize", warn=True) if self.force_disconnect or self.shutdown: for server in self.servers: for nw in server.idle_threads | server.busy_threads: # Send goodbye if we have open socket if nw.nntp: self.__reset_nw(nw, "Forcing disconnect", wait=False, count_article_try=False) # Make sure server address resolution is refreshed server.addrinfo = None server.reset_article_queue() self.force_disconnect = False # Make sure we update the stats BPSMeter.update() # Exit-point if self.shutdown: logging.info("Shutting down") break # If less data than possible was received then it should be ok to sleep a bit if self.sleep_time: if self.last_max_chunk_size > self.max_chunk_size: self.max_chunk_size = self.last_max_chunk_size elif self.last_max_chunk_size < self.max_chunk_size / 3: time.sleep(self.sleep_time) now = time.time() self.last_max_chunk_size = 0 # Use select to find sockets ready for reading/writing if readkeys := self.read_fds.keys(): read, _, _ = select.select(readkeys, (), (), 1.0) else: read = [] BPSMeter.reset() time.sleep(0.1) self.max_chunk_size = _DEFAULT_CHUNK_SIZE with DOWNLOADER_CV: while ( (sabnzbd.NzbQueue.is_empty() or self.no_active_jobs() or self.paused_for_postproc) and not self.shutdown and not self.force_disconnect and not self.server_restarts ): DOWNLOADER_CV.wait() if now > next_bpsmeter_update: # Do not update statistics and check levels every loop BPSMeter.update() next_bpsmeter_update = now + _BPSMETER_UPDATE_DELAY self.check_assembler_levels() if not read: continue # Submit all readable sockets to be processed and wait for completion process_nw_queue.put_multiple(read) process_nw_queue.join() except: logging.error(T("Fatal error in Downloader"), exc_info=True) def process_nw_worker(self, read_fds: Dict[int, NewsWrapper], nw_queue: MultiAddQueue): """Worker for the daemon thread to process results. Wrapped in try/except because in case of an exception, logging might get lost and the queue.join() would block forever.""" try: logging.debug("Starting Downloader receive thread: %s", current_thread().name) while True: # The read_fds is passed by reference, so we can access its items! self.process_nw(read_fds[nw_queue.get()]) nw_queue.task_done() except: # We cannot break out of the Downloader from here, so just pause logging.error(T("Fatal error in Downloader"), exc_info=True) self.pause() def process_nw(self, nw: NewsWrapper): """Receive data from a NewsWrapper and handle the response""" try: bytes_received, end_of_line, article_done = nw.recv_chunk() except ssl.SSLWantReadError: return except (ConnectionError, ConnectionAbortedError): # The ConnectionAbortedError is thrown by sabctools in case of fatal SSL-layer problems self.__reset_nw(nw, "Server closed connection", wait=False) return article = nw.article server = nw.server with DOWNLOADER_LOCK: sabnzbd.BPSMeter.update(server.id, bytes_received) if bytes_received > self.last_max_chunk_size: self.last_max_chunk_size = bytes_received # Update statistics only when we fetched a whole article # The side effect is that we don't count things like article-not-available messages if article_done: article.nzf.nzo.update_download_stats(sabnzbd.BPSMeter.bps, server.id, nw.data_position) # Check speedlimit if ( self.bandwidth_limit and sabnzbd.BPSMeter.bps + sabnzbd.BPSMeter.sum_cached_amount > self.bandwidth_limit ): sabnzbd.BPSMeter.update() while sabnzbd.BPSMeter.bps > self.bandwidth_limit: time.sleep(0.01) sabnzbd.BPSMeter.update() # If we are not at the end of a line, more data will follow if not end_of_line: return # Response code depends on request command: # 220 = ARTICLE, 222 = BODY if nw.status_code not in (220, 222) and not article_done: if not nw.connected or nw.status_code == 480: if not self.__finish_connect_nw(nw): return if nw.connected: logging.info("Connecting %s@%s finished", nw.thrdnum, nw.server.host) self.__request_article(nw) elif nw.status_code == 223: article_done = True logging.debug("Article <%s> is present", article.article) elif nw.status_code in (411, 423, 430, 451): article_done = True logging.debug( "Thread %s@%s: Article %s missing (error=%s)", nw.thrdnum, nw.server.host, article.article, nw.status_code, ) nw.reset_data_buffer() elif nw.status_code == 500: if article.nzf.nzo.precheck: # Assume "STAT" command is not supported server.have_stat = False logging.debug("Server %s does not support STAT", server.host) else: # Assume "BODY" command is not supported server.have_body = False logging.debug("Server %s does not support BODY", server.host) nw.reset_data_buffer() self.__request_article(nw) else: # Don't warn for (internal) server errors during downloading if nw.status_code not in (400, 502, 503): logging.warning( T("%s@%s: Received unknown status code %s for article %s"), nw.thrdnum, nw.server.host, nw.status_code, article.article, ) # Ditch this thread, we don't know what data we got now so the buffer can be bad self.__reset_nw(nw, f"Server error or unknown status code: {nw.status_code}", wait=False) return if article_done: # Successful data, clear "bad" counter server.bad_cons = 0 server.errormsg = server.warning = "" # Decode self.decode(article, nw.data_view[: nw.data_position]) if sabnzbd.LOG_ALL: logging.debug("Thread %s@%s: %s done", nw.thrdnum, server.host, article.article) # Reset connection for new activity nw.soft_reset() # Request a new article immediately if possible if ( nw.connected and server.active and not server.restart and not (self.paused or self.shutdown or self.paused_for_postproc) ): nw.article = server.get_article() if nw.article: self.__request_article(nw) return # Make socket available again server.busy_threads.discard(nw) server.idle_threads.add(nw) self.remove_socket(nw) def check_assembler_levels(self): """Check the Assembler queue to see if we need to delay, depending on queue size""" if (assembler_level := sabnzbd.Assembler.queue_level()) > SOFT_QUEUE_LIMIT: time.sleep(min((assembler_level - SOFT_QUEUE_LIMIT) / 4, 0.15)) sabnzbd.BPSMeter.delayed_assembler += 1 logged_counter = 0 while not self.shutdown and sabnzbd.Assembler.queue_level() >= 1: # Only log/update once every second, to not waste any CPU-cycles if not logged_counter % 10: # Make sure the BPS-meter is updated sabnzbd.BPSMeter.update() # Update who is delaying us logging.debug( "Delayed - %d seconds - Assembler queue: %d", logged_counter / 10, sabnzbd.Assembler.queue.qsize(), ) # Wait and update the queue sizes time.sleep(0.1) logged_counter += 1 @synchronized(DOWNLOADER_LOCK) def __finish_connect_nw(self, nw: NewsWrapper) -> bool: server = nw.server try: nw.finish_connect(nw.status_code) if sabnzbd.LOG_ALL: logging.debug("%s@%s last message -> %s", nw.thrdnum, server.host, nw.nntp_msg) nw.reset_data_buffer() except NNTPPermanentError as error: # Handle login problems block = False penalty = 0 errormsg = None logging.debug("Server login problem: %s", error.msg) if error.code in (502, 400, 481, 482) and clues_too_many(error.msg): # Too many connections: remove this thread and reduce thread-setting for server # Plan to go back to the full number after a penalty timeout errormsg = T("Too many connections to server %s [%s]") % (server.host, error.msg) if server.active: # Don't count this for the tries (max_art_tries) on this server self.__reset_nw(nw) self.plan_server(server, _PENALTY_TOOMANY) server.threads -= 1 elif error.code in (502, 481, 482) and clues_too_many_ip(error.msg): # Login from (too many) different IP addresses errormsg = T( "Login from too many different IP addresses to server %s [%s] - https://sabnzbd.org/multiple-adresses" ) % (server.host, error.msg) penalty = _PENALTY_SHARE block = True elif error.code in (452, 481, 482, 381) or (error.code in (500, 502) and clues_login(error.msg)): # Cannot login, block this server errormsg = T("Failed login for server %s [%s]") % (server.host, error.msg) penalty = _PENALTY_PERM block = True elif error.code in (502, 482): # Cannot connect (other reasons), block this server errormsg = T("Cannot connect to server %s [%s]") % (server.host, error.msg) if clues_pay(error.msg): penalty = _PENALTY_PERM else: penalty = _PENALTY_502 block = True elif error.code == 400: # Temp connection problem? logging.debug("Unspecified error 400 from server %s", server.host) penalty = _PENALTY_VERYSHORT block = True else: # Unknown error, just keep trying errormsg = T("Cannot connect to server %s [%s]") % (server.host, error.msg) penalty = _PENALTY_UNKNOWN block = True # Set error for server and warn user if it was first time thrown if errormsg and server.active and server.errormsg != errormsg: server.errormsg = errormsg logging.warning(errormsg) # Take action on the problem if block or (penalty and server.optional): retry_article = False if server.active: if server.required: sabnzbd.Scheduler.plan_required_server_resume() retry_article = True else: server.deactivate() if penalty and (block or server.optional): self.plan_server(server, penalty) # Note that the article is discard for this server if the server is not required self.__reset_nw(nw, retry_article=retry_article) return False except Exception as err: logging.error( T("Connecting %s@%s failed, message=%s"), nw.thrdnum, nw.server.host, err, ) logging.info("Traceback: ", exc_info=True) # No reset-warning needed, above logging is sufficient self.__reset_nw(nw, retry_article=False) return True @synchronized(DOWNLOADER_LOCK) def __reset_nw( self, nw: NewsWrapper, reset_msg: Optional[str] = None, warn: bool = False, wait: bool = True, count_article_try: bool = True, retry_article: bool = True, ): # Some warnings are errors, and not added as server.warning if warn and reset_msg: nw.server.warning = reset_msg logging.info("Thread %s@%s: %s", nw.thrdnum, nw.server.host, reset_msg) elif reset_msg: logging.debug("Thread %s@%s: %s", nw.thrdnum, nw.server.host, reset_msg) # Make sure this NewsWrapper is in the idle threads nw.server.busy_threads.discard(nw) nw.server.idle_threads.add(nw) # Make sure it is not in the readable sockets self.remove_socket(nw) if nw.article and not nw.article.nzf.nzo.removed_from_queue: # Only some errors should count towards the total tries for each server if count_article_try: nw.article.tries += 1 # Do we discard, or try again for this server if not retry_article or (not nw.server.required and nw.article.tries > cfg.max_art_tries()): # Too many tries on this server, consider article missing self.decode(nw.article) nw.article.tries = 0 else: # Retry again with the same server logging.debug( "Re-adding article %s from %s to server %s", nw.article.article, nw.article.nzf.filename, nw.article.fetcher, ) nw.article.fetcher.article_queue.append(nw.article) # Reset connection object nw.hard_reset(wait) # Empty SSL info, it might change on next connect nw.server.ssl_info = "" def __request_article(self, nw: NewsWrapper): try: if sabnzbd.LOG_ALL: logging.debug("Thread %s@%s: BODY %s", nw.thrdnum, nw.server.host, nw.article.article) nw.body() # Mark as ready to be read self.add_socket(nw.nntp.fileno, nw) except socket.error as err: logging.info("Looks like server closed connection: %s", err) self.__reset_nw(nw, "Server broke off connection", warn=True) except: logging.error(T("Suspect error in downloader")) logging.info("Traceback: ", exc_info=True) self.__reset_nw(nw, "Server broke off connection", warn=True) # ------------------------------------------------------------------------------ # Timed restart of servers admin. # For each server all planned events are kept in a list. # When the first timer of a server fires, all other existing timers # are neutralized. # Each server has a dictionary entry, consisting of a list of timestamps. @synchronized(TIMER_LOCK) def plan_server(self, server: Server, interval: int): """Plan the restart of a server in 'interval' minutes""" if cfg.no_penalties() and interval > _PENALTY_SHORT: # Overwrite in case of no_penalties interval = _PENALTY_SHORT logging.debug("Set planned server resume %s in %s mins", server.host, interval) if server.id not in self.timers: self.timers[server.id] = [] stamp = time.time() + 60.0 * interval self.timers[server.id].append(stamp) if interval: sabnzbd.Scheduler.plan_server(self.trigger_server, [server.id, stamp], interval) @synchronized(TIMER_LOCK) def trigger_server(self, server_id: str, timestamp: float): """Called by scheduler, start server if timer still valid""" logging.debug("Trigger planned server resume for server-id %s", server_id) if server_id in self.timers: if timestamp in self.timers[server_id]: del self.timers[server_id] self.init_server(server_id, server_id) @NzbQueueLocker @synchronized(TIMER_LOCK) def unblock(self, server_id: str): # Remove timer try: del self.timers[server_id] except KeyError: pass # Activate server if it was inactive for server in self.servers: if server.id == server_id and not server.active: logging.debug("Unblock server %s", server.host) self.init_server(server_id, server_id) break def unblock_all(self): for server_id in self.timers.keys(): self.unblock(server_id) @NzbQueueLocker @synchronized(TIMER_LOCK) def check_timers(self): """Make sure every server without a non-expired timer is active""" # Clean expired timers now = time.time() kicked = [] # Create a copy so we can remove during iteration for server_id in list(self.timers): if not [stamp for stamp in self.timers[server_id] if stamp >= now]: logging.debug("Forcing re-evaluation of server-id %s", server_id) del self.timers[server_id] self.init_server(server_id, server_id) kicked.append(server_id) # Activate every inactive server without an active timer for server in self.servers: if server.id not in self.timers: if server.id not in kicked and not server.active: logging.debug("Forcing activation of server %s", server.host) self.init_server(server.id, server.id) def update_server(self, oldserver: str, newserver: Optional[str]): """Update the server and make sure we trigger the update in the loop to do housekeeping""" self.init_server(oldserver, newserver) self.wakeup() @NzbQueueLocker def wakeup(self): """Just rattle the semaphore""" pass @NzbQueueLocker def stop(self): """Shutdown, wrapped so the semaphore is notified""" self.shutdown = True sabnzbd.notifier.send_notification("SABnzbd", T("Shutting down"), "startup") def clues_login(text: str) -> bool: """Check for any "failed login" clues in the response code""" text = text.lower() for clue in ("username", "password", "invalid", "authen", "access denied"): if clue in text: return True return False def clues_too_many(text: str) -> bool: """Check for any "too many connections" clues in the response code""" text = text.lower() for clue in ("exceed", "connections", "too many", "threads", "limit"): # Not 'download limit exceeded' error if (clue in text) and ("download" not in text) and ("byte" not in text): return True return False def clues_too_many_ip(text: str) -> bool: """Check for any "account sharing" clues in the response code""" text = text.lower() for clue in ("simultaneous ip", "multiple ip"): if clue in text: return True return False def clues_pay(text: str) -> bool: """Check for messages about payments""" text = text.lower() for clue in ("credits", "paym", "expired", "exceeded"): if clue in text: return True return False def check_server_expiration(): """Check if user should get warning about server date expiration""" for server in config.get_servers().values(): if server.expire_date(): try: days_to_expire = (date.fromisoformat(server.expire_date()) - date.today()).days except ValueError: # In case of invalid date, just warn days_to_expire = 0 # Notify from 5 days in advance if days_to_expire < 6: logging.warning(T("Server %s is expiring in %s day(s)"), server.displayname(), days_to_expire) # Reset on the day of expiration if days_to_expire <= 0: server.expire_date.set("") config.save_config() def check_server_quota(): """Check quota on servers""" for srv, server in config.get_servers().items(): if server.quota(): if server.quota.get_int() + server.usage_at_start() < sabnzbd.BPSMeter.grand_total.get(srv, 0): logging.warning(T("Server %s has used the specified quota"), server.displayname()) server.quota.set("") config.save_config() def pause_all(): """Pause all activities than cause disk access""" sabnzbd.PAUSED_ALL = True sabnzbd.Downloader.pause() logging.debug("PAUSED_ALL active") def unpause_all(): """Resume all activities""" sabnzbd.PAUSED_ALL = False sabnzbd.Downloader.resume() logging.debug("PAUSED_ALL inactive") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4465513 SABnzbd-4.3.2/sabnzbd/zconfig.py0000644000000000000000000000704114625637243015661 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.zconfig - bonjour/zeroconfig support """ import logging import socket _HOST_PORT = (None, None) try: from sabnzbd.utils import pybonjour from threading import Thread _HAVE_BONJOUR = True except: _HAVE_BONJOUR = False import sabnzbd import sabnzbd.cfg as cfg from sabnzbd.misc import is_localhost _BONJOUR_OBJECT = None def _zeroconf_callback(sdRef, flags, errorCode, name, regtype, domain): logging.debug( "Full Bonjour-callback sdRef=%s, flags=%s, errorCode=%s, name=%s, regtype=%s, domain=%s", sdRef, flags, errorCode, name, regtype, domain, ) if errorCode == pybonjour.kDNSServiceErr_NoError: logging.info('Registered in Bonjour as "%s" (%s)', name, domain) def set_bonjour(host=None, port=None): """Publish host/port combo through Bonjour""" global _HOST_PORT, _BONJOUR_OBJECT if not _HAVE_BONJOUR or not cfg.enable_broadcast(): logging.info("No bonjour/zeroconf support installed") return if host is None and port is None: host, port = _HOST_PORT else: _HOST_PORT = (host, port) scope = pybonjour.kDNSServiceInterfaceIndexAny zhost = None domain = None if is_localhost(host): logging.info("Cannot setup bonjour/zeroconf for localhost (%s)", host) # All implementations fail to implement "localhost" properly # A false address is published even when scope==kDNSServiceInterfaceIndexLocalOnly return name = socket.gethostname() logging.debug('Try to publish in Bonjour as "%s" (%s:%s)', name, host, port) try: refObject = pybonjour.DNSServiceRegister( interfaceIndex=scope, name="SABnzbd on %s:%s" % (name, port), regtype="_http._tcp", domain=domain, host=zhost, port=int(port), txtRecord=pybonjour.TXTRecord({"path": cfg.url_base(), "https": cfg.enable_https()}), callBack=_zeroconf_callback, ) except sabnzbd.utils.pybonjour.BonjourError as e: _BONJOUR_OBJECT = None logging.debug("Failed to start Bonjour service: %s", str(e)) except: _BONJOUR_OBJECT = None logging.debug("Failed to start Bonjour service due to non-pybonjour related problem", exc_info=True) else: Thread(target=_bonjour_server, args=(refObject,)) _BONJOUR_OBJECT = refObject logging.debug("Successfully started Bonjour service") def _bonjour_server(refObject): while 1: pybonjour.DNSServiceProcessResult(refObject) logging.debug("GOT A BONJOUR CALL") def remove_server(): """Remove Bonjour registration""" global _BONJOUR_OBJECT if _BONJOUR_OBJECT: _BONJOUR_OBJECT.close() _BONJOUR_OBJECT = None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4466233 SABnzbd-4.3.2/sabnzbd/par2file.py0000644000000000000000000002533514625637243015734 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.par2file - All par2-related functionality """ import hashlib import logging import os import re import struct import sabctools from dataclasses import dataclass from typing import Dict, Optional, Tuple from sabnzbd.constants import MEBI from sabnzbd.encoding import correct_unknown_encoding from sabnzbd.filesystem import get_basename PROBABLY_PAR2_RE = re.compile(r"(.*)\.vol(\d*)[+\-](\d*)\.par2", re.I) SCAN_LIMIT = 10 * MEBI PAR_PKT_ID = b"PAR2\x00PKT" PAR_MAIN_ID = b"PAR 2.0\x00Main\x00\x00\x00\x00" PAR_FILE_ID = b"PAR 2.0\x00FileDesc" PAR_CREATOR_ID = b"PAR 2.0\x00Creator\x00" PAR_SLICE_ID = b"PAR 2.0\x00IFSC\x00\x00\x00\x00" PAR_RECOVERY_ID = b"RecvSlic" @dataclass class FilePar2Info: """Class for keeping track of par2 information of a file""" filename: str hash16k: bytes filesize: int filehash: Optional[int] = None has_duplicate: bool = False def is_parfile(filename: str) -> bool: """Check quickly whether file has par2 signature or if the filename has '.par2' in it """ if os.path.exists(filename): try: with open(filename, "rb") as f: buf = f.read(8) return buf.startswith(PAR_PKT_ID) except: pass elif ".par2" in filename.lower(): return True return False def analyse_par2(name: str, filepath: Optional[str] = None) -> Tuple[str, int, int]: """Check if file is a par2-file and determine vol/block return setname, vol, block setname is empty when not a par2 file """ name = name.strip() vol = block = 0 if m := PROBABLY_PAR2_RE.search(name): setname = m.group(1) vol = m.group(2) block = m.group(3) else: # Base-par2 file setname = get_basename(name).strip() # Could not parse the filename, need deep inspection # We already know it's a par2 from the is_parfile if filepath: try: # Quick loop to find number blocks # Assumes blocks are larger than 128 bytes # Worst case, we only count 1, still good with open(filepath, "rb") as f: buf = f.read(128) while buf: if PAR_RECOVERY_ID in buf: block += 1 buf = f.read(128) except: pass return setname, vol, block def parse_par2_file(fname: str, md5of16k: Dict[bytes, str]) -> Tuple[str, Dict[str, FilePar2Info]]: """Get the hash table and the first-16k hash table from a PAR2 file Return as dictionary, indexed on names or hashes for the first-16 table The input md5of16k is modified in place and thus not returned! Note that par2 can and will appear in random order, so the code has to collect data first before we process them! For a full description of the par2 specification, visit: http://parchive.sourceforge.net/docs/specifications/parity-volume-spec/article-spec.html """ set_id = slice_size = coeff = nr_files = None filepar2info = {} filecrc32 = {} table = {} duplicates16k = [] try: total_size = os.path.getsize(fname) with open(fname, "rb") as f: while header := f.read(8): if header == PAR_PKT_ID: # All packages start with a header before the body # 8 : PAR2\x00PKT # 8 : Length of the entire packet. Must be multiple of 4. (NB: Includes length of header.) # 16 : MD5 Hash of packet. # 16 : Recovery Set ID. # 16 : Type of packet. # ?*4 : Body of Packet. Must be a multiple of 4 bytes. # Length must be multiple of 4 and at least 20 pack_len = struct.unpack(" SCAN_LIMIT and len(filepar2info) == nr_files: break # Process all the data for fileid in filepar2info.keys(): # Sanity check par2info = filepar2info[fileid] if not filecrc32.get(fileid) or not nr_files or not slice_size: logging.debug("Missing essential information for %s", par2info) continue # Handle also cases where slice_size is exact match for filesize # We currently don't have an unittest for that! slices = par2info.filesize // slice_size slice_nr = 0 crc32 = 0 while slice_nr < slices: crc32 = sabctools.crc32_multiply(crc32, coeff) ^ filecrc32[fileid][slice_nr] slice_nr += 1 if tail_size := par2info.filesize % slice_size: crc32 = sabctools.crc32_combine( crc32, sabctools.crc32_zero_unpad(filecrc32[fileid][-1], slice_size - tail_size), tail_size ) par2info.filehash = crc32 # We found hash data, add it to final tabel table[par2info.filename] = par2info # Check for md5of16k duplicates if par2info.hash16k not in md5of16k: md5of16k[par2info.hash16k] = par2info.filename elif md5of16k[par2info.hash16k] != par2info.filename: # Not unique and not already linked to this file # Mark and remove to avoid false-renames duplicates16k.append(par2info.hash16k) table[par2info.filename].has_duplicate = True except: logging.info("Par2 parser crashed in file %s", fname) logging.debug("Traceback: ", exc_info=True) table = {} set_id = None # Have to remove duplicates at the end to make sure # no trace is left in case of multi-duplicates for hash16k in duplicates16k: if hash16k in md5of16k: old_name = md5of16k.pop(hash16k) logging.debug("Par2-16k signature of %s not unique, discarding", old_name) # Sort table by filename # This is necessary because of the rare case that a set contains duplicate files. # The crc32 quick check loops over files in the set and considered if they match an NzbFile. # For example in a set with the packets in the order 003, 004, 001, 002 with 002 and 003 being identical files: # We would start with 003 and the first match would be 002, therefore rename 002 to 003 overwriting the also # downloaded 003 file. # Finally, we would process 002 and the first unverified path will be 003 so rename 003 back to 002. # The end result is we would have moved a single file from 002 to 003 to 002 and end up missing 003. table = {filename: table[filename] for filename in sorted(table.keys())} return set_id, table ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.446696 SABnzbd-4.3.2/sabnzbd/panic.py0000644000000000000000000001723414625637243015321 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.panic - Send panic message to the browser """ import os import logging import tempfile import ctypes try: import webbrowser except ImportError: webbrowser = None import sabnzbd import sabnzbd.cfg as cfg from sabnzbd.encoding import utob PANIC_PORT = 1 PANIC_TEMPL = 2 PANIC_QUEUE = 3 PANIC_OTHER = 5 PANIC_SQLITE = 7 PANIC_HOST = 8 def MSG_BAD_NEWS(): return ( r""" """ + T("Problem with") + """ %s %s

%s %s

 

%s

%s
""" ) def MSG_BAD_PORT(): return ( T( r""" SABnzbd needs a free tcp/ip port for its internal web server.
Port %s on %s was tried , but it is not available.
Some other software uses the port or SABnzbd is already running.

Please restart SABnzbd with a different port number.""" ) + """

%s
    %s --server %s:%s

""" + T(r"If you get this error message again, please try a different number.
") ) def MSG_BAD_HOST(): return ( T( r""" SABnzbd needs a valid host address for its internal web server.
You have specified an invalid address.
Safe values are localhost and 0.0.0.0

Please restart SABnzbd with a proper host address.""" ) + """

%s
    %s --server %s:%s

""" ) def MSG_BAD_QUEUE(): return ( T( r""" SABnzbd detected saved data from an other SABnzbd version
but cannot re-use the data of the other program.

You may want to finish your queue first with the other program.

After that, start this program with the "--clean" option.
This will erase the current queue and history!
SABnzbd read the file "%s".""" ) + """

%s
    %s --clean

""" ) def MSG_BAD_TEMPL(): return T( r""" SABnzbd cannot find its web interface files in %s.
Please install the program again.

""" ) def MSG_OTHER(): return T("SABnzbd detected a fatal error:") + "
%s

%s
" def MSG_SQLITE(): return T( r""" SABnzbd detected that the file sqlite3.dll is missing.

Some poorly designed virus-scanners remove this file.
Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

""" ) def panic_message(panic_code, a=None, b=None): """Create the panic message from templates""" if sabnzbd.WIN32: os_str = T("Press Startkey+R and type the line (example):") prog_path = '"%s"' % sabnzbd.MY_FULLNAME else: os_str = T("Open a Terminal window and type the line (example):") prog_path = sabnzbd.MY_FULLNAME if panic_code == PANIC_PORT: newport = int(b) + 1 newport = "%s" % newport msg = MSG_BAD_PORT() % (b, a, os_str, prog_path, a, newport) elif panic_code == PANIC_TEMPL: msg = MSG_BAD_TEMPL() % a elif panic_code == PANIC_QUEUE: msg = MSG_BAD_QUEUE() % (a, os_str, prog_path) elif panic_code == PANIC_SQLITE: msg = MSG_SQLITE() elif panic_code == PANIC_HOST: msg = MSG_BAD_HOST() % (os_str, prog_path, "localhost", b) else: msg = MSG_OTHER() % (a, b) msg = MSG_BAD_NEWS() % ( sabnzbd.MY_NAME, sabnzbd.__version__, sabnzbd.MY_NAME, sabnzbd.__version__, msg, T("Program did not start!"), ) if sabnzbd.WIN_SERVICE: sabnzbd.WIN_SERVICE.ErrLogger("Panic exit", msg) if (not cfg.autobrowser()) or sabnzbd.DAEMON: return msgfile, url = tempfile.mkstemp(suffix=".html") os.write(msgfile, utob(msg)) os.close(msgfile) return url def panic_port(host, port): show_error_dialog( "\n%s:\n %s" % ( T("Fatal error"), T("Unable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running.") % (port, host), ) ) launch_a_browser(panic_message(PANIC_PORT, host, port)) def panic_host(host, port): launch_a_browser(panic_message(PANIC_HOST, host, port)) def panic_queue(name): launch_a_browser(panic_message(PANIC_QUEUE, name, 0)) def panic_tmpl(name): launch_a_browser(panic_message(PANIC_TEMPL, name, 0)) def panic(reason, remedy=""): show_error_dialog("\n%s:\n %s\n%s" % (T("Fatal error"), reason, remedy)) launch_a_browser(panic_message(PANIC_OTHER, reason, remedy)) def launch_a_browser(url, force=False): """Launch a browser pointing to the URL""" if not force and not cfg.autobrowser() or sabnzbd.DAEMON: return if "::1" in url and "[::1]" not in url: # Get around idiosyncrasy in Python runtime url = url.replace("::1", "[::1]") if cfg.enable_https() and not cfg.https_port.get_int(): # Must use https, because http is not available url = url.replace("http:", "https:") if "localhost" in url and not cfg.ipv6_hosting(): url = url.replace("localhost", "127.0.0.1") logging.info("Launching browser with %s", url) try: if url and not url.startswith("http"): url = "file:///%s" % url if webbrowser: webbrowser.open(url, 2, True) else: logging.info("Not showing panic message in webbrowser, no support found") except: logging.warning(T("Cannot launch the browser, probably not found")) logging.info("Traceback: ", exc_info=True) def show_error_dialog(msg): """Show a pop-up when program cannot start Windows-only, otherwise only print to console """ if sabnzbd.WIN32: ctypes.windll.user32.MessageBoxW(0, msg, T("Fatal error"), 0) print(msg) def error_page_401(status, message, traceback, version): """Custom handler for 401 error""" title = T("Access denied") body = T("Error %s: You need to provide a valid username and password.") % status return r""" %s

%s """ % ( title, body, ) def error_page_404(status, message, traceback, version): """Custom handler for 404 error, redirect to main page""" return ( r"""
""" % cfg.url_base() ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4467742 SABnzbd-4.3.2/sabnzbd/notifier.py0000644000000000000000000004700714625637243016047 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # """ sabnzbd.notifier - Send notifications to any notification services """ import os.path import logging import platform import urllib.request import urllib.parse import http.client import json import apprise from threading import Thread from typing import Optional, Dict, Union import sabnzbd import sabnzbd.cfg from sabnzbd.encoding import utob from sabnzbd.filesystem import make_script_path from sabnzbd.misc import build_and_run_command, int_conv from sabnzbd.newsunpack import create_env if sabnzbd.WIN32: try: from win32comext.shell import shell from windows_toasts import InteractableWindowsToaster, Toast, ToastActivatedEventArgs, ToastButton # Only Windows 10 and above are supported if int_conv(platform.release()) < 10: raise OSError # Set a custom AUMID to display the right icon, it is written to the registry by the installer shell.SetCurrentProcessExplicitAppUserModelID("SABnzbd") _HAVE_WINDOWS_TOASTER = True except: # Sending toasts on non-supported platforms results in segfaults _HAVE_WINDOWS_TOASTER = False try: import notify2 _HAVE_NTFOSD = True # Check for working version, not all pynotify are the same # Without DISPLAY, notify2 cannot autolaunch a dbus-daemon if not hasattr(notify2, "init") or "DISPLAY" not in os.environ: _HAVE_NTFOSD = False except: _HAVE_NTFOSD = False ############################################################################## # Define translatable message table ############################################################################## TT = lambda x: x NOTIFICATION_TYPES = { "startup": TT("Startup/Shutdown"), #: Notification "pause_resume": TT("Pause") + "/" + TT("Resume"), #: Notification "download": TT("Added NZB"), #: Notification "pp": TT("Post-processing started"), # : Notification "complete": TT("Job finished"), #: Notification "failed": TT("Job failed"), #: Notification "warning": TT("Warning"), #: Notification "error": TT("Error"), #: Notification "disk_full": TT("Disk full"), #: Notification "queue_done": TT("Queue finished"), #: Notification "new_login": TT("User logged in"), #: Notification "other": TT("Other Messages"), #: Notification } NOTIFICATION_ACTIONS = { "open_folder": TT("Open folder"), #: Notification action "open_complete": TT("Open complete folder"), #: Notification action } def have_ntfosd() -> bool: """Return if any PyNotify (notify2) support is present""" return bool(_HAVE_NTFOSD) def check_classes(notification_type: str, section: str) -> bool: """Check if `notification_type` is enabled in `section`""" try: return sabnzbd.config.get_config(section, "%s_prio_%s" % (section, notification_type))() > 0 except TypeError: logging.debug("Incorrect Notify option %s:%s_prio_%s", section, section, notification_type) return False def get_prio(notification_type: str, section: str) -> int: """Check prio of `notification_type` in `section`""" try: return sabnzbd.config.get_config(section, "%s_prio_%s" % (section, notification_type))() except TypeError: logging.debug("Incorrect Notify option %s:%s_prio_%s", section, section, notification_type) return -1000 def get_targets(notification_type: str, section: str) -> Union[str, bool, None]: """Check target of `notification_type` in `section` if enabled is set""" try: if sabnzbd.config.get_config(section, "%s_target_%s_enable" % (section, notification_type))() > 0: if result := sabnzbd.config.get_config(section, "%s_target_%s" % (section, notification_type))(): return result # Use Default return True except TypeError: logging.debug("Incorrect Notify option %s:%s_target_%s", section, section, notification_type) return False return False def check_cat(section: str, job_cat: str, keyword: Optional[str] = None) -> bool: """Check if `job_cat` is enabled in `section`. * = All, if no other categories selected. """ if not job_cat: return True try: if not keyword: keyword = section section_cats = sabnzbd.config.get_config(section, "%s_cats" % keyword)() return ["*"] == section_cats or job_cat in section_cats except TypeError: logging.debug("Incorrect Notify option %s:%s_cats", section, section) return True def send_notification( title: str, msg: str, notification_type: str, job_cat: Optional[str] = None, actions: Optional[Dict[str, str]] = None, ): """Send Notification message""" logging.info("Sending notification: %s - %s (type=%s, job_cat=%s)", title, msg, notification_type, job_cat) # Notification Center if sabnzbd.MACOS and sabnzbd.cfg.ncenter_enable(): if check_classes(notification_type, "ncenter") and check_cat("ncenter", job_cat): send_notification_center(title, msg, notification_type, actions) # Windows if sabnzbd.WIN32 and sabnzbd.cfg.acenter_enable(): if check_classes(notification_type, "acenter") and check_cat("acenter", job_cat): send_windows(title, msg, notification_type, actions) # Prowl if sabnzbd.cfg.prowl_enable() and check_cat("prowl", job_cat): if sabnzbd.cfg.prowl_apikey(): Thread(target=send_prowl, args=(title, msg, notification_type)).start() # Pushover if sabnzbd.cfg.pushover_enable() and check_cat("pushover", job_cat): if sabnzbd.cfg.pushover_token(): Thread(target=send_pushover, args=(title, msg, notification_type)).start() # Pushbullet if sabnzbd.cfg.pushbullet_enable() and check_cat("pushbullet", job_cat): if sabnzbd.cfg.pushbullet_apikey() and check_classes(notification_type, "pushbullet"): Thread(target=send_pushbullet, args=(title, msg, notification_type)).start() # Apprise if sabnzbd.cfg.apprise_enable() and check_cat("apprise", job_cat): # it is possible to not define global apprise_urls() but only URLs for a specific type # such as complete or disk_full. if get_targets(notification_type, "apprise"): Thread(target=send_apprise, args=(title, msg, notification_type)).start() # Notification script. if sabnzbd.cfg.nscript_enable() and check_cat("nscript", job_cat): if sabnzbd.cfg.nscript_script(): Thread(target=send_nscript, args=(title, msg, notification_type)).start() # NTFOSD if have_ntfosd() and sabnzbd.cfg.ntfosd_enable(): if check_classes(notification_type, "ntfosd") and check_cat("ntfosd", job_cat): send_notify_osd(title, msg) ############################################################################## # Ubuntu NotifyOSD Support ############################################################################## _NTFOSD = False def send_notify_osd(title, message): """Send a message to NotifyOSD""" global _NTFOSD if not _HAVE_NTFOSD: return T("Not available") # : Function is not available on this OS error = "NotifyOSD not working" icon = os.path.join(sabnzbd.DIR_PROG, "interfaces/Config/templates/staticcfg/images/logo-arrow.svg") # Wrap notify2.init to prevent blocking in dbus # when there's no active notification daemon try: _NTFOSD = _NTFOSD or notify2.init("SABnzbd") except: _NTFOSD = False if _NTFOSD: logging.info("Send to NotifyOSD: %s / %s", title, message) try: note = notify2.Notification(title, message, icon) note.show() except: # Apparently not implemented on this system logging.info(error) return error return None else: return error def send_notification_center(title: str, msg: str, notification_type: str, actions: Optional[Dict[str, str]] = None): """Send message to macOS Notification Center. Only 1 button is possible on macOS!""" logging.debug("Sending macOS notification") try: subtitle = T(NOTIFICATION_TYPES.get(notification_type, "other")) button_text = button_action = None if actions: for action in actions: button_text = NOTIFICATION_ACTIONS[action] button_action = actions[action] break sabnzbd.MACOSTRAY.send_notification(title, subtitle, msg, button_text, button_action) except: logging.info(T("Failed to send macOS notification")) logging.debug("Traceback: ", exc_info=True) return T("Failed to send macOS notification") def send_prowl(title, msg, notification_type, force=False, test=None): """Send message to Prowl""" logging.debug("Sending Prowl notification") if test: apikey = test.get("prowl_apikey") else: apikey = sabnzbd.cfg.prowl_apikey() if not apikey: return T("Cannot send, missing required data") title = T(NOTIFICATION_TYPES.get(notification_type, "other")) title = urllib.parse.quote(utob(title)) msg = urllib.parse.quote(utob(msg)) prio = get_prio(notification_type, "prowl") if force: prio = 0 if prio > -3: url = ( "https://api.prowlapp.com/publicapi/add?apikey=%s&application=SABnzbd" "&event=%s&description=%s&priority=%d" % (apikey, title, msg, prio) ) try: urllib.request.urlopen(url) return "" except: logging.warning(T("Failed to send Prowl message")) logging.info("Traceback: ", exc_info=True) return T("Failed to send Prowl message") return "" def send_apprise(title, msg, notification_type, force=False, test=None): """send apprise message""" logging.debug("Sending Apprise notification") if test: urls = test.get("apprise_urls") else: urls = sabnzbd.cfg.apprise_urls() # Notification mapper n_map = { # Startup/Shutdown "startup": apprise.common.NotifyType.INFO, # Pause/Resume "pause_resume": apprise.common.NotifyType.INFO, # Added NZB "download": apprise.common.NotifyType.INFO, # Post-processing started "pp": apprise.common.NotifyType.INFO, # Job finished "complete": apprise.common.NotifyType.SUCCESS, # Job failed "failed": apprise.common.NotifyType.FAILURE, # Warning "warning": apprise.common.NotifyType.WARNING, # Error "error": apprise.common.NotifyType.FAILURE, # Disk full "disk_full": apprise.common.NotifyType.WARNING, # Queue finished "queue_done": apprise.common.NotifyType.INFO, # User logged in "new_login": apprise.common.NotifyType.INFO, # Other Messages "other": apprise.common.NotifyType.INFO, } # Prepare our Asset Object asset = apprise.AppriseAsset( app_id="SABnzbd", app_desc="SABnzbd Notification", app_url="https://sabnzbd.org/", image_url_logo="https://sabnzbd.org/images/icons/apple-touch-icon-180x180-precomposed.png", ) # Initialize our Apprise Instance apobj = apprise.Apprise(asset=asset) if not test: # Get a list of tags that are set to use the common list if target := get_targets(notification_type, "apprise"): if target is True: if not urls: # Nothing to notify logging.warning(T("Failed to send Apprise message - no URLs defined")) return "" # Use default list apobj.add(urls) elif not apobj.add(target): # Target is string of URLs to over-ride with # Store our URL and assign our key logging.warning("%s - %s", notification_type, T("One or more Apprise URLs could not be loaded.")) else: # Nothing to notify return "" else: # Use default list apobj.add(urls) try: # The below notifies anything added to our list if not apobj.notify( body=msg, title=title, notify_type=n_map[notification_type], body_format=apprise.NotifyFormat.TEXT, ): return T("Failed to send one or more Apprise Notifications") except: logging.warning(T("Failed to send Apprise message")) logging.info("Traceback: ", exc_info=True) return T("Failed to send Apprise message") return "" def send_pushover(title, msg, notification_type, force=False, test=None): """Send message to pushover""" logging.debug("Sending Pushover notification") if test: apikey = test.get("pushover_token") userkey = test.get("pushover_userkey") device = test.get("pushover_device") else: apikey = sabnzbd.cfg.pushover_token() userkey = sabnzbd.cfg.pushover_userkey() device = sabnzbd.cfg.pushover_device() emergency_retry = sabnzbd.cfg.pushover_emergency_retry() emergency_expire = sabnzbd.cfg.pushover_emergency_expire() if not apikey or not userkey: return T("Cannot send, missing required data") title = T(NOTIFICATION_TYPES.get(notification_type, "other")) prio = get_prio(notification_type, "pushover") if force: prio = 1 if prio == 2: body = { "token": apikey, "user": userkey, "device": device, "title": title, "message": msg, "priority": prio, "retry": emergency_retry, "expire": emergency_expire, } return do_send_pushover(body) if -3 < prio < 2: body = { "token": apikey, "user": userkey, "device": device, "title": title, "message": msg, "priority": prio, } return do_send_pushover(body) def do_send_pushover(body): try: conn = http.client.HTTPSConnection("api.pushover.net:443") conn.request( "POST", "/1/messages.json", urllib.parse.urlencode(body), {"Content-type": "application/x-www-form-urlencoded"}, ) res = conn.getresponse() if res.status != 200: logging.error(T("Bad response from Pushover (%s): %s"), res.status, res.read()) return T("Failed to send pushover message") else: return "" except: logging.warning(T("Failed to send pushover message")) logging.info("Traceback: ", exc_info=True) return T("Failed to send pushover message") def send_pushbullet(title, msg, notification_type, force=False, test=None): """Send message to Pushbullet""" logging.debug("Sending Pushbullet notification") if test: apikey = test.get("pushbullet_apikey") device = test.get("pushbullet_device") else: apikey = sabnzbd.cfg.pushbullet_apikey() device = sabnzbd.cfg.pushbullet_device() if not apikey: return T("Cannot send, missing required data") title = "SABnzbd: " + T(NOTIFICATION_TYPES.get(notification_type, "other")) try: conn = http.client.HTTPSConnection("api.pushbullet.com:443") conn.request( "POST", "/v2/pushes", json.dumps({"type": "note", "device": device, "title": title, "body": msg}), headers={"Authorization": "Bearer " + apikey, "Content-type": "application/json"}, ) res = conn.getresponse() if res.status != 200: logging.error(T("Bad response from Pushbullet (%s): %s"), res.status, res.read()) else: logging.info("Successfully sent to Pushbullet") except: logging.warning(T("Failed to send pushbullet message")) logging.info("Traceback: ", exc_info=True) return T("Failed to send pushbullet message") return "" def send_nscript(title, msg, notification_type, force=False, test=None): """Run user's notification script""" logging.debug("Sending notification script notification") if test: script = test.get("nscript_script") env_params = {"notification_parameters": test.get("nscript_parameters")} else: script = sabnzbd.cfg.nscript_script() env_params = {"notification_parameters": sabnzbd.cfg.nscript_parameters()} if not script: return T("Cannot send, missing required data") title = "SABnzbd: " + T(NOTIFICATION_TYPES.get(notification_type, "other")) if force or check_classes(notification_type, "nscript"): script_path = make_script_path(script) if script_path: ret = -1 output = None try: p = build_and_run_command( [ script_path, notification_type, title, msg, ], env=create_env(extra_env_fields=env_params), ) output = p.stdout.read() ret = p.wait() except: logging.info("Failed to run script %s", script, exc_info=True) if ret: logging.error(T('Script returned exit code %s and output "%s"'), ret, output) return T('Script returned exit code %s and output "%s"') % (ret, output) else: logging.info("Successfully executed notification script %s", script_path) logging.debug("Script output: %s", output) else: return T('Notification script "%s" does not exist') % script_path return "" def send_windows(title: str, msg: str, notification_type: str, actions: Optional[Dict[str, str]] = None): """Send Windows notifications, either fancy with buttons (Windows 10+) or basic ones""" # Skip any notifications if ran as a Windows Service, it can result in crashes if sabnzbd.WIN_SERVICE: return None logging.debug("Sending Windows notification") try: if _HAVE_WINDOWS_TOASTER: notification_sender = InteractableWindowsToaster("SABnzbd", notifierAUMID="SABnzbd") toast_notification = Toast([title, msg], group=notification_type, launch_action=sabnzbd.BROWSER_URL) # Add any buttons if actions: for action in actions: toast_notification.AddAction(ToastButton(NOTIFICATION_ACTIONS[action], launch=actions[action])) notification_sender.show_toast(toast_notification) elif sabnzbd.WINTRAY and not sabnzbd.WINTRAY.terminate: sabnzbd.WINTRAY.sendnotification(title, msg) except: logging.info(T("Failed to send Windows notification")) logging.debug("Traceback: ", exc_info=True) return T("Failed to send Windows notification") return None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4469404 SABnzbd-4.3.2/sabnzbd/database.py0000644000000000000000000005556314625637243016002 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.database - Database Support """ import os import time import zlib import logging import sys import threading import sqlite3 from sqlite3 import Connection, Cursor from typing import Optional, List, Sequence, Dict, Any, Tuple, Union import sabnzbd import sabnzbd.cfg from sabnzbd.constants import DB_HISTORY_NAME, STAGES, Status, PP_LOOKUP from sabnzbd.bpsmeter import this_week, this_month from sabnzbd.decorators import synchronized from sabnzbd.encoding import ubtou, utob from sabnzbd.misc import int_conv, caller_name, opts_to_pp, to_units from sabnzbd.filesystem import remove_file, clip_path DB_LOCK = threading.Lock() class HistoryDB: """Class to access the History database Each class-instance will create an access channel that can be used in one thread. Each thread needs its own class-instance! """ # These class attributes will be accessed directly because # they need to be shared by all instances db_path = None # Full path to history database startup_done = False @synchronized(DB_LOCK) def __init__(self): """Determine database path and create connection""" self.connection: Optional[Connection] = None self.cursor: Optional[Cursor] = None self.connect() def connect(self): """Create a connection to the database""" if not HistoryDB.db_path: HistoryDB.db_path = os.path.join(sabnzbd.cfg.admin_dir.get_path(), DB_HISTORY_NAME) create_table = not HistoryDB.startup_done and not os.path.exists(HistoryDB.db_path) self.connection = sqlite3.connect(HistoryDB.db_path) self.connection.isolation_level = None # autocommit attribute only introduced in Python 3.12 self.connection.row_factory = sqlite3.Row self.cursor = self.connection.cursor() # Perform initialization only once if not HistoryDB.startup_done: if create_table: self.create_history_db() # When an object (table, index, or trigger) is dropped from the database, it leaves behind empty space # http://www.sqlite.org/lang_vacuum.html self.execute("VACUUM") # See if we need to perform any updates self.execute("PRAGMA user_version;") try: version = self.cursor.fetchone()["user_version"] except (IndexError, TypeError): version = 0 # Add any new columns added since last DB version # Use "and" to stop when database has been reset due to corruption if version < 1: _ = ( self.execute("PRAGMA user_version = 1;") and self.execute("ALTER TABLE history ADD COLUMN series TEXT;") and self.execute("ALTER TABLE history ADD COLUMN md5sum TEXT;") ) if version < 2: _ = self.execute("PRAGMA user_version = 2;") and self.execute( "ALTER TABLE history ADD COLUMN password TEXT;" ) if version < 3: # Transfer data to new column (requires WHERE-hack), original column should be removed later _ = ( self.execute("PRAGMA user_version = 3;") and self.execute("ALTER TABLE history ADD COLUMN duplicate_key TEXT;") and self.execute("UPDATE history SET duplicate_key = series WHERE 1 = 1;") ) if version < 4: _ = self.execute("PRAGMA user_version = 4;") and self.execute( "ALTER TABLE history ADD COLUMN archive INTEGER;" ) HistoryDB.startup_done = True def execute(self, command: str, args: Sequence = ()) -> bool: """Wrapper for executing SQL commands""" for tries in (4, 3, 2, 1, 0): try: self.cursor.execute(command, args) return True except: error = str(sys.exc_info()[1]) if tries > 0 and "is locked" in error: logging.debug("Database locked, wait and retry") time.sleep(0.5) continue elif "readonly" in error: logging.error(T("Cannot write to History database, check access rights!")) # Report back success, because there's no recovery possible return True elif "not a database" in error or "malformed" in error or "duplicate column name" in error: logging.error(T("Damaged History database, created empty replacement")) logging.info("Traceback: ", exc_info=True) self.close() try: remove_file(HistoryDB.db_path) except: pass HistoryDB.startup_done = False self.connect() # Return False in case of "duplicate column" error # because the column addition in connect() must be terminated return "duplicate column name" not in error else: logging.error(T("SQL Command Failed, see log")) logging.info("SQL: %s", command) logging.info("Arguments: %s", repr(args)) logging.info("Traceback: ", exc_info=True) try: self.connection.rollback() except: # Can fail in case of automatic rollback logging.debug("Rollback Failed:", exc_info=True) return False def create_history_db(self): """Create a new (empty) database file""" self.execute( """ CREATE TABLE history ( "id" INTEGER PRIMARY KEY, "completed" INTEGER NOT NULL, "name" TEXT NOT NULL, "nzb_name" TEXT NOT NULL, "category" TEXT, "pp" TEXT, "script" TEXT, "report" TEXT, "url" TEXT, "status" TEXT, "nzo_id" TEXT, "storage" TEXT, "path" TEXT, "script_log" BLOB, "script_line" TEXT, "download_time" INTEGER, "postproc_time" INTEGER, "stage_log" TEXT, "downloaded" INTEGER, "completeness" INTEGER, "fail_message" TEXT, "url_info" TEXT, "bytes" INTEGER, "meta" TEXT, "series" TEXT, "md5sum" TEXT, "password" TEXT, "duplicate_key" TEXT, "archive" INTEGER ) """ ) self.execute("PRAGMA user_version = 4;") def close(self): """Close database connection""" try: self.cursor.close() self.connection.close() except: logging.error(T("Failed to close database, see log")) logging.info("Traceback: ", exc_info=True) def archive(self, job: str): """Move job to the archive""" self.execute("""UPDATE history SET archive = 1 WHERE nzo_id = ?""", (job,)) logging.info("[%s] Moved job %s to archive", caller_name(), job) def remove(self, job: str): """Permanently remove job from the history""" self.execute("""DELETE FROM history WHERE nzo_id = ?""", (job,)) logging.info("[%s] Removing job %s from history", caller_name(), job) def archive_with_status(self, status: str, search: Optional[str] = None): """Archive all jobs with a specific status, optional with `search` pattern""" search = convert_search(search) logging.info("Archiving all jobs with status=%s", status) self.execute( """UPDATE history SET archive = 1 WHERE archive IS NULL AND name LIKE ? AND status = ?""", (search, status), ) def remove_with_status(self, status: str, search: Optional[str] = None): """Remove all jobs from the database with a specific status, optional with `search` pattern""" search = convert_search(search) logging.info("Removing all jobs with status=%s", status) self.execute("""DELETE FROM history WHERE name LIKE ? AND status = ?""", (search, status)) def get_failed_paths(self, search: Optional[str] = None) -> List[str]: """Return list of all storage paths of failed jobs (may contain non-existing or empty paths)""" search = convert_search(search) fetch_ok = self.execute( """SELECT path FROM history WHERE name LIKE ? AND status = ?""", (search, Status.FAILED) ) if fetch_ok: return [item["path"] for item in self.cursor.fetchall()] else: return [] def auto_history_purge(self): """Archive or remove history items based on the configured history-retention""" history_retention_option = sabnzbd.cfg.history_retention_option() to_keep = sabnzbd.cfg.history_retention_number() if history_retention_option == "all": return elif history_retention_option == "number-archive": # Archive if more than X jobs logging.info("Archiving all but last %s completed jobs", to_keep) self.execute( """UPDATE history SET archive = 1 WHERE status = ? AND archive IS NULL AND id NOT IN ( SELECT id FROM history WHERE status = ? AND archive IS NULL ORDER BY completed DESC LIMIT ? )""", (Status.COMPLETED, Status.COMPLETED, to_keep), ) elif history_retention_option == "number-delete": # Delete if more than X jobs logging.info("Removing all but last %s completed jobs from history", to_keep) self.execute( """DELETE FROM history WHERE status = ? AND id NOT IN ( SELECT id FROM history WHERE status = ? ORDER BY completed DESC LIMIT ? )""", (Status.COMPLETED, Status.COMPLETED, to_keep), ) elif history_retention_option == "days-archive": # Archive jobs older dan X days seconds_to_keep = int(time.time()) - to_keep * 86400 logging.info("Archiving completed jobs older than %s days from history", to_keep) self.execute( """UPDATE history SET archive = 1 WHERE status = ? AND archive IS NULL AND completed < ?""", (Status.COMPLETED, seconds_to_keep), ) elif history_retention_option == "days-delete": # Delete jobs older dan X days seconds_to_keep = int(time.time()) - to_keep * 86400 logging.info("Removing completed jobs older than %s days from history", to_keep) self.execute( """DELETE FROM history WHERE status = ? AND completed < ?""", (Status.COMPLETED, seconds_to_keep), ) elif history_retention_option == "all-archive": # Archive all non-failed ones self.archive_with_status(Status.COMPLETED) elif history_retention_option == "all-delete": # Delete all non-failed ones self.remove_with_status(Status.COMPLETED) def add_history_db(self, nzo, storage: str, postproc_time: int, script_output: str, script_line: str): """Add a new job entry to the database""" t = build_history_info(nzo, storage, postproc_time, script_output, script_line) self.execute( """INSERT INTO history (completed, name, nzb_name, category, pp, script, report, url, status, nzo_id, storage, path, script_log, script_line, download_time, postproc_time, stage_log, downloaded, fail_message, url_info, bytes, duplicate_key, md5sum, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", t, ) logging.info("Added job %s to history", nzo.final_name) def fetch_history( self, start: Optional[int] = None, limit: Optional[int] = None, archive: Optional[bool] = None, search: Optional[str] = None, categories: Optional[List[str]] = None, statuses: Optional[List[str]] = None, nzo_ids: Optional[List[str]] = None, ) -> Tuple[List[Dict[str, Any]], int]: """Return records for specified jobs""" command_args = [convert_search(search)] post = "" if archive: post += " AND archive = 1" else: post += " AND archive IS NULL" if categories: categories = ["*" if c == "Default" else c for c in categories] post += " AND (category = ?" post += " OR category = ? " * (len(categories) - 1) post += ")" command_args.extend(categories) if statuses: post += " AND (status = ?" post += " OR status = ? " * (len(statuses) - 1) post += ")" command_args.extend(statuses) if nzo_ids: post += " AND (nzo_id = ?" post += " OR nzo_id = ? " * (len(nzo_ids) - 1) post += ")" command_args.extend(nzo_ids) cmd = "SELECT COUNT(*) FROM history WHERE name LIKE ?" total_items = -1 if self.execute(cmd + post, command_args): total_items = self.cursor.fetchone()["COUNT(*)"] if not start: start = 0 if not limit: limit = total_items command_args.extend([start, limit]) cmd = "SELECT * FROM history WHERE name LIKE ?" if self.execute(cmd + post + " ORDER BY completed desc LIMIT ?, ?", command_args): items = self.cursor.fetchall() else: items = [] # Unpack the single line stage log # Stage Name is separated by ::: stage lines by ; and stages by \r\n items = [unpack_history_info(item) for item in items] return items, total_items def have_duplicate_key(self, duplicate_key: str) -> bool: """Check whether History contains this duplicate key""" total = 0 if self.execute( """ SELECT COUNT(*) FROM History WHERE duplicate_key = ? AND STATUS != ?""", (duplicate_key, Status.FAILED), ): total = self.cursor.fetchone()["COUNT(*)"] return total > 0 def have_name_or_md5sum(self, name: str, md5sum: str) -> bool: """Check whether this name or md5sum is already in History""" total = 0 if self.execute( """ SELECT COUNT(*) FROM History WHERE ( LOWER(name) = LOWER(?) OR md5sum = ? ) AND STATUS != ?""", (name, md5sum, Status.FAILED), ): total = self.cursor.fetchone()["COUNT(*)"] return total > 0 def get_history_size(self) -> Tuple[int, int, int]: """Returns the total size of the history and amounts downloaded in the last month and week """ # Total Size of the history total = 0 if self.execute("""SELECT sum(bytes) FROM history"""): total = self.cursor.fetchone()["sum(bytes)"] # Amount downloaded this month month_timest = int(this_month(time.time())) month = 0 if self.execute("""SELECT sum(bytes) FROM history WHERE completed > ?""", (month_timest,)): month = self.cursor.fetchone()["sum(bytes)"] # Amount downloaded this week week_timest = int(this_week(time.time())) week = 0 if self.execute("""SELECT sum(bytes) FROM history WHERE completed > ?""", (week_timest,)): week = self.cursor.fetchone()["sum(bytes)"] return total, month, week def get_script_log(self, nzo_id: str) -> str: """Return decompressed log file""" data = "" if self.execute("""SELECT script_log FROM history WHERE nzo_id = ?""", (nzo_id,)): try: data = ubtou(zlib.decompress(self.cursor.fetchone()["script_log"])) except: pass return data def get_name(self, nzo_id: str) -> str: """Return name of the job `nzo_id`""" name = "" if self.execute("""SELECT name FROM history WHERE nzo_id = ?""", (nzo_id,)): try: return self.cursor.fetchone()["name"] except TypeError: # No records found pass return name def get_incomplete_path(self, nzo_id: str) -> str: """Return the `incomplete` path of the job `nzo_id` if the job failed and if the path is still there""" path = "" if self.execute("""SELECT path FROM history WHERE nzo_id = ? AND status = ?""", (nzo_id, Status.FAILED)): try: path = self.cursor.fetchone()["path"] except TypeError: # No records found pass if os.path.exists(path): return path return path def get_other(self, nzo_id: str) -> Tuple[str, str, str, str, str]: """Return additional data for job `nzo_id`""" if self.execute("""SELECT * FROM history WHERE nzo_id = ?""", (nzo_id,)): try: item = self.cursor.fetchone() return item["report"], item["url"], item["pp"], item["script"], item["category"] except TypeError: # No records found pass return "", "", "", "", "" def __enter__(self): """For context manager support""" return self def __exit__(self, exc_type, exc_val, exc_tb): """For context manager support, ignore any exception""" self.close() def convert_search(search: str) -> str: """Convert classic wildcard to SQL wildcard""" if not search or not isinstance(search, str): # Default value search = "" else: # Allow * for wildcard matching and space search = search.replace("*", "%").replace(" ", "%") # Allow ^ for start of string and $ for end of string if search and search.startswith("^"): search = search.replace("^", "") search += "%" elif search and search.endswith("$"): search = search.replace("$", "") search = "%" + search else: search = "%" + search + "%" return search def build_history_info(nzo, workdir_complete: str, postproc_time: int, script_output: str, script_line: str): """Collects all the information needed for the database""" nzo: sabnzbd.nzbstuff.NzbObject completed = int(time.time()) pp = PP_LOOKUP.get(opts_to_pp(nzo.repair, nzo.unpack, nzo.delete), "X") if script_output: # Compress the output of the script script_output = sqlite3.Binary(zlib.compress(utob(script_output))) download_time = nzo.nzo_info.get("download_time", 0) url_info = nzo.nzo_info.get("details", "") or nzo.nzo_info.get("more_info", "") # Get the dictionary containing the stages and their unpack process # Pack the dictionary up into a single string # Stage Name is separated by ::: stage lines by ; and stages by \r\n lines = [] for key, results in nzo.unpack_info.items(): lines.append("%s:::%s" % (key, ";".join(results))) stage_log = "\r\n".join(lines) # Reuse the old 'report' column to indicate a URL-fetch report = "future" if nzo.futuretype else "" # Make sure we have the duplicate key nzo.set_duplicate_key() return ( completed, nzo.final_name, nzo.filename, nzo.cat, pp, nzo.script, report, nzo.url, nzo.status, nzo.nzo_id, clip_path(workdir_complete), clip_path(nzo.download_path), script_output, script_line, download_time, postproc_time, stage_log, nzo.bytes_downloaded, nzo.fail_msg, url_info, nzo.bytes_downloaded, nzo.duplicate_key, nzo.md5sum, nzo.correct_password, ) def unpack_history_info(item: sqlite3.Row) -> Dict[str, Any]: """Expands the single line stage_log from the DB into a python dictionary for use in the history display """ # Convert result to dictionary item = dict(item) # Stage Name is separated by ::: stage lines by ; and stages by \r\n lst = item["stage_log"] if lst: parsed_stage_log = [] try: all_stages_lines = lst.split("\r\n") except: logging.warning(T("Invalid stage logging in history for %s"), item["name"]) logging.debug("Lines: %s", lst) all_stages_lines = [] for stage_lines in all_stages_lines: try: key, logs = stage_lines.split(":::") except: logging.info('Missing key:::logs "%s"', stage_lines) continue stage = {"name": key, "actions": []} try: stage["actions"] = logs.split(";") except: logging.warning(T("Invalid stage logging in history for %s"), item["name"]) logging.debug("Logs: %s", logs) parsed_stage_log.append(stage) # Sort it so it is more logical parsed_stage_log.sort(key=lambda stage_log: STAGES.get(stage_log["name"], 100)) item["stage_log"] = parsed_stage_log else: item["stage_log"] = [] # Remove database id item.pop("id") # Human-readable size item["size"] = to_units(item["bytes"], "B") # We do not want the raw script output here item.pop("script_log") # The action line and loaded is only available for items in the postproc queue item["action_line"] = "" item["loaded"] = False item["archive"] = bool(item["archive"]) # Retry and retry for failed URL-fetch item["retry"] = int_conv(item["status"] == Status.FAILED and item["path"] and os.path.exists(item["path"])) if item["report"] == "future": item["retry"] = True return item def scheduled_history_purge(): logging.info("Scheduled history purge") with HistoryDB() as history_db: history_db.auto_history_purge() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4470344 SABnzbd-4.3.2/sabnzbd/filesystem.py0000644000000000000000000014364514625637243016421 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2008-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.misc - filesystem operations """ import gzip import os import pickle import sys import logging import logging.handlers import re import shutil import tempfile import threading import time import fnmatch import stat import ctypes import random import functools from typing import Union, List, Tuple, Any, Dict, Optional, BinaryIO try: import win32api import win32file import win32con except ImportError: pass import sabnzbd from sabnzbd.decorators import synchronized, cache_maintainer from sabnzbd.constants import FUTURE_Q_FOLDER, JOB_ADMIN, GIGI, DEF_FILE_MAX, IGNORED_FILES_AND_FOLDERS, DEF_LOG_FILE from sabnzbd.encoding import correct_unknown_encoding, utob, ubtou from sabnzbd.utils import rarfile # For Windows: determine executable extensions if os.name == "nt": PATHEXT = os.environ.get("PATHEXT", "").lower().split(";") else: PATHEXT = [] def get_ext(filename: str) -> str: """Return lowercased file extension""" try: return os.path.splitext(filename)[1].lower() except: return "" def get_basename(filename: str) -> str: """Shorthand for getting the basename of a filename""" return os.path.splitext(filename)[0] def is_listed_ext(ext: str, ext_list: list) -> bool: """Check if the extension is listed. In case of a regexp the entire extension must be matched; partial matches aren't accepted (e.g. 'r[0-9]{2}' will be treated the same as '^r[0-9]{2}$' and thus return false for extensions such as 'r007' despite the substring match on 'r00'). """ for item in ext_list: if RE_EXT := sabnzbd.misc.convert_filter(item): try: if len(RE_EXT.match(ext).group()) == len(ext): return True except Exception: pass elif item == ext: return True # No match found return False def has_unwanted_extension(filename: str) -> bool: """Determine if a filename has an unwanted extension, given the configured mode""" extension = get_ext(filename).replace(".", "") if extension and sabnzbd.cfg.unwanted_extensions(): return ( # Blacklisted sabnzbd.cfg.unwanted_extensions_mode() == 0 and is_listed_ext(extension, sabnzbd.cfg.unwanted_extensions()) ) or ( # Not whitelisted sabnzbd.cfg.unwanted_extensions_mode() == 1 and not is_listed_ext(extension, sabnzbd.cfg.unwanted_extensions()) ) else: # Don't consider missing extensions unwanted to prevent indiscriminate blocking of # obfuscated jobs in whitelist mode. If there is an extension but nothing listed as # (un)wanted, the result only depends on the configured mode. return bool(extension and sabnzbd.cfg.unwanted_extensions_mode()) def get_filename(path: str) -> str: """Return path without the file extension""" try: return os.path.split(path)[1] except: return "" def setname_from_path(path: str) -> str: """Get the setname from a path""" return get_basename(os.path.basename(path)) def is_writable(path: str) -> bool: """Return True is file is writable (also when non-existent)""" if os.path.isfile(path): return bool(os.stat(path).st_mode & stat.S_IWUSR) else: return True def is_size(filepath: str, size: int) -> bool: """Return True if filepath exists and is specified size""" try: return os.path.getsize(filepath) == size except: return False _DEVICES = ( "con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", ) def replace_win_devices(name: str) -> str: """Remove reserved Windows device names from a name. aux.txt ==> _aux.txt txt.aux ==> txt.aux """ if name: lname = name.lower() for dev in _DEVICES: if lname == dev or lname.startswith(dev + "."): name = "_" + name break # Remove special NTFS filename if lname.startswith("$mft"): name = name.replace("$", "S", 1) return name def has_win_device(filename: str) -> bool: """Return True if filename part contains forbidden name Before and after sanitizing """ filename = os.path.split(filename)[1].lower() for dev in _DEVICES: if filename == dev or filename.startswith(dev + ".") or filename.startswith("_" + dev + "."): return True return False CH_ILLEGAL = "\0/" CH_LEGAL = "_+" CH_ILLEGAL_WIN = '\\/<>?*|":' CH_LEGAL_WIN = "++{}!@#'-" for i in range(1, 32): CH_ILLEGAL_WIN += chr(i) CH_LEGAL_WIN += "_" def sanitize_filename(name: str) -> str: """Return filename with illegal chars converted to legal ones and with the par2 extension always in lowercase """ if not name: return name illegal = CH_ILLEGAL legal = CH_LEGAL if sabnzbd.WIN32 or sabnzbd.cfg.sanitize_safe(): # Remove all bad Windows chars too illegal += CH_ILLEGAL_WIN legal += CH_LEGAL_WIN if ":" in name and sabnzbd.MACOS: # Compensate for the foolish way par2 on macOS handles a colon character name = name[name.rfind(":") + 1 :] lst = [] for ch in name.strip(): if ch in illegal: ch = legal[illegal.find(ch)] lst.append(ch) name = "".join(lst) if sabnzbd.WIN32 or sabnzbd.cfg.sanitize_safe(): name = replace_win_devices(name) if not name: name = "unknown" # now split name into name, ext name, ext = os.path.splitext(name) # If filename is too long (more than DEF_FILE_MAX bytes), brute-force truncate it, # preserving the extension (max ext length 20) # Note: some filesystem can handle up to 255 UTF chars (which is more than 255 bytes) in the filename, # but we stay on the safe side: max DEF_FILE_MAX bytes try: if len(utob(name)) + len(utob(ext)) > DEF_FILE_MAX: logging.debug("Filename %s is too long, so truncating", name + ext) # Too long filenames are often caused by incorrect non-ascii chars, # so brute-force remove those non-ascii chars name = ubtou(name.encode("ascii", "ignore")) # Now it's plain ASCII, so no need for len(str.encode()) anymore; plain len() is enough if len(name) + len(ext) > DEF_FILE_MAX: # still too long, limit the extension maxextlength = 20 # max length of an extension if len(ext) > maxextlength: # allow first chars, including the starting dot ext = ext[:maxextlength] if len(name) + len(ext) > DEF_FILE_MAX: # Still too long, limit the basename name = name[: DEF_FILE_MAX - len(ext)] except UnicodeError: # Just in case of strange encoding problems, like #2714 pass lowext = ext.lower() if lowext == ".par2" and lowext != ext: ext = lowext return name + ext def sanitize_foldername(name: str) -> str: """Return foldername with dodgy chars converted to safe ones Remove any leading and trailing dot and space characters """ if not name: return name illegal = CH_ILLEGAL + ':"' legal = CH_LEGAL + "-'" if sabnzbd.WIN32 or sabnzbd.cfg.sanitize_safe(): # Remove all bad Windows chars too illegal += CH_ILLEGAL_WIN legal += CH_LEGAL_WIN lst = [] for ch in name.strip(): if ch in illegal: ch = legal[illegal.find(ch)] lst.append(ch) else: lst.append(ch) name = "".join(lst) if sabnzbd.WIN32 or sabnzbd.cfg.sanitize_safe(): name = replace_win_devices(name) if len(name) >= sabnzbd.cfg.max_foldername_length(): name = name[: sabnzbd.cfg.max_foldername_length()] # And finally, make sure it doesn't end in a dot or a space # This is invalid on Windows and can cause trouble for some other tools if name != "." and name != "..": while len(name) > len(name := name.strip().rstrip(".")): continue # Just to be sure we don't return nothing if not name: name = "unknown" return name def sanitize_and_trim_path(path: str) -> str: """Remove illegal characters and trim element size""" path = path.strip() new_path = "" if sabnzbd.WIN32: if path.startswith("\\\\?\\UNC\\"): new_path = "\\\\?\\UNC\\" path = path[8:] elif path.startswith("\\\\?\\"): new_path = "\\\\?\\" path = path[4:] path = path.replace("\\", "/") parts = path.split("/") if sabnzbd.WIN32 and len(parts[0]) == 2 and ":" in parts[0]: new_path += parts[0] + "/" parts.pop(0) elif path.startswith("//"): new_path = "//" elif path.startswith("/"): new_path = "/" for part in parts: new_path = os.path.join(new_path, sanitize_foldername(part)) return os.path.abspath(os.path.normpath(new_path)) def sanitize_files(folder: Optional[str] = None, filelist: Optional[List[str]] = None) -> List[str]: """Sanitize each file in the folder or list of filepaths, return list of new names""" logging.info("Checking if any resulting filenames need to be sanitized") if folder: filelist = listdir_full(folder) else: filelist = filelist or [] # Loop over all the files output_filelist = [] for old_path in filelist: # Will skip files if there's nothing to sanitize output_filelist.append(renamer(old_path, old_path)) return output_filelist def strip_extensions(name: str, ext_to_remove: Tuple[str, ...] = (".nzb", ".par", ".par2")): """Strip extensions from a filename, without sanitizing the filename""" name_base, ext = os.path.splitext(name) while ext.lower() in ext_to_remove: name = name_base name_base, ext = os.path.splitext(name) return name def real_path(loc: str, path: str) -> str: """When 'path' is relative, return normalized join of 'loc' and 'path' When 'path' is absolute, return normalized path A path starting with ~ will be located in the user's Home folder """ # The Windows part is a bit convoluted because # C: and C:\ are 2 different things if path: path = path.strip() else: path = "" if path: if not sabnzbd.WIN32 and path.startswith("~/"): path = path.replace("~", os.environ.get("HOME", sabnzbd.DIR_HOME), 1) if sabnzbd.WIN32: # The Windows-functions work differently on long-path # So we bring it back to normal and make it long-path at the end loc = clip_path(loc) path = path.replace("/", "\\") if len(path) > 1 and path[0].isalpha() and path[1] == ":": if len(path) == 2 or path[2] != "\\": path = path.replace(":", ":\\", 1) elif path.startswith("\\\\"): pass elif path.startswith("\\"): if len(loc) > 1 and loc[0].isalpha() and loc[1] == ":": path = loc[:2] + path else: path = os.path.join(loc, path) elif path[0] != "/": path = os.path.join(loc, path) else: path = loc return long_path(os.path.normpath(os.path.abspath(path))) def create_real_path( name: str, loc: str, path: str, apply_permissions: bool = False, writable: bool = True ) -> Tuple[bool, str, Optional[str]]: """When 'path' is relative, create join of 'loc' and 'path' When 'path' is absolute, create normalized path 'name' is used for logging. Optional 'umask' will be applied. 'writable' means that an existing folder should be writable Returns ('success', 'full path', 'error_msg') """ if path: my_dir = real_path(loc, path) if not os.path.exists(my_dir): if not create_all_dirs(my_dir, apply_permissions): msg = T("Cannot create directory %s") % clip_path(my_dir) logging.error(msg) return False, my_dir, msg checks = (os.W_OK + os.R_OK) if writable else os.R_OK if os.access(my_dir, checks): return True, my_dir, None else: msg = T("%s directory: %s error accessing") % (name, clip_path(my_dir)) logging.error(msg) return False, my_dir, msg else: return False, path, None def same_directory(a: str, b: str) -> int: """Return 0 if A and B have nothing in common return 1 if A and B are actually the same path return 2 if B is a sub-folder of A """ if sabnzbd.WIN32 or sabnzbd.MACOS: a = clip_path(a.lower()) b = clip_path(b.lower()) a = os.path.normpath(os.path.abspath(a)) b = os.path.normpath(os.path.abspath(b)) # Need to add seperator so /mnt/sabnzbd and /mnt/sabnzbd-data are not detected as equal # But only if it doesn't already end in a slash, for example C:\ if not a.endswith(os.sep): a = a + os.sep if not b.endswith(os.sep): b = b + os.sep # If it's the same file, it's also a sub-folder is_subfolder = 0 if b.startswith(a): is_subfolder = 2 try: # Only available on Linux if os.path.samefile(a, b) is True: return 1 return is_subfolder except: if int(a == b): return 1 else: return is_subfolder def is_network_path(path: str) -> bool: """Check weither a path is a network path. On Windows, use win32 functions to detect users that try to avoid this detection by using a mapped drive letter. We don't check on Linux for mnt or media, since those could also be used for internal drives.""" path = clip_path(path) if path.startswith(r"\\"): return True if sabnzbd.WIN32: drive_letter, _ = os.path.splitdrive(path) return win32file.GetDriveType(drive_letter) == win32file.DRIVE_REMOTE return False def mount_is_available(path: str) -> bool: """Return False if volume isn't mounted on Linux or macOS or the network path isn't available on Windows. Retry wait_ext_drive times with an interval of 1 sec. """ if sabnzbd.MACOS: m = re.search(r"^(/Volumes/[^/]+)", path, re.I) elif sabnzbd.WIN32: m = re.search(r"^([a-z]:\\)", path, re.I) else: m = re.search(r"^(/(?:mnt|media)/[^/]+)", path) if m: for n in range(sabnzbd.cfg.wait_ext_drive() or 1): if os.path.exists(m.group(1)): return True logging.debug("Waiting for %s to come online", m.group(1)) time.sleep(1) return not m RAR_RE = re.compile(r"\.(part\d*\.rar|rar|r\d\d|s\d\d|t\d\d|u\d\d|v\d\d|\d\d\d?\d)$", re.I) SPLITFILE_RE = re.compile(r"\.(\d\d\d?\d$)", re.I) SEVENZIP_RE = re.compile(r"\.(zip|7z)$", re.I) SEVENMULTI_RE = re.compile(r"\.7z\.\d+$", re.I) TS_RE = re.compile(r"\.(\d+)\.(ts$)", re.I) def build_filelists( workdir: Optional[str], workdir_complete: Optional[str] = None, check_both: bool = False, check_rar: bool = True ) -> Tuple[List[str], List[str], List[str], List[str]]: """Build filelists, if workdir_complete has files, ignore workdir. Optionally scan both directories. Optionally test content to establish RAR-ness """ sevens, joinables, rars, ts, filelist = ([], [], [], [], []) if workdir_complete: filelist.extend(listdir_full(workdir_complete)) if workdir and (not filelist or check_both): filelist.extend(listdir_full(workdir, recursive=False)) for file in filelist: # Extra check for rar (takes CPU/disk) file_is_rar = False if check_rar: file_is_rar = rarfile.is_rarfile(file) # Run through all the checks if SEVENZIP_RE.search(file) or SEVENMULTI_RE.search(file): # 7zip or zip files sevens.append(file) elif SPLITFILE_RE.search(file) and not file_is_rar: # Joinables, optional with RAR check joinables.append(file) elif RAR_RE.search(file): # RAR files rars.append(file) elif TS_RE.search(file): # TS split files ts.append(file) logging.debug("build_filelists(): joinables: %s", joinables) logging.debug("build_filelists(): rars: %s", rars) logging.debug("build_filelists(): 7zips: %s", sevens) logging.debug("build_filelists(): ts: %s", ts) return joinables, rars, sevens, ts def safe_fnmatch(f: str, pattern: str) -> bool: """fnmatch will fail if the pattern contains any of it's key characters, like [, ] or !. """ try: return fnmatch.fnmatch(f, pattern) except re.error: return False def globber(path: str, pattern: str = "*") -> List[str]: """Return matching base file/folder names in folder `path`""" # Cannot use glob.glob() because it doesn't support Windows long name notation if os.path.exists(path): return [f for f in os.listdir(path) if safe_fnmatch(f, pattern)] return [] def globber_full(path: str, pattern: str = "*") -> List[str]: """Return matching full file/folder names in folder `path`""" # Cannot use glob.glob() because it doesn't support Windows long name notation if os.path.exists(path): return [os.path.join(path, f) for f in os.listdir(path) if safe_fnmatch(f, pattern)] return [] def fix_unix_encoding(folder: str): """Fix bad name encoding for Unix systems This happens for example when files are created on Windows but unpacked/repaired on linux """ if not sabnzbd.WIN32 and not sabnzbd.MACOS: for root, dirs, files in os.walk(folder): for name in files: new_name = correct_unknown_encoding(name) if name != new_name: try: renamer(os.path.join(root, name), os.path.join(root, new_name)) except: logging.info("Cannot correct name of %s", os.path.join(root, name)) def is_valid_script(basename: str) -> bool: """Determine if 'basename' is a valid script""" return basename in list_scripts(default=False, none=False) def list_scripts(default: bool = False, none: bool = True) -> List[str]: """Return a list of script names, optionally with 'Default' added""" lst = [] path = sabnzbd.cfg.script_dir.get_path() if path and os.access(path, os.R_OK): for script in globber_full(path): if os.path.isfile(script): if ( ( sabnzbd.WIN32 and get_ext(script) in PATHEXT and not win32api.GetFileAttributes(script) & win32file.FILE_ATTRIBUTE_HIDDEN ) or script.endswith(".py") or (not sabnzbd.WIN32 and userxbit(script) and not os.path.basename(script).startswith(".")) ): lst.append(os.path.basename(script)) # Make sure capitalization is ignored to avoid strange results lst = sorted(lst, key=str.casefold) if none: lst.insert(0, "None") if default: lst.insert(0, "Default") return lst def make_script_path(script: str) -> Optional[str]: """Return full script path, if any valid script exists, else None""" script_path = None script_dir = sabnzbd.cfg.script_dir.get_path() if script_dir and script: if script.lower() not in ("none", "default") and is_valid_script(script): script_path = os.path.join(script_dir, script) if not os.path.exists(script_path): script_path = None else: # Paths to scripts should not be long-path notation script_path = clip_path(script_path) return script_path def get_admin_path(name: str, future: bool): """Return news-style full path to job-admin folder of names job or else the old cache path """ if future: return os.path.join(sabnzbd.cfg.admin_dir.get_path(), FUTURE_Q_FOLDER) else: return os.path.join(os.path.join(sabnzbd.cfg.download_dir.get_path(), name), JOB_ADMIN) def set_chmod(path: str, permissions: int, allow_failures: bool = False): """Set 'permissions' on 'path'""" try: logging.debug("Applying permissions %s (octal) to %s", oct(permissions), path) os.chmod(path, permissions) except: if not allow_failures and not sabnzbd.misc.match_str(path, IGNORED_FILES_AND_FOLDERS): logging.error(T("Cannot change permissions of %s"), clip_path(path)) logging.info("Traceback: ", exc_info=True) else: logging.debug("Could not change permissions of %s", path) def set_permissions(path: str, recursive: bool = True): """Give folder tree and its files their proper permissions""" if not sabnzbd.WIN32: if custom_permissions := sabnzbd.cfg.permissions(): # If user set permissions, parse them custom_permissions = int(custom_permissions, 8) if os.path.isdir(path): if recursive: # Parse the dir/file tree and set permissions for root, _, files in os.walk(path): if custom_permissions: set_chmod(root, custom_permissions) for name in files: removexbits(os.path.join(root, name), custom_permissions) elif custom_permissions: set_chmod(path, custom_permissions) else: removexbits(path, custom_permissions) UNWANTED_FILE_PERMISSIONS = stat.S_ISUID | stat.S_ISGID | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH def removexbits(path: str, custom_permissions: int = None): """Remove all the x-bits from files, respecting current or custom permissions""" if os.path.isfile(path): # Use custom permissions as base current_permissions = custom_permissions allow_failures = False if not custom_permissions: current_permissions = os.stat(path).st_mode # Allow failures if no custom permissions are set, changing permissions might not be supported allow_failures = True # Check if the file has any x-bits, no need to remove them otherwise if custom_permissions or current_permissions & UNWANTED_FILE_PERMISSIONS: # Mask out the X-bits set_chmod(path, current_permissions & ~UNWANTED_FILE_PERMISSIONS, allow_failures) def userxbit(path: str) -> bool: """Returns boolean if the x-bit for user is set on the given file. This is a workaround: os.access(filename, os.X_OK) does not work on certain mounted file systems. Does not work at all on Windows. """ # rwx rwx rwx # 876 543 210 # we want bit 6 from the right, counting from 0 userxbit = 1 << 6 # bit 6 rwxbits = os.stat(path)[0] # the first element of os.stat() is "mode" # do logical AND, check if it is not 0: xbitset = (rwxbits & userxbit) > 0 return xbitset def clip_path(path: str) -> str: r"""Remove \\?\ or \\?\UNC\ prefix from Windows path""" if sabnzbd.WIN32 and path and "?" in path: path = path.replace("\\\\?\\UNC\\", "\\\\", 1).replace("\\\\?\\", "", 1) return path def long_path(path: str) -> str: """For Windows, convert to long style path; others, return same path""" if sabnzbd.WIN32 and path and not path.startswith("\\\\?\\"): if path.startswith("\\\\"): # Special form for UNC paths path = path.replace("\\\\", "\\\\?\\UNC\\", 1) else: # Normal form for local paths path = "\\\\?\\" + path return path ############################################################################## # Locked directory operations to avoid problems with simultaneous add/remove ############################################################################## DIR_LOCK = threading.RLock() @synchronized(DIR_LOCK) def create_all_dirs(path: str, apply_permissions: bool = False) -> Union[str, bool]: """Create all required path elements and set permissions on all The apply_permissions argument is ignored on Windows Return path if elements could be made or exists """ try: logging.info("Creating directories: %s", path) if sabnzbd.WIN32: # On Windows it can fail on UNC-paths in long-path notation # https://bugs.python.org/issue41705 if not os.path.exists(path): os.makedirs(path) else: # We need to build the directory recursively, so we can # apply permissions to only the newly created folders # We cannot use os.makedirs() as it could ignore the mode path_part_combined = "/" for path_part in path.split("/"): if path_part: path_part_combined = os.path.join(path_part_combined, path_part) # Only create if it doesn't exist if not os.path.exists(path_part_combined): os.mkdir(path_part_combined) # Try to set permissions if desired, ignore failures if apply_permissions: set_permissions(path_part_combined, recursive=False) return path except OSError: logging.error(T("Failed making (%s)"), clip_path(path), exc_info=True) return False @synchronized(DIR_LOCK) def get_unique_dir(path: str, n: int = 0, create_dir: bool = True) -> Union[str, bool]: """Determine a unique folder or filename""" if not mount_is_available(path): return path new_path = path if n: new_path = "%s.%s" % (path, n) if not os.path.exists(new_path): if create_dir: return create_all_dirs(new_path, apply_permissions=True) else: return new_path else: return get_unique_dir(path, n=n + 1, create_dir=create_dir) @synchronized(DIR_LOCK) def get_unique_filename(path: str) -> str: """Check if path is unique. If not, add number like: "/path/name.NUM.ext". """ num = 1 new_path, filename = os.path.split(path) name, ext = os.path.splitext(filename) while os.path.exists(path): filename = "%s.%d%s" % (name, num, ext) num += 1 path = os.path.join(new_path, filename) return path @synchronized(DIR_LOCK) def listdir_full(input_dir: str, recursive: bool = True) -> List[str]: """List all files in dirs and sub-dirs""" filelist = [] for root, dirs, files in os.walk(input_dir): for file in files: # Ignore special folders and resources files created by macOS if not sabnzbd.misc.match_str(root, IGNORED_FILES_AND_FOLDERS) and not file.startswith("._"): filelist.append(os.path.join(root, file)) if not recursive: break return filelist @synchronized(DIR_LOCK) def move_to_path(path: str, new_path: str) -> Tuple[bool, Optional[str]]: """Move a file to a new path, optionally give unique filename Return (ok, new_path) """ ok = True overwrite = sabnzbd.cfg.overwrite_files() new_path = os.path.abspath(new_path) new_path_dir = os.path.dirname(new_path) if overwrite and os.path.exists(new_path): try: os.remove(new_path) except: overwrite = False if not overwrite: new_path = get_unique_filename(new_path) if new_path: logging.debug("Moving (overwrite: %s) %s => %s", overwrite, path, new_path) if not os.path.exists(new_path_dir): create_all_dirs(os.path.dirname(new_path), apply_permissions=True) try: # First try cheap rename renamer(path, new_path) except Exception as err: # Cannot rename, try copying logging.debug("File could not be renamed (error: %s), trying copying: %s", err, path) try: shutil.copyfile(path, new_path) os.remove(path) except: # Check if the old-file actually exists (possible delete-delays) if not os.path.exists(path): logging.debug("File not moved, original path gone: %s", path) return True, None if not (sabnzbd.cfg.marker_file() and sabnzbd.cfg.marker_file() in path): logging.error(T("Failed moving %s to %s"), clip_path(path), clip_path(new_path)) logging.info("Traceback: ", exc_info=True) ok = False return ok, new_path @synchronized(DIR_LOCK) def cleanup_empty_directories(path: str): """Remove all empty folders inside (and including) 'path'""" path = os.path.normpath(path) while 1: repeat = False for root, dirs, files in os.walk(path, topdown=False): if not dirs and not files and root != path: try: remove_dir(root) repeat = True except: pass if not repeat: break # Only remove if main folder is now also empty if not os.listdir(path): try: remove_dir(path) except: pass @synchronized(DIR_LOCK) def renamer(old: str, new: str, create_local_directories: bool = False) -> str: """Rename file/folder with retries for Win32 Optionally allows the creation of local directories if they don't exist yet Returns new filename (which could be changed due to sanitize_filename) on success""" # Sanitize last part of new name, just to be sure path, name = os.path.split(new) if os.path.isdir(old): name = sanitize_foldername(name) else: name = sanitize_filename(name) new = os.path.join(path, name) # Skip if nothing changes if old == new: return new # In case we want nonexistent directories to be created, check for directory escape (forbidden) if create_local_directories: oldpath, _ = os.path.split(old) # Check not outside directory # In case of "same_file() == 1": same directory, so nothing to do if same_directory(oldpath, path) == 0: # Outside current directory, this is most likely malicious logging.error(T("Blocked attempt to create directory %s"), path) raise OSError("Refusing to go outside directory") elif same_directory(oldpath, path) == 2: # Sub-directory, so create if does not yet exist: create_all_dirs(path) logging.debug('Renaming "%s" to "%s"', old, new) if sabnzbd.WIN32: retries = 10 while retries > 0: try: # First we try 3 times with os.rename if retries > 7: os.rename(old, new) else: # Now we try the back-up method logging.debug("Could not rename, trying move for %s to %s", old, new) shutil.move(old, new) return new except OSError as err: logging.debug('Error renaming "%s" to "%s" <%s>', old, new, err) if err.winerror == 17: # Error 17 - Rename can't move to different disk # Jump to moving with shutil.move retries -= 3 elif err.winerror == 32 or err.winerror == 5: # Error 32 - Used by another process # Error 5 - Access is denied (virus scanners) logging.debug("File busy, retrying rename %s to %s", old, new) retries -= 1 # Wait for the other process time.sleep(2) else: raise raise OSError("Failed to rename (Winerr %s)" % hex(ctypes.windll.ntdll.RtlGetLastNtStatus() + 2**32)) else: shutil.move(old, new) return new def remove_file(path: str): """Wrapper function so any file removal is logged""" logging.debug("[%s] Deleting file %s", sabnzbd.misc.caller_name(), path) os.remove(path) @synchronized(DIR_LOCK) def remove_dir(path: str): """Remove directory with retries for Win32""" logging.debug("[%s] Removing dir %s", sabnzbd.misc.caller_name(), path) if sabnzbd.WIN32: retries = 15 while retries > 0: try: os.rmdir(path) return except OSError as err: # In use by another process if err.winerror == 32: logging.debug("Retry delete %s", path) retries -= 1 else: raise time.sleep(3) raise OSError("Failed to remove") else: os.rmdir(path) @synchronized(DIR_LOCK) def remove_all(path: str, pattern: str = "*", keep_folder: bool = False, recursive: bool = False): """Remove folder and all its content (optionally recursive)""" if path and os.path.exists(path): # Fast-remove the whole tree if recursive if pattern == "*" and not keep_folder and recursive: logging.debug("Removing dir recursively %s", path) try: shutil.rmtree(path) except: logging.info("Cannot remove folder %s", path, exc_info=True) else: # Get files based on pattern files = globber_full(path, pattern) if pattern == "*" and not sabnzbd.WIN32: files.extend(globber_full(path, ".*")) for f in files: if os.path.isfile(f): try: remove_file(f) except: logging.info("Cannot remove file %s", f, exc_info=True) elif recursive: remove_all(f, pattern, False, True) if not keep_folder: try: remove_dir(path) except: logging.info("Cannot remove folder %s", path, exc_info=True) ############################################################################## # Diskfree ############################################################################## def disk_free_macos_clib_statfs64(directory: str) -> Tuple[int, int]: # MacOS only! # direct system call to c-lib's statfs(), not python's os.statvfs() # because statvfs() on MacOS has a rollover at 4TB (possibly a 32bit rollover with 10bit block size) # See https://bugs.python.org/issue43638 # Based on code of pudquick and blackntan # Input: directory. # Output: disksize and available space, in bytes # format & parameters: on MacOS, see "man statfs", lines starting at # "struct statfs { /* when _DARWIN_FEATURE_64_BIT_INODE is defined */" class statfs64(ctypes.Structure): _fields_ = [ ("f_bsize", ctypes.c_uint32), ("f_iosize", ctypes.c_int32), ("f_blocks", ctypes.c_uint64), ("f_bfree", ctypes.c_uint64), ("f_bavail", ctypes.c_uint64), ("f_files", ctypes.c_uint64), ("f_ffree", ctypes.c_uint64), ("f_fsid", ctypes.c_uint64), ("f_owner", ctypes.c_uint32), ("f_type", ctypes.c_uint32), ("f_flags", ctypes.c_uint32), ("f_fssubtype", ctypes.c_uint32), ("f_fstypename", ctypes.c_char * 16), ("f_mntonname", ctypes.c_char * 1024), ("f_mntfromname", ctypes.c_char * 1024), ("f_reserved", ctypes.c_uint32 * 8), ] fs_info64 = statfs64() # set up the parameters to be filled out result = sabnzbd.MACOSLIBC.statfs64( ctypes.create_string_buffer(utob(directory)), ctypes.byref(fs_info64) ) # fs_info64 gets filled out via the byref() if result == 0: # result = 0: "Upon successful completion, a value of 0 is returned." return fs_info64.f_blocks * fs_info64.f_bsize, fs_info64.f_bavail * fs_info64.f_bsize else: # result = -1: "Otherwise, -1 is returned and the global variable errno is set to indicate the error." logging.debug("Call to MACOSLIBC.statfs64 not successful. Value of errno is %s", ctypes.get_errno()) return 0, 0 def diskspace_base(dir_to_check: str) -> Tuple[float, float]: """Return amount of free and used diskspace in GBytes""" # Find first folder level that exists in the path x = "x" while x and not os.path.exists(dir_to_check): dir_to_check, x = os.path.split(dir_to_check) if sabnzbd.WIN32: # windows diskfree try: available, disk_size, total_free = win32api.GetDiskFreeSpaceEx(dir_to_check) return disk_size / GIGI, available / GIGI except: return 0.0, 0.0 elif sabnzbd.MACOS: # MacOS diskfree ... via c-lib call statfs() disk_size, available = disk_free_macos_clib_statfs64(dir_to_check) return disk_size / GIGI, available / GIGI elif hasattr(os, "statvfs"): # posix diskfree try: s = os.statvfs(dir_to_check) if s.f_blocks < 0: disk_size = float(sys.maxsize) * float(s.f_frsize) else: disk_size = float(s.f_blocks) * float(s.f_frsize) if s.f_bavail < 0: available = float(sys.maxsize) * float(s.f_frsize) else: available = float(s.f_bavail) * float(s.f_frsize) return disk_size / GIGI, available / GIGI except: return 0.0, 0.0 else: return 20.0, 10.0 @cache_maintainer(clear_time=10) @functools.lru_cache(maxsize=None) def diskspace(force: bool = False) -> Dict[str, Tuple[float, float]]: """Wrapper to keep results cached by cache_maintainer If called with force=True, the wrapper will clear the results""" return { "download_dir": diskspace_base(sabnzbd.cfg.download_dir.get_path()), "complete_dir": diskspace_base(sabnzbd.cfg.complete_dir.get_path()), } def get_new_id(prefix, folder, check_list=None): """Return unique prefixed admin identifier within folder optionally making sure that id is not in the check_list. """ for n in range(100): try: if not os.path.exists(folder): os.makedirs(folder) fd, path = tempfile.mkstemp("", "SABnzbd_%s_" % prefix, folder) os.close(fd) head, tail = os.path.split(path) if not check_list or tail not in check_list: return tail except: logging.error(T("Failure in tempfile.mkstemp")) logging.info("Traceback: ", exc_info=True) break # Cannot create unique id, crash the process raise IOError def save_data(data, _id, path, do_pickle=True, silent=False): """Save data to a diskfile""" if not silent: logging.debug("[%s] Saving data for %s in %s", sabnzbd.misc.caller_name(), _id, path) path = os.path.join(path, _id) # We try 3 times, to avoid any dict or access problems for t in range(3): try: with open(path, "wb") as data_file: if do_pickle: pickle.dump(data, data_file, protocol=pickle.HIGHEST_PROTOCOL) else: data_file.write(data) break except: if silent: # This can happen, probably a removed folder pass elif t == 2: logging.error(T("Saving %s failed"), path) logging.info("Traceback: ", exc_info=True) else: # Wait a tiny bit before trying again time.sleep(0.1) def load_data(data_id, path, remove=True, do_pickle=True, silent=False): """Read data from disk file""" path = os.path.join(path, data_id) if not os.path.exists(path): logging.info("[%s] %s missing", sabnzbd.misc.caller_name(), path) return None if not silent: logging.debug("[%s] Loading data for %s from %s", sabnzbd.misc.caller_name(), data_id, path) try: with open(path, "rb") as data_file: if do_pickle: try: data = pickle.load(data_file, encoding=sabnzbd.encoding.CODEPAGE) except UnicodeDecodeError: # Could be Python 2 data that we can load using old encoding data = pickle.load(data_file, encoding="latin1") else: data = data_file.read() if remove: remove_file(path) except: logging.error(T("Loading %s failed"), path) logging.info("Traceback: ", exc_info=True) return None return data def remove_data(_id: str, path: str): """Remove admin file""" path = os.path.join(path, _id) try: if os.path.exists(path): remove_file(path) except: logging.debug("Failed to remove %s", path) def save_admin(data: Any, data_id: str): """Save data in admin folder in specified format""" logging.debug("[%s] Saving data for %s", sabnzbd.misc.caller_name(), data_id) save_data(data, data_id, sabnzbd.cfg.admin_dir.get_path()) def load_admin(data_id: str, remove=False, silent=False) -> Any: """Read data in admin folder in specified format""" logging.debug("[%s] Loading data for %s", sabnzbd.misc.caller_name(), data_id) return load_data(data_id, sabnzbd.cfg.admin_dir.get_path(), remove=remove, silent=silent) def wait_for_download_folder(): """Wait for download folder to become available""" while not sabnzbd.cfg.download_dir.test_path(): logging.info("Waiting for incomplete folder") time.sleep(2.0) def backup_exists(filename: str) -> bool: """Return True if backup exists and no_dupes is set""" return os.path.exists(os.path.join(sabnzbd.cfg.nzb_backup_dir.get_path(), filename + ".gz")) def backup_nzb(nzb_path: str): """Backup NZB file, return path to nzb if it was saved""" if nzb_backup_dir := sabnzbd.cfg.nzb_backup_dir.get_path(): logging.debug("Saving copy of %s in %s", get_filename(nzb_path), nzb_backup_dir) shutil.copy(nzb_path, nzb_backup_dir) def save_compressed(folder: str, filename: str, data_fp: BinaryIO) -> str: """Save compressed NZB file in folder, return path to saved nzb file""" # Make sure it's a clean filename filename = sanitize_filename(filename) if filename.endswith(".nzb"): filename += ".gz" else: filename += ".nzb.gz" full_nzb_path = os.path.join(folder, filename) # Skip existing ones, as it might be queue-repair if not os.path.exists(full_nzb_path): logging.info("Saving %s", full_nzb_path) try: # Have to get around the path being put inside the tgz with open(full_nzb_path, "wb") as tgz_file: # We only need minimal compression to prevent huge files with gzip.GzipFile(filename, mode="wb", compresslevel=1, fileobj=tgz_file) as gzip_file: shutil.copyfileobj(data_fp, gzip_file) except: logging.error(T("Saving %s failed"), full_nzb_path) logging.info("Traceback: ", exc_info=True) else: logging.info("Skipping existing file %s", full_nzb_path) return full_nzb_path def purge_log_files(): """Purge all existing log files""" # First we need to do a rollover for handler in logging.root.manager.root.handlers: if isinstance(handler, logging.handlers.RotatingFileHandler): # Only if we have a FilderHandler we can rollover and delete older ones logging.debug("Purging log files") handler.doRollover() # Keep sabnzbd.log but remove all older ones remove_all(sabnzbd.cfg.log_dir.get_path(), pattern=DEF_LOG_FILE + ".*", keep_folder=True) logging.debug("Finished puring log files") def directory_is_writable_with_file(mydir, myfilename): filename = os.path.join(mydir, myfilename) if os.path.exists(filename): try: os.remove(filename) except: return False try: with open(filename, "w") as f: f.write("Some random content") os.remove(filename) return True except: return False def directory_is_writable(test_dir: str) -> bool: """Checks if dir is writable at all, with long filenames, with unicode, and (on non-Windows), writable with special chars. Returns True if all OK, otherwise False""" if not directory_is_writable_with_file(test_dir, "sab_test.txt"): sabnzbd.misc.helpful_warning(T("%s is not writable at all. This blocks downloads."), test_dir) return False return True def check_filesystem_capabilities(test_dir: str) -> bool: """Checks if we can write long and unicode filenames to the given directory. If not on Windows, also check for special chars like slashes and : Returns True if all OK, otherwise False""" allgood = True # default return value: all OK # long filename; normal filesystems accept 255 byte filenames if not directory_is_writable_with_file(test_dir, "A" * 245 + str(random.randrange(10000, 99999))): sabnzbd.misc.helpful_warning(T("Cannot write a long filename to %s. This can cause problems."), test_dir) allgood = False # unicode in filename if not directory_is_writable_with_file(test_dir, "🚀" * 20): sabnzbd.misc.helpful_warning(T("Cannot write a unicode filename to %s. This can cause problems."), test_dir) allgood = False # if not on Windows, check special chars like \ and : if not sabnzbd.WIN32 and not directory_is_writable_with_file(test_dir, "sab_test \\ bla :: , bla.txt"): sabnzbd.misc.helpful_warning( T("%s is not writable with special character filenames. This can cause problems."), test_dir ) allgood = False return allgood def get_win_drives() -> List[str]: """Return list of detected drives, adapted from: http://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python/827490 """ return filter(len, win32api.GetLogicalDriveStrings().split("\000")) PATHBROWSER_JUNKFOLDERS = ( "boot", "bootmgr", "cache", "msocache", "recovery", "$recycle.bin", "recycler", "system volume information", "temporary internet files", "perflogs", # windows specific ".fseventd", ".spotlight", ".trashes", ".vol", "cachedmessages", "caches", "trash", # osx specific ) def pathbrowser(path: str, show_hidden: bool = False, show_files: bool = False) -> List[Dict[str, str]]: """Returns a list of dictionaries with the folders and folders contained at the given path Give the empty string as the path to list the contents of the root path under Unix this means "/", on Windows this will be a list of drive letters """ if path == "": if sabnzbd.WIN32: entries = [{"current_path": "Root"}] for letter in get_win_drives(): entries.append( { "name": letter, "path": letter, "dir": True, } ) return entries else: path = "/" # Walk up the tree until we find a valid path path = real_path(sabnzbd.DIR_HOME, path) while path and not os.path.isdir(path): if path == os.path.dirname(path): return pathbrowser(path="") else: path = os.path.dirname(path) # Fix up the path and find the parent path = os.path.abspath(os.path.normpath(path)) parent_path = os.path.dirname(path) # If we're at the root then the next step is the meta-node showing our drive letters if path == parent_path and sabnzbd.WIN32: parent_path = "" # List all files and folders file_list = [] for filename in os.listdir(path): fpath = os.path.join(path, filename) isdir = os.path.isdir(fpath) # Skip unwanted folders if isdir and filename.lower() in PATHBROWSER_JUNKFOLDERS: continue # Skip files if not isdir and not show_files: continue # Skip hidden files if not show_hidden: if sabnzbd.WIN32: try: if win32api.GetFileAttributes(fpath) & win32con.FILE_ATTRIBUTE_HIDDEN: continue except win32api.error: # Can be thrown if file is in use continue elif filename.startswith("."): continue file_list.append( { "name": clip_path(filename), "path": clip_path(fpath), "dir": isdir, } ) # Sort results, folders first (using string value of the bool) file_list = sorted(file_list, key=lambda x: str(not x["dir"]) + os.path.basename(x["name"]).lower()) # Add current path file_list.insert(0, {"current_path": clip_path(path)}) if parent_path != path: file_list.insert( 1, { "name": "..", "path": clip_path(parent_path), "dir": True, }, ) return file_list ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4471176 SABnzbd-4.3.2/sabnzbd/constants.py0000644000000000000000000001352114625637243016236 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os from collections import namedtuple CONFIG_VERSION = 19 QUEUE_VERSION = 10 POSTPROC_QUEUE_VERSION = 2 REC_RAR_VERSION = 550 ANFO = namedtuple("ANFO", "article_sum cache_size cache_limit") # Leave some space for "_UNPACK_" which we append during post-proc # Or, when extra ".1", ".2" etc. are added for identically named jobs DEF_FOLDER_MAX = 256 - 10 DEF_FILE_MAX = 255 - 10 # max filename length on modern filesystems, minus some room for extra chars later on GIGI = float(2**30) MEBI = float(2**20) KIBI = float(2**10) BYTES_FILE_NAME = "totals10.sab" QUEUE_FILE_TMPL = "queue%s.sab" QUEUE_FILE_NAME = QUEUE_FILE_TMPL % QUEUE_VERSION POSTPROC_QUEUE_FILE_NAME = "postproc%s.sab" % POSTPROC_QUEUE_VERSION RSS_FILE_NAME = "rss_data.sab" SCAN_FILE_NAME = "watched_data2.sab" FUTURE_Q_FOLDER = "future" JOB_ADMIN = "__ADMIN__" VERIFIED_FILE = "__verified__" RENAMES_FILE = "__renames__" ATTRIB_FILE = "SABnzbd_attrib" REPAIR_REQUEST = "repair-all.sab" SABCTOOLS_VERSION_REQUIRED = "8.2.0" DB_HISTORY_VERSION = 1 DB_HISTORY_NAME = "history%s.db" % DB_HISTORY_VERSION DEF_DOWNLOAD_DIR = os.path.normpath("Downloads/incomplete") DEF_COMPLETE_DIR = os.path.normpath("Downloads/complete") DEF_ADMIN_DIR = "admin" DEF_NZBBACK_DIR = "" DEF_LANGUAGE = "locale" DEF_INTERFACES = "interfaces" DEF_EMAIL_TMPL = "email" DEF_STD_CONFIG = "Config" DEF_STD_WEB_DIR = "Glitter" DEF_STD_WEB_COLOR = "Auto" DEF_MAIN_TMPL = os.path.normpath("templates/main.tmpl") DEF_INI_FILE = "sabnzbd.ini" DEF_HOST = "127.0.0.1" DEF_PORT = 8080 DEF_WORKDIR = "sabnzbd" DEF_LOG_FILE = "sabnzbd.log" DEF_LOG_ERRFILE = "sabnzbd.error.log" DEF_LOG_CHERRY = "cherrypy.log" DEF_ARTICLE_CACHE_DEFAULT = "500M" DEF_ARTICLE_CACHE_MAX = "1G" DEF_TIMEOUT = 60 DEF_TEST_TIMEOUT = 5 DEF_SCANRATE = 5 DEF_HTTPS_CERT_FILE = "server.cert" DEF_HTTPS_KEY_FILE = "server.key" DEF_SORTER_RENAME_SIZE = "50M" MAX_WARNINGS = 20 MAX_BAD_ARTICLES = 5 CONFIG_BACKUP_FILES = [ BYTES_FILE_NAME, RSS_FILE_NAME, DB_HISTORY_NAME, ] CONFIG_BACKUP_HTTPS = { # "basename": "associated setting" DEF_HTTPS_CERT_FILE: "https_cert", DEF_HTTPS_KEY_FILE: "https_key", "server.chain": "https_chain", } # Constants affecting download performance MAX_ASSEMBLER_QUEUE = 12 SOFT_QUEUE_LIMIT = 0.5 # Percentage of cache to use before adding file to assembler ASSEMBLER_WRITE_THRESHOLD = 5 NNTP_BUFFER_SIZE = int(800 * KIBI) REPAIR_PRIORITY = 3 FORCE_PRIORITY = 2 HIGH_PRIORITY = 1 NORMAL_PRIORITY = 0 LOW_PRIORITY = -1 DEFAULT_PRIORITY = -100 PAUSED_PRIORITY = -2 STOP_PRIORITY = -4 PP_LOOKUP = {0: "", 1: "R", 2: "U", 3: "D"} INTERFACE_PRIORITIES = { FORCE_PRIORITY: "Force", REPAIR_PRIORITY: "Repair", HIGH_PRIORITY: "High", NORMAL_PRIORITY: "Normal", LOW_PRIORITY: "Low", } STAGES = { "RSS": 0, "Source": 1, "Download": 2, "Servers": 3, "Repair": 4, "Filejoin": 5, "Unpack": 6, "Deobfuscate": 7, "Script": 8, } VALID_ARCHIVES = (".zip", ".rar", ".7z") VALID_NZB_FILES = (".nzb", ".gz", ".bz2") CHEETAH_DIRECTIVES = {"directiveStartToken": "", "prioritizeSearchListOverSelf": True} IGNORED_FILES_AND_FOLDERS = ("@eaDir", ".appleDouble", ".DS_Store") IGNORED_MOVIE_FOLDERS = ("video_ts", "audio_ts", "bdmv") EXCLUDED_GUESSIT_PROPERTIES = [ "part", ] GUESSIT_PART_INDICATORS = ("cd", "part") GUESSIT_SORT_TYPES = {0: "all", 1: "tv", 2: "date", 3: "movie", 4: "unknown"} class Status: IDLE = "Idle" # Q: Nothing in the queue COMPLETED = "Completed" # PP: Job is finished CHECKING = "Checking" # Q: Pre-check is running DOWNLOADING = "Downloading" # Q: Normal downloading EXTRACTING = "Extracting" # PP: Archives are being extracted FAILED = "Failed" # PP: Job has failed, now in History FETCHING = "Fetching" # Q: Job is downloading extra par2 files GRABBING = "Grabbing" # Q: Getting an NZB from an external site MOVING = "Moving" # PP: Files are being moved PAUSED = "Paused" # Q: Job is paused QUEUED = "Queued" # Q: Job is waiting for its turn to download or post-process QUICK_CHECK = "QuickCheck" # PP: QuickCheck verification is running REPAIRING = "Repairing" # PP: Job is being repaired (by par2) RUNNING = "Running" # PP: User's post processing script is running VERIFYING = "Verifying" # PP: Job is being verified (by par2) DELETED = "Deleted" # Q: Job has been deleted (and is almost gone) PROPAGATING = "Propagating" # Q: Delayed download class DuplicateStatus: DUPLICATE = "Duplicate" # Simple duplicate DUPLICATE_ALTERNATIVE = "Duplicate Alternative" # Alternative duplicate for a queued job SMART_DUPLICATE = "Smart Duplicate" # Simple Series duplicate SMART_DUPLICATE_ALTERNATIVE = "Smart Duplicate Alternative" # Alternative duplicate for a queued job DUPLICATE_IGNORED = "Duplicate Ignored" class AddNzbFileResult: RETRY = "Retry" # File could not be read ERROR = "Error" # Rejected as duplicate, by pre-queue script or other failure to process file OK = "OK" # Added to queue NO_FILES_FOUND = "No files found" # Malformed or might not be an NZB file ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4471931 SABnzbd-4.3.2/sabnzbd/interface.py0000644000000000000000000021601314625637243016163 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.interface - webinterface """ import os import time import datetime import cherrypy import logging import urllib.parse import re import hashlib import socket import ssl import functools import copy from random import randint from xml.sax.saxutils import escape from Cheetah.Template import Template from typing import Optional, Callable, Union, Any, Dict from guessit.api import properties as guessit_properties import sabnzbd from sabnzbd.misc import ( to_units, from_units, time_format, calc_age, int_conv, get_base_url, is_ipv4_addr, is_ipv6_addr, is_lan_addr, is_local_addr, is_loopback_addr, recursive_html_escape, is_none, get_cpu_name, clean_comma_separated_list, ) from sabnzbd.happyeyeballs import happyeyeballs from sabnzbd.filesystem import ( real_path, globber, globber_full, clip_path, same_directory, setname_from_path, ) from sabnzbd.encoding import xml_name, utob import sabnzbd.config as config import sabnzbd.cfg as cfg import sabnzbd.notifier as notifier import sabnzbd.newsunpack import sabnzbd.utils.ssdp from sabnzbd.constants import ( DEF_STD_CONFIG, DEFAULT_PRIORITY, CHEETAH_DIRECTIVES, EXCLUDED_GUESSIT_PROPERTIES, DEF_HTTPS_CERT_FILE, DEF_SORTER_RENAME_SIZE, GUESSIT_SORT_TYPES, VALID_NZB_FILES, VALID_ARCHIVES, DEF_TEST_TIMEOUT, ) from sabnzbd.lang import list_languages from sabnzbd.api import ( list_scripts, list_cats, del_from_section, api_handler, build_header, Ttemplate, ) ############################################################################## # Security functions ############################################################################## _MSG_ACCESS_DENIED = "External internet access denied - https://sabnzbd.org/access-denied" _MSG_ACCESS_DENIED_CONFIG_LOCK = "Access denied - Configuration locked" _MSG_ACCESS_DENIED_HOSTNAME = "Access denied - Hostname verification failed: https://sabnzbd.org/hostname-check" _MSG_MISSING_AUTH = "Missing authentication" _MSG_APIKEY_REQUIRED = "API Key Required" _MSG_APIKEY_INCORRECT = "API Key Incorrect" def secured_expose( wrap_func: Optional[Callable] = None, check_configlock: bool = False, check_for_login: bool = True, check_api_key: bool = False, access_type: int = 4, ) -> Union[Callable, str]: """Wrapper for both cherrypy.expose and login/access check""" if not wrap_func: return functools.partial( secured_expose, check_configlock=check_configlock, check_for_login=check_for_login, check_api_key=check_api_key, access_type=access_type, ) # Expose to cherrypy wrap_func.exposed = True @functools.wraps(wrap_func) def internal_wrap(*args, **kwargs): # Label for logging in this and other functions, handling X-Forwarded-For # The cherrypy.request object allows adding custom attributes if cherrypy.request.headers.get("X-Forwarded-For"): cherrypy.request.remote_label = "%s (X-Forwarded-For: %s) [%s]" % ( cherrypy.request.remote.ip, cherrypy.request.headers.get("X-Forwarded-For"), cherrypy.request.headers.get("User-Agent"), ) else: cherrypy.request.remote_label = "%s [%s]" % ( cherrypy.request.remote.ip, cherrypy.request.headers.get("User-Agent"), ) # Log all requests if cfg.api_logging(): logging.debug( "Request %s %s from %s %s", cherrypy.request.method, cherrypy.request.path_info, cherrypy.request.remote_label, kwargs, ) # Add X-Frame-Headers headers to page-requests if cfg.x_frame_options(): cherrypy.response.headers["X-Frame-Options"] = "SameOrigin" # Check if config is locked if check_configlock and cfg.configlock(): cherrypy.response.status = 403 if cfg.api_warnings(): return _MSG_ACCESS_DENIED_CONFIG_LOCK return # Check if external access and if it's allowed if not check_access(access_type=access_type, warn_user=True): cherrypy.response.status = 403 if cfg.api_warnings(): return _MSG_ACCESS_DENIED return # Verify login status, only for non-key pages if check_for_login and not check_api_key and not check_login(): raise Raiser("/login/") # Verify host used for the visit if not check_hostname(): cherrypy.response.status = 403 if cfg.api_warnings(): return _MSG_ACCESS_DENIED_HOSTNAME return # Some pages need correct API key if check_api_key: if msg := check_apikey(kwargs): cherrypy.response.status = 403 if cfg.api_warnings(): return msg return # All good, cool! return wrap_func(*args, **kwargs) return internal_wrap def check_access(access_type: int = 4, warn_user: bool = False) -> bool: """Check if external address is allowed given access_type: 1=nzb 2=api 3=full_api 4=webui 5=webui with login for external """ # Easy, it's allowed if access_type <= cfg.inet_exposure(): return True remote_ip = cherrypy.request.remote.ip # Check if the client IP is a loopback address or considered local is_allowed = is_loopback_addr(remote_ip) or is_local_addr(remote_ip) # Never check the XFF header unless access would have been granted based on the remote IP alone! if ( is_allowed and cfg.verify_xff_header() and (xff_ips := clean_comma_separated_list(cherrypy.request.headers.get("X-Forwarded-For"))) ): is_allowed = all(is_local_addr(ip) or is_loopback_addr(ip) for ip in xff_ips) if not is_allowed: logging.debug("Denying access based on X-Forwarded-For IPs '%s'", xff_ips) if not is_allowed and warn_user: log_warning_and_ip(T("Refused connection from:")) return is_allowed def check_hostname(): """Check if hostname is allowed, to mitigate DNS-rebinding attack. Similar to CVE-2019-5702, we need to add protection even if only allowed to be accessed via localhost. """ # If login is enabled, no API-key can be deducted if cfg.username() and cfg.password(): return True # Don't allow requests without Host host = cherrypy.request.headers.get("Host") if not host: return False # Remove the port-part (like ':8080'), if it is there, always on the right hand side. # Not to be confused with IPv6 colons (within square brackets) host = re.sub(":[0123456789]+$", "", host).lower() # Fine if localhost or IP if host == "localhost" or is_ipv4_addr(host) or is_ipv6_addr(host): return True # Check on the whitelist if host in cfg.host_whitelist(): return True # Fine if ends with ".local" or ".local.", aka mDNS name # See rfc6762 Multicast DNS if host.endswith((".local", ".local.")): return True # Ohoh, bad log_warning_and_ip(T('Refused connection with hostname "%s" from:') % host) return False # Create a more unique ID for each instance COOKIE_SECRET = str(randint(1000, 100000) * os.getpid()) def set_login_cookie(remove=False, remember_me=False): """We try to set a cookie as unique as possible to the current user. Based on it's IP and the current process ID of the SAB instance and a random number, so cookies cannot be re-used """ salt = randint(1, 1000) cookie_str = utob(str(salt) + cherrypy.request.remote.ip + COOKIE_SECRET) cherrypy.response.cookie["login_cookie"] = hashlib.sha1(cookie_str).hexdigest() cherrypy.response.cookie["login_cookie"]["path"] = "/" cherrypy.response.cookie["login_cookie"]["httponly"] = 1 cherrypy.response.cookie["login_salt"] = salt cherrypy.response.cookie["login_salt"]["path"] = "/" cherrypy.response.cookie["login_salt"]["httponly"] = 1 # If we want to be remembered if remember_me: cherrypy.response.cookie["login_cookie"]["max-age"] = 3600 * 24 * 14 cherrypy.response.cookie["login_salt"]["max-age"] = 3600 * 24 * 14 # To remove if remove: cherrypy.response.cookie["login_cookie"]["expires"] = 0 cherrypy.response.cookie["login_salt"]["expires"] = 0 else: # Notify about new login notifier.send_notification(T("User logged in"), T("User logged in to the web interface"), "new_login") def check_login_cookie(): # Do we have everything? if "login_cookie" not in cherrypy.request.cookie or "login_salt" not in cherrypy.request.cookie: return False cookie_str = utob(str(cherrypy.request.cookie["login_salt"].value) + cherrypy.request.remote.ip + COOKIE_SECRET) return cherrypy.request.cookie["login_cookie"].value == hashlib.sha1(cookie_str).hexdigest() def check_login(): # Not when no authentication required or basic-auth is on if not cfg.html_login() or not cfg.username() or not cfg.password(): return True # If we show login for external IP, by using access_type=6 we can check if IP match if cfg.inet_exposure() == 5 and check_access(access_type=6): return True # Check the cookie return check_login_cookie() def check_basic_auth(_, username, password): """CherryPy basic authentication validation""" return username == cfg.username() and password == cfg.password() def set_auth(conf): """Set the authentication for CherryPy""" if cfg.username() and cfg.password() and not cfg.html_login(): conf.update( { "tools.auth_basic.on": True, "tools.auth_basic.realm": "SABnzbd", "tools.auth_basic.checkpassword": check_basic_auth, } ) conf.update( { "/api": {"tools.auth_basic.on": False}, "%s/api" % cfg.url_base(): {"tools.auth_basic.on": False}, } ) else: conf.update({"tools.auth_basic.on": False}) def check_apikey(kwargs): """Check API-key or NZB-key Return None when OK, otherwise an error message """ mode = kwargs.get("mode", "") name = kwargs.get("name", "") # Lookup required access level for the specific api-call req_access = sabnzbd.api.api_level(mode, name) if not check_access(req_access, warn_user=True): return _MSG_ACCESS_DENIED # Skip for auth and version calls if mode in ("version", "auth"): return None # First check API-key, if OK that's sufficient key = kwargs.get("apikey") if not key: log_warning_and_ip( T("API Key missing, please enter the api key from Config->General into your 3rd party program:") ) return _MSG_APIKEY_REQUIRED elif req_access == 1 and key == cfg.nzb_key(): return None elif key == cfg.api_key(): return None else: log_warning_and_ip(T("API Key incorrect, Use the api key from Config->General in your 3rd party program:")) return _MSG_APIKEY_INCORRECT def template_filtered_response(file: str, search_list: Dict[str, Any]): """Wrapper for Cheetah response""" # We need a copy, because otherwise source-dicts might be modified search_list_copy = copy.deepcopy(search_list) # 'filters' is excluded because the RSS-filters are listed twice recursive_html_escape(search_list_copy, exclude_items=("webdir", "filters")) return Template(file=file, searchList=[search_list_copy], compilerSettings=CHEETAH_DIRECTIVES).respond() def log_warning_and_ip(txt): """Include the IP and the Proxy-IP for warnings""" if cfg.api_warnings(): logging.warning("%s %s", txt, cherrypy.request.remote_label) ############################################################################## # Helper raiser functions ############################################################################## def Raiser(root: str = "", **kwargs): # Add extras if kwargs: root = "%s?%s" % (root, urllib.parse.urlencode(kwargs)) # Optionally add the leading /sabnzbd/ (or what the user set) if not root.startswith(cfg.url_base()): root = cherrypy.request.script_name + root # Log the redirect if cfg.api_logging(): logging.debug("Request %s %s redirected to %s", cherrypy.request.method, cherrypy.request.path_info, root) # Send the redirect return cherrypy.HTTPRedirect(root) def rssRaiser(root, kwargs): return Raiser(root, feed=kwargs.get("feed")) ############################################################################## # Page definitions ############################################################################## class MainPage: def __init__(self): self.__root = "/" # Add all sub-pages self.login = LoginPage() self.config = ConfigPage("/config/") self.wizard = Wizard("/wizard/") @secured_expose def index(self, **kwargs): # Redirect to wizard if no servers are set if kwargs.get("skip_wizard") or config.get_servers(): info = build_header() info["have_rss_defined"] = bool(config.get_rss()) info["have_watched_dir"] = bool(cfg.dirscan_dir()) info["cpumodel"] = get_cpu_name() info["cpusimd"] = sabnzbd.decoder.SABCTOOLS_SIMD # Have logout only with HTML and if inet=5, only when we are external info["have_logout"] = ( cfg.username() and cfg.password() and ( cfg.html_login() and (cfg.inet_exposure() < 5 or (cfg.inet_exposure() == 5 and not check_access(access_type=6))) ) ) bytespersec_list = sabnzbd.BPSMeter.get_bps_list() info["bytespersec_list"] = ",".join([str(bps) for bps in bytespersec_list]) return template_filtered_response(file=os.path.join(sabnzbd.WEB_DIR, "main.tmpl"), search_list=info) else: # Redirect to the setup wizard raise cherrypy.HTTPRedirect("%s/wizard/" % cfg.url_base()) @secured_expose(check_api_key=True) def shutdown(self, **kwargs): # Check for PID pid_in = kwargs.get("pid") if pid_in and int(pid_in) != os.getpid(): return "Incorrect PID for this instance, remove PID from URL to initiate shutdown." sabnzbd.shutdown_program() return T("SABnzbd shutdown finished") @secured_expose(check_api_key=True, access_type=1) def api(self, **kwargs): """Redirect to API-handler, we check the access_type in the API-handler""" return api_handler(kwargs) @secured_expose def scriptlog(self, **kwargs): """Needed for all skins, URL is fixed due to postproc""" # No session key check, due to fixed URLs if name := kwargs.get("name"): history_db = sabnzbd.get_db_connection() return ShowString(history_db.get_name(name), history_db.get_script_log(name)) else: raise Raiser(self.__root) @secured_expose def robots_txt(self, **kwargs): """Keep web crawlers out""" cherrypy.response.headers["Content-Type"] = "text/plain" return "User-agent: *\nDisallow: /\n" @secured_expose def description_xml(self, **kwargs): """Provide the description.xml which was broadcast via SSDP""" if is_lan_addr(cherrypy.request.remote.ip): cherrypy.response.headers["Content-Type"] = "application/xml" return utob(sabnzbd.utils.ssdp.server_ssdp_xml()) else: return None ############################################################################## class Wizard: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): """Show the language selection page""" if sabnzbd.WIN32: from sabnzbd.utils.apireg import get_install_lng cfg.language.set(get_install_lng()) logging.debug('Installer language code "%s"', cfg.language()) info = build_header(sabnzbd.WIZARD_DIR) info["languages"] = list_languages() return template_filtered_response(file=os.path.join(sabnzbd.WIZARD_DIR, "index.html"), search_list=info) @secured_expose(check_configlock=True) def one(self, **kwargs): """Accept language and show server page""" if kwargs.get("lang"): cfg.language.set(kwargs.get("lang")) info = build_header(sabnzbd.WIZARD_DIR) # Just in case, add server servers = config.get_servers() if not servers: info["server"] = "" info["host"] = "" info["port"] = "" info["username"] = "" info["password"] = "" info["connections"] = "" info["ssl"] = 1 info["ssl_verify"] = 2 else: # Sort servers to get the first enabled one server_names = sorted( servers, key=lambda svr: "%d%02d%s" % (int(not servers[svr].enable()), servers[svr].priority(), servers[svr].displayname().lower()), ) for server in server_names: # If there are multiple servers, just use the first enabled one s = servers[server] info["server"] = server info["host"] = s.host() info["port"] = s.port() info["username"] = s.username() info["password"] = s.password.get_stars() info["connections"] = s.connections() info["ssl"] = s.ssl() info["ssl_verify"] = s.ssl_verify() if s.enable(): break return template_filtered_response(file=os.path.join(sabnzbd.WIZARD_DIR, "one.html"), search_list=info) @secured_expose(check_configlock=True) def two(self, **kwargs): """Accept server and show the final page for restart""" # Save server details if kwargs: kwargs["enable"] = 1 handle_server(kwargs) config.save_config() # Show Restart screen info = build_header(sabnzbd.WIZARD_DIR) info["access_url"], info["urls"] = get_access_info() info["download_dir"] = cfg.download_dir.get_clipped_path() info["complete_dir"] = cfg.complete_dir.get_clipped_path() return template_filtered_response(file=os.path.join(sabnzbd.WIZARD_DIR, "two.html"), search_list=info) def get_access_info(): """Build up a list of url's that sabnzbd can be accessed from""" # Access_url is used to provide the user a link to SABnzbd depending on the host cherryhost = cfg.cherryhost() host = socket.gethostname().lower() logging.info("hostname is", host) socks = [host] try: addresses = socket.getaddrinfo(host, None) except: addresses = [] if cherryhost == "0.0.0.0": # Grab a list of all ips for the hostname for addr in addresses: address = addr[4][0] # Filter out ipv6 addresses (should not be allowed) if ":" not in address and address not in socks: socks.append(address) socks.insert(0, "localhost") elif cherryhost == "::": # Grab a list of all ips for the hostname for addr in addresses: address = addr[4][0] # Only ipv6 addresses will work if ":" in address: address = "[%s]" % address if address not in socks: socks.append(address) socks.insert(0, "localhost") elif cherryhost: socks = [cherryhost] # Add the current requested URL as the base access_url = urllib.parse.urljoin(cherrypy.request.base, cfg.url_base()) urls = [access_url] for sock in socks: if sock: if cfg.enable_https() and cfg.https_port(): url = "https://%s:%s%s" % (sock, cfg.https_port(), cfg.url_base()) elif cfg.enable_https(): url = "https://%s:%s%s" % (sock, cfg.cherryport(), cfg.url_base()) else: url = "http://%s:%s%s" % (sock, cfg.cherryport(), cfg.url_base()) urls.append(url) # Return a unique list return access_url, set(urls) ############################################################################## class LoginPage: @secured_expose(check_for_login=False) def index(self, **kwargs): # Base output var info = build_header(sabnzbd.WEB_DIR_CONFIG) info["error"] = "" # Logout? if kwargs.get("logout"): set_login_cookie(remove=True) raise Raiser() # Check if there's even a username/password set if check_login(): raise Raiser(cherrypy.request.script_name + "/") # Check login info if kwargs.get("username") == cfg.username() and kwargs.get("password") == cfg.password(): # Save login cookie set_login_cookie(remember_me=kwargs.get("remember_me", False)) # Log the success logging.info("Successful login from %s", cherrypy.request.remote_label) # Redirect raise Raiser(cherrypy.request.script_name + "/") elif kwargs.get("username") or kwargs.get("password"): info["error"] = T("Authentication failed, check username/password.") # Warn about the potential security problem logging.warning(T("Unsuccessful login attempt from %s"), cherrypy.request.remote_label) # Show login return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "login", "main.tmpl"), search_list=info, ) ############################################################################## class ConfigPage: def __init__(self, root): self.__root = root self.folders = ConfigFolders("/config/folders/") self.notify = ConfigNotify("/config/notify/") self.general = ConfigGeneral("/config/general/") self.rss = ConfigRss("/config/rss/") self.scheduling = ConfigScheduling("/config/scheduling/") self.server = ConfigServer("/config/server/") self.switches = ConfigSwitches("/config/switches/") self.categories = ConfigCats("/config/categories/") self.sorting = ConfigSorting("/config/sorting/") self.special = ConfigSpecial("/config/special/") @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["configfn"] = clip_path(config.get_filename()) conf["cmdline"] = sabnzbd.CMDLINE conf["build"] = sabnzbd.__baseline__[:7] conf["have_7zip"] = bool(sabnzbd.newsunpack.SEVENZIP_COMMAND) conf["have_par2_turbo"] = sabnzbd.newsunpack.PAR2_TURBO conf["ssl_version"] = ssl.OPENSSL_VERSION return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config.tmpl"), search_list=conf, ) ############################################################################## LIST_DIRPAGE = ( "download_dir", "download_free", "complete_dir", "complete_free", "admin_dir", "nzb_backup_dir", "dirscan_dir", "dirscan_speed", "script_dir", "email_dir", "permissions", "log_dir", "backup_dir", "password_file", ) LIST_BOOL_DIRPAGE = ("fulldisk_autoresume",) class ConfigFolders: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["file_exts"] = ", ".join(VALID_NZB_FILES + VALID_ARCHIVES) for kw in LIST_DIRPAGE + LIST_BOOL_DIRPAGE: conf[kw] = config.get_config("misc", kw)() return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_folders.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def saveDirectories(self, **kwargs): for kw in LIST_DIRPAGE + LIST_BOOL_DIRPAGE: if msg := config.get_config("misc", kw).set(kwargs.get(kw)): return badParameterResponse(msg, kwargs.get("ajax")) config.save_config() if kwargs.get("ajax"): return sabnzbd.api.report() else: raise Raiser(self.__root) ############################################################################## SWITCH_LIST = ( "par_option", "top_only", "direct_unpack", "win_process_prio", "auto_sort", "propagation_delay", "auto_disconnect", "flat_unpack", "safe_postproc", "no_dupes", "replace_underscores", "replace_spaces", "replace_dots", "ignore_samples", "pause_on_post_processing", "nice", "ionice", "pre_script", "end_queue_script", "pause_on_pwrar", "sfv_check", "deobfuscate_final_filenames", "folder_rename", "quota_size", "quota_day", "quota_resume", "quota_period", "history_retention_option", "history_retention_number", "pre_check", "max_art_tries", "fail_hopeless_jobs", "enable_all_par", "enable_recursive", "no_smart_dupes", "dupes_propercheck", "script_can_fail", "unwanted_extensions", "action_on_unwanted_extensions", "unwanted_extensions_mode", "cleanup_list", "sanitize_safe", ) class ConfigSwitches: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["have_nice"] = bool(sabnzbd.newsunpack.NICE_COMMAND) conf["have_ionice"] = bool(sabnzbd.newsunpack.IONICE_COMMAND) for kw in SWITCH_LIST: conf[kw] = config.get_config("misc", kw)() conf["cleanup_list"] = cfg.cleanup_list.get_string() conf["unwanted_extensions"] = cfg.unwanted_extensions.get_string() conf["scripts"] = list_scripts() or ["None"] return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_switches.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def saveSwitches(self, **kwargs): for kw in SWITCH_LIST: if msg := config.get_config("misc", kw).set(kwargs.get(kw)): return badParameterResponse(msg, kwargs.get("ajax")) config.save_config() if kwargs.get("ajax"): return sabnzbd.api.report() else: raise Raiser(self.__root) ############################################################################## SPECIAL_BOOL_LIST = ( "start_paused", "preserve_paused_state", "no_penalties", "ipv6_servers", "ipv6_staging", "fast_fail", "overwrite_files", "enable_par_cleanup", "process_unpacked_par2", "queue_complete_pers", "api_warnings", "helpful_warnings", "ampm", "enable_multipar", "enable_unrar", "enable_7zip", "enable_filejoin", "enable_tsjoin", "ignore_unrar_dates", "tray_icon", "allow_incomplete_nzb", "rss_filenames", "ipv6_hosting", "keep_awake", "empty_postproc", "new_nzb_on_failure", "html_login", "disable_archive", "wait_for_dfolder", "enable_broadcast", "warn_dupl_jobs", "backup_for_duplicates", "api_logging", "x_frame_options", "allow_old_ssl_tls", "enable_season_sorting", "verify_xff_header", ) SPECIAL_VALUE_LIST = ( "downloader_sleep_time", "size_limit", "nomedia_marker", "max_url_retries", "req_completion_rate", "wait_ext_drive", "max_foldername_length", "url_base", "receive_threads", "switchinterval", "direct_unpack_threads", "selftest_host", "ssdp_broadcast_interval", ) SPECIAL_LIST_LIST = ( "rss_odd_titles", "quick_check_ext_ignore", "host_whitelist", "local_ranges", "ext_rename_ignore", ) class ConfigSpecial: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["switches"] = [ (kw, config.get_config("misc", kw)(), config.get_config("misc", kw).default) for kw in SPECIAL_BOOL_LIST ] conf["entries"] = [ (kw, config.get_config("misc", kw)(), config.get_config("misc", kw).default) for kw in SPECIAL_VALUE_LIST ] conf["entries"].extend( [ (kw, config.get_config("misc", kw).get_string(), config.get_config("misc", kw).default_string()) for kw in SPECIAL_LIST_LIST ] ) return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_special.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def saveSpecial(self, **kwargs): for kw in SPECIAL_BOOL_LIST + SPECIAL_VALUE_LIST + SPECIAL_LIST_LIST: if msg := config.get_config("misc", kw).set(kwargs.get(kw)): return badParameterResponse(msg) config.save_config() raise Raiser(self.__root) ############################################################################## GENERAL_LIST = ( "host", "port", "username", "language", "cache_limit", "inet_exposure", "enable_https", "https_port", "https_cert", "https_key", "https_chain", "enable_https_verification", "socks5_proxy_url", "auto_browser", "check_new_rel", "bandwidth_max", "bandwidth_perc", ) class ConfigGeneral: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) web_list = [] for interface_dir in globber_full(sabnzbd.DIR_INTERFACES): # Ignore the config if not interface_dir.endswith(DEF_STD_CONFIG): # Check the available templates for colorscheme in globber( os.path.join(interface_dir, "templates", "static", "stylesheets", "colorschemes") ): web_list.append("%s - %s" % (setname_from_path(interface_dir), setname_from_path(colorscheme))) conf["web_list"] = web_list conf["web_dir"] = "%s - %s" % (cfg.web_dir(), cfg.web_color()) conf["password"] = cfg.password.get_stars() conf["language"] = cfg.language() conf["lang_list"] = list_languages() conf["def_https_cert_file"] = DEF_HTTPS_CERT_FILE for kw in GENERAL_LIST: conf[kw] = config.get_config("misc", kw)() conf["nzb_key"] = cfg.nzb_key() conf["caller_url"] = cherrypy.request.base + cfg.url_base() return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_general.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def saveGeneral(self, **kwargs): # Handle general options for kw in GENERAL_LIST: if msg := config.get_config("misc", kw).set(kwargs.get(kw)): return badParameterResponse(msg, ajax=kwargs.get("ajax")) # Handle special options cfg.password.set(kwargs.get("password")) web_dir = kwargs.get("web_dir") change_web_dir(web_dir) config.save_config() # Update CherryPy authentication set_auth(cherrypy.config) if kwargs.get("ajax"): return sabnzbd.api.report(data={"success": True, "restart_req": sabnzbd.RESTART_REQ}) else: raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def uploadConfig(self, **kwargs): """Restore a config backup""" config_backup_file = kwargs.get("config_backup_file") # Only accept the backup file if it can be opened as a zip archive and only contains a config file try: config_backup_data = config_backup_file.file.read() config_backup_file.file.close() if config.validate_config_backup(config_backup_data): sabnzbd.RESTORE_DATA = config_backup_data return sabnzbd.api.report(data={"success": True, "restart_req": True}) except: pass return sabnzbd.api.report(error=T("Invalid backup archive")) def change_web_dir(web_dir): web_dir, web_color = web_dir.split(" - ") web_dir_path = real_path(sabnzbd.DIR_INTERFACES, web_dir) if not os.path.exists(web_dir_path): return badParameterResponse("Cannot find web template: %s" % web_dir_path) else: cfg.web_dir.set(web_dir) cfg.web_color.set(web_color) ############################################################################## class ConfigServer: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) new = [] servers = config.get_servers() server_names = sorted( servers, key=lambda svr: "%d%02d%s" % (int(not servers[svr].enable()), servers[svr].priority(), servers[svr].displayname().lower()), ) for svr in server_names: new.append(servers[svr].get_dict(for_public_api=True)) t, m, w, d, daily, articles_tried, articles_success = sabnzbd.BPSMeter.amounts(svr) if t: new[-1]["amounts"] = ( to_units(t), to_units(m), to_units(w), to_units(d), daily, articles_tried, articles_success, ) new[-1]["quota_left"] = to_units( servers[svr].quota.get_int() - sabnzbd.BPSMeter.grand_total.get(svr, 0) + servers[svr].usage_at_start() ) conf["servers"] = new conf["cats"] = list_cats(default=True) return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_server.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def addServer(self, **kwargs): return handle_server(kwargs, self.__root, True) @secured_expose(check_api_key=True, check_configlock=True) def saveServer(self, **kwargs): return handle_server(kwargs, self.__root) @secured_expose(check_api_key=True, check_configlock=True) def delServer(self, **kwargs): kwargs["section"] = "servers" kwargs["keyword"] = kwargs.get("server") del_from_section(kwargs) raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def clrServer(self, **kwargs): server = kwargs.get("server") if server: sabnzbd.BPSMeter.clear_server(server) raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def toggleServer(self, **kwargs): server = kwargs.get("server") if server: svr = config.get_config("servers", server) if svr: svr.enable.set(not svr.enable()) config.save_config() sabnzbd.Downloader.update_server(server, server) raise Raiser(self.__root) def unique_svr_name(server): """Return a unique variant on given server name""" num = 0 svr = 1 new_name = server while svr: if num: new_name = "%s@%d" % (server, num) else: new_name = "%s" % server svr = config.get_config("servers", new_name) num += 1 return new_name def handle_server(kwargs, root=None, new_svr=False): """Internal server handler""" ajax = kwargs.get("ajax") host = kwargs.get("host", "").strip() if not host: return badParameterResponse(T("Server address required"), ajax) port = kwargs.get("port", "").strip() if not port: if not kwargs.get("ssl", "").strip(): port = "119" else: port = "563" kwargs["port"] = port if kwargs.get("connections", "").strip() == "": kwargs["connections"] = "1" if kwargs.get("enable") == "1": if not happyeyeballs(host, int_conv(port), int_conv(kwargs.get("timeout"), default=DEF_TEST_TIMEOUT)): return badParameterResponse(T('Server address "%s:%s" is not valid.') % (host, port), ajax) # Default server name is just the host name server = host svr = None old_server = kwargs.get("server") if old_server: svr = config.get_config("servers", old_server) if svr: server = old_server else: svr = config.get_config("servers", server) if new_svr: server = unique_svr_name(server) for kw in ("ssl", "enable", "required", "optional"): if kw not in kwargs.keys(): kwargs[kw] = None if svr and not new_svr: svr.set_dict(kwargs) else: old_server = None config.ConfigServer(server, kwargs) config.save_config() sabnzbd.Downloader.update_server(old_server, server) if root: if ajax: return sabnzbd.api.report() else: raise Raiser(root) ############################################################################## class ConfigRss: def __init__(self, root): self.__root = root self.__refresh_readout = None # Set to URL when new readout is needed self.__refresh_download = False # True when feed needs to be read self.__refresh_force = False # True if forced download of all matches is required self.__refresh_ignore = False # True if first batch of new feed must be ignored self.__evaluate = False # True if feed needs to be re-filtered self.__show_eval_button = False # True if the "Apply filers" button should be shown self.__last_msg = "" # Last error message from RSS reader @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["scripts"] = list_scripts(default=True) pick_script = conf["scripts"] != [] conf["categories"] = list_cats(default=True) pick_cat = conf["categories"] != [] conf["rss_rate"] = cfg.rss_rate() rss = {} feeds = config.get_rss() for feed in feeds: rss[feed] = feeds[feed].get_dict() filters = feeds[feed].filters() rss[feed]["filters"] = filters rss[feed]["filter_states"] = [bool(sabnzbd.rss.convert_filter(f[4])) for f in filters] rss[feed]["filtercount"] = len(filters) rss[feed]["pick_cat"] = pick_cat rss[feed]["pick_script"] = pick_script rss[feed]["link"] = urllib.parse.quote_plus(feed) rss[feed]["baselink"] = [get_base_url(uri) for uri in rss[feed]["uri"]] rss[feed]["uris"] = feeds[feed].uri.get_string() active_feed = kwargs.get("feed", "") conf["active_feed"] = active_feed conf["rss"] = rss conf["rss_next"] = time.strftime(time_format("%H:%M"), time.localtime(sabnzbd.RSSReader.next_run)) if active_feed: readout = bool(self.__refresh_readout) logging.debug("RSS READOUT = %s", readout) if not readout: self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = False if self.__evaluate: msg = sabnzbd.RSSReader.run_feed( active_feed, download=self.__refresh_download, force=self.__refresh_force, ignoreFirst=self.__refresh_ignore, readout=readout, ) else: msg = "" self.__evaluate = False if readout: sabnzbd.RSSReader.save() self.__last_msg = msg else: msg = self.__last_msg self.__refresh_readout = None conf["evalButton"] = self.__show_eval_button conf["error"] = msg conf["downloaded"], conf["matched"], conf["unmatched"] = GetRssLog(active_feed) else: self.__last_msg = "" # Find a unique new Feed name unum = 1 txt = T("Feed") # : Used as default Feed name in Config->RSS while txt + str(unum) in feeds: unum += 1 conf["feed"] = txt + str(unum) return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_rss.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def save_rss_rate(self, **kwargs): """Save changed RSS automatic readout rate""" cfg.rss_rate.set(kwargs.get("rss_rate")) config.save_config() sabnzbd.Scheduler.restart() raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def upd_rss_feed(self, **kwargs): """Update Feed level attributes, legacy version: ignores 'enable' parameter """ if kwargs.get("enable") is not None: del kwargs["enable"] try: cf = config.get_rss()[kwargs.get("feed")] except KeyError: cf = None uri = Strip(kwargs.get("uri")) if cf and uri: kwargs["uri"] = uri cf.set_dict(kwargs) config.save_config() self.__evaluate = False self.__show_eval_button = True raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def save_rss_feed(self, **kwargs): """Update Feed level attributes""" feed_name = kwargs.get("feed") try: cf = config.get_rss()[feed_name] except KeyError: cf = None if "enable" not in kwargs: kwargs["enable"] = 0 uri = Strip(kwargs.get("uri")) if cf and uri: kwargs["uri"] = uri cf.set_dict(kwargs) # Did we get a new name for this feed? new_name = kwargs.get("feed_new_name") if new_name and new_name != feed_name: # Update the feed name for the redirect kwargs["feed"] = cf.rename(new_name) config.save_config() raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def toggle_rss_feed(self, **kwargs): """Toggle automatic read-out flag of Feed""" try: item = config.get_rss()[kwargs.get("feed")] except KeyError: item = None if cfg: item.enable.set(not item.enable()) config.save_config() if kwargs.get("table"): raise Raiser(self.__root) else: raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def add_rss_feed(self, **kwargs): """Add one new RSS feed definition""" feed = Strip(kwargs.get("feed")).strip("[]") uri = Strip(kwargs.get("uri")) if feed and uri: try: rss_cfg = config.get_rss()[feed] except KeyError: rss_cfg = None if not rss_cfg and uri: kwargs["feed"] = feed kwargs["uri"] = uri config.ConfigRSS(feed, kwargs) # Clear out any existing reference to this feed name # Otherwise first-run detection can fail sabnzbd.RSSReader.clear_feed(feed) config.save_config() self.__refresh_readout = feed self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = True self.__evaluate = True raise rssRaiser(self.__root, kwargs) else: raise Raiser(self.__root) else: raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def upd_rss_filter(self, **kwargs): """Wrapper, so we can call from api.py""" self.internal_upd_rss_filter(**kwargs) def internal_upd_rss_filter(self, **kwargs): """Save updated filter definition""" try: feed_cfg = config.get_rss()[kwargs.get("feed")] except KeyError: raise rssRaiser(self.__root, kwargs) pp = kwargs.get("pp", "") if is_none(pp): pp = "" script = ConvertSpecials(kwargs.get("script")) cat = ConvertSpecials(kwargs.get("cat")) prio = ConvertSpecials(kwargs.get("priority")) filt = kwargs.get("filter_text") enabled = kwargs.get("enabled", "0") if filt: feed_cfg.filters.update( int(kwargs.get("index", 0)), [cat, pp, script, kwargs.get("filter_type"), filt, prio, enabled] ) # Move filter if requested index = int_conv(kwargs.get("index", "")) new_index = kwargs.get("new_index", "") if new_index and int_conv(new_index) != index: feed_cfg.filters.move(int(index), int_conv(new_index)) config.save_config() self.__evaluate = False self.__show_eval_button = True raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def del_rss_feed(self, *args, **kwargs): """Remove complete RSS feed""" kwargs["section"] = "rss" kwargs["keyword"] = kwargs.get("feed") del_from_section(kwargs) sabnzbd.RSSReader.clear_feed(kwargs.get("feed")) raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def del_rss_filter(self, **kwargs): """Wrapper, so we can call from api.py""" self.internal_del_rss_filter(**kwargs) def internal_del_rss_filter(self, **kwargs): """Remove one RSS filter""" try: feed_cfg = config.get_rss()[kwargs.get("feed")] except KeyError: raise rssRaiser(self.__root, kwargs) feed_cfg.filters.delete(int(kwargs.get("index", 0))) config.save_config() self.__evaluate = False self.__show_eval_button = True raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def download_rss_feed(self, *args, **kwargs): """Force download of all matching jobs in a feed""" if "feed" in kwargs: feed = kwargs["feed"] self.__refresh_readout = feed self.__refresh_download = True self.__refresh_force = True self.__refresh_ignore = False self.__evaluate = True raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def clean_rss_jobs(self, *args, **kwargs): """Remove processed RSS jobs from UI""" sabnzbd.RSSReader.clear_downloaded(kwargs["feed"]) self.__evaluate = True raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def test_rss_feed(self, *args, **kwargs): """Read the feed content again and show results""" if "feed" in kwargs: feed = kwargs["feed"] self.__refresh_readout = feed self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = True self.__evaluate = True self.__show_eval_button = False raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def eval_rss_feed(self, *args, **kwargs): """Re-apply the filters to the feed""" if "feed" in kwargs: self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = False self.__show_eval_button = False self.__evaluate = True raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def download(self, **kwargs): """Download NZB from provider (Download button)""" feed = kwargs.get("feed") url = kwargs.get("url") if att := sabnzbd.RSSReader.lookup_url(feed, url): nzbname = kwargs.get("nzbname") pp = att.get("pp") cat = att.get("cat") script = att.get("script") priority = att.get("prio") if url: logging.info("Adding %s (%s) to queue", url, nzbname) sabnzbd.urlgrabber.add_url( url, pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname, nzo_info={"RSS": feed}, ) # Need to pass the title instead sabnzbd.RSSReader.flag_downloaded(feed, url) raise rssRaiser(self.__root, kwargs) @secured_expose(check_api_key=True, check_configlock=True) def rss_now(self, *args, **kwargs): """Run an automatic RSS run now""" sabnzbd.Scheduler.force_rss() raise Raiser(self.__root) def ConvertSpecials(p): """Convert None to 'None' and 'Default' to ''""" if p is None: p = "None" elif p.lower() == T("Default").lower(): p = "" return p def Strip(txt): """Return stripped string, can handle None""" try: return txt.strip() except: return None ############################################################################## _SCHED_ACTIONS = ( "resume", "pause", "pause_all", "shutdown", "restart", "speedlimit", "pause_post", "resume_post", "scan_folder", "rss_scan", "create_backup", "remove_failed", "remove_completed", "pause_all_low", "pause_all_normal", "pause_all_high", "resume_all_low", "resume_all_normal", "resume_all_high", "enable_quota", "disable_quota", ) class ConfigScheduling: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): def get_days(): days = { "*": T("Daily"), "1": T("Monday"), "2": T("Tuesday"), "3": T("Wednesday"), "4": T("Thursday"), "5": T("Friday"), "6": T("Saturday"), "7": T("Sunday"), } return days conf = build_header(sabnzbd.WEB_DIR_CONFIG) actions = [] actions.extend(_SCHED_ACTIONS) day_names = get_days() categories = list_cats(False) snum = 1 conf["schedlines"] = [] conf["taskinfo"] = [] for ev in sabnzbd.scheduler.sort_schedules(all_events=False): line = ev[3] conf["schedlines"].append(line) try: enabled, m, h, day_numbers, action = line.split(" ", 4) except: continue action = action.strip() try: action, value = action.split(" ", 1) except: value = "" value = value.strip() if value and not value.lower().strip("0123456789kmgtp%."): if "%" not in value and from_units(value) < 1.0: value = T("off") # : "Off" value for speedlimit in scheduler else: if "%" not in value and 1 < int_conv(value) < 101: value += "%" value = value.upper() if action in actions: action = Ttemplate("sch-" + action) else: if action in ("enable_server", "disable_server"): try: value = '"%s"' % config.get_servers()[value].displayname() except KeyError: value = '"%s" <<< %s' % (value, T("Undefined server!")) action = Ttemplate("sch-" + action) if action in ("pause_cat", "resume_cat"): action = Ttemplate("sch-" + action) if value not in categories: # Category name change value = '"%s" <<< %s' % (value, T("Incorrect parameter")) else: value = '"%s"' % value if day_numbers == "1234567": days_of_week = "Daily" elif day_numbers == "12345": days_of_week = "Weekdays" elif day_numbers == "67": days_of_week = "Weekends" else: days_of_week = ", ".join([day_names.get(i, "**") for i in day_numbers]) item = (snum, "%02d" % int(h), "%02d" % int(m), days_of_week, "%s %s" % (action, value), enabled) conf["taskinfo"].append(item) snum += 1 actions_lng = {} for action in actions: actions_lng[action] = Ttemplate("sch-" + action) actions_servers = {} servers = config.get_servers() for srv in servers: actions_servers[srv] = servers[srv].displayname() conf["actions_servers"] = actions_servers conf["actions"] = actions conf["actions_lng"] = actions_lng conf["categories"] = categories return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_scheduling.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def addSchedule(self, **kwargs): servers = config.get_servers() minute = kwargs.get("minute") hour = kwargs.get("hour") days_of_week = "".join([str(x) for x in kwargs.get("daysofweek", "")]) if not days_of_week: days_of_week = "1234567" action = kwargs.get("action") arguments = kwargs.get("arguments") arguments = arguments.strip().lower() if arguments in ("on", "enable"): arguments = "1" elif arguments in ("off", "disable"): arguments = "0" if minute and hour and days_of_week and action: if action == "speedlimit": if not arguments or arguments.strip("0123456789kmgtp%."): arguments = 0 elif action in _SCHED_ACTIONS: arguments = "" elif action in servers: if arguments == "1": arguments = action action = "enable_server" else: arguments = action action = "disable_server" elif action in ("pause_cat", "resume_cat"): # Need original category name, not lowercased arguments = arguments.strip() else: # Something else, leave empty action = None if action: sched = cfg.schedules() sched.append("%s %s %s %s %s %s" % (1, minute, hour, days_of_week, action, arguments)) cfg.schedules.set(sched) config.save_config() sabnzbd.Scheduler.restart() raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def delSchedule(self, **kwargs): schedules = cfg.schedules() line = kwargs.get("line") if line and line in schedules: schedules.remove(line) cfg.schedules.set(schedules) config.save_config() sabnzbd.Scheduler.restart() raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def toggleSchedule(self, **kwargs): schedules = cfg.schedules() line = kwargs.get("line") if line: for i, schedule in enumerate(schedules): if schedule == line: # Toggle the schedule schedule_split = schedule.split() schedule_split[0] = "%d" % (schedule_split[0] == "0") schedules[i] = " ".join(schedule_split) break cfg.schedules.set(schedules) config.save_config() sabnzbd.Scheduler.restart() raise Raiser(self.__root) ############################################################################## class ConfigCats: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["scripts"] = list_scripts(default=True) conf["defdir"] = cfg.complete_dir.get_clipped_path() categories = config.get_ordered_categories() new_cat_order = max(cat["order"] for cat in categories) + 1 # Add empty line to add new categories empty = { "name": "", "order": str(new_cat_order), "pp": "-1", "script": "", "dir": "", "newzbin": "", "priority": DEFAULT_PRIORITY, } categories.insert(1, empty) conf["slotinfo"] = categories return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_cat.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def delete(self, **kwargs): kwargs["section"] = "categories" kwargs["keyword"] = kwargs.get("name") del_from_section(kwargs) raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def save(self, **kwargs): name = kwargs.get("name", "*") newname = kwargs.get("newname", "") if name == "*": newname = name if newname: # Check if this cat-dir is not sub-folder of incomplete if same_directory(cfg.download_dir.get_path(), real_path(cfg.complete_dir.get_path(), kwargs["dir"])): return T("Category folder cannot be a subfolder of the Temporary Download Folder.") # Delete current one and replace with new one if name: config.delete("categories", name) config.ConfigCat(newname.lower(), kwargs) config.save_config() raise Raiser(self.__root) ############################################################################## class ConfigSorting: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) sorters = config.get_ordered_sorters() # Add empty sorter entry, used as a template at the top of the page empty = { "is_active": "1", "name": "", "order": len(sorters), # Last in line "min_size": DEF_SORTER_RENAME_SIZE, "sort_string": "", "sort_cats": "", "sort_type": "0,", "multipart_label": "", } sorters.insert(0, empty) conf["slotinfo"] = sorters conf["categories"] = list_cats(False) conf["guessit_properties"] = tuple( prop for prop in guessit_properties().keys() if prop not in EXCLUDED_GUESSIT_PROPERTIES ) conf["sort_types"] = GUESSIT_SORT_TYPES return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_sorting.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def delete(self, **kwargs): kwargs["section"] = "sorters" kwargs["keyword"] = kwargs.get("name") del_from_section(kwargs) raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def save_sorter(self, **kwargs): name = kwargs.get("name", "*") newname = kwargs.get("newname", "") newname = config.clean_section_name(newname) if name == "*": newname = name if newname: # Delete current one and replace with new one if name: config.delete("sorters", name) config.ConfigSorter(newname, kwargs) config.save_config() raise Raiser(self.__root) @secured_expose(check_api_key=True, check_configlock=True) def toggle_sorter(self, **kwargs): """Toggle is_active flag of a sorter""" try: sorter = config.get_sorters()[kwargs.get("sorter")] sorter.is_active.set(not sorter.is_active()) config.save_config() except Exception: pass raise Raiser(self.__root) def badParameterResponse(msg, ajax=None): """Return a html page with error message and a 'back' button""" if ajax: return sabnzbd.api.report(error=msg) else: return """ SABnzbd %s - %s

%s

%s

""" % ( sabnzbd.__version__, T("ERROR:"), T("Incorrect parameter"), msg, T("Back"), ) def ShowString(name, msg): """Return a html page listing a file and a 'back' button""" return """ %s

%s

%s
""" % ( xml_name(name), T("Back"), xml_name(name), escape(msg), ) def GetRssLog(feed): def make_item(job): # Make a copy job = job.copy() # Now we apply some formatting job["title"] = job["title"] job["skip"] = "*" * int(job.get("status", "").endswith("*")) # These fields could be empty job["cat"] = job.get("cat", "") job["size"] = job.get("size", "") job["infourl"] = job.get("infourl", "") # Auto-fetched jobs didn't have these fields set if job.get("url"): job["baselink"] = get_base_url(job.get("url")) if sabnzbd.rss.special_rss_site(job.get("url")): job["nzbname"] = "" else: job["nzbname"] = job["title"] else: job["baselink"] = "" job["nzbname"] = job["title"] if job.get("size", 0): job["size_units"] = to_units(job["size"]) else: job["size_units"] = "-" # And we add extra fields for sorting if job.get("age", 0): job["age_ms"] = (job["age"] - datetime.datetime(1970, 1, 1)).total_seconds() job["age"] = calc_age(job["age"], True) else: job["age_ms"] = "" job["age"] = "" if job.get("time_downloaded"): job["time_downloaded_ms"] = time.mktime(job["time_downloaded"]) job["time_downloaded"] = time.strftime(time_format("%H:%M %a %d %b"), job["time_downloaded"]) else: job["time_downloaded_ms"] = "" job["time_downloaded"] = "" return job jobs = sabnzbd.RSSReader.show_result(feed).values() good, bad, done = ([], [], []) for job in jobs: if job["status"][0] == "G": good.append(make_item(job)) elif job["status"][0] == "B": bad.append(make_item(job)) elif job["status"] == "D": done.append(make_item(job)) try: # Sort based on actual age, in try-catch just to be sure good.sort(key=lambda job: job["age_ms"], reverse=True) bad.sort(key=lambda job: job["age_ms"], reverse=True) done.sort(key=lambda job: job["time_downloaded_ms"], reverse=True) except: # Let the javascript do it then.. pass return done, good, bad ############################################################################## NOTIFY_OPTIONS = { "misc": ( "email_endjob", "email_cats", "email_full", "email_server", "email_to", "email_from", "email_account", "email_pwd", "email_rss", ), "ncenter": ( "ncenter_enable", "ncenter_cats", "ncenter_prio_startup", "ncenter_prio_download", "ncenter_prio_pause_resume", "ncenter_prio_pp", "ncenter_prio_pp", "ncenter_prio_complete", "ncenter_prio_failed", "ncenter_prio_disk_full", "ncenter_prio_warning", "ncenter_prio_error", "ncenter_prio_queue_done", "ncenter_prio_other", "ncenter_prio_new_login", ), "acenter": ( "acenter_enable", "acenter_cats", "acenter_prio_startup", "acenter_prio_download", "acenter_prio_pause_resume", "acenter_prio_pp", "acenter_prio_complete", "acenter_prio_failed", "acenter_prio_disk_full", "acenter_prio_warning", "acenter_prio_error", "acenter_prio_queue_done", "acenter_prio_other", "acenter_prio_new_login", ), "ntfosd": ( "ntfosd_enable", "ntfosd_cats", "ntfosd_prio_startup", "ntfosd_prio_download", "ntfosd_prio_pause_resume", "ntfosd_prio_pp", "ntfosd_prio_complete", "ntfosd_prio_failed", "ntfosd_prio_disk_full", "ntfosd_prio_warning", "ntfosd_prio_error", "ntfosd_prio_queue_done", "ntfosd_prio_other", "ntfosd_prio_new_login", ), "prowl": ( "prowl_enable", "prowl_cats", "prowl_apikey", "prowl_prio_startup", "prowl_prio_download", "prowl_prio_pause_resume", "prowl_prio_pp", "prowl_prio_complete", "prowl_prio_failed", "prowl_prio_disk_full", "prowl_prio_warning", "prowl_prio_error", "prowl_prio_queue_done", "prowl_prio_other", "prowl_prio_new_login", ), "pushover": ( "pushover_enable", "pushover_cats", "pushover_token", "pushover_userkey", "pushover_device", "pushover_prio_startup", "pushover_prio_download", "pushover_prio_pause_resume", "pushover_prio_pp", "pushover_prio_complete", "pushover_prio_failed", "pushover_prio_disk_full", "pushover_prio_warning", "pushover_prio_error", "pushover_prio_queue_done", "pushover_prio_other", "pushover_prio_new_login", "pushover_emergency_retry", "pushover_emergency_expire", ), "pushbullet": ( "pushbullet_enable", "pushbullet_cats", "pushbullet_apikey", "pushbullet_device", "pushbullet_prio_startup", "pushbullet_prio_download", "pushbullet_prio_pause_resume", "pushbullet_prio_pp", "pushbullet_prio_complete", "pushbullet_prio_failed", "pushbullet_prio_disk_full", "pushbullet_prio_warning", "pushbullet_prio_error", "pushbullet_prio_queue_done", "pushbullet_prio_other", "pushbullet_prio_new_login", ), "apprise": ( "apprise_enable", "apprise_cats", "apprise_urls", "apprise_target_startup", "apprise_target_startup_enable", "apprise_target_download", "apprise_target_download_enable", "apprise_target_pause_resume", "apprise_target_pause_resume_enable", "apprise_target_pp", "apprise_target_pp_enable", "apprise_target_complete", "apprise_target_complete_enable", "apprise_target_failed", "apprise_target_failed_enable", "apprise_target_disk_full", "apprise_target_disk_full_enable", "apprise_target_warning", "apprise_target_warning_enable", "apprise_target_error", "apprise_target_error_enable", "apprise_target_queue_done", "apprise_target_queue_done_enable", "apprise_target_other", "apprise_target_other_enable", "apprise_target_new_login", "apprise_target_new_login_enable", ), "nscript": ( "nscript_enable", "nscript_cats", "nscript_script", "nscript_parameters", "nscript_prio_startup", "nscript_prio_download", "nscript_prio_pause_resume", "nscript_prio_pp", "nscript_prio_complete", "nscript_prio_failed", "nscript_prio_disk_full", "nscript_prio_warning", "nscript_prio_error", "nscript_prio_queue_done", "nscript_prio_other", "nscript_prio_new_login", ), } class ConfigNotify: def __init__(self, root): self.__root = root @secured_expose(check_configlock=True) def index(self, **kwargs): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf["notify_types"] = sabnzbd.notifier.NOTIFICATION_TYPES conf["categories"] = list_cats(False) conf["have_ntfosd"] = sabnzbd.notifier.have_ntfosd() conf["have_ncenter"] = sabnzbd.MACOS and sabnzbd.FOUNDATION conf["scripts"] = list_scripts(default=False, none=True) for section in NOTIFY_OPTIONS: for option in NOTIFY_OPTIONS[section]: # Use get_string to make sure lists are displayed correctly conf[option] = config.get_config(section, option).get_string() return template_filtered_response( file=os.path.join(sabnzbd.WEB_DIR_CONFIG, "config_notify.tmpl"), search_list=conf, ) @secured_expose(check_api_key=True, check_configlock=True) def saveNotify(self, **kwargs): for section in NOTIFY_OPTIONS: for option in NOTIFY_OPTIONS[section]: if msg := config.get_config(section, option).set(kwargs.get(option)): return badParameterResponse(msg, kwargs.get("ajax")) config.save_config() if kwargs.get("ajax"): return sabnzbd.api.report() else: raise Raiser(self.__root) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.447278 SABnzbd-4.3.2/sabnzbd/sorting.py0000644000000000000000000011531714625637243015715 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.sorting - Sorting Functions """ import os import logging import re import guessit from rebulk.match import MatchesDict from string import whitespace, punctuation from typing import Optional, Union, List, Tuple, Dict import sabnzbd from sabnzbd.filesystem import ( move_to_path, cleanup_empty_directories, get_unique_filename, get_ext, globber, renamer, sanitize_foldername, clip_path, ) import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.constants import ( EXCLUDED_GUESSIT_PROPERTIES, IGNORED_MOVIE_FOLDERS, GUESSIT_PART_INDICATORS, GUESSIT_SORT_TYPES, ) from sabnzbd.misc import is_sample, from_units, sort_to_opts from sabnzbd.nzbstuff import NzbObject, scan_password # Do not rename .vob files as they are usually DVD's EXCLUDED_FILE_EXTS = (".vob", ".bin") LOWERCASE = ("the", "of", "and", "at", "vs", "a", "an", "but", "nor", "for", "on", "so", "yet", "with") UPPERCASE = ("III", "II", "IV") REPLACE_AFTER = {"()": "", "..": ".", "__": "_", " ": " ", " .%ext": ".%ext"} RE_GI = re.compile(r"(%G([._]?)I<(\w+)>)") # %GI, %G.I, or %G_I RE_LOWERCASE = re.compile(r"{([^{]*)}") RE_ENDEXT = re.compile(r"\.%ext}?$", re.I) RE_ENDFN = re.compile(r"%fn}?$", re.I) # Prevent guessit/rebulk from spamming the log when debug logging is active in SABnzbd logging.getLogger("rebulk").setLevel(logging.WARNING) class Sorter: """Generic Sorter class""" def __init__( self, nzo: Optional[NzbObject], job_name: str, path: Optional[str] = None, cat: Optional[str] = None, force: Optional[bool] = False, sorter_config: Optional[dict] = None, ): self.sorter_active = False self.original_job_name = job_name self.original_path = path self.nzo = nzo self.cat = cat self.sorter_config = sorter_config self.force = force self.filename_set = "" self.rename_files = False self.rename_limit = -1 self.info = {} self.type = None # tv, date, movie, unknown self.guess = None self.sort_string = None self.multipart_label = None self.is_season_pack = False self.season_pack_setname = "" self.match_sorters() def match_sorters(self): # If a sorter configuration is passed as an argument, only use that one sorters = [self.sorter_config] if self.sorter_config else config.get_ordered_sorters() # Figure out which sorter should be applied (if any) for sorter in sorters: # Check for category match (or forced) if self.force or ( sorter["is_active"] and sorter["sort_string"] and sorter["sort_cats"] and self.cat and self.cat.lower() in [cat.lower() for cat in sorter["sort_cats"]] ): # Let guessit do its thing, and set the job type if not self.guess: self.guess = guess_what(self.original_job_name) # Set the detected job type if self.guess["type"] == "episode": self.type = "date" if self.guess.get("date") else "tv" else: self.type = self.guess["type"] # movie, other # Check if the sorter should be applied to the guessed type (or forced) if ( not self.force and sorter["sort_type"] and not any(sort_to_opts(t) in sorter["sort_type"] for t in (self.type, "all")) ): # Sorter is restricted to some other content type(s) logging.debug( "Guessed type %s of job %s doesn't match sorter %s (%s)", self.type, self.original_job_name, sorter["name"], ", ".join({GUESSIT_SORT_TYPES[t] for t in sorter["sort_type"]}), ) # Move on to the next candidate continue # Bingo! logging.debug( "Matched sorter %s to job %s (forced: %s, custom: %s)", sorter["name"], self.original_job_name, self.force, bool(self.sorter_config), ) self.sorter_active = True self.sort_string = sorter["sort_string"] self.multipart_label = sorter["multipart_label"] self.rename_limit = int(from_units(sorter["min_size"])) # Check for season pack indicators if ( self.type == "tv" and cfg.enable_season_sorting() and self.guess.get("season") and not isinstance(self.guess.get("season"), list) # No support for multi-season packs (yet) and ((not self.guess.get("episode")) or isinstance(self.guess.get("episode"), list)) ): # The jobname indicates a season pack, i.e. guessit found a single season number but: # either no episodes at all ("S01"), or multiple episodes ("S01E01-02-03") self.is_season_pack = True logging.debug("Activated season pack handling for job %s", self.original_job_name) # Don't consider any further sorters break else: logging.debug("No matching sorter found for job %s", self.original_job_name) def get_values(self): self.get_year() self.get_names() self.get_resolution() self.get_seasons() self.get_episodes() self.get_showdescriptions() self.get_date() def format_series_numbers(self, numbers: Union[int, List[int]], info_name: str): """Format the numbers in both plain and alternative (zero-padded) format and set as showinfo""" # Guessit returns multiple episodes or seasons as a list of integers, single values as int if isinstance(numbers, int): self.info[info_name] = str(numbers) # 1 self.info[info_name + "_alt"] = str(numbers).rjust(2, "0") # 01 else: self.info[info_name] = "-".join([str(num) for num in numbers]) # 1-2-3 self.info[info_name + "_alt"] = "-".join([str(num).rjust(2, "0") for num in numbers]) # 01-02-03 def get_date(self): """Get month and day""" self.info["month"] = self.info["day"] = self.info["month_two"] = self.info["day_two"] = "" try: self.info["month"] = str(self.guess.get("date").month) self.info["day"] = str(self.guess.get("date").day) # Zero-padded versions of the same if self.info["month"]: self.info["month_two"] = self.info["month"].rjust(2, "0") if self.info["day"]: self.info["day_two"] = self.info["day"].rjust(2, "0") except AttributeError: pass def get_episodes(self): """Fetch the guessed episode number(s)""" self.format_series_numbers(self.guess.get("episode", ""), "episode_num") def get_final_path(self) -> str: if self.sorter_active: # Construct the final path self.get_values() return os.path.join(self.original_path, self.construct_path()) else: # No matching sorter found return os.path.join(self.original_path, self.original_job_name) def get_names(self): """Get the show or movie name from the guess and format it""" # Get the formatted title and alternate title formats self.info["ttitle"], self.info["ttitle_two"], self.info["ttitle_three"] = get_titles( self.nzo, self.guess, self.original_job_name, True ) self.info["title"], self.info["title_two"], self.info["title_three"] = get_titles( self.nzo, self.guess, self.original_job_name ) def get_resolution(self): self.info["resolution"] = self.guess.get("screen_size", "") def get_seasons(self): """Fetch the guessed season number(s)""" self.format_series_numbers(self.guess.get("season", ""), "season_num") def get_showdescriptions(self): """Get the show descriptions based on metadata, guessit and jobname""" self.info["ep_name"], self.info["ep_name_two"], self.info["ep_name_three"] = get_descriptions( self.nzo, self.guess ) def get_year(self): """Get the year and the corresponding two and four digit decade values""" year = "" if self.nzo: year = self.nzo.nzo_info.get("year") if not year: year = self.guess.get("year", "") if not year: # Try extracting the year from the guessed date instead try: year = self.guess.get("date").year or "" except Exception: pass self.info["year"] = str(year) self.info["decade"] = "" self.info["decade_two"] = "" if self.info["year"]: try: self.info["decade"] = self.info["year"][2:3] + "0" self.info["decade_two"] = self.info["year"][:3] + "0" except TypeError: pass def is_proper(self) -> bool: """Determine if the release is tagged 'Proper'. Note that guessit also sets this for similar tags such as 'Real' and 'Repack', saving us the trouble of checking for additional keywords.""" if not self.guess: return False other = self.guess.get("other", "") if isinstance(other, list): return "Proper" in other else: return other == "Proper" def construct_path(self) -> str: """Map all markers and replace the sort string with real values""" sort_string = self.sort_string mapping = [] if ends_in_file(sort_string): extension = True if sort_string.endswith(".%ext"): sort_string = sort_string[:-5] # Strip '.%ext' off the end; other %ext may remain in sort_string if self.is_season_pack: # Create a record of the filename part of the sort_string _, self.season_pack_setname = os.path.split(sort_string) if not any( substring in self.season_pack_setname for substring in ("%e", "%0e", "%GI", "%G.I", "%G_I") ): # Cancel season pack handling if the sort string for the filename lacks episode mapping self.is_season_pack = False logging.debug( "Cancelled season pack handling for job %s: no episode mapper in season pack setname %s", self.original_job_name, self.season_pack_setname, ) else: extension = False if self.is_season_pack: self.is_season_pack = False logging.debug( "Cancelled season pack handling for job %s: sort string %s does not rename files", self.original_job_name, sort_string, ) # Title mapping.append(("%title", self.info["title"])) mapping.append(("%.title", self.info["title_two"])) mapping.append(("%_title", self.info["title_three"])) # Legacy markers for the same; note that %t must come after %title mapping.append(("%t", self.info["title"])) mapping.append(("%.t", self.info["title_two"])) mapping.append(("%_t", self.info["title_three"])) mapping.append(("%sN", self.info["title"])) mapping.append(("%s.N", self.info["title_two"])) mapping.append(("%s_N", self.info["title_three"])) # Titlecased title mapping.append(("%sn", self.info["ttitle"])) mapping.append(("%s.n", self.info["ttitle_two"])) mapping.append(("%s_n", self.info["ttitle_three"])) # Original directory name mapping.append(("%dn", self.original_job_name)) # Resolution mapping.append(("%r", self.info["resolution"])) # Year mapping.append(("%year", self.info["year"])) mapping.append(("%y", self.info["year"])) # Decades mapping.append(("%decade", self.info["decade"])) mapping.append(("%0decade", self.info["decade_two"])) # Episode name mapping.append(("%en", self.info["ep_name"])) mapping.append(("%e.n", self.info["ep_name_two"])) mapping.append(("%e_n", self.info["ep_name_three"])) # Legacy %desc if self.type == "date" and self.info.get("ep_name"): # For date, %desc was no longer listed but still supported in the backend. For tv, # it was invalid and %en (etc.) used instead. For backward compatibility, map %desc # to %en for 'date' only and remove for 'tv' and other types. mapping.append(("%desc", self.info["ep_name"])) else: mapping.append(("%desc", "")) # Season number mapping.append(("%s", self.info["season_num"])) mapping.append(("%0s", self.info["season_num_alt"])) # Month mapping.append(("%m", self.info["month"])) mapping.append(("%0m", self.info["month_two"])) # Day mapping.append(("%d", self.info["day"])) mapping.append(("%0d", self.info["day_two"])) # Handle generic guessit markers for marker, spacer, guess_property in re.findall(RE_GI, sort_string): # Keep the episode property around until after the season pack handling, same as %e and %0e if guess_property != "episode": value = self.guess.get(guess_property, "") if self.guess else "" # Guessit returns a list for some properties in case they have multiple entries/values if isinstance(value, list): value = "-".join([str(v) for v in value]) # Format as value1-value2 else: value = str(value) if spacer: value = value.replace(" ", spacer) mapping.append((marker, value)) # Create a record of the season pack setname before the episode number markers are added to the mapping if self.is_season_pack: self.season_pack_setname = path_subst(self.season_pack_setname, mapping) for key, name in REPLACE_AFTER.items(): self.season_pack_setname = self.season_pack_setname.replace(key, name) # Episode numbers; note these must come last (after both the %en variants and setting self.season_pack_setname) mapping.append(("%e", self.info["episode_num"])) mapping.append(("%0e", self.info["episode_num_alt"])) # Map the GI episode property to episode_num; their formatting is identical for every spacer option mapping.append(("%GI", self.info["episode_num"])) mapping.append(("%G.I", self.info["episode_num"])) mapping.append(("%G_I", self.info["episode_num"])) # Replace elements path = path_subst(sort_string, mapping) for key, name in REPLACE_AFTER.items(): path = path.replace(key, name) # Lowercase all characters wrapped in {} path = to_lowercase(path) # Strip any extra spaces, dots, and underscores around directory names path = strip_path_elements(path) # Split the last part of the path up for the renamer if extension: path, self.filename_set = os.path.split(path) self.rename_files = True # Avoid turning the path absolute on *nix (e.g. sort_string '%r/...' with an empty mapping for %r) if path.startswith(os.path.sep) and not sort_string.startswith(os.path.sep): path = path.lstrip(os.path.sep) # The normpath function translates "" to "." which results in an incorrect path return os.path.normpath(path) if path else path def _rename_season_pack(self, files: List[str], base_path: str, all_job_files: List[str] = []) -> bool: success = False for f in files: f_name, f_ext = os.path.splitext(os.path.basename(f)) if f_episode := guessit.api.guessit(f_name).get("episode"): # Insert formatted episode number(s) into self.info self.format_series_numbers(f_episode, "episode_num") # Build the new filename from self.season_pack_setname, filling in the remaining markers f_name_new = path_subst( self.season_pack_setname, [ ("%e", self.info["episode_num"]), ("%GI", self.info["episode_num"]), ("%G.I", self.info["episode_num"]), ("%G_I", self.info["episode_num"]), ("%0e", self.info["episode_num_alt"]), ("%fn", f_name), ("%ext", f_ext.lstrip(".")), ], ) f_new = to_lowercase(f_name_new + f_ext) try: logging.debug("Renaming season pack file %s to %s", f, f_new) renamer(self._to_filepath(f, base_path), self._to_filepath(f_new, base_path)) success = True except Exception: logging.error("Failed to rename file %s to %s in season pack %s", f, f_new, self.original_job_name) logging.info("Traceback: ", exc_info=True) # Move on to the next file continue # Rename similar files and move to base_path for sim_f in globber(base_path, f_name + "*"): # Only take into consideration: # * existing files (but not directories), # * that were created as part of this job, # * and didn't qualify for processing in the own right. if os.path.isfile(os.path.join(base_path, sim_f)) and sim_f in all_job_files and sim_f not in files: sim_f_new = os.path.basename(sim_f).replace(f_name, f_name_new, 1) logging.debug("Renaming %s to %s (alongside season pack file %s)", sim_f, sim_f_new, f) try: renamer(self._to_filepath(sim_f, base_path), self._to_filepath(sim_f_new, base_path)) except Exception: logging.error( "Failed to rename similar file %s to %s (alongside %s in season pack %s)", sim_f, sim_f_new, f, self.original_job_name, ) logging.info("Traceback: ", exc_info=True) else: logging.debug( "Failed to get episode info from filename %s in season pack %s", f, self.original_job_name ) return success def _rename_sequential(self, sequential_files: Dict[str, str], base_path: str) -> bool: success = False for index, f in sequential_files.items(): filepath = self._to_filepath(f, base_path) f_name, f_ext = os.path.splitext(os.path.split(f)[1]) new_filepath = os.path.join( base_path, to_lowercase( path_subst( self.filename_set + self.multipart_label, [("%1", str(index)), ("%fn", f_name), ("%ext", f_ext.lstrip("."))], ) + f_ext, ), ) try: logging.debug("Renaming %s to %s", filepath, new_filepath) renamer(filepath, new_filepath) success = True rename_similar(base_path, f_ext, self.filename_set, [new_filepath]) except Exception: logging.error(T("Failed to rename %s to %s"), clip_path(filepath), clip_path(new_filepath)) logging.info("Traceback: ", exc_info=True) return success def _to_filepath(self, f: str, base_path: str) -> str: if not is_full_path(f): f = os.path.join(base_path, f) return os.path.normpath(f) def _filter_files(self, f: str, base_path: str) -> bool: filepath = self._to_filepath(f, base_path) return ( not is_sample(f) and get_ext(f) not in EXCLUDED_FILE_EXTS and os.path.exists(filepath) and os.stat(filepath).st_size >= self.rename_limit ) def rename(self, files: List[str], base_path: str) -> Tuple[str, bool]: if not self.rename_files: return move_to_parent_directory(base_path) # Log the minimum filesize for renaming if self.rename_limit > 0: logging.debug("Minimum filesize for renaming set to %s bytes", self.rename_limit) # Store the list of all files for later use all_files = files # Filter files to remove nonexistent, undersized, samples, and excluded extensions files = [f for f in files if self._filter_files(f, base_path)] if len(files) == 0: logging.debug("No files left to rename after applying filter") return move_to_parent_directory(base_path) # Check for season packs or sequential filenames and handle their renaming separately; # if neither applies or succeeds, fall back to going with the single largest file instead. if len(files) > 1: # Season packs handling if self.is_season_pack: logging.debug("Trying to rename season pack files %s", files) if self._rename_season_pack(files, base_path, all_files): cleanup_empty_directories(base_path) return move_to_parent_directory(base_path) else: logging.debug("Season pack sorting didn´t rename any files") # Try generic sequential files handling if self.multipart_label and (sequential_files := check_for_multiple(files)): logging.debug("Trying to rename sequential files %s", sequential_files) if self._rename_sequential(sequential_files, base_path): cleanup_empty_directories(base_path) return move_to_parent_directory(base_path) else: logging.debug("Sequential file handling didn't rename any files") # Find the largest file largest_file = {"name": None, "size": 0} for f in files: f_size = os.stat(self._to_filepath(f, base_path)).st_size if f_size > largest_file.get("size"): largest_file.update({"name": f, "size": f_size}) # Rename it f_name, f_ext = os.path.splitext(largest_file.get("name")) filepath = self._to_filepath(largest_file.get("name"), base_path) new_filepath = os.path.join( base_path, to_lowercase(path_subst(self.filename_set, [("%fn", f_name), ("%ext", f_ext.lstrip("."))]) + f_ext), ) if not os.path.exists(new_filepath): renamed_files = [] try: logging.debug("Renaming %s to %s", filepath, new_filepath) renamer(filepath, new_filepath) renamed_files.append(new_filepath) except Exception: logging.error(T("Failed to rename %s to %s"), clip_path(base_path), clip_path(new_filepath)) logging.info("Traceback: ", exc_info=True) rename_similar(base_path, f_ext, self.filename_set, renamed_files) else: logging.debug("Cannot rename %s, new path %s already exists.", largest_file.get("name"), new_filepath) return move_to_parent_directory(base_path) class BasicAnalyzer(Sorter): def __init__(self, job_name: str): """Very basic sorter that doesn't require a config""" super().__init__(nzo=None, job_name=job_name) # Directly trigger setting all values self.get_values() def match_sorters(self): """Much more basic matching""" self.guess = guess_what(self.original_job_name) # Set the detected job type self.type = self.guess["type"] if self.guess["type"] == "episode": self.type = "date" if self.guess.get("date") else "tv" def ends_in_file(path: str) -> bool: """Return True when path ends with '.%ext' or '%fn' while allowing for a lowercase marker""" return bool(RE_ENDEXT.search(path) or RE_ENDFN.search(path)) def move_to_parent_directory(workdir: str) -> Tuple[str, bool]: """Move all files under 'workdir' into 'workdir/..'""" # Determine 'folder'/.. workdir = os.path.abspath(os.path.normpath(workdir)) dest = os.path.abspath(os.path.normpath(os.path.join(workdir, ".."))) logging.debug("Moving all files from %s to %s", workdir, dest) # Check for DVD folders and bail out if found for item in os.listdir(workdir): if item.lower() in IGNORED_MOVIE_FOLDERS: return workdir, True for root, dirs, files in os.walk(workdir): for _file in files: path = os.path.join(root, _file) new_path = path.replace(workdir, dest) ok, new_path = move_to_path(path, new_path) if not ok: return dest, False cleanup_empty_directories(workdir) return dest, True def guess_what(name: str) -> MatchesDict: """Guess metadata for movies or episodes from their name.""" if not name: raise ValueError("Need a name for guessing") # Remove any passwords from the name name = scan_password(name)[0] # Avoid trouble with names starting with a digit (esp. with no year in the name) digit_fix = "FIX" if name[0].isdigit() else "" guessit_options = { # "no-user-config": True, "expected_title": [], # This isn't empty by default? # "allowed_countries": [], # "allowed_languages": [], "excludes": EXCLUDED_GUESSIT_PROPERTIES, "date_year_first": True, # Make sure also short-dates are detected as YY-MM-DD } guess = guessit.api.guessit(digit_fix + name, options=guessit_options) logging.debug("Initial guess for %s is %s", digit_fix + name, guess) if digit_fix: # Unfix the title guess["title"] = guess.get("title", "")[len(digit_fix) :] # Force season to 1 for seasonless episodes with no date if guess.get("type") == "episode" and "date" not in guess: guess.setdefault("season", 1) # Try to avoid setting the type to movie on arbitrary jobs (e.g. 'Setup.exe') just because guessit defaults to that table = str.maketrans({char: "" for char in whitespace + "_.-()[]{}"}) if guess.get("type") == "movie": if ( guess.get("title", "").translate(table) == name.translate(table) # Check for full name used as title or any( c in guess.get("release_group", "") for c in (whitespace + punctuation) ) # interpuction of white spaces in the groupname or not any( [key in guess for key in ("year", "screen_size", "video_codec")] ) # No typical movie properties set or ( name.lower().startswith(("http://", "https://")) and name.lower().endswith(".nzb") and guess.get("container") == "nzb" ) # URL to an nzb file, can happen when pre-queue script rejects a job ): guess["type"] = "unknown" return guess def path_subst(path: str, mapping: List[Tuple[str, str]]) -> str: """Replace the sort string elements in the path with the real values provided by the mapping; non-elements are copied verbatim.""" # Added ugly hack to prevent %ext from being masked by %e newpath = [] plen = len(path) n = 0 while n < plen: result = path[n] if result == "%": for key, value in mapping: if path.startswith(key, n) and not path.startswith("%ext", n): n += len(key) - 1 result = value break if result: newpath.append(result) n += 1 return "".join(newpath) def get_titles( nzo: Optional[NzbObject], guess: Optional[MatchesDict], jobname: str, titleing: bool = False ) -> Tuple[str, str, str]: """Get the title from NZB metadata or jobname, and return it in various formats. Formatting mostly deals with working around quirks of Python's str.title(). NZB metadata is used as-is, further processing done only for info obtained from guessit or the jobname.""" title = "" if nzo: # Fetch NZB metadata title = nzo.nzo_info.get("propername") if not title: # Try guessit next if guess: title = guess.get("title", "") # Fallback to the jobname if neither of the better options yielded a title if not title: title = jobname.replace(".", " ").replace("_", " ").strip(whitespace + "._-") if titleing: # Titlecase the show name so it is in a consistent letter case title = title.title() # Get rid of 's uppercased by str.title() title = title.replace("'S", "'s") # Make sure some words such as 'and' or 'of' stay lowercased. for x in LOWERCASE: xtitled = x.title() title = replace_word(title, xtitled, x) # Make sure some words such as 'III' or 'IV' stay uppercased. for x in UPPERCASE: xtitled = x.title() title = replace_word(title, xtitled, x) # Make sure the first letter of the title is always uppercase if title: title = title[0].title() + title[1:] if guess and "country" in guess: title += " " + str(guess.get("country")) # Append ' CC' # Alternative formats dots = re.sub( r"\.{2,}", ".", title.replace(" - ", "-").replace(" ", ".").replace("_", ".").replace("(", ".").replace(")", "."), ).rstrip(".") underscores = re.sub("_{2,}", "_", title.replace(" ", "_").replace(".", "_")).rstrip("_") return title, dots, underscores def replace_word(word_input: str, one: str, two: str) -> str: """Regex replace on just words""" if matches := re.findall(r"\W(%s)(\W|$)" % one, word_input, re.I): for _ in matches: word_input = word_input.replace(one, two) return word_input def get_descriptions(nzo: Optional[NzbObject], guess: Optional[MatchesDict]) -> Tuple[str, str, str]: """Try to get an episode title or similar description from the NZB metadata or jobname, e.g. 'Download This' in Show.S01E23.Download.This.1080p.HDTV.x264 and return multiple formats""" ep_name = None if nzo: ep_name = nzo.nzo_info.get("episodename") if (not ep_name) and guess: ep_name = guess.get("episode_title") ep_name = ep_name or "" ep_name = ep_name.strip("- _.") if "." in ep_name and " " not in ep_name: ep_name = ep_name.replace(".", " ") # Return the episode names with spaces, dots, and underscores return ep_name.replace("_", " "), ep_name.replace(" - ", "-").replace(" ", "."), ep_name.replace(" ", "_") def to_lowercase(path: str) -> str: """Lowercases any characters enclosed in {}""" while True: m = RE_LOWERCASE.search(path) if not m: break path = path[: m.start()] + m.group(1).lower() + path[m.end() :] # Remove any remaining '{' and '}' return path.replace("{", "").replace("}", "") def strip_path_elements(path: str) -> str: """Return 'path' without leading and trailing spaces and underscores in each element""" # Clear the most deviant of UNC notations path = clip_path(path) if sabnzbd.WIN32: path = path.replace("\\", "/") # Switch to unix style directory separators is_unc = sabnzbd.WIN32 and path.startswith("//") path_elements = path.strip("/").split("/") # Insert an empty element to prevent loss, if path starts with a slash try: if not is_unc and path.strip()[0] in "/": path_elements.insert(0, "") except IndexError: pass # For Windows, also remove leading and trailing dots: it cannot handle trailing dots, and # leading dots carry no significance like on macOS, Linux, etc. chars = whitespace + "_" + ("." if sabnzbd.WIN32 else "") # Clean all elements and reconstruct the path path = os.path.normpath("/".join([element.strip(chars) for element in path_elements])) path = path.replace("//", "/") # Re: https://bugs.python.org/issue26329 return "\\\\" + path if is_unc else path def rename_similar(folder: str, skip_ext: str, name: str, skipped_files: Optional[List[str]] = None): """Rename all other files in the 'folder' hierarchy after 'name' and move them to the root of 'folder'. Files having extension 'skip_ext' will be moved, but not renamed. Don't touch files in list `skipped_files` """ logging.debug('Give files in set "%s" matching names.', name) folder = os.path.normpath(folder) skip_ext = skip_ext.lower() for root, dirs, files in os.walk(folder): for f in files: path = os.path.join(root, f) if skipped_files and path in skipped_files: continue org, ext = os.path.splitext(f) if ext.lower() == skip_ext: # Move file, but do not rename newpath = os.path.join(folder, f) else: # Move file and rename newname = "%s%s" % (name, ext) newname = newname.replace("%fn", org) newpath = os.path.join(folder, newname) if path != newpath: newpath = get_unique_filename(newpath) try: logging.debug("Rename: %s to %s", path, newpath) renamer(path, newpath) except: logging.error(T("Failed to rename similar file: %s to %s"), clip_path(path), clip_path(newpath)) logging.info("Traceback: ", exc_info=True) cleanup_empty_directories(folder) def is_full_path(file: str) -> bool: """Determine whether file has an absolute path""" return file.startswith("/") or (sabnzbd.WIN32 and (file.startswith("\\") or file[1:3] == ":\\")) def eval_sort(sort_string: str, job_name: str, multipart_label: str = "") -> Optional[str]: """Preview results for a given jobname and sort_string""" job_name = sanitize_foldername(job_name) if not job_name or not sort_string: return None # Fire up a dummy Sorter with settings and jobname from the preview sorter = Sorter( None, job_name, "", None, force=True, sorter_config={ "name": "config__eval_sort", "order": 0, "min_size": -1, "multipart_label": multipart_label, "sort_string": sort_string, "sort_cats": [], # Don't bother with categories or types, ignored with force=True "sort_type": [], "is_active": True, }, ) sorted_path = os.path.normpath(os.path.join(sorter.get_final_path(), sorter.filename_set)) if not sorted_path: return None # Append a (placeholder) filename, multipart label, and extension or slash from sabnzbd.api import Ttemplate original_filename = Ttemplate("orgFilename") if "%fn" in sorted_path: sorted_path = sorted_path.replace("%fn", original_filename) if multipart_label: sorted_path = sorted_path.replace("%1", multipart_label.replace("%1", "1")) if sorter.rename_files: sorted_path += ".ext" else: sorted_path += "\\" if sabnzbd.WIN32 else "/" return sorted_path def check_for_multiple(files: List[str]) -> Optional[Dict[str, str]]: """Return a dictionary of a single set of files that look like parts of a multi-part post. Takes a limited set of indicators from guessit into consideration and only accepts numerical sequences. The files argument is expected to be a list of basenames, not full paths.""" candidates = {} wanted_title = None wanted_indicators = GUESSIT_PART_INDICATORS for f in files: # Add a prefix to make guessit hit on indicators at the start of filenames as well guess = guessit.api.guessit("PREFIX " + f) # Ignore filenames without part indicators if "title" in guess and any(key in guess for key in GUESSIT_PART_INDICATORS): # Create a record of the first title found if not wanted_title: wanted_title = guess["title"] # Take only files with a matching title into consideration if wanted_title == guess["title"]: for indicator in wanted_indicators: if value := guess.get(indicator): if isinstance(value, int) and value not in candidates.keys(): # Store the candidate candidates[value] = f # e.g. { int(1): str('filename part 1.txt') } # Lock down the indicator, akin to the title if len(wanted_indicators) > 1: wanted_indicators = (indicator,) break # Verify the candidates form a numerical sequence: if len(candidates) < 2 or sorted(candidates) != list(range(min(candidates), max(candidates) + 1)): return None else: # Return sequential files with the integer dictionary keys converted to strings return {str(key): value for key, value in candidates.items()} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4473495 SABnzbd-4.3.2/sabnzbd/__init__.py0000644000000000000000000004034314625637243015763 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os import logging import datetime import ctypes.util import time import socket import cherrypy import platform import concurrent.futures import sys from threading import Lock, Condition ############################################################################## # Determine platform flags ############################################################################## WIN32 = WIN64 = MACOS = MACOSARM64 = FOUNDATION = DOCKER = False KERNEL32 = LIBC = MACOSLIBC = None if os.name == "nt": WIN32 = True WIN64 = platform.uname().machine == "AMD64" from sabnzbd.utils.apireg import del_connection_info try: KERNEL32 = ctypes.windll.LoadLibrary("Kernel32.dll") except: pass elif os.name == "posix": ORG_UMASK = os.umask(18) os.umask(ORG_UMASK) # Check if running in a Docker container. Note: fake-able, but good enough for normal setups DOCKER = os.path.exists("/.dockerenv") # See if we have the GNU glibc malloc_trim() memory release function try: LIBC = ctypes.CDLL("libc.so.6") LIBC.malloc_trim(0) # try the malloc_trim() call, which is a GNU extension except: # No malloc_trim(), probably because no glibc LIBC = None pass # Parse macOS version numbers if platform.system().lower() == "darwin": MACOS = True MACOSARM64 = platform.uname().machine == "arm64" MACOSLIBC = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True) # the MacOS C library try: import Foundation import sabnzbd.utils.sleepless as sleepless FOUNDATION = True except: pass # Imported to be referenced from other files directly from sabnzbd.version import __version__, __baseline__ # Now we can import safely import sabnzbd.misc as misc import sabnzbd.filesystem as filesystem import sabnzbd.powersup as powersup import sabnzbd.rss as rss import sabnzbd.emailer as emailer import sabnzbd.encoding as encoding import sabnzbd.config as config import sabnzbd.cfg as cfg import sabnzbd.database import sabnzbd.lang as lang import sabnzbd.nzbparser as nzbparser import sabnzbd.nzbstuff import sabnzbd.getipaddress import sabnzbd.newsunpack import sabnzbd.par2file import sabnzbd.api import sabnzbd.interface import sabnzbd.zconfig import sabnzbd.directunpacker as directunpacker import sabnzbd.dirscanner import sabnzbd.urlgrabber import sabnzbd.nzbqueue import sabnzbd.postproc import sabnzbd.downloader import sabnzbd.decoder import sabnzbd.assembler import sabnzbd.articlecache import sabnzbd.bpsmeter import sabnzbd.scheduler as scheduler import sabnzbd.notifier as notifier import sabnzbd.sorting from sabnzbd.decorators import synchronized import sabnzbd.utils.ssdp # Storage for the threads, variables are filled during initialization ArticleCache: sabnzbd.articlecache.ArticleCache Assembler: sabnzbd.assembler.Assembler Downloader: sabnzbd.downloader.Downloader PostProcessor: sabnzbd.postproc.PostProcessor NzbQueue: sabnzbd.nzbqueue.NzbQueue URLGrabber: sabnzbd.urlgrabber.URLGrabber DirScanner: sabnzbd.dirscanner.DirScanner BPSMeter: sabnzbd.bpsmeter.BPSMeter RSSReader: sabnzbd.rss.RSSReader Scheduler: sabnzbd.scheduler.Scheduler # Regular constants START = datetime.datetime.now() MY_NAME = None MY_FULLNAME = None RESTART_ARGS = [] NEW_VERSION = (None, None) DIR_HOME = None DIR_LCLDATA = None DIR_PROG = None DIR_INTERFACES = None DIR_LANGUAGE = None DIR_PID = None QUEUECOMPLETE = None # stores the nice name of the action QUEUECOMPLETEACTION = None # stores the name of the function to be called DAEMON = None LINUX_POWER = powersup.HAVE_DBUS LOGFILE = None WEBLOGFILE = None GUIHANDLER = None LOG_ALL = False WIN_SERVICE = None # Instance of our Win32 Service Class BROWSER_URL = None NO_DOWNLOADING = False # When essentials are missing (SABCTools/par2/unrar) WEB_DIR = None WEB_DIR_CONFIG = None WIZARD_DIR = None WEB_COLOR = None SABSTOP = False RESTART_REQ = False PAUSED_ALL = False TRIGGER_RESTART = False # To trigger restart for Scheduler, WinService and Mac WINTRAY = None # Thread for the Windows SysTray icon MACOSTRAY = None # Thread for the macOS tray icon WEBUI_READY = False LAST_HISTORY_UPDATE = 1 RESTORE_DATA = None # Condition used to handle the main loop in SABnzbd.py SABSTOP_CONDITION = Condition(Lock()) # General threadpool THREAD_POOL = concurrent.futures.ThreadPoolExecutor(max_workers=2) # Performance measure for dashboard PYSTONE_SCORE = 0 DOWNLOAD_DIR_SPEED = 0 COMPLETE_DIR_SPEED = 0 INTERNET_BANDWIDTH = 0 # Record of HTTPS config files at startup CONFIG_BACKUP_HTTPS_OK = [] # Rendering of original command line arguments in Config CMDLINE = " ".join(['"%s"' % arg for arg in sys.argv]) __INITIALIZED__ = False __SHUTTING_DOWN__ = False ############################################################################## # Signal Handler ############################################################################## def sig_handler(signum=None, frame=None): if sabnzbd.WIN32 and signum is not None and DAEMON and signum == 5: # Ignore the "logoff" event when running as a Win32 daemon return True if signum is not None: logging.warning(T("Signal %s caught, saving and exiting..."), signum) sabnzbd.shutdown_program() ############################################################################## # Initializing ############################################################################## INIT_LOCK = Lock() def get_db_connection(thread_index=0): # Create a connection and store it in the current thread if not (hasattr(cherrypy.thread_data, "history_db") and cherrypy.thread_data.history_db): cherrypy.thread_data.history_db = sabnzbd.database.HistoryDB() return cherrypy.thread_data.history_db @synchronized(INIT_LOCK) def initialize(pause_downloader=False, clean_up=False, repair=0): if sabnzbd.__INITIALIZED__: return False sabnzbd.__SHUTTING_DOWN__ = False sys.setswitchinterval(cfg.switchinterval()) # Set global database connection for Web-UI threads cherrypy.engine.subscribe("start_thread", get_db_connection) # Paused? pause_downloader = pause_downloader or cfg.start_paused() # Clean-up, if requested if clean_up: # New admin folder filesystem.remove_all(cfg.admin_dir.get_path(), "*.sab") # Optionally wait for "incomplete" to become online if cfg.wait_for_dfolder(): filesystem.wait_for_download_folder() # Create the folders, now that we waited for them to be available cfg.download_dir.set_create(True) cfg.download_dir.create_path() cfg.complete_dir.set_create(True) cfg.complete_dir.create_path() # Set call backs for Config items cfg.cache_limit.callback(cfg.new_limit) cfg.cherryhost.callback(cfg.guard_restart) cfg.cherryport.callback(cfg.guard_restart) cfg.web_dir.callback(cfg.guard_restart) cfg.web_color.callback(cfg.guard_restart) cfg.username.callback(cfg.guard_restart) cfg.password.callback(cfg.guard_restart) cfg.log_dir.callback(cfg.guard_restart) cfg.https_port.callback(cfg.guard_restart) cfg.https_cert.callback(cfg.guard_restart) cfg.https_key.callback(cfg.guard_restart) cfg.enable_https.callback(cfg.guard_restart) cfg.socks5_proxy_url.callback(cfg.guard_restart) cfg.top_only.callback(cfg.guard_top_only) cfg.pause_on_post_processing.callback(cfg.guard_pause_on_pp) cfg.quota_size.callback(cfg.guard_quota_size) cfg.quota_day.callback(cfg.guard_quota_dp) cfg.quota_period.callback(cfg.guard_quota_dp) cfg.language.callback(cfg.guard_language) cfg.enable_https_verification.callback(cfg.guard_https_ver) cfg.guard_https_ver() # Set language files lang.set_locale_info("SABnzbd", DIR_LANGUAGE) lang.set_language(cfg.language()) sabnzbd.api.clear_trans_cache() # Set end-of-queue action sabnzbd.misc.change_queue_complete_action(cfg.queue_complete(), new=False) # Convert auto-sort if cfg.auto_sort() == "0": cfg.auto_sort.set("") elif cfg.auto_sort() == "1": cfg.auto_sort.set("avg_age asc") # Convert old series/date/movie sorters if not cfg.sorters_converted(): misc.convert_sorter_settings() cfg.sorters_converted.set(True) # Convert duplicate settings if cfg.no_series_dupes(): cfg.no_smart_dupes.set(cfg.no_series_dupes()) cfg.no_series_dupes.set(0) # Convert history retention setting if cfg.history_retention(): misc.convert_history_retention() cfg.history_retention.set("") # Add hostname to the whitelist if not cfg.host_whitelist(): cfg.host_whitelist.set(socket.gethostname()) # Do repair if requested if misc.check_repair_request(): repair = 2 pause_downloader = True # Initialize threads sabnzbd.ArticleCache = sabnzbd.articlecache.ArticleCache() sabnzbd.BPSMeter = sabnzbd.bpsmeter.BPSMeter() sabnzbd.NzbQueue = sabnzbd.nzbqueue.NzbQueue() sabnzbd.Downloader = sabnzbd.downloader.Downloader(sabnzbd.BPSMeter.read() or pause_downloader) sabnzbd.Assembler = sabnzbd.assembler.Assembler() sabnzbd.PostProcessor = sabnzbd.postproc.PostProcessor() sabnzbd.DirScanner = sabnzbd.dirscanner.DirScanner() sabnzbd.URLGrabber = sabnzbd.urlgrabber.URLGrabber() sabnzbd.RSSReader = sabnzbd.rss.RSSReader() sabnzbd.Scheduler = sabnzbd.scheduler.Scheduler() # Run startup tasks sabnzbd.NzbQueue.read_queue(repair) sabnzbd.Scheduler.analyse(pause_downloader) # Set cache limit for new users if not cfg.cache_limit(): cfg.cache_limit.set(misc.get_cache_limit()) sabnzbd.ArticleCache.new_limit(cfg.cache_limit.get_int()) logging.info("All processes started") sabnzbd.RESTART_REQ = False sabnzbd.__INITIALIZED__ = True @synchronized(INIT_LOCK) def start(): if sabnzbd.__INITIALIZED__: logging.debug("Starting postprocessor") sabnzbd.PostProcessor.start() logging.debug("Starting assembler") sabnzbd.Assembler.start() logging.debug("Starting downloader") sabnzbd.Downloader.start() logging.debug("Starting scheduler") sabnzbd.Scheduler.start() logging.debug("Starting dirscanner") sabnzbd.DirScanner.start() logging.debug("Starting urlgrabber") sabnzbd.URLGrabber.start() @synchronized(INIT_LOCK) def halt(): if sabnzbd.__INITIALIZED__: logging.info("SABnzbd shutting down...") sabnzbd.__SHUTTING_DOWN__ = True # Stop the windows tray icon if sabnzbd.WINTRAY: sabnzbd.WINTRAY.stop() # Remove registry information if sabnzbd.WIN32: del_connection_info() sabnzbd.zconfig.remove_server() sabnzbd.utils.ssdp.stop_ssdp() sabnzbd.directunpacker.abort_all() sabnzbd.THREAD_POOL.shutdown(wait=False) logging.debug("Stopping RSSReader") sabnzbd.RSSReader.stop() logging.debug("Stopping URLGrabber") sabnzbd.URLGrabber.stop() try: sabnzbd.URLGrabber.join(timeout=3) except: pass logging.debug("Stopping dirscanner") sabnzbd.DirScanner.stop() try: sabnzbd.DirScanner.join(timeout=3) except: pass logging.debug("Stopping downloader") sabnzbd.Downloader.stop() try: sabnzbd.Downloader.join(timeout=3) except: pass logging.debug("Stopping assembler") sabnzbd.Assembler.stop() try: sabnzbd.Assembler.join(timeout=3) except: pass logging.debug("Stopping postprocessor") sabnzbd.PostProcessor.stop() try: sabnzbd.PostProcessor.join(timeout=3) except: pass # Save State try: save_state() except: logging.error(T("Fatal error at saving state"), exc_info=True) # The Scheduler cannot be stopped when the stop was scheduled. # Since all warm-restarts have been removed, it's not longer # needed to stop the scheduler. # We must tell the scheduler to deactivate. logging.debug("Terminating scheduler") sabnzbd.Scheduler.abort() logging.info("All processes stopped") sabnzbd.__INITIALIZED__ = False def notify_shutdown_loop(): """Trigger the main loop to wake up""" with sabnzbd.SABSTOP_CONDITION: sabnzbd.SABSTOP_CONDITION.notify() def shutdown_program(): """Stop program after halting and saving""" if not sabnzbd.SABSTOP: logging.info("[%s] Performing SABnzbd shutdown", misc.caller_name()) sabnzbd.halt() cherrypy.engine.exit() sabnzbd.SABSTOP = True notify_shutdown_loop() def trigger_restart(timeout=None): """Trigger a restart by setting a flag an shutting down CP""" # Sometimes we need to wait a bit to send good-bye to the browser if timeout: time.sleep(timeout) # Set the flag and wake up the main loop sabnzbd.TRIGGER_RESTART = True notify_shutdown_loop() def save_state(): """Save all internal bookkeeping to disk""" config.save_config() sabnzbd.ArticleCache.flush_articles() sabnzbd.NzbQueue.save() sabnzbd.BPSMeter.save() sabnzbd.DirScanner.save() sabnzbd.PostProcessor.save() sabnzbd.RSSReader.save() def check_all_tasks(): """Check every task and restart safe ones, else restart program Return True when everything is under control """ if __SHUTTING_DOWN__ or not __INITIALIZED__: return True # Non-restartable threads, require program restart if not sabnzbd.PostProcessor.is_alive(): logging.warning(T("Restarting because of crashed postprocessor")) return False if not sabnzbd.Downloader.is_alive(): logging.warning(T("Restarting because of crashed downloader")) return False if not sabnzbd.Assembler.is_alive(): logging.warning(T("Restarting because of crashed assembler")) return False # Kick the downloader, in case it missed the semaphore sabnzbd.Downloader.wakeup() # Make sure the right servers are active sabnzbd.Downloader.check_timers() # Restartable threads if not sabnzbd.DirScanner.is_alive(): logging.info("Restarting crashed dirscanner") sabnzbd.DirScanner.__init__() if not sabnzbd.URLGrabber.is_alive(): logging.info("Restarting crashed urlgrabber") sabnzbd.URLGrabber.__init__() if not sabnzbd.Scheduler.is_alive(): logging.info("Restarting crashed scheduler") sabnzbd.Scheduler.restart() sabnzbd.Downloader.unblock_all() # Check one-shot pause sabnzbd.Scheduler.pause_check() # Check (and terminate) idle jobs sabnzbd.NzbQueue.stop_idle_jobs() # Check that the queue is sorted correctly sabnzbd.NzbQueue.update_sort_order() return True def pid_file(pid_path=None, pid_file=None, port=0): """Create or remove pid file""" if not sabnzbd.WIN32: if pid_path and pid_path.startswith("/"): sabnzbd.DIR_PID = os.path.join(pid_path, "sabnzbd-%d.pid" % port) elif pid_file and pid_file.startswith("/"): sabnzbd.DIR_PID = pid_file if sabnzbd.DIR_PID: try: if port: with open(sabnzbd.DIR_PID, "w") as f: f.write("%d\n" % os.getpid()) else: filesystem.remove_file(sabnzbd.DIR_PID) except: logging.warning(T("Cannot access PID file %s"), sabnzbd.DIR_PID) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4474328 SABnzbd-4.3.2/sabnzbd/newswrapper.py0000644000000000000000000004060414625637243016601 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.newswrapper """ import errno import socket from threading import Thread import time import logging import ssl import sabctools from typing import Optional, Tuple, Union import sabnzbd import sabnzbd.cfg from sabnzbd.constants import DEF_TIMEOUT, NNTP_BUFFER_SIZE from sabnzbd.encoding import utob, ubtou from sabnzbd.happyeyeballs import AddrInfo from sabnzbd.decorators import synchronized, DOWNLOADER_LOCK from sabnzbd.misc import int_conv # Set pre-defined socket timeout socket.setdefaulttimeout(DEF_TIMEOUT) class NNTPPermanentError(Exception): def __init__(self, msg: str, code: int): super().__init__() self.msg = msg self.code = code def __str__(self) -> str: return self.msg class NewsWrapper: # Pre-define attributes to save memory __slots__ = ( "server", "thrdnum", "blocking", "timeout", "article", "data", "data_view", "data_position", "nntp", "connected", "user_sent", "pass_sent", "group", "user_ok", "pass_ok", "force_login", ) def __init__(self, server, thrdnum, block=False): self.server: sabnzbd.downloader.Server = server self.thrdnum: int = thrdnum self.blocking: bool = block self.timeout: Optional[float] = None self.article: Optional[sabnzbd.nzbstuff.Article] = None self.data: Optional[bytearray] = None self.data_view: Optional[memoryview] = None self.data_position: int = 0 self.nntp: Optional[NNTP] = None self.connected: bool = False self.user_sent: bool = False self.pass_sent: bool = False self.user_ok: bool = False self.pass_ok: bool = False self.force_login: bool = False self.group: Optional[str] = None @property def status_code(self) -> Optional[int]: if self.data_position >= 3: return int_conv(self.data[:3]) @property def nntp_msg(self) -> str: return ubtou(self.data[: self.data_position]).strip() def init_connect(self): """Setup the connection in NNTP object""" # Sanity check, especially for the server test if not self.server.addrinfo: raise socket.error(errno.EADDRNOTAVAIL, T("Invalid server address.")) # Construct buffer and NNTP object self.data = sabctools.bytearray_malloc(NNTP_BUFFER_SIZE) self.data_view = memoryview(self.data) self.reset_data_buffer() self.nntp = NNTP(self, self.server.addrinfo) self.timeout = time.time() + self.server.timeout def finish_connect(self, code: int): """Perform login options""" if not (self.server.username or self.server.password or self.force_login): self.connected = True self.user_sent = True self.user_ok = True self.pass_sent = True self.pass_ok = True if code == 480: self.force_login = True self.connected = False self.user_sent = False self.user_ok = False self.pass_sent = False self.pass_ok = False if code in (400, 500, 502): raise NNTPPermanentError(self.nntp_msg, code) elif not self.user_sent: command = utob("authinfo user %s\r\n" % self.server.username) self.nntp.sock.sendall(command) self.reset_data_buffer() self.user_sent = True elif not self.user_ok: if code == 381: self.user_ok = True elif code == 281: # No login required self.user_ok = True self.pass_sent = True self.pass_ok = True self.connected = True if self.user_ok and not self.pass_sent: command = utob("authinfo pass %s\r\n" % self.server.password) self.nntp.sock.sendall(command) self.reset_data_buffer() self.pass_sent = True elif self.user_ok and not self.pass_ok: if code != 281: # Assume that login failed (code 481 or other) raise NNTPPermanentError(self.nntp_msg, code) else: self.connected = True self.timeout = time.time() + self.server.timeout def body(self): """Request the body of the article""" self.timeout = time.time() + self.server.timeout if self.article.nzf.nzo.precheck: if self.server.have_stat: command = utob("STAT <%s>\r\n" % self.article.article) else: command = utob("HEAD <%s>\r\n" % self.article.article) elif self.server.have_body: command = utob("BODY <%s>\r\n" % self.article.article) else: command = utob("ARTICLE <%s>\r\n" % self.article.article) self.nntp.sock.sendall(command) self.reset_data_buffer() def recv_chunk(self) -> Tuple[int, bool, bool]: """Receive data, return #bytes, end-of-line, end-of-article""" # Resize the buffer in the extremely unlikely case that it got full if self.data_position == len(self.data): self.nntp.nw.increase_data_buffer() # Receive data into the pre-allocated buffer if self.nntp.nw.server.ssl and not self.nntp.nw.blocking and sabctools.openssl_linked: # Use patched version when downloading bytes_recv = sabctools.unlocked_ssl_recv_into(self.nntp.sock, self.data_view[self.data_position :]) else: bytes_recv = self.nntp.sock.recv_into(self.data_view[self.data_position :]) # No data received if bytes_recv == 0: raise ConnectionError("Server closed connection") # Success, move timeout and internal data position self.timeout = time.time() + self.server.timeout self.data_position += bytes_recv # The SSL-layer might still contain data even though the socket does not. Another Downloader-loop would # not identify this socket anymore as it is not returned by select(). So, we have to forcefully trigger # another recv_chunk so the buffer is increased and the data from the SSL-layer is read. See #2752. if self.nntp.nw.server.ssl and self.data_position == len(self.data) and self.nntp.sock.pending() > 0: # We do not perform error-handling, as we know there is data available to read additional_bytes_recv, additional_end_of_line, additional_end_of_article = self.recv_chunk() return bytes_recv + additional_bytes_recv, additional_end_of_line, additional_end_of_article # Check for end of line # Using the data directly seems faster than the memoryview if self.data[self.data_position - 2 : self.data_position] == b"\r\n": # Official end-of-article is "\r\n.\r\n" if self.data[self.data_position - 5 : self.data_position] == b"\r\n.\r\n": return bytes_recv, True, True return bytes_recv, True, False # Still in middle of data, so continue! return bytes_recv, False, False def soft_reset(self): """Reset for the next article""" self.timeout = None self.article = None self.reset_data_buffer() def reset_data_buffer(self): """Reset the data position""" self.data_position = 0 def increase_data_buffer(self): """Resize the buffer in the extremely unlikely case that it overflows""" # Input needs to be integer, floats don't work new_buffer = sabctools.bytearray_malloc(len(self.data) + NNTP_BUFFER_SIZE // 2) new_buffer[: len(self.data)] = self.data logging.info("Increased buffer from %d to %d for %s", len(self.data), len(new_buffer), str(self)) self.data = new_buffer self.data_view = memoryview(self.data) def hard_reset(self, wait: bool = True): """Destroy and restart""" if self.nntp: self.nntp.close(send_quit=self.connected) self.nntp = None # Reset all variables (including the NNTP connection) self.__init__(self.server, self.thrdnum) # Wait before re-using this newswrapper if wait: # Reset due to error condition, use server timeout self.timeout = time.time() + self.server.timeout else: # Reset for internal reasons, just wait 5 sec self.timeout = time.time() + 5 def __repr__(self): return "" % ( self.server.host, self.server.port, self.thrdnum, self.connected, ) class NNTP: # Pre-define attributes to save memory __slots__ = ("nw", "addrinfo", "error_msg", "sock", "fileno", "closed") def __init__(self, nw: NewsWrapper, addrinfo: AddrInfo): self.nw: NewsWrapper = nw # Add local reference to prevent crash in case the server.addrinfo is reset self.addrinfo: AddrInfo = addrinfo self.error_msg: Optional[str] = None # Prevent closing this socket until it's done connecting self.closed = False # Create SSL-context if it is needed and not created yet if self.nw.server.ssl and not self.nw.server.ssl_context: # Setup the SSL socket self.nw.server.ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) # Only verify hostname when we're strict if self.nw.server.ssl_verify < 2: self.nw.server.ssl_context.check_hostname = False # Certificates optional if self.nw.server.ssl_verify == 0: self.nw.server.ssl_context.verify_mode = ssl.CERT_NONE # Did the user set a custom cipher-string? if self.nw.server.ssl_ciphers: # At their own risk, socket will error out in case it was invalid self.nw.server.ssl_context.set_ciphers(self.nw.server.ssl_ciphers) # Python does not allow setting ciphers on TLSv1.3, so have to force TLSv1.2 as the maximum self.nw.server.ssl_context.maximum_version = ssl.TLSVersion.TLSv1_2 else: # Support at least TLSv1.2+ ciphers, as some essential ones are removed by default in Python 3.10 self.nw.server.ssl_context.set_ciphers("HIGH") if sabnzbd.cfg.allow_old_ssl_tls(): # Allow anything that the system has self.nw.server.ssl_context.minimum_version = ssl.TLSVersion.MINIMUM_SUPPORTED else: # We want a modern TLS (1.2 or higher), so we disallow older protocol versions (<= TLS 1.1) self.nw.server.ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 # Create socket and store fileno of the socket self.sock: Union[socket.socket, ssl.SSLSocket] = socket.socket(self.addrinfo.family, self.addrinfo.type) self.fileno: int = self.sock.fileno() # Open the connection in a separate thread due to avoid blocking # For server-testing we do want blocking if not self.nw.blocking: Thread(target=self.connect).start() else: self.connect() def connect(self): """Start of connection, can be performed a-sync""" try: # Wait the defined timeout during connect and SSL-setup self.sock.settimeout(self.nw.server.timeout) # Connect self.sock.connect(self.addrinfo.sockaddr) # Secured or unsecured? if self.nw.server.ssl: # Wrap socket and log SSL/TLS diagnostic info self.sock = self.nw.server.ssl_context.wrap_socket(self.sock, server_hostname=self.nw.server.host) logging.info( "%s@%s: Connected using %s (%s)", self.nw.thrdnum, self.nw.server.host, self.sock.version(), self.sock.cipher()[0], ) self.nw.server.ssl_info = "%s (%s)" % (self.sock.version(), self.sock.cipher()[0]) # Skip during server test if not self.nw.blocking: # Set to non-blocking mode self.sock.setblocking(False) # Only add to active sockets if it's not somehow already closing # Locked, so it can't interleave with any of the Downloader "__nw" actions with DOWNLOADER_LOCK: if not self.closed: sabnzbd.Downloader.add_socket(self.fileno, self.nw) except OSError as e: self.error(e) def error(self, error: OSError): raw_error_str = str(error) if "SSL23_GET_SERVER_HELLO" in str(error) or "SSL3_GET_RECORD" in raw_error_str: error = T("This server does not allow SSL on this port") # Catch certificate errors if type(error) == ssl.CertificateError or "CERTIFICATE_VERIFY_FAILED" in raw_error_str: # Log the raw message for debug purposes logging.info("Certificate error for host %s: %s", self.nw.server.host, raw_error_str) # Try to see if we should catch this message and provide better text if "hostname" in raw_error_str: raw_error_str = T( "Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue." ) elif "certificate verify failed" in raw_error_str: raw_error_str = T("Certificate not valid. This is most probably a server issue.") # Reformat error and overwrite str-representation error_str = T("Server %s uses an untrusted certificate [%s]") % (self.nw.server.host, raw_error_str) error_str = "%s - %s: %s" % (error_str, T("Wiki"), "https://sabnzbd.org/certificate-errors") error.strerror = error_str # Prevent throwing a lot of errors or when testing server if error_str not in self.nw.server.warning and not self.nw.blocking: logging.error(error_str) # Pass to server-test if self.nw.blocking: raise error # Blocking = server-test, pass directly to display code if self.nw.blocking: raise socket.error(errno.ECONNREFUSED, str(error)) # Ignore if the socket was already closed, resulting in errors if not self.closed: msg = T("Failed to connect: %s %s@%s:%s (%s)") % ( str(error), self.nw.thrdnum, self.nw.server.host, self.nw.server.port, self.addrinfo.canonname, ) self.error_msg = msg self.nw.server.next_busy_threads_check = 0 if self.nw.server.warning == msg: logging.info(msg) else: logging.warning(msg) self.nw.server.warning = msg @synchronized(DOWNLOADER_LOCK) def close(self, send_quit: bool): """Safely close socket. Locked to match connect(), even though most likely the caller already holds the same lock.""" # Set status first, so any calls in connect/error are handled correctly self.closed = True try: if send_quit: self.sock.sendall(b"QUIT\r\n") time.sleep(0.01) self.sock.close() except Exception as e: logging.info("%s@%s: Failed to close socket (error=%s)", self.nw.thrdnum, self.nw.server.host, str(e)) def __repr__(self): return "" % (self.addrinfo.canonname, self.nw.server.port) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4475107 SABnzbd-4.3.2/sabnzbd/sabtray.py0000644000000000000000000001520314625637243015666 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabtray.py - Systray icon for SABnzbd on Windows, contributed by Jan Schejbal """ import os import logging from threading import Thread from time import sleep import sabnzbd from sabnzbd.panic import launch_a_browser import sabnzbd.api as api import sabnzbd.cfg as cfg from sabnzbd.misc import to_units # contains the tray icon, which demands its own thread from sabnzbd.utils.systrayiconthread import SysTrayIconThread class SABTrayThread(SysTrayIconThread): # When updating these paths, also update them in the NSIS script! sabicons = { "default": "icons/sabnzbd16_32.ico", "green": "icons/sabnzbd16_32green.ico", "pause": "icons/sabnzbd16_32paused.ico", } def __init__(self): # Wait for translated texts to be loaded while not sabnzbd.WEBUI_READY: sleep(0.2) logging.debug("language file not loaded, waiting") self.sabpaused = False self.counter = 0 self.set_texts() menu_options = ( (T("Show interface"), None, self.browse), (T("Open complete folder"), None, self.opencomplete), ("SEPARATOR", None, None), (T("Pause") + "/" + T("Resume"), None, self.pauseresume), ( T("Pause for"), None, ( (T("Pause for 5 minutes"), None, self.pausefor5min), (T("Pause for 15 minutes"), None, self.pausefor15min), (T("Pause for 30 minutes"), None, self.pausefor30min), (T("Pause for 1 hour"), None, self.pausefor1hour), (T("Pause for 3 hours"), None, self.pausefor3hour), (T("Pause for 6 hours"), None, self.pausefor6hour), ), ), ("SEPARATOR", None, None), (T("Read all RSS feeds"), None, self.rss), ("SEPARATOR", None, None), ( T("Troubleshoot"), None, ( (T("Restart"), None, self.restart_sab), (T("Restart without login"), None, self.nologin), (T("Restart") + " - 127.0.0.1:8080", None, self.defhost), ), ), (T("Shutdown"), None, self.shutdown), ) super().__init__(self.sabicons["default"], "SABnzbd", menu_options, None, 0, "SabTrayIcon") def set_texts(self): """Cache texts for performance, doUpdates is called often""" self.txt_idle = T("Idle") self.txt_paused = T("Paused") self.txt_remaining = T("Remaining") # called every few ms by SysTrayIconThread def doUpdates(self): """Update menu info, once every 10 calls""" self.counter += 1 if self.counter > 10: self.sabpaused, bytes_left, bpsnow, time_left = api.fast_queue() mb_left = to_units(bytes_left) speed = to_units(bpsnow) if self.sabpaused: if bytes_left > 0: self.hover_text = "%s - %s: %sB" % (self.txt_paused, self.txt_remaining, mb_left) else: self.hover_text = self.txt_paused self.icon = self.sabicons["pause"] elif bytes_left > 0: self.hover_text = "%sB/s - %s: %sB (%s)" % (speed, self.txt_remaining, mb_left, time_left) self.icon = self.sabicons["green"] else: self.hover_text = self.txt_idle self.icon = self.sabicons["default"] self.hover_text = "SABnzbd %s\n%s" % (sabnzbd.__version__, self.hover_text) self.refresh_icon() self.counter = 0 # left-click handler def click(self, *args): # Make sure to stop the timer self.stop_click_timer() # Pause/resume and force update of icon/text self.pauseresume(None) self.counter = 11 # menu handler def opencomplete(self, icon): try: os.startfile(cfg.complete_dir.get_path()) except OSError: pass # menu handler def browse(self, icon): launch_a_browser(sabnzbd.BROWSER_URL, True) # menu handler def pauseresume(self, icon): if self.sabpaused: self.resume() else: self.pause() def pausefor(self, minutes): """Need function for each pause-timer""" sabnzbd.Scheduler.plan_resume(minutes) def pausefor5min(self, icon): self.pausefor(5) def pausefor15min(self, icon): self.pausefor(15) def pausefor30min(self, icon): self.pausefor(30) def pausefor1hour(self, icon): self.pausefor(60) def pausefor3hour(self, icon): self.pausefor(3 * 60) def pausefor6hour(self, icon): self.pausefor(6 * 60) def restart_sab(self, icon): self.hover_text = T("Restart") logging.info("Restart requested by tray") sabnzbd.trigger_restart() def rss(self, icon): self.hover_text = T("Read all RSS feeds") sabnzbd.Scheduler.force_rss() def nologin(self, icon): sabnzbd.cfg.username.set("") sabnzbd.cfg.password.set("") sabnzbd.config.save_config() self.hover_text = T("Restart") sabnzbd.trigger_restart() def defhost(self, icon): sabnzbd.cfg.cherryhost.set("127.0.0.1") sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config() self.hover_text = T("Restart") sabnzbd.trigger_restart() def shutdown(self, icon): self.hover_text = T("Shutdown") # In separate thread, because the shutdown also stops the tray icon Thread(target=sabnzbd.shutdown_program).start() def pause(self): sabnzbd.Scheduler.plan_resume(0) sabnzbd.Downloader.pause() def resume(self): sabnzbd.Scheduler.plan_resume(0) sabnzbd.downloader.unpause_all() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4475825 SABnzbd-4.3.2/sabnzbd/articlecache.py0000644000000000000000000001560314625637243016634 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.articlecache - Article cache handling """ import logging import threading import struct from typing import Dict, Collection import sabnzbd from sabnzbd.decorators import synchronized from sabnzbd.constants import GIGI, ANFO, ASSEMBLER_WRITE_THRESHOLD from sabnzbd.nzbstuff import Article # Operations on the article table are handled via try/except. # The counters need to be made atomic to ensure consistency. ARTICLE_COUNTER_LOCK = threading.RLock() class ArticleCache: def __init__(self): self.__cache_limit_org = 0 self.__cache_limit = 0 self.__cache_size = 0 self.__article_table: Dict[Article, bytes] = {} # Dict of buffered articles self.assembler_write_trigger: int = 1 # On 32 bit we only allow the user to set 1GB # For 64 bit we allow up to 4GB, in case somebody wants that self.__cache_upper_limit = GIGI if sabnzbd.MACOS or sabnzbd.WIN64 or (struct.calcsize("P") * 8) == 64: self.__cache_upper_limit = 4 * GIGI def cache_info(self): return ANFO(len(self.__article_table), abs(self.__cache_size), self.__cache_limit_org) def new_limit(self, limit: int): """Called when cache limit changes""" self.__cache_limit_org = limit if limit < 0: self.__cache_limit = self.__cache_upper_limit else: self.__cache_limit = min(limit, self.__cache_upper_limit) # Set assembler_write_trigger to be the equivalent of ASSEMBLER_WRITE_THRESHOLD % # of the total cache, assuming an article size of 750 000 bytes self.assembler_write_trigger = int(self.__cache_limit * ASSEMBLER_WRITE_THRESHOLD / 100 / 750_000) + 1 logging.debug( "Assembler trigger = %d", self.assembler_write_trigger, ) @synchronized(ARTICLE_COUNTER_LOCK) def reserve_space(self, data_size: int): """Reserve space in the cache""" self.__cache_size += data_size @synchronized(ARTICLE_COUNTER_LOCK) def free_reserved_space(self, data_size: int): """Remove previously reserved space""" self.__cache_size -= data_size def space_left(self) -> bool: """Is there space left in the set limit?""" return self.__cache_size < self.__cache_limit def save_article(self, article: Article, data: bytes): """Save article in cache, either memory or disk""" nzo = article.nzf.nzo # Skip if already post-processing or fully finished if nzo.pp_or_finished: return # Register article for bookkeeping in case the job is deleted nzo.saved_articles.add(article) if article.lowest_partnum and not (article.nzf.import_finished or article.nzf.filename_checked): # Write the first-fetched articles to temporary file unless downloading # of the rest of the parts has started or filename is verified. # Otherwise the cache could overflow. self.__flush_article_to_disk(article, data) return if self.__cache_limit: # Check if we exceed the limit data_size = len(data) self.reserve_space(data_size) if self.space_left(): # Add new article to the cache self.__article_table[article] = data else: # Return the space and save to disk self.free_reserved_space(data_size) self.__flush_article_to_disk(article, data) else: # No data saved in memory, direct to disk self.__flush_article_to_disk(article, data) def load_article(self, article: Article): """Load the data of the article""" data = None nzo = article.nzf.nzo if article in self.__article_table: try: data = self.__article_table.pop(article) self.free_reserved_space(len(data)) except KeyError: # Could fail due the article already being deleted by purge_articles, for example # when post-processing deletes the job while delayed articles still come in logging.debug("Failed to load %s from cache, probably already deleted", article) return data elif article.art_id: data = sabnzbd.filesystem.load_data( article.art_id, nzo.admin_path, remove=True, do_pickle=False, silent=True ) nzo.saved_articles.discard(article) return data def flush_articles(self): logging.debug("Saving %s cached articles to disk", len(self.__article_table)) self.__cache_size = 0 while self.__article_table: try: article, data = self.__article_table.popitem() self.__flush_article_to_disk(article, data) except KeyError: # Could fail if already deleted by purge_articles or load_data logging.debug("Failed to flush item from cache, probably already deleted or written to disk") def purge_articles(self, articles: Collection[Article]): """Remove all saved articles, from memory and disk""" logging.debug("Purging %s articles from the cache/disk", len(articles)) for article in articles: if article in self.__article_table: try: data = self.__article_table.pop(article) self.free_reserved_space(len(data)) except KeyError: # Could fail if already deleted by flush_articles or load_data logging.debug("Failed to flush %s from cache, probably already deleted or written to disk", article) elif article.art_id: sabnzbd.filesystem.remove_data(article.art_id, article.nzf.nzo.admin_path) @staticmethod def __flush_article_to_disk(article: Article, data): # Save data, but don't complain when destination folder is missing # because this flush may come after completion of the NZO. sabnzbd.filesystem.save_data( data, article.get_art_id(), article.nzf.nzo.admin_path, do_pickle=False, silent=True ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4477432 SABnzbd-4.3.2/sabnzbd/assembler.py0000644000000000000000000004055114625637243016202 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.assembler - threaded assembly of files """ import os import queue import logging import re from threading import Thread import ctypes from typing import Tuple, Optional, List import sabnzbd from sabnzbd.misc import get_all_passwords, match_str from sabnzbd.filesystem import ( set_permissions, clip_path, has_win_device, diskspace, get_filename, has_unwanted_extension, get_basename, ) from sabnzbd.constants import Status, GIGI, MAX_ASSEMBLER_QUEUE import sabnzbd.cfg as cfg from sabnzbd.nzbstuff import NzbObject, NzbFile import sabnzbd.par2file as par2file import sabnzbd.utils.rarfile as rarfile class Assembler(Thread): def __init__(self): super().__init__() self.queue: queue.Queue[Tuple[Optional[NzbObject], Optional[NzbFile], Optional[bool]]] = queue.Queue() def stop(self): self.queue.put((None, None, None)) def process(self, nzo: NzbObject, nzf: Optional[NzbFile] = None, file_done: Optional[bool] = None): self.queue.put((nzo, nzf, file_done)) def queue_level(self) -> float: return self.queue.qsize() / MAX_ASSEMBLER_QUEUE def run(self): while 1: # Set NzbObject and NzbFile objects to None so references # from this thread do not keep the objects alive (see #1628) nzo = nzf = None nzo, nzf, file_done = self.queue.get() if not nzo: logging.debug("Shutting down assembler") break if nzf: # Check if enough disk space is free after each file is done if file_done and not sabnzbd.Downloader.paused: self.diskspace_check(nzo, nzf) # Prepare filepath if filepath := nzf.prepare_filepath(): try: logging.debug("Decoding part of %s", filepath) self.assemble(nzo, nzf, file_done) # Continue after partly written data if not file_done: continue # Clean-up admin data logging.info("Decoding finished %s", filepath) nzf.remove_admin() # Do rar-related processing if rarfile.is_rarfile(filepath): # Check for encrypted files, unwanted extensions and add to direct unpack self.check_encrypted_and_unwanted(nzo, nzf) nzo.add_to_direct_unpacker(nzf) elif par2file.is_parfile(filepath): # Parse par2 files, cloaked or not nzo.handle_par2(nzf, filepath) except IOError as err: # If job was deleted/finished or in active post-processing, ignore error if not nzo.pp_or_finished: # 28 == disk full => pause downloader if err.errno == 28: logging.error(T("Disk full! Forcing Pause")) else: logging.error(T("Disk error on creating file %s"), clip_path(filepath)) # Log traceback if sabnzbd.WIN32: logging.info( "Winerror: %s - %s", err.winerror, hex(ctypes.windll.ntdll.RtlGetLastNtStatus() + 2**32), ) logging.info("Traceback: ", exc_info=True) # Pause without saving sabnzbd.Downloader.pause() else: logging.debug("Ignoring error %s for %s, already finished or in post-proc", err, filepath) except: logging.error(T("Fatal error in Assembler"), exc_info=True) break else: sabnzbd.NzbQueue.remove(nzo.nzo_id, cleanup=False) sabnzbd.PostProcessor.process(nzo) @staticmethod def diskspace_check(nzo: NzbObject, nzf: NzbFile): """Check diskspace requirements. If not enough space left, pause downloader and send email""" freespace = diskspace(force=True) full_dir = None required_space = (cfg.download_free.get_float() + nzf.bytes) / GIGI if freespace["download_dir"][1] < required_space: full_dir = "download_dir" # Enough space in download_dir, check complete_dir complete_free = cfg.complete_free.get_float() if complete_free > 0 and not full_dir: required_space = 0 if cfg.direct_unpack(): # We unpack while we download, so we should check every time # if the unpack maybe already filled up the drive required_space = complete_free / GIGI elif nzo.bytes_tried > (nzo.bytes - nzo.bytes_par2) * 0.95: # Since only at 100% unpack is started, continue # downloading until 95% complete before checking required_space = (complete_free + nzo.bytes) / GIGI if required_space and freespace["complete_dir"][1] < required_space: full_dir = "complete_dir" if full_dir: logging.warning(T("Too little diskspace forcing PAUSE")) # Pause downloader, but don't save, since the disk is almost full! sabnzbd.Downloader.pause() if cfg.fulldisk_autoresume(): sabnzbd.Scheduler.plan_diskspace_resume(full_dir, required_space) sabnzbd.notifier.send_notification("SABnzbd", T("Too little diskspace forcing PAUSE"), "disk_full") sabnzbd.emailer.diskfull_mail() @staticmethod def assemble(nzo: NzbObject, nzf: NzbFile, file_done: bool): """Assemble a NZF from its table of articles 1) Partial write: write what we have 2) Nothing written before: write all """ # We write large article-sized chunks, so we can safely skip the buffering of Python with open(nzf.filepath, "ab", buffering=0) as fout: for article in nzf.decodetable: # Break if deleted during writing if nzo.status is Status.DELETED: break # Skip already written articles if article.on_disk: continue # Write all decoded articles if article.decoded: # Could be empty in case nzo was deleted if data := sabnzbd.ArticleCache.load_article(article): written = fout.write(data) # In raw/non-buffered mode fout.write may not write everything requested: # https://docs.python.org/3/library/io.html?highlight=write#io.RawIOBase.write while written < len(data): written += fout.write(data[written:]) nzf.update_crc32(article.crc32, len(data)) article.on_disk = True else: logging.info("No data found when trying to write %s", article) else: # If the article was not decoded but the file # is done, it is just a missing piece, so keep writing if file_done: continue else: # We reach an article that was not decoded break # Final steps if file_done: set_permissions(nzf.filepath) nzf.assembled = True @staticmethod def check_encrypted_and_unwanted(nzo: NzbObject, nzf: NzbFile): """Encryption and unwanted extension detection""" rar_encrypted, unwanted_file = check_encrypted_and_unwanted_files(nzo, nzf.filepath) if rar_encrypted: if cfg.pause_on_pwrar() == 1: logging.warning( T('Paused job "%s" because of encrypted RAR file (if supplied, all passwords were tried)'), nzo.final_name, ) nzo.pause() else: logging.warning( T('Aborted job "%s" because of encrypted RAR file (if supplied, all passwords were tried)'), nzo.final_name, ) nzo.fail_msg = T("Aborted, encryption detected") sabnzbd.NzbQueue.end_job(nzo) if unwanted_file: # Don't repeat the warning after a user override of an unwanted extension pause if nzo.unwanted_ext == 0: logging.warning( T('In "%s" unwanted extension in RAR file. Unwanted file is %s '), nzf.nzo.final_name, unwanted_file, ) logging.debug(T("Unwanted extension is in rar file %s"), nzf.filename) if cfg.action_on_unwanted_extensions() == 1 and nzo.unwanted_ext == 0: logging.debug("Unwanted extension ... pausing") nzo.unwanted_ext = 1 nzo.pause() if cfg.action_on_unwanted_extensions() == 2: logging.debug("Unwanted extension ... aborting") nzo.fail_msg = T("Aborted, unwanted extension detected") sabnzbd.NzbQueue.end_job(nzo) RE_SUBS = re.compile(r"\W+sub|subs|subpack|subtitle|subtitles(?![a-z])", re.I) SAFE_EXTS = (".mkv", ".mp4", ".avi", ".wmv", ".mpg", ".webm") def is_cloaked(nzo: NzbObject, path: str, names: List[str]) -> bool: """Return True if this is likely to be a cloaked encrypted post""" fname = get_basename(get_filename(path.lower())) for name in names: name = get_filename(name.lower()) name, ext = os.path.splitext(name) if ( ext == ".rar" and fname.startswith(name) and (len(fname) - len(name)) < 8 and len(names) < 3 and not RE_SUBS.search(fname) ): # Only warn once if nzo.encrypted == 0: logging.warning( T('Job "%s" is probably encrypted due to RAR with same name inside this RAR'), nzo.final_name ) nzo.encrypted = 1 return True elif "password" in name and ext not in SAFE_EXTS: # Only warn once if nzo.encrypted == 0: logging.warning(T('Job "%s" is probably encrypted: "password" in filename "%s"'), nzo.final_name, name) nzo.encrypted = 1 return True return False def check_encrypted_and_unwanted_files(nzo: NzbObject, filepath: str) -> Tuple[bool, Optional[str]]: """Combines check for unwanted and encrypted files to save on CPU and IO""" encrypted = False unwanted = None if (cfg.unwanted_extensions() and cfg.action_on_unwanted_extensions()) or ( nzo.encrypted == 0 and cfg.pause_on_pwrar() ): # These checks should not break the assembler try: # Rarfile freezes on Windows special names, so don't try those! if sabnzbd.WIN32 and has_win_device(filepath): return encrypted, unwanted # Is it even a rarfile? if rarfile.is_rarfile(filepath): # Open the rar zf = rarfile.RarFile(filepath, single_file_check=True) # Check for encryption if ( nzo.encrypted == 0 and cfg.pause_on_pwrar() and (zf.needs_password() or is_cloaked(nzo, filepath, zf.namelist())) ): # Load all passwords passwords = get_all_passwords(nzo) # Cloaked job? if is_cloaked(nzo, filepath, zf.namelist()): encrypted = True elif not passwords: # Only error when no password was set nzo.encrypted = 1 encrypted = True else: # Lets test if any of the password work password_hit = False for password in passwords: if password: logging.info('Trying password "%s" on job "%s"', password, nzo.final_name) try: zf.setpassword(password) except rarfile.Error: # On weird passwords the setpassword() will fail # but the actual testrar() will work pass try: zf.testrar() password_hit = password break except rarfile.RarWrongPassword: # This one really didn't work pass except rarfile.RarCRCError as e: # CRC errors can be thrown for wrong password or # missing the next volume (with correct password) if match_str(str(e), ("cannot find volume", "unexpected end of archive")): # We assume this one worked! password_hit = password break # This one didn't work pass except: # All the other errors we skip, they might be fixable in post-proc. # For example starting from the wrong volume, or damaged files # This will cause the check to be performed again for the next rar, might # be disk-intensive! Could be removed later and just accept the password. return encrypted, unwanted # Did any work? if password_hit: # Record the successful password nzo.correct_password = password_hit # Don't check other files logging.info('Password "%s" matches for job "%s"', password_hit, nzo.final_name) nzo.encrypted = -1 encrypted = False else: # Encrypted and none of them worked nzo.encrypted = 1 encrypted = True # Check for unwanted extensions if cfg.unwanted_extensions() and cfg.action_on_unwanted_extensions(): for somefile in zf.namelist(): logging.debug("File contains: %s", somefile) if has_unwanted_extension(somefile): logging.debug("Unwanted file %s", somefile) unwanted = somefile zf.close() del zf except rarfile.Error as e: logging.info("Error during inspection of RAR-file %s: %s", filepath, e) return encrypted, unwanted ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.447858 SABnzbd-4.3.2/sabnzbd/api.py0000644000000000000000000021535514625637243015004 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.api - api """ import os import logging import re import gc import socket import time import getpass import cherrypy from threading import Thread from typing import Tuple, Optional, List, Dict, Any, Union # For json.dumps, orjson is magnitudes faster than ujson, but it is harder to # compile due to Rust dependency. Since the output is the same, we support all modules. try: import orjson as json except ImportError: try: import ujson as json except ImportError: import json import sabnzbd from sabnzbd.constants import ( VALID_ARCHIVES, VALID_NZB_FILES, Status, FORCE_PRIORITY, NORMAL_PRIORITY, INTERFACE_PRIORITIES, KIBI, MEBI, GIGI, AddNzbFileResult, PP_LOOKUP, STAGES, DEF_TEST_TIMEOUT, ) import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.skintext import SKIN_TEXT from sabnzbd.utils.diskspeed import diskspeedmeasure from sabnzbd.internetspeed import internetspeed from sabnzbd.utils.getperformance import getpystone from sabnzbd.misc import ( loadavg, to_units, int_conv, create_https_certificates, calc_age, opts_to_pp, format_time_left, is_none, history_updated, request_repair, change_queue_complete_action, clean_comma_separated_list, match_str, ) from sabnzbd.filesystem import diskspace, get_ext, clip_path, remove_all, list_scripts, purge_log_files, pathbrowser from sabnzbd.encoding import xml_name, utob from sabnzbd.getipaddress import local_ipv4, public_ipv4, public_ipv6, dnslookup, active_socks5_proxy from sabnzbd.database import HistoryDB from sabnzbd.lang import is_rtl from sabnzbd.nzbstuff import NzbObject from sabnzbd.newswrapper import NewsWrapper, NNTPPermanentError import sabnzbd.emailer import sabnzbd.sorting ############################################################################## # API error messages ############################################################################## _MSG_NO_VALUE = "expects one parameter" _MSG_NO_VALUE2 = "expects two parameters" _MSG_INT_VALUE = "expects integer value" _MSG_NO_ITEM = "item does not exist" _MSG_NOT_IMPLEMENTED = "not implemented" _MSG_NO_FILE = "no file given" _MSG_NO_PATH = "file does not exist" _MSG_OUTPUT_FORMAT = "Format not supported" _MSG_NO_SUCH_CONFIG = "Config item does not exist" _MSG_CONFIG_LOCKED = "Configuration locked" def api_handler(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API Dispatcher""" # Clean-up the arguments for vr in ("mode", "name", "value", "value2", "value3", "start", "limit", "search"): if vr in kwargs and isinstance(kwargs[vr], list): kwargs[vr] = kwargs[vr][0] mode = kwargs.get("mode", "") name = kwargs.get("name", "") response = _api_table.get(mode, (_api_undefined, 2))[0](name, kwargs) return response def _api_get_config(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts keyword, section""" _, data = config.get_dconfig(kwargs.get("section"), kwargs.get("keyword")) return report(keyword="config", data=data) def _api_set_config(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts keyword, section""" if cfg.configlock(): return report(_MSG_CONFIG_LOCKED) if kwargs.get("section") == "servers": kwargs["keyword"] = handle_server_api(kwargs) elif kwargs.get("section") == "rss": kwargs["keyword"] = handle_rss_api(kwargs) elif kwargs.get("section") == "categories": kwargs["keyword"] = handle_cat_api(kwargs) elif kwargs.get("section") == "sorters": kwargs["keyword"] = handle_sorter_api(kwargs) else: res = config.set_config(kwargs) if not res: return report(_MSG_NO_SUCH_CONFIG) config.save_config() res, data = config.get_dconfig(kwargs.get("section"), kwargs.get("keyword")) return report(keyword="config", data=data) def _api_set_config_default(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: Reset requested config variables back to defaults. Currently only for misc-section""" if cfg.configlock(): return report(_MSG_CONFIG_LOCKED) keywords = kwargs.get("keyword", []) if not isinstance(keywords, list): keywords = [keywords] for keyword in keywords: item = config.get_config("misc", keyword) if item: item.set(item.default) config.save_config() return report() def _api_del_config(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts keyword, section""" if cfg.configlock(): return report(_MSG_CONFIG_LOCKED) if del_from_section(kwargs): return report() else: return report(_MSG_NOT_IMPLEMENTED) def _api_queue(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: Dispatcher for mode=queue""" value = kwargs.get("value", "") return _api_queue_table.get(name, (_api_queue_default, 2))[0](value, kwargs) def _api_queue_delete(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value""" if value.lower() == "all": removed = sabnzbd.NzbQueue.remove_all(kwargs.get("search")) return report(keyword="", data={"status": bool(removed), "nzo_ids": removed}) elif items := clean_comma_separated_list(value): delete_all_data = int_conv(kwargs.get("del_files")) removed = sabnzbd.NzbQueue.remove_multiple(items, delete_all_data=delete_all_data) return report(keyword="", data={"status": bool(removed), "nzo_ids": removed}) else: return report(_MSG_NO_VALUE) def _api_queue_delete_nzf(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id), value2(=nzf_ids)""" nzf_ids = clean_comma_separated_list(kwargs.get("value2")) if value and nzf_ids: removed = sabnzbd.NzbQueue.remove_nzfs(value, nzf_ids) return report(keyword="", data={"status": bool(removed), "nzf_ids": removed}) else: return report(_MSG_NO_VALUE2) def _api_queue_rename(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=old name), value2(=new name), value3(=password)""" value2 = kwargs.get("value2") value3 = kwargs.get("value3") if value and value2: ret = sabnzbd.NzbQueue.change_name(value, value2, value3) return report(keyword="", data={"status": ret}) else: return report(_MSG_NO_VALUE2) def _api_queue_change_complete_action(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=action)""" change_queue_complete_action(value) return report() def _api_queue_purge(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: removed = sabnzbd.NzbQueue.remove_all(kwargs.get("search")) return report(keyword="", data={"status": bool(removed), "nzo_ids": removed}) def _api_queue_pause(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=list of nzo_id)""" if items := clean_comma_separated_list(value): handled = sabnzbd.NzbQueue.pause_multiple_nzo(items) else: handled = False return report(keyword="", data={"status": bool(handled), "nzo_ids": handled}) def _api_queue_resume(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=list of nzo_id)""" if items := clean_comma_separated_list(value): handled = sabnzbd.NzbQueue.resume_multiple_nzo(items) else: handled = False return report(keyword="", data={"status": bool(handled), "nzo_ids": handled}) def _api_queue_priority(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id), value2(=priority)""" nzo_ids = clean_comma_separated_list(value) priority = kwargs.get("value2") if nzo_ids and priority: try: try: priority = int(priority) except: return report(_MSG_INT_VALUE) pos = sabnzbd.NzbQueue.set_priority(nzo_ids, priority) # Returns the position in the queue, -1 is incorrect job-id return report(keyword="position", data=pos) except: return report(_MSG_NO_VALUE2) else: return report(_MSG_NO_VALUE2) def _api_queue_sort(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts sort, dir""" sort = kwargs.get("sort", "") direction = kwargs.get("dir", "") if sort: sabnzbd.NzbQueue.sort_queue(sort, direction) return report() else: return report(_MSG_NO_VALUE2) def _api_queue_default(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts sort, dir, start, limit and search terms""" start = int_conv(kwargs.get("start")) limit = int_conv(kwargs.get("limit")) search = kwargs.get("search") categories = clean_comma_separated_list(kwargs.get("cat") or kwargs.get("category")) priorities = clean_comma_separated_list(kwargs.get("priority")) statuses = clean_comma_separated_list(kwargs.get("status")) nzo_ids = clean_comma_separated_list(kwargs.get("nzo_ids")) if priorities: # Make sure it's an integer priorities = [int_conv(prio) for prio in priorities] return report( keyword="queue", data=build_queue( start=start, limit=limit, search=search, categories=categories, priorities=priorities, statuses=statuses, nzo_ids=nzo_ids, ), ) def _api_translate(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=acronym)""" return report(keyword="value", data=T(kwargs.get("value", ""))) def _api_addfile(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name, pp, script, cat, priority, nzbname""" # Normal upload will send the nzb in a kw arg called name or nzbfile if not name or isinstance(name, str): name = kwargs.get("nzbfile", None) if hasattr(name, "file") and hasattr(name, "filename") and name.filename: # Add the NZB-file res, nzo_ids = sabnzbd.nzbparser.add_nzbfile( name, pp=kwargs.get("pp"), script=kwargs.get("script"), cat=kwargs.get("cat"), priority=kwargs.get("priority"), nzbname=kwargs.get("nzbname"), password=kwargs.get("password"), ) return report(keyword="", data={"status": res is AddNzbFileResult.OK, "nzo_ids": nzo_ids}) else: return report(_MSG_NO_VALUE) def _api_retry(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name, value(=nzo_id), nzbfile(=optional NZB), password (optional)""" value = kwargs.get("value") # Normal upload will send the nzb in a kw arg called nzbfile if name is None or isinstance(name, str): name = kwargs.get("nzbfile") password = kwargs.get("password") password = password[0] if isinstance(password, list) else password if nzo_id := retry_job(value, name, password): return report(keyword="", data={"status": True, "nzo_id": nzo_id}) else: return report(_MSG_NO_ITEM) def _api_cancel_pp(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name, value(=nzo_ids)""" if nzo_ids := clean_comma_separated_list(kwargs.get("value")): if sabnzbd.PostProcessor.cancel_pp(nzo_ids): return report(keyword="", data={"status": True, "nzo_ids": nzo_ids}) return report(_MSG_NO_ITEM) def _api_addlocalfile(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name, pp, script, cat, priority, nzbname""" if name: if os.path.exists(name): if get_ext(name) in VALID_ARCHIVES + VALID_NZB_FILES: res, nzo_ids = sabnzbd.nzbparser.add_nzbfile( name, pp=kwargs.get("pp"), script=kwargs.get("script"), cat=kwargs.get("cat"), priority=kwargs.get("priority"), keep=True, nzbname=kwargs.get("nzbname"), password=kwargs.get("password"), ) return report(keyword="", data={"status": res is AddNzbFileResult.OK, "nzo_ids": nzo_ids}) else: logging.info('API-call addlocalfile: "%s" is not a supported file', name) return report(_MSG_NO_FILE) else: logging.info('API-call addlocalfile: file "%s" not found', name) return report(_MSG_NO_PATH) else: logging.info("API-call addlocalfile: no file name given") return report(_MSG_NO_VALUE) def _api_switch(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=first id), value2(=second id)""" value = kwargs.get("value") value2 = kwargs.get("value2") if value and value2: pos, prio = sabnzbd.NzbQueue.switch(value, value2) # Returns the new position and new priority (if different) return report(keyword="result", data={"position": pos, "priority": prio}) else: return report(_MSG_NO_VALUE2) def _api_change_cat(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id), value2(=category)""" nzo_ids = clean_comma_separated_list(kwargs.get("value")) cat = kwargs.get("value2") if nzo_ids and cat: if is_none(cat): cat = None result = sabnzbd.NzbQueue.change_cat(nzo_ids, cat) return report(keyword="status", data=bool(result > 0)) else: return report(_MSG_NO_VALUE) def _api_change_script(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id), value2(=script)""" nzo_ids = clean_comma_separated_list(kwargs.get("value")) script = kwargs.get("value2") if nzo_ids and script: if is_none(script): script = None result = sabnzbd.NzbQueue.change_script(nzo_ids, script) return report(keyword="status", data=bool(result > 0)) else: return report(_MSG_NO_VALUE) def _api_change_opts(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id), value2(=pp)""" nzo_ids = clean_comma_separated_list(kwargs.get("value")) pp = kwargs.get("value2") if nzo_ids and pp and pp.isdigit(): result = sabnzbd.NzbQueue.change_opts(nzo_ids, int(pp)) return report(keyword="status", data=bool(result > 0)) return report(_MSG_NO_ITEM) def _api_fullstatus(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: full history status""" status = build_status( calculate_performance=int_conv(kwargs.get("calculate_performance", 0)), skip_dashboard=int_conv(kwargs.get("skip_dashboard", 1)), ) return report(keyword="status", data=status) def _api_status(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: Dispatcher for mode=status, passing on the value""" value = kwargs.get("value", "") return _api_status_table.get(name, (_api_fullstatus, 2))[0](value, kwargs) def _api_unblock_server(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Unblock a blocked server""" sabnzbd.Downloader.unblock(value) return report() def _api_delete_orphan(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Remove orphaned job""" if value: path = os.path.join(cfg.download_dir.get_path(), value) logging.info("Removing orphaned job %s", path) remove_all(path, recursive=True) return report() else: return report(_MSG_NO_ITEM) def _api_delete_all_orphan(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Remove all orphaned jobs""" paths = sabnzbd.NzbQueue.scan_jobs(all_jobs=False, action=False) for path in paths: _api_delete_orphan(path, kwargs) return report() def _api_add_orphan(value: str, kwargs: Dict[str, Union[str, List[str]]]): """Add orphaned job""" if value: path = os.path.join(cfg.download_dir.get_path(), value) logging.info("Re-adding orphaned job %s", path) sabnzbd.NzbQueue.repair_job(path, None, None) return report() else: return report(_MSG_NO_ITEM) def _api_add_all_orphan(value: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Add all orphaned jobs""" paths = sabnzbd.NzbQueue.scan_jobs(all_jobs=False, action=False) for path in paths: _api_add_orphan(path, kwargs) return report() def _api_history(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id), start, limit, search, nzo_ids""" value = kwargs.get("value", "") start = int_conv(kwargs.get("start")) limit = int_conv(kwargs.get("limit")) last_history_update = int_conv(kwargs.get("last_history_update", 0)) search = kwargs.get("search") categories = clean_comma_separated_list(kwargs.get("cat") or kwargs.get("category")) statuses = clean_comma_separated_list(kwargs.get("status")) failed_only = int_conv(kwargs.get("failed_only")) nzo_ids = clean_comma_separated_list(kwargs.get("nzo_ids")) archive = True if name == "delete": # Only skip archive if specifically requested if kwargs.get("archive") == "0" or cfg.disable_archive(): archive = False special = value.lower() del_files = bool(int_conv(kwargs.get("del_files"))) if special in ("all", "failed", "completed"): history_db = sabnzbd.get_db_connection() if special in ("all", "failed"): if del_files: del_job_files(history_db.get_failed_paths(search)) if archive: history_db.archive_with_status(Status.FAILED, search) else: history_db.remove_with_status(Status.FAILED, search) if special in ("all", "completed"): if archive: history_db.archive_with_status(Status.COMPLETED, search) else: history_db.remove_with_status(Status.COMPLETED, search) history_updated() return report() elif value: for job in clean_comma_separated_list(value): if sabnzbd.PostProcessor.get_path(job): # This is always a permanent delete, no archiving sabnzbd.PostProcessor.delete(job, del_files=del_files) else: history_db = sabnzbd.get_db_connection() if del_files: remove_all(history_db.get_incomplete_path(job), recursive=True) if archive: history_db.archive(job) else: history_db.remove(job) history_updated() return report() else: return report(_MSG_NO_VALUE) elif not name: # Do we need to send anything? if last_history_update == sabnzbd.LAST_HISTORY_UPDATE: return report(keyword="history", data=False) if failed_only: # We ignore any other statuses, having both doesn't make sense statuses = [Status.FAILED] if not limit: limit = cfg.history_limit() # Only show archive if specifically requested if not int_conv(kwargs.get("archive")): archive = False history = {} grand, month, week, day = sabnzbd.BPSMeter.get_sums() history["total_size"] = to_units(grand) history["month_size"] = to_units(month) history["week_size"] = to_units(week) history["day_size"] = to_units(day) history["slots"], history["ppslots"], history["noofslots"] = build_history( start=start, limit=limit, archive=archive, search=search, categories=categories, statuses=statuses, nzo_ids=nzo_ids, ) history["last_history_update"] = sabnzbd.LAST_HISTORY_UPDATE history["version"] = sabnzbd.__version__ return report(keyword="history", data=history) else: return report(_MSG_NOT_IMPLEMENTED) def _api_get_files(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=nzo_id)""" value = kwargs.get("value") if value: return report(keyword="files", data=build_file_list(value)) else: return report(_MSG_NO_VALUE) def _api_move_nzf_bulk(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name(=top/up/down/bottom), value=(=nzo_id), nzf_ids, size (optional)""" nzo_id = kwargs.get("value") nzf_ids = clean_comma_separated_list(kwargs.get("nzf_ids")) size = int_conv(kwargs.get("size")) if nzo_id and nzf_ids and name: name = name.lower() nzf_moved = False if name == "up" and size: sabnzbd.NzbQueue.move_nzf_up_bulk(nzo_id, nzf_ids, size) nzf_moved = True elif name == "top": sabnzbd.NzbQueue.move_nzf_top_bulk(nzo_id, nzf_ids) nzf_moved = True elif name == "down" and size: sabnzbd.NzbQueue.move_nzf_down_bulk(nzo_id, nzf_ids, size) nzf_moved = True elif name == "bottom": sabnzbd.NzbQueue.move_nzf_bottom_bulk(nzo_id, nzf_ids) nzf_moved = True if nzf_moved: return report(keyword="", data={"status": True, "nzf_ids": nzf_ids}) return report(_MSG_NO_VALUE) def _api_addurl(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name, output, pp, script, cat, priority, nzbname""" pp = kwargs.get("pp") script = kwargs.get("script") cat = kwargs.get("cat") priority = kwargs.get("priority") nzbname = kwargs.get("nzbname", "") password = kwargs.get("password", "") if name: # Reporting a list of NZO's, for compatibility with other add-methods res, nzo_ids = sabnzbd.urlgrabber.add_url(name, pp, script, cat, priority, nzbname, password) return report(keyword="", data={"status": res is AddNzbFileResult.OK, "nzo_ids": nzo_ids}) else: logging.info("API-call addurl: no URLs received") return report(_MSG_NO_VALUE) def _api_pause(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.Scheduler.plan_resume(0) sabnzbd.Downloader.pause() return report() def _api_resume(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.Scheduler.plan_resume(0) sabnzbd.downloader.unpause_all() return report() def _api_shutdown(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.shutdown_program() return report() def _api_warnings(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts name, output""" if name == "clear": return report(keyword="warnings", data=sabnzbd.GUIHANDLER.clear()) elif name == "show": return report(keyword="warnings", data=sabnzbd.GUIHANDLER.content()) elif name: return report(_MSG_NOT_IMPLEMENTED) return report(keyword="warnings", data=sabnzbd.GUIHANDLER.content()) LOG_JSON_RE = re.compile(rb"'(apikey|api|username|password)': '(.*?)'", re.I) LOG_INI_HIDE_RE = re.compile( rb"(apikey|api|user|username|password|email_pwd|email_account|email_to|email_from|pushover_token|pushover_userkey" rb"|apprise_(target_[a-z_]+|urls)|pushbullet_apikey|prowl_apikey|growl_password|growl_server|IPv[4|6] address|Public address IPv[4|6]-only|Local IPv6 address)\s?=.*", re.I, ) LOG_HASH_RE = re.compile(rb"([a-zA-Z\d]{25})", re.I) def _api_showlog(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Fetch the INI and the log-data and add a message at the top""" log_data = b"--------------------------------\n\n" log_data += b"The log includes a copy of your sabnzbd.ini with\nall usernames, passwords and API-keys removed." log_data += b"\n\n--------------------------------\n" with open(sabnzbd.LOGFILE, "rb") as f: log_data += f.read() with open(config.get_filename(), "rb") as f: log_data += f.read() # We need to remove all passwords/usernames/api-keys log_data = LOG_JSON_RE.sub(b"'REMOVED': ''", log_data) log_data = LOG_INI_HIDE_RE.sub(b"\\1 = ", log_data) log_data = LOG_HASH_RE.sub(b"", log_data) # Try to replace the username try: if cur_user := getpass.getuser(): log_data = log_data.replace(utob(cur_user), b"") except: pass # Set headers cherrypy.response.headers["Content-Type"] = "application/x-download;charset=utf-8" cherrypy.response.headers["Content-Disposition"] = 'attachment;filename="sabnzbd.log"' return log_data def _api_get_cats(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: return report(keyword="categories", data=list_cats(False)) def _api_get_scripts(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: return report(keyword="scripts", data=list_scripts()) def _api_version(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: return report(keyword="version", data=sabnzbd.__version__) def _api_auth(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: key = kwargs.get("key", "") if not key: auth = "apikey" else: auth = "badkey" if key == cfg.nzb_key(): auth = "nzbkey" if key == cfg.api_key(): auth = "apikey" return report(keyword="auth", data=auth) def _api_restart(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: logging.info("Restart requested by API") # Do the shutdown async to still send goodbye to browser Thread(target=sabnzbd.trigger_restart, kwargs={"timeout": 1}).start() return report() def _api_restart_repair(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: logging.info("Queue repair requested by API") request_repair() # Do the shutdown async to still send goodbye to browser Thread(target=sabnzbd.trigger_restart, kwargs={"timeout": 1}).start() return report() def _api_disconnect(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.Downloader.disconnect() return report() def _api_eval_sort(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: evaluate sorting expression""" sort_string = kwargs.get("sort_string", "") job_name = kwargs.get("job_name", "") multipart_label = kwargs.get("multipart_label", "") path = sabnzbd.sorting.eval_sort(sort_string, job_name, multipart_label) if path is None: return report(_MSG_NOT_IMPLEMENTED) else: return report(keyword="result", data=path) def _api_watched_now(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.DirScanner.scan() return report() def _api_resume_pp(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.PostProcessor.paused = False return report() def _api_pause_pp(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sabnzbd.PostProcessor.paused = True return report() def _api_rss_now(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: # Run RSS scan async, because it can take a long time sabnzbd.Scheduler.force_rss() return report() def _api_retry_all(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: Retry all failed items in History""" items = sabnzbd.api.build_history()[0] nzo_ids = [] for item in items: if item["retry"]: nzo_ids.append(retry_job(item["nzo_id"])) return report(keyword="status", data=nzo_ids) def _api_reset_quota(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Reset quota left""" sabnzbd.BPSMeter.reset_quota(force=True) return report() def _api_test_email(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test email, return result""" logging.info("Sending test email") pack = {"download": ["action 1", "action 2"], "unpack": ["action 1", "action 2"]} res = sabnzbd.emailer.endjob( "I had a d\xe8ja vu", "unknown", True, os.path.normpath(os.path.join(cfg.complete_dir.get_path(), "/unknown/I had a d\xe8ja vu")), 123 * MEBI, None, pack, "my_script", "Line 1\nLine 2\nLine 3\nd\xe8ja vu\n", 0, test=kwargs, ) if res == T("Email succeeded"): return report() return report(error=res) def _api_test_windows(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test to Windows, return result""" logging.info("Sending test notification") res = sabnzbd.notifier.send_windows("SABnzbd", T("Test Notification"), "other") return report(error=res) def _api_test_notif(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test to Notification Center, return result""" logging.info("Sending test notification") res = sabnzbd.notifier.send_notification_center("SABnzbd", T("Test Notification"), "other") return report(error=res) def _api_test_osd(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test OSD notification, return result""" logging.info("Sending OSD notification") res = sabnzbd.notifier.send_notify_osd("SABnzbd", T("Test Notification")) return report(error=res) def _api_test_prowl(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test Prowl notification, return result""" logging.info("Sending Prowl notification") res = sabnzbd.notifier.send_prowl("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs) return report(error=res) def _api_test_pushover(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test Pushover notification, return result""" logging.info("Sending Pushover notification") res = sabnzbd.notifier.send_pushover("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs) return report(error=res) def _api_test_pushbullet(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test Pushbullet notification, return result""" logging.info("Sending Pushbullet notification") res = sabnzbd.notifier.send_pushbullet("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs) return report(error=res) def _api_test_apprise(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: send a test Apprise notification, return result""" logging.info("Sending Apprise notification") res = sabnzbd.notifier.send_apprise("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs) return report(error=res) def _api_test_nscript(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: execute a test notification script, return result""" logging.info("Executing notification script") res = sabnzbd.notifier.send_nscript("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs) return report(error=res) def _api_undefined(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: return report(_MSG_NOT_IMPLEMENTED) def _api_browse(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Return tree of local path""" compact = bool(int_conv(kwargs.get("compact"))) show_files = bool(int_conv(kwargs.get("show_files"))) show_hidden = bool(int_conv(kwargs.get("show_hidden_folders"))) if compact: # Used for typeahead paths = [] for entry in pathbrowser(os.path.dirname(name), show_hidden, show_files): if "path" in entry: paths.append(entry["path"]) else: paths = pathbrowser(name, show_hidden, show_files) return report(keyword="paths", data=paths) def _api_config(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: Dispatcher for "config" """ if cfg.configlock(): return report(_MSG_CONFIG_LOCKED) return _api_config_table.get(name, (_api_config_undefined, 2))[0](kwargs) def _api_config_speedlimit(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=speed)""" value = kwargs.get("value") if not value: value = "0" sabnzbd.Downloader.limit_speed(value) return report() def _api_config_set_pause(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts value(=pause interval)""" value = kwargs.get("value") sabnzbd.Scheduler.plan_resume(int_conv(value)) return report() def _api_config_set_apikey(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: cfg.api_key.set(config.create_api_key()) config.save_config() return report(keyword="apikey", data=cfg.api_key()) def _api_config_set_nzbkey(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: cfg.nzb_key.set(config.create_api_key()) config.save_config() return report(keyword="nzbkey", data=cfg.nzb_key()) def _api_config_regenerate_certs(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: # Make sure we only over-write default locations result = False if ( sabnzbd.cfg.https_cert() is sabnzbd.cfg.https_cert.default and sabnzbd.cfg.https_key() is sabnzbd.cfg.https_key.default ): https_cert = sabnzbd.cfg.https_cert.get_path() https_key = sabnzbd.cfg.https_key.get_path() result = create_https_certificates(https_cert, https_key) sabnzbd.RESTART_REQ = True return report(data=result) def _api_config_test_server(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """API: accepts server-params""" result, msg = test_nntp_server_dict(kwargs) return report(data={"result": result, "message": msg}) def _api_config_create_backup(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: backup_file = config.create_config_backup() return report(data={"result": bool(backup_file), "message": backup_file}) def _api_config_purge_log_files(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: purge_log_files() return report() def _api_config_undefined(kwargs: Dict[str, Union[str, List[str]]]) -> bytes: return report(_MSG_NOT_IMPLEMENTED) def _api_server_stats(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: sum_t, sum_m, sum_w, sum_d = sabnzbd.BPSMeter.get_sums() stats = {"total": sum_t, "month": sum_m, "week": sum_w, "day": sum_d, "servers": {}} for svr in config.get_servers(): t, m, w, d, daily, articles_tried, articles_success = sabnzbd.BPSMeter.amounts(svr) stats["servers"][svr] = { "total": t, "month": m, "week": w, "day": d, "daily": daily, "articles_tried": articles_tried, "articles_success": articles_success, } return report(keyword="", data=stats) def _api_gc_stats(name: str, kwargs: Dict[str, Union[str, List[str]]]) -> bytes: """Function only intended for internal testing of the memory handling""" # Collect before we check gc.collect() # We cannot create any lists/dicts, as they would create a reference return report(data=[str(obj) for obj in gc.get_objects() if isinstance(obj, sabnzbd.nzbstuff.TryList)]) ############################################################################## _api_table = { "server_stats": (_api_server_stats, 2), "get_config": (_api_get_config, 3), "set_config": (_api_set_config, 3), "set_config_default": (_api_set_config_default, 3), "del_config": (_api_del_config, 3), "queue": (_api_queue, 2), "translate": (_api_translate, 2), "addfile": (_api_addfile, 1), "retry": (_api_retry, 2), "cancel_pp": (_api_cancel_pp, 2), "addlocalfile": (_api_addlocalfile, 1), "switch": (_api_switch, 2), "change_cat": (_api_change_cat, 2), "change_script": (_api_change_script, 2), "change_opts": (_api_change_opts, 2), "fullstatus": (_api_fullstatus, 2), "status": (_api_status, 2), "history": (_api_history, 2), "get_files": (_api_get_files, 2), "move_nzf_bulk": (_api_move_nzf_bulk, 2), "addurl": (_api_addurl, 1), "pause": (_api_pause, 2), "resume": (_api_resume, 2), "shutdown": (_api_shutdown, 3), "warnings": (_api_warnings, 2), "showlog": (_api_showlog, 3), "config": (_api_config, 2), "get_cats": (_api_get_cats, 2), "get_scripts": (_api_get_scripts, 2), "version": (_api_version, 1), "auth": (_api_auth, 1), "restart": (_api_restart, 3), "restart_repair": (_api_restart_repair, 3), "disconnect": (_api_disconnect, 2), "gc_stats": (_api_gc_stats, 3), "eval_sort": (_api_eval_sort, 3), "watched_now": (_api_watched_now, 2), "resume_pp": (_api_resume_pp, 2), "pause_pp": (_api_pause_pp, 2), "rss_now": (_api_rss_now, 2), "browse": (_api_browse, 3), "retry_all": (_api_retry_all, 2), "reset_quota": (_api_reset_quota, 3), "test_email": (_api_test_email, 3), "test_windows": (_api_test_windows, 3), "test_notif": (_api_test_notif, 3), "test_osd": (_api_test_osd, 3), "test_pushover": (_api_test_pushover, 3), "test_pushbullet": (_api_test_pushbullet, 3), "test_apprise": (_api_test_apprise, 3), "test_prowl": (_api_test_prowl, 3), "test_nscript": (_api_test_nscript, 3), } _api_queue_table = { "delete": (_api_queue_delete, 2), "delete_nzf": (_api_queue_delete_nzf, 2), "rename": (_api_queue_rename, 2), "change_complete_action": (_api_queue_change_complete_action, 2), "purge": (_api_queue_purge, 2), "pause": (_api_queue_pause, 2), "resume": (_api_queue_resume, 2), "priority": (_api_queue_priority, 2), "sort": (_api_queue_sort, 2), } _api_status_table = { "unblock_server": (_api_unblock_server, 2), "delete_orphan": (_api_delete_orphan, 2), "delete_all_orphan": (_api_delete_all_orphan, 2), "add_orphan": (_api_add_orphan, 2), "add_all_orphan": (_api_add_all_orphan, 2), } _api_config_table = { "speedlimit": (_api_config_speedlimit, 2), "set_pause": (_api_config_set_pause, 2), "set_apikey": (_api_config_set_apikey, 3), "set_nzbkey": (_api_config_set_nzbkey, 3), "regenerate_certs": (_api_config_regenerate_certs, 3), "test_server": (_api_config_test_server, 3), "create_backup": (_api_config_create_backup, 3), "purge_log_files": (_api_config_purge_log_files, 3), } def api_level(mode: str, name: str) -> int: """Return access level required for this API call""" if mode == "queue" and name in _api_queue_table: return _api_queue_table[name][1] if mode == "status" and name in _api_status_table: return _api_status_table[name][1] if mode == "config" and name in _api_config_table: return _api_config_table[name][1] if mode in _api_table: return _api_table[mode][1] # It is invalid if it's none of these, but that's is handled somewhere else return 4 def report(error: Optional[str] = None, keyword: str = "value", data: Optional[Any] = None) -> bytes: """Report message in json, xml or plain text If error is set, only a status/error report is made. If no error and no data, only a status report is made. Else, a data report is made (optional 'keyword' for outer XML section). """ if cherrypy.request.params.get("output") == "xml": if not keyword: # xml always needs an outer keyword, even when json doesn't keyword = "result" content = "text/xml" xmlmaker = XmlOutputFactory() if error: status_str = xmlmaker.run("result", {"status": False, "error": error}) elif data is None: status_str = xmlmaker.run("result", {"status": True}) else: status_str = xmlmaker.run(keyword, data) response = '\n%s\n' % status_str else: content = "application/json;charset=UTF-8" if error: info = {"status": False, "error": error} elif data is None: info = {"status": True} else: if hasattr(data, "__iter__") and not keyword: info = data else: info = {keyword: data} response = utob(json.dumps(info)) cherrypy.response.headers["Content-Type"] = content cherrypy.response.headers["Pragma"] = "no-cache" return response class XmlOutputFactory: """Recursive xml string maker. Feed it a mixed tuple/dict/item object and will output into an xml string Current limitations: In Two tiered lists hard-coded name of "item": In Three tiered lists hard-coded name of "slot": """ def _tuple(self, keyw, lst): text = [] for item in lst: text.append(self.run(keyw, item)) return "".join(text) def _dict(self, keyw, lst): text = [] for key in lst.keys(): text.append(self.run(key, lst[key])) if keyw: return "<%s>%s\n" % (keyw, "".join(text), keyw) else: return "" def _list(self, keyw, lst): text = [] for cat in lst: if isinstance(cat, dict): text.append(self._dict(plural_to_single(keyw, "slot"), cat)) elif isinstance(cat, list): text.append(self._list(plural_to_single(keyw, "list"), cat)) elif isinstance(cat, tuple): text.append(self._tuple(plural_to_single(keyw, "tuple"), cat)) else: if not isinstance(cat, str): cat = str(cat) name = plural_to_single(keyw, "item") text.append("<%s>%s\n" % (name, xml_name(cat), name)) if keyw: return "<%s>%s\n" % (keyw, "".join(text), keyw) else: return "" def run(self, keyw, lst): if isinstance(lst, dict): text = self._dict(keyw, lst) elif isinstance(lst, list): text = self._list(keyw, lst) elif isinstance(lst, tuple): text = self._tuple(keyw, lst) elif keyw: text = "<%s>%s\n" % (keyw, xml_name(lst), keyw) else: text = "" return text def handle_server_api(kwargs: Dict[str, Union[str, List[str]]]) -> str: """Special handler for API-call 'set_config' [servers]""" name = kwargs.get("keyword") if not name: name = kwargs.get("name") if name: server = config.get_config("servers", name) if server: server.set_dict(kwargs) old_name = name else: config.ConfigServer(name, kwargs) old_name = None sabnzbd.Downloader.update_server(old_name, name) return name def handle_sorter_api(kwargs: Dict[str, Union[str, List[str]]]) -> Optional[str]: """Special handler for API-call 'set_config' [sorters]""" name = kwargs.get("keyword") if not name: name = kwargs.get("name") if not name: return None sorter = config.get_config("sorters", name) if sorter: sorter.set_dict(kwargs) else: config.ConfigSorter(name, kwargs) return name def handle_rss_api(kwargs: Dict[str, Union[str, List[str]]]) -> Optional[str]: """Special handler for API-call 'set_config' [rss]""" name = kwargs.get("keyword") if not name: name = kwargs.get("name") if not name: return None feed = config.get_config("rss", name) if feed: feed.set_dict(kwargs) else: config.ConfigRSS(name, kwargs) action = kwargs.get("filter_action") if action in ("add", "update"): # Use the general function, but catch the redirect-raise try: kwargs["feed"] = name sabnzbd.interface.ConfigRss("/").internal_upd_rss_filter(**kwargs) except cherrypy.HTTPRedirect: pass elif action == "delete": # Use the general function, but catch the redirect-raise try: kwargs["feed"] = name sabnzbd.interface.ConfigRss("/").internal_del_rss_filter(**kwargs) except cherrypy.HTTPRedirect: pass return name def handle_cat_api(kwargs: Dict[str, Union[str, List[str]]]) -> Optional[str]: """Special handler for API-call 'set_config' [categories]""" name = kwargs.get("keyword") if not name: name = kwargs.get("name") if not name: return None name = name.lower() cat = config.get_config("categories", name) if cat: cat.set_dict(kwargs) else: config.ConfigCat(name, kwargs) return name def test_nntp_server_dict(kwargs: Dict[str, Union[str, List[str]]]) -> Tuple[bool, str]: """Will connect (blocking) to the NNTP server and report back any errors""" host = kwargs.get("host", "").strip() port = int_conv(kwargs.get("port", 0)) username = kwargs.get("username", "").strip() password = kwargs.get("password", "").strip() server = kwargs.get("server", "").strip() connections = int_conv(kwargs.get("connections", 0)) timeout = int_conv(kwargs.get("timeout", DEF_TEST_TIMEOUT)) ssl = int_conv(kwargs.get("ssl", 0)) ssl_verify = int_conv(kwargs.get("ssl_verify", 1)) ssl_ciphers = kwargs.get("ssl_ciphers", "").strip() if not host: return False, T("The hostname is not set.") if not connections: return False, T("There are no connections set. Please set at least one connection.") if not port: if ssl: port = 563 else: port = 119 if not timeout: # Lower value during new server testing timeout = DEF_TEST_TIMEOUT if "*" in password and not password.strip("*"): # If the password is masked, try retrieving it from the config if srv := config.get_servers().get(server): password = srv.password() else: return False, T("Password masked in ******, please re-enter") try: test_server = sabnzbd.downloader.Server( server_id=-1, displayname="", host=host, port=port, timeout=timeout, threads=0, priority=0, use_ssl=ssl, ssl_verify=ssl_verify, ssl_ciphers=ssl_ciphers, username=username, password=password, ) except: return False, T("Invalid server details") # All exceptions are caught internally test_server.request_addrinfo_blocking() if not test_server.addrinfo: # Try if we can connect on port 80 (so web server), forcing a short timeout test_server.port = 80 test_server.timeout = DEF_TEST_TIMEOUT test_server.request_addrinfo_blocking() if test_server.addrinfo: return False, T( "Could not connect to %s on port %s. It appears that %s operates as a web server (port 80), " "possibly an indexer, not a usenet server. You have to fill a usenet server." ) % (host, port, host) return False, T('Server address "%s:%s" is not valid.') % (host, port) try: nw = NewsWrapper(server=test_server, thrdnum=-1, block=True) nw.init_connect() while not nw.connected: nw.recv_chunk() nw.finish_connect(nw.status_code) except socket.timeout: if port != 119 and not ssl: return False, T("Timed out: Try enabling SSL or connecting on a different port.") else: return False, T("Timed out") except socket.error as err: # Trying SSL on non-SSL port? if match_str(str(err), ("unknown protocol", "wrong version number")): return False, T("Unknown SSL protocol: Try disabling SSL or connecting on a different port.") return False, str(err) except NNTPPermanentError: # Handled by the code below pass except Exception as err: return False, str(err) if not username or not password: nw.nntp.sock.sendall(b"ARTICLE \r\n") try: nw.reset_data_buffer() nw.recv_chunk() except Exception as err: # Some internal error, not always safe to close connection return False, str(err) # Parse result return_status = () if nw.status_code: if nw.status_code == 480: return_status = (False, T("Server requires username and password.")) elif nw.status_code < 300 or nw.status_code in (411, 423, 430): # If no username/password set and we requested fake-article, it will return 430 Not Found return_status = (True, T("Connection Successful!")) elif nw.status_code == 502 or sabnzbd.downloader.clues_login(nw.nntp_msg): return_status = (False, T("Authentication failed, check username/password.")) elif sabnzbd.downloader.clues_too_many(nw.nntp_msg): return_status = (False, T("Too many connections, please pause downloading or try again later")) # Fallback in case no data was received or unknown status if not return_status: return_status = (False, T("Could not determine connection result (%s)") % nw.nntp_msg) # Close the connection and return result nw.hard_reset() return return_status def build_status(calculate_performance: int = False, skip_dashboard: int = False) -> Dict[str, Any]: # build up header full of basic information info = build_header(trans_functions=False) info["logfile"] = clip_path(sabnzbd.LOGFILE) info["weblogfile"] = clip_path(sabnzbd.WEBLOGFILE) info["webdir"] = clip_path(info["webdir"]) info["loglevel"] = str(cfg.log_level()) info["folders"] = sabnzbd.NzbQueue.scan_jobs(all_jobs=False, action=False) info["configfn"] = clip_path(config.get_filename()) info["warnings"] = sabnzbd.GUIHANDLER.content() # Calculate performance measures, if requested if calculate_performance: # PyStone sabnzbd.PYSTONE_SCORE = getpystone() # Disk speed of download (aka incomplete) and complete directory: sabnzbd.DOWNLOAD_DIR_SPEED = diskspeedmeasure(sabnzbd.cfg.download_dir.get_path()) sabnzbd.COMPLETE_DIR_SPEED = diskspeedmeasure(sabnzbd.cfg.complete_dir.get_path()) # Internet bandwidth sabnzbd.INTERNET_BANDWIDTH = internetspeed() # How often did we delay? info["delayed_assembler"] = sabnzbd.BPSMeter.delayed_assembler # Dashboard: Speed and load of System info["loadavg"] = loadavg() info["pystone"] = sabnzbd.PYSTONE_SCORE # Dashboard: Speed of Download directory: info["downloaddir"] = cfg.download_dir.get_clipped_path() info["downloaddirspeed"] = sabnzbd.DOWNLOAD_DIR_SPEED # Dashboard: Speed of Complete directory: info["completedir"] = cfg.complete_dir.get_clipped_path() info["completedirspeed"] = sabnzbd.COMPLETE_DIR_SPEED # Dashboard: Measured download-speed info["internetbandwidth"] = sabnzbd.INTERNET_BANDWIDTH # Dashboard: Connection information if not skip_dashboard: info["active_socks5_proxy"] = active_socks5_proxy() info["localipv4"] = local_ipv4() info["publicipv4"] = public_ipv4() info["ipv6"] = public_ipv6() info["dnslookup"] = dnslookup() info["servers"] = [] # Servers-list could be modified during iteration, so we need a copy for server in sabnzbd.Downloader.servers[:]: activeconn = sum(nw.connected for nw in server.idle_threads.copy()) serverconnections = [] for nw in server.busy_threads.copy(): if nw.connected: activeconn += 1 if nw.article: serverconnections.append( { "thrdnum": nw.thrdnum, "art_name": nw.article.article, "nzf_name": nw.article.nzf.filename, "nzo_name": nw.article.nzf.nzo.final_name, } ) server_info = { "servername": server.displayname, "serveractive": server.active, "serveractiveconn": activeconn, "servertotalconn": server.threads, "serverconnections": serverconnections, "serverssl": server.ssl, "serversslinfo": server.ssl_info, "serveripaddress": None, "servercanonname": None, "serverwarning": server.warning, "servererror": server.errormsg, "serverpriority": server.priority, "serveroptional": server.optional, "serverbps": to_units(sabnzbd.BPSMeter.server_bps.get(server.id, 0)), } # Only add this information if we are connected if activeconn and server.addrinfo: server_info["serveripaddress"] = server.addrinfo.ipaddress server_info["servercanonname"] = server.addrinfo.canonname if server.request and not server.addrinfo: server_info["serverwarning"] = T("Resolving address") info["servers"].append(server_info) return info def build_queue( start: int = 0, limit: int = 0, search: Optional[str] = None, categories: Optional[List[str]] = None, priorities: Optional[List[str]] = None, statuses: Optional[List[str]] = None, nzo_ids: Optional[List[str]] = None, ) -> Dict[str, Any]: info = build_header(for_template=False) ( queue_bytes_total, queue_bytes_left, bytes_left_previous_page, nzo_list, queue_fullsize, nzos_matched, ) = sabnzbd.NzbQueue.queue_info( search=search, categories=categories, priorities=priorities, statuses=statuses, nzo_ids=nzo_ids, start=start, limit=limit, ) info["kbpersec"] = "%.2f" % (sabnzbd.BPSMeter.bps / KIBI) info["speed"] = to_units(sabnzbd.BPSMeter.bps) info["mbleft"] = "%.2f" % (queue_bytes_left / MEBI) info["mb"] = "%.2f" % (queue_bytes_total / MEBI) info["sizeleft"] = to_units(queue_bytes_left, "B") info["size"] = to_units(queue_bytes_total, "B") info["noofslots_total"] = queue_fullsize info["noofslots"] = nzos_matched info["start"] = start info["limit"] = limit info["finish"] = start + limit if sabnzbd.Downloader.paused or sabnzbd.Downloader.paused_for_postproc: status = Status.PAUSED elif sabnzbd.BPSMeter.bps > 0: status = Status.DOWNLOADING else: status = Status.IDLE info["status"] = status info["timeleft"] = calc_timeleft(queue_bytes_left, sabnzbd.BPSMeter.bps) n = start running_bytes = bytes_left_previous_page slotinfo = [] for nzo in nzo_list: mbleft = nzo.remaining / MEBI mb = nzo.bytes / MEBI slot = {} slot["index"] = n slot["nzo_id"] = str(nzo.nzo_id) slot["unpackopts"] = str(opts_to_pp(nzo.repair, nzo.unpack, nzo.delete)) slot["priority"] = INTERFACE_PRIORITIES.get(nzo.priority, NORMAL_PRIORITY) slot["script"] = nzo.script if nzo.script else "None" slot["filename"] = nzo.final_name slot["labels"] = nzo.labels slot["password"] = nzo.password if nzo.password else "" slot["cat"] = nzo.cat if nzo.cat else "None" slot["mbleft"] = "%.2f" % mbleft slot["mb"] = "%.2f" % mb slot["size"] = to_units(nzo.bytes, "B") slot["sizeleft"] = to_units(nzo.remaining, "B") slot["percentage"] = "%s" % (int(((mb - mbleft) / mb) * 100)) if mb != mbleft else "0" slot["mbmissing"] = "%.2f" % (nzo.bytes_missing / MEBI) slot["direct_unpack"] = nzo.direct_unpack_progress if not sabnzbd.Downloader.paused and nzo.status not in (Status.PAUSED, Status.FETCHING, Status.GRABBING): if nzo.propagation_delay_left: slot["status"] = Status.PROPAGATING elif nzo.status == Status.CHECKING: slot["status"] = Status.CHECKING else: slot["status"] = Status.DOWNLOADING else: # Ensure compatibility of API status if nzo.status == Status.DELETED or nzo.priority == FORCE_PRIORITY: nzo.status = Status.DOWNLOADING slot["status"] = nzo.status if ( sabnzbd.Downloader.paused or sabnzbd.Downloader.paused_for_postproc or nzo.propagation_delay_left or nzo.status not in (Status.DOWNLOADING, Status.FETCHING, Status.QUEUED) ) and nzo.priority != FORCE_PRIORITY: slot["timeleft"] = "0:00:00" else: running_bytes += nzo.remaining slot["timeleft"] = calc_timeleft(running_bytes, sabnzbd.BPSMeter.bps) # Do not show age when it's not known if nzo.avg_date.year < 2000: slot["avg_age"] = "-" else: slot["avg_age"] = calc_age(nzo.avg_date) slotinfo.append(slot) n += 1 if slotinfo: info["slots"] = slotinfo else: info["slots"] = [] return info def fast_queue() -> Tuple[bool, int, float, str]: """Return paused, bytes_left, bpsnow, time_left""" bytes_left = sabnzbd.sabnzbd.NzbQueue.remaining() paused = sabnzbd.Downloader.paused bpsnow = sabnzbd.BPSMeter.bps time_left = calc_timeleft(bytes_left, bpsnow) return paused, bytes_left, bpsnow, time_left def build_file_list(nzo_id: str) -> List[Dict[str, Any]]: """Build file lists for specified job""" jobs = [] nzo = sabnzbd.sabnzbd.NzbQueue.get_nzo(nzo_id) if nzo: for nzf in nzo.finished_files: jobs.append( { "filename": nzf.filename, "mbleft": "%.2f" % (nzf.bytes_left / MEBI), "mb": "%.2f" % (nzf.bytes / MEBI), "bytes": "%.2f" % nzf.bytes, "age": calc_age(nzf.date), "nzf_id": nzf.nzf_id, "status": "finished", } ) for nzf in nzo.files: jobs.append( { "filename": nzf.filename, "mbleft": "%.2f" % (nzf.bytes_left / MEBI), "mb": "%.2f" % (nzf.bytes / MEBI), "bytes": "%.2f" % nzf.bytes, "age": calc_age(nzf.date), "nzf_id": nzf.nzf_id, "status": "active", } ) # extrapars can change during iteration for parset in nzo.extrapars.keys(): extrapar_set = nzo.extrapars.get(parset, []) for nzf in extrapar_set[:]: # Prevent listing files twice if nzf not in nzo.files and nzf not in nzo.finished_files: jobs.append( { "filename": nzf.filename, "set": nzf.setname, "mbleft": "%.2f" % (nzf.bytes_left / MEBI), "mb": "%.2f" % (nzf.bytes / MEBI), "bytes": "%.2f" % nzf.bytes, "age": calc_age(nzf.date), "nzf_id": nzf.nzf_id, "status": "queued", } ) return jobs def retry_job( job: str, new_nzb: Optional[cherrypy._cpreqbody.Part] = None, password: Optional[str] = None, ) -> Optional[str]: """Re enter failed job in the download queue""" if job: history_db = sabnzbd.get_db_connection() futuretype, url, pp, script, cat = history_db.get_other(job) if futuretype: nzo_id = sabnzbd.urlgrabber.add_url(url, pp, script, cat, dup_check=False) else: path = history_db.get_incomplete_path(job) nzo_id = sabnzbd.NzbQueue.repair_job(path, new_nzb, password) if nzo_id: # Only remove from history if we repaired something history_db.remove(job) return nzo_id return None def del_job_files(job_paths: List[str]): """Remove files of each path in the list""" for path in job_paths: if path and clip_path(path).lower().startswith(cfg.download_dir.get_clipped_path().lower()): remove_all(path, recursive=True) def Tspec(txt: str) -> str: """Translate special terms""" if is_none(txt): return T("None") elif txt in ("Default", "*"): return T("Default") else: return txt _SKIN_CACHE = {} # Stores pre-translated acronyms def Ttemplate(txt: str) -> str: """Translation function for Skin texts This special is to be used in interface.py for template processing to be passed for the $T function: so { ..., 'T' : Ttemplate, ...} """ global _SKIN_CACHE if txt in _SKIN_CACHE: return _SKIN_CACHE[txt] else: # We need to remove the " and ' to be JS/JSON-string-safe # Saving it in dictionary is 20x faster on next look-up tra = T(SKIN_TEXT.get(txt, txt)).replace('"', """).replace("'", "'") _SKIN_CACHE[txt] = tra return tra def clear_trans_cache(): """Clean cache for skin translations""" global _SKIN_CACHE _SKIN_CACHE = {} sabnzbd.WEBUI_READY = True def build_header(webdir: str = "", for_template: bool = True, trans_functions: bool = True) -> Dict[str, Any]: """Build the basic header""" header = {} # We don't output everything for API if for_template: # These are functions, and cause problems for JSON if trans_functions: header["T"] = Ttemplate header["Tspec"] = Tspec header["uptime"] = calc_age(sabnzbd.START) header["color_scheme"] = sabnzbd.WEB_COLOR or "" header["confighelpuri"] = f"https://sabnzbd.org/wiki/configuration/{sabnzbd.__version__[:3]}/" header["pid"] = os.getpid() header["active_lang"] = cfg.language() header["rtl"] = is_rtl(header["active_lang"]) header["my_lcldata"] = clip_path(sabnzbd.DIR_LCLDATA) header["my_home"] = clip_path(sabnzbd.DIR_HOME) header["webdir"] = webdir or sabnzbd.WEB_DIR header["url_base"] = cfg.url_base() header["windows"] = sabnzbd.WIN32 header["macos"] = sabnzbd.MACOS header["power_options"] = sabnzbd.WIN32 or sabnzbd.MACOS or sabnzbd.LINUX_POWER header["pp_pause_event"] = sabnzbd.Scheduler.pp_pause_event header["apikey"] = cfg.api_key() header["new_release"], header["new_rel_url"] = sabnzbd.NEW_VERSION header["version"] = sabnzbd.__version__ header["paused"] = bool(sabnzbd.Downloader.paused or sabnzbd.Downloader.paused_for_postproc) header["pause_int"] = sabnzbd.Scheduler.pause_int() header["paused_all"] = sabnzbd.PAUSED_ALL diskspace_info = diskspace() header["diskspace1"] = "%.2f" % diskspace_info["download_dir"][1] header["diskspace2"] = "%.2f" % diskspace_info["complete_dir"][1] header["diskspace1_norm"] = to_units(diskspace_info["download_dir"][1] * GIGI) header["diskspace2_norm"] = to_units(diskspace_info["complete_dir"][1] * GIGI) header["diskspacetotal1"] = "%.2f" % diskspace_info["download_dir"][0] header["diskspacetotal2"] = "%.2f" % diskspace_info["complete_dir"][0] header["speedlimit"] = str(sabnzbd.Downloader.bandwidth_perc) header["speedlimit_abs"] = str(sabnzbd.Downloader.bandwidth_limit) header["have_warnings"] = str(sabnzbd.GUIHANDLER.count()) header["finishaction"] = sabnzbd.QUEUECOMPLETE header["quota"] = to_units(sabnzbd.BPSMeter.quota) header["have_quota"] = bool(sabnzbd.BPSMeter.quota > 0.0) header["left_quota"] = to_units(sabnzbd.BPSMeter.left) anfo = sabnzbd.ArticleCache.cache_info() header["cache_art"] = str(anfo.article_sum) header["cache_size"] = to_units(anfo.cache_size, "B") return header def build_history( start: int = 0, limit: int = 1000000, archive: bool = False, search: Optional[str] = None, categories: Optional[List[str]] = None, statuses: Optional[List[str]] = None, nzo_ids: Optional[List[str]] = None, ) -> Tuple[List[Dict[str, Any]], int, int]: """Combine the jobs still in post-processing and the database history""" if not archive: # Grab any items that are active or queued in postproc postproc_queue = sabnzbd.PostProcessor.get_queue( search=search, categories=categories, statuses=statuses, nzo_ids=nzo_ids, ) # Multi-page support for postproc items postproc_queue_size = len(postproc_queue) if start > postproc_queue_size: # On a page where we shouldn't show postproc items postproc_queue = [] database_history_limit = limit else: if limit: postproc_queue = postproc_queue[start : start + limit] else: postproc_queue = postproc_queue[start:] # Remove the amount of postproc items from the db request for history items database_history_limit = max(limit - len(postproc_queue), 0) database_history_start = max(start - postproc_queue_size, 0) else: database_history_start = start database_history_limit = limit postproc_queue = [] postproc_queue_size = 0 # Acquire the db instance try: history_db = sabnzbd.get_db_connection() close_db = False except: # Required for repairs at startup because Cherrypy isn't active yet history_db = HistoryDB() close_db = True # Fetch history items if not database_history_limit: items, total_items = history_db.fetch_history( start=database_history_start, limit=1, archive=archive, search=search, categories=categories, statuses=statuses, nzo_ids=nzo_ids, ) items = [] else: items, total_items = history_db.fetch_history( start=database_history_start, limit=database_history_limit, archive=archive, search=search, categories=categories, statuses=statuses, nzo_ids=nzo_ids, ) # Add the postproc items to the top of the history # Reverse the queue to add items to the top (faster than insert) items.reverse() add_active_history(postproc_queue, items) total_items += postproc_queue_size items.reverse() if close_db: history_db.close() return items, postproc_queue_size, total_items def add_active_history(postproc_queue: List[NzbObject], items: List[Dict[str, Any]]): """Get the active history queue and add it to the existing items list""" for nzo in postproc_queue: # This output has to be the same as fetch_history! item = { "completed": int(time.time()), "name": nzo.final_name, "nzb_name": nzo.filename, "category": nzo.cat, "pp": PP_LOOKUP.get(opts_to_pp(nzo.repair, nzo.unpack, nzo.delete), "X"), "script": nzo.script, "report": "", "url": nzo.url, "status": nzo.status, "nzo_id": nzo.nzo_id, "storage": "", "path": clip_path(nzo.download_path), "script_line": "", "download_time": nzo.nzo_info.get("download_time", 0), "postproc_time": 0, "stage_log": [], "downloaded": nzo.bytes_downloaded, "completeness": None, "fail_message": nzo.fail_msg, "url_info": nzo.nzo_info.get("details", "") or nzo.nzo_info.get("more_info", ""), "bytes": nzo.bytes_downloaded, "size": to_units(nzo.bytes_downloaded, "B"), "meta": None, "series": "", "duplicate_key": nzo.duplicate_key, "md5sum": "", "password": nzo.correct_password, "action_line": nzo.action_line, "loaded": nzo.pp_active, "retry": False, "archive": False, } # Add stage information, in the correct order for stage in STAGES: if stage in nzo.unpack_info: item["stage_log"].append({"name": stage, "actions": nzo.unpack_info[stage]}) items.append(item) def calc_timeleft(bytesleft: float, bps: float) -> str: """Based on bytesleft and bps calculate the time left in the format HH:MM:SS""" if bytesleft <= 0 or bps <= 0: return "0:00:00" return format_time_left(int(bytesleft / bps)) def list_cats(default: bool = True) -> List[str]: """Return list of (ordered) categories, when default==False use '*' for Default category """ lst = [cat["name"] for cat in config.get_ordered_categories()] if default: lst.remove("*") lst.insert(0, "Default") return lst _PLURAL_TO_SINGLE = { "categories": "category", "servers": "server", "rss": "feed", "scripts": "script", "warnings": "warning", "files": "file", "jobs": "job", } def plural_to_single(kw, def_kw=""): try: return _PLURAL_TO_SINGLE[kw] except KeyError: return def_kw def del_from_section(kwargs: Dict[str, Union[str, List[str]]]) -> bool: """Remove keyword in section""" section = kwargs.get("section", "") if section in ("sorters", "servers", "rss", "categories"): keyword = kwargs.get("keyword") if keyword: item = config.get_config(section, keyword) if item: item.delete() del item config.save_config() if section == "servers": sabnzbd.Downloader.update_server(keyword, None) return True else: return False def history_remove_failed(): """Remove all failed jobs from history, including files""" logging.info("Scheduled removal of all failed jobs") with HistoryDB() as history_db: del_job_files(history_db.get_failed_paths()) history_db.remove_with_status(Status.FAILED) def history_remove_completed(): """Remove all completed jobs from history""" logging.info("Scheduled removal of all completed jobs") with HistoryDB() as history_db: history_db.remove_with_status(Status.COMPLETED) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4479418 SABnzbd-4.3.2/sabnzbd/powersup.py0000644000000000000000000002167614625637243016120 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.powersup - System power management support """ import os import subprocess import logging import time ############################################################################## # Power management for Windows ############################################################################## try: import win32security import win32api import ntsecuritycon except ImportError: pass def win_power_privileges(): """To do any power-options, the process needs higher privileges""" flags = ntsecuritycon.TOKEN_ADJUST_PRIVILEGES | ntsecuritycon.TOKEN_QUERY htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags) id_ = win32security.LookupPrivilegeValue(None, ntsecuritycon.SE_SHUTDOWN_NAME) newPrivileges = [(id_, ntsecuritycon.SE_PRIVILEGE_ENABLED)] win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges) def win_hibernate(): """Hibernate Windows system, returns after wakeup""" try: win_power_privileges() win32api.SetSystemPowerState(False, True) except: logging.error(T("Failed to hibernate system")) logging.info("Traceback: ", exc_info=True) def win_standby(): """Standby Windows system, returns after wakeup""" try: win_power_privileges() win32api.SetSystemPowerState(True, True) except: logging.error(T("Failed to standby system")) logging.info("Traceback: ", exc_info=True) def win_shutdown(): """Shutdown Windows system, never returns""" try: win_power_privileges() win32api.InitiateSystemShutdown("", "", 30, 1, 0) finally: os._exit(0) ############################################################################## # Power management for macOS ############################################################################## def osx_shutdown(): """Shutdown macOS system, never returns""" try: subprocess.call(["osascript", "-e", 'tell app "System Events" to shut down']) except: logging.error(T("Error while shutting down system")) logging.info("Traceback: ", exc_info=True) os._exit(0) def osx_standby(): """Make macOS system sleep, returns after wakeup""" try: subprocess.call(["pmset", "sleepnow"]) time.sleep(10) except: logging.error(T("Failed to standby system")) logging.info("Traceback: ", exc_info=True) def osx_hibernate(): """Make macOS system sleep, returns after wakeup""" osx_standby() ############################################################################## # Power management for Linux ############################################################################## # Requires DBus plus either HAL [1] or the more modern ConsoleKit [2] and # DeviceKit(-power) [3]. HAL will eventually be deprecated but older systems # might still use it. # [1] http://people.freedesktop.org/~hughsient/temp/dbus-interface.html # [2] http://www.freedesktop.org/software/ConsoleKit/doc/ConsoleKit.html # [3] http://hal.freedesktop.org/docs/DeviceKit-power/ # # Original code was contributed by Marcel de Vries # try: import dbus HAVE_DBUS = True except ImportError: HAVE_DBUS = False _IS_NOT_INTERACTIVE = False _LOGIND_SUCCESSFUL_RESULT = "yes" def _get_sessionproxy(): """Return (proxy-object, interface), (None, None) if not available""" name = "org.freedesktop.PowerManagement" path = "/org/freedesktop/PowerManagement" interface = "org.freedesktop.PowerManagement" try: bus = dbus.SessionBus() return bus.get_object(name, path), interface except dbus.exceptions.DBusException: return None, None def _get_systemproxy(method): """Return (proxy-object, interface, pinterface), (None, None, None) if not available""" if method == "ConsoleKit": name = "org.freedesktop.ConsoleKit" path = "/org/freedesktop/ConsoleKit/Manager" interface = "org.freedesktop.ConsoleKit.Manager" pinterface = None elif method == "DeviceKit": name = "org.freedesktop.DeviceKit.Power" path = "/org/freedesktop/DeviceKit/Power" interface = "org.freedesktop.DeviceKit.Power" pinterface = "org.freedesktop.DBus.Properties" elif method == "UPower": name = "org.freedesktop.UPower" path = "/org/freedesktop/UPower" interface = "org.freedesktop.UPower" pinterface = "org.freedesktop.DBus.Properties" elif method == "Logind": name = "org.freedesktop.login1" path = "/org/freedesktop/login1" interface = "org.freedesktop.login1.Manager" pinterface = None try: bus = dbus.SystemBus() return bus.get_object(name, path), interface, pinterface except dbus.exceptions.DBusException as msg: logging.info("DBus not reachable (%s)", msg) return None, None, None def linux_shutdown(): """Make Linux system shutdown, never returns""" if not HAVE_DBUS: os._exit(0) try: proxy, interface = _get_sessionproxy() if proxy: if proxy.CanShutdown(): proxy.Shutdown(dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy("Logind") if proxy: if proxy.CanPowerOff(dbus_interface=interface) == _LOGIND_SUCCESSFUL_RESULT: proxy.PowerOff(_IS_NOT_INTERACTIVE, dbus_interface=interface) else: proxy, interface, _pinterface = _get_systemproxy("ConsoleKit") if proxy: if proxy.CanStop(dbus_interface=interface): proxy.Stop(dbus_interface=interface) else: logging.info("DBus does not support Stop (shutdown)") except dbus.exceptions.DBusException as msg: logging.error(T("Received a DBus exception %s"), msg) os._exit(0) def linux_hibernate(): """Make Linux system go into hibernate, returns after wakeup""" if not HAVE_DBUS: return try: proxy, interface = _get_sessionproxy() if proxy: if proxy.CanHibernate(): proxy.Hibernate(dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy("Logind") if proxy: if proxy.CanHibernate(dbus_interface=interface) == _LOGIND_SUCCESSFUL_RESULT: proxy.Hibernate(_IS_NOT_INTERACTIVE, dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy("UPower") if not proxy: proxy, interface, pinterface = _get_systemproxy("DeviceKit") if proxy: if proxy.Get(interface, "can-hibernate", dbus_interface=pinterface): proxy.Hibernate(dbus_interface=interface) else: logging.info("DBus does not support Hibernate") time.sleep(10) except dbus.exceptions.DBusException as msg: logging.error(T("Received a DBus exception %s"), msg) def linux_standby(): """Make Linux system go into standby, returns after wakeup""" if not HAVE_DBUS: return try: proxy, interface = _get_sessionproxy() if proxy: if proxy.CanSuspend(): proxy.Suspend(dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy("Logind") if proxy: if proxy.CanSuspend(dbus_interface=interface) == _LOGIND_SUCCESSFUL_RESULT: proxy.Suspend(_IS_NOT_INTERACTIVE, dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy("UPower") if not proxy: proxy, interface, pinterface = _get_systemproxy("DeviceKit") if proxy: if proxy.Get(interface, "can-suspend", dbus_interface=pinterface): proxy.Suspend(dbus_interface=interface) else: logging.info("DBus does not support Suspend (standby)") time.sleep(10) except dbus.exceptions.DBusException as msg: logging.error(T("Received a DBus exception %s"), msg) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4480288 SABnzbd-4.3.2/sabnzbd/sabtraylinux.py0000644000000000000000000001507114625637243016751 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.sabtraylinux - System tray icon for Linux, inspired from the Windows one """ import gi from gi.repository import Gtk, GLib import logging try: gi.require_version("XApp", "1.0") from gi.repository import XApp if not hasattr(XApp, "StatusIcon"): raise ImportError HAVE_XAPP = True logging.debug("XApp found: %s" % XApp) except Exception: HAVE_XAPP = False logging.debug("XApp not available, falling back to Gtk.StatusIcon") from time import sleep import subprocess from threading import Thread from os.path import abspath import sabnzbd from sabnzbd.panic import launch_a_browser import sabnzbd.api as api import sabnzbd.cfg as cfg from sabnzbd.misc import to_units class StatusIcon(Thread): sabicons = { "default": abspath("icons/logo-arrow.svg"), "green": abspath("icons/logo-arrow_green.svg"), "pause": abspath("icons/logo-arrow_gray.svg"), } updatefreq = 1000 # ms def __init__(self): self.mythread = Thread(target=self.dowork) self.mythread.start() def dowork(self): # Wait for translated texts to be loaded while not sabnzbd.WEBUI_READY: sleep(0.2) logging.debug("language file not loaded, waiting") self.sabpaused = False if HAVE_XAPP: self.statusicon = XApp.StatusIcon() else: self.statusicon = Gtk.StatusIcon() self.statusicon.set_name("SABnzbd") self.statusicon.set_visible(True) self.icon = self.sabicons["default"] self.refresh_icon() self.tooltip = "SABnzbd %s" % sabnzbd.__version__ self.refresh_tooltip() if HAVE_XAPP: self.statusicon.connect("activate", self.right_click_event) else: self.statusicon.connect("popup-menu", self.right_click_event) GLib.timeout_add(self.updatefreq, self.run) Gtk.main() def refresh_icon(self): if HAVE_XAPP: # icon path must be absolute in XApp self.statusicon.set_icon_name(self.icon) else: self.statusicon.set_from_file(self.icon) def refresh_tooltip(self): self.statusicon.set_tooltip_text(self.tooltip) # run this every updatefreq ms def run(self): self.sabpaused, bytes_left, bpsnow, time_left = api.fast_queue() mb_left = to_units(bytes_left) speed = to_units(bpsnow) if self.sabpaused: self.tooltip = T("Paused") self.icon = self.sabicons["pause"] elif bytes_left > 0: self.tooltip = "%sB/s %s: %sB (%s)" % (speed, T("Remaining"), mb_left, time_left) self.icon = self.sabicons["green"] else: self.tooltip = T("Idle") self.icon = self.sabicons["default"] self.refresh_icon() self.tooltip = "SABnzbd %s\n%s" % (sabnzbd.__version__, self.tooltip) self.refresh_tooltip() return 1 def right_click_event(self, icon, button, time): """menu""" menu = Gtk.Menu() maddnzb = Gtk.MenuItem(label=T("Add NZB")) mshowinterface = Gtk.MenuItem(label=T("Show interface")) mopencomplete = Gtk.MenuItem(label=T("Open complete folder")) mrss = Gtk.MenuItem(label=T("Read all RSS feeds")) if self.sabpaused: mpauseresume = Gtk.MenuItem(label=T("Resume")) else: mpauseresume = Gtk.MenuItem(label=T("Pause")) mrestart = Gtk.MenuItem(label=T("Restart")) mshutdown = Gtk.MenuItem(label=T("Shutdown")) maddnzb.connect("activate", self.addnzb) mshowinterface.connect("activate", self.browse) mopencomplete.connect("activate", self.opencomplete) mrss.connect("activate", self.rss) mpauseresume.connect("activate", self.pauseresume) mrestart.connect("activate", self.restart) mshutdown.connect("activate", self.shutdown) menu.append(maddnzb) menu.append(mshowinterface) menu.append(mopencomplete) menu.append(mrss) menu.append(mpauseresume) menu.append(mrestart) menu.append(mshutdown) menu.show_all() menu.popup(None, None, None, self.statusicon, button, time) def addnzb(self, icon): """menu handlers""" dialog = Gtk.FileChooserDialog(title="SABnzbd - " + T("Add NZB"), action=Gtk.FileChooserAction.OPEN) dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK) dialog.set_select_multiple(True) filter = Gtk.FileFilter() filter.set_name("*.nzb,*.gz,*.bz2,*.zip,*.rar,*.7z") filter.add_pattern("*.nzb") filter.add_pattern("*.gz") filter.add_pattern("*.bz2") filter.add_pattern("*.zip") filter.add_pattern("*.rar") filter.add_pattern("*.7z") dialog.add_filter(filter) response = dialog.run() if response == Gtk.ResponseType.OK: for filename in dialog.get_filenames(): sabnzbd.nzbparser.add_nzbfile(filename) dialog.destroy() def opencomplete(self, icon): subprocess.Popen(["xdg-open", cfg.complete_dir.get_path()]) def browse(self, icon): launch_a_browser(sabnzbd.BROWSER_URL, True) def pauseresume(self, icon): if self.sabpaused: self.resume() else: self.pause() def restart(self, icon): self.hover_text = T("Restart") sabnzbd.trigger_restart() def shutdown(self, icon): self.hover_text = T("Shutdown") sabnzbd.shutdown_program() def pause(self): sabnzbd.Scheduler.plan_resume(0) sabnzbd.Downloader.pause() def resume(self): sabnzbd.Scheduler.plan_resume(0) sabnzbd.downloader.unpause_all() def rss(self, icon): sabnzbd.Scheduler.force_rss() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4481387 SABnzbd-4.3.2/sabnzbd/nzbstuff.py0000644000000000000000000024636014625637243016074 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.nzbstuff - misc """ import os import time import re import logging import datetime import threading import functools import difflib from typing import List, Dict, Any, Tuple, Optional, Union, BinaryIO, Set # SABnzbd modules import sabnzbd import sabctools from sabnzbd.constants import ( GIGI, ATTRIB_FILE, JOB_ADMIN, REPAIR_PRIORITY, FORCE_PRIORITY, HIGH_PRIORITY, NORMAL_PRIORITY, LOW_PRIORITY, DEFAULT_PRIORITY, PAUSED_PRIORITY, STOP_PRIORITY, RENAMES_FILE, MAX_BAD_ARTICLES, Status, DuplicateStatus, ) from sabnzbd.misc import ( to_units, cat_to_opts, cat_convert, int_conv, format_time_string, calc_age, cmp, caller_name, opts_to_pp, pp_to_opts, duplicate_warning, ) from sabnzbd.filesystem import ( sanitize_foldername, get_unique_dir, get_admin_path, remove_all, sanitize_filename, set_permissions, long_path, fix_unix_encoding, get_ext, get_filename, get_unique_filename, renamer, remove_file, make_script_path, globber, is_valid_script, has_unwanted_extension, create_all_dirs, get_basename, backup_exists, get_new_id, save_data, load_data, save_compressed, backup_nzb, remove_data, strip_extensions, ) from sabnzbd.par2file import FilePar2Info from sabnzbd.decorators import synchronized import sabnzbd.config as config import sabnzbd.cfg as cfg import sabnzbd.nzbparser from sabnzbd.downloader import Server from sabnzbd.database import HistoryDB from sabnzbd.deobfuscate_filenames import is_probably_obfuscated # Name patterns # In the subject, we expect the filename within double quotes RE_SUBJECT_FILENAME_QUOTES = re.compile(r'"([^"]*)"') # Otherwise something that looks like a filename RE_SUBJECT_BASIC_FILENAME = re.compile(r"\b([\w\-+()' .,]+(?:\[[\w\-/+()' .,]*][\w\-+()' .,]*)*\.[A-Za-z0-9]{2,4})\b") RE_RAR = re.compile(r"(\.rar|\.r\d\d|\.s\d\d|\.t\d\d|\.u\d\d|\.v\d\d)$", re.I) ############################################################################## # Trylist ############################################################################## TRYLIST_LOCK = threading.Lock() class TryList: """TryList keeps track of which servers have been tried for a specific article""" # Pre-define attributes to save memory __slots__ = ("try_list",) def __init__(self): # Sets are faster than lists self.try_list: Set[Server] = set() def server_in_try_list(self, server: Server) -> bool: """Return whether specified server has been tried""" with TRYLIST_LOCK: return server in self.try_list def all_servers_in_try_list(self, servers: List[Server]) -> bool: """Check if all servers have been tried""" with TRYLIST_LOCK: for server in servers: if server not in self.try_list: return False return True def add_to_try_list(self, server: Server): """Register server as having been tried already""" with TRYLIST_LOCK: # Sets cannot contain duplicate items self.try_list.add(server) def remove_from_try_list(self, server: Server): """Remove server from list of tried servers""" with TRYLIST_LOCK: # Discard does not require the item to be present self.try_list.discard(server) def reset_try_list(self): """Clean the list""" with TRYLIST_LOCK: self.try_list = set() def __getstate__(self): """Save the servers""" return set(server.id for server in self.try_list) def __setstate__(self, servers_ids: List[str]): self.try_list = set() for server in sabnzbd.Downloader.servers: if server.id in servers_ids: self.add_to_try_list(server) ############################################################################## # Article ############################################################################## ArticleSaver = ( "article", "art_id", "bytes", "lowest_partnum", "decoded", "file_size", "data_begin", "data_size", "on_disk", "nzf", "crc32", ) class Article(TryList): """Representation of one article""" # Pre-define attributes to save memory __slots__ = ArticleSaver + ("fetcher", "fetcher_priority", "tries") def __init__(self, article, article_bytes, nzf): super().__init__() self.article: str = article self.art_id: Optional[str] = None self.bytes: int = article_bytes self.lowest_partnum: bool = False self.fetcher: Optional[Server] = None self.fetcher_priority: int = 0 self.tries: int = 0 # Try count self.decoded: bool = False self.file_size: Optional[int] = None self.data_begin: Optional[int] = None self.data_size: Optional[int] = None self.on_disk: bool = False self.crc32: Optional[int] = None self.nzf: NzbFile = nzf def reset_try_list(self): """In addition to resetting the try list, also reset fetcher so all servers are tried again""" self.fetcher = None self.fetcher_priority = 0 super().reset_try_list() def get_article(self, server: Server, servers: List[Server]): """Return article when appropriate for specified server""" if self.fetcher or self.server_in_try_list(server): return None if server.priority > self.fetcher_priority: # Check for higher priority server, taking advantage of servers list being sorted by priority for server_check in servers: if server_check.priority < server.priority: if server_check.active and not self.server_in_try_list(server_check): # There is a higher priority server, so set article priority and return self.fetcher_priority = server_check.priority return None else: # All servers with a higher priority have been checked break # If no higher priority servers, use this server self.fetcher_priority = server.priority self.fetcher = server self.tries += 1 return self def get_art_id(self): """Return unique article storage name, create if needed""" if not self.art_id: self.art_id = get_new_id("article", self.nzf.nzo.admin_path) return self.art_id def search_new_server(self): """Search for a new server for this article""" # Since we need a new server, this one can be listed as failed sabnzbd.BPSMeter.register_server_article_failed(self.fetcher.id) self.add_to_try_list(self.fetcher) # Servers-list could be modified during iteration, so we need a copy for server in sabnzbd.Downloader.servers[:]: if server.active and not self.server_in_try_list(server): if server.priority >= self.fetcher.priority: self.tries = 0 # Allow all servers for this nzo and nzf again (but not this fetcher for this article) sabnzbd.NzbQueue.reset_try_lists(self, remove_fetcher_from_trylist=False) return True logging.info("Article %s unavailable on all servers, discarding", self.article) return False def __getstate__(self): """Save to pickle file, selecting attributes""" dict_ = {} for item in ArticleSaver: dict_[item] = getattr(self, item) dict_["try_list"] = super().__getstate__() return dict_ def __setstate__(self, dict_): """Load from pickle file, selecting attributes""" for item in ArticleSaver: try: setattr(self, item, dict_[item]) except KeyError: # Handle new attributes setattr(self, item, None) super().__setstate__(dict_.get("try_list", [])) self.fetcher = None self.fetcher_priority = 0 self.tries = 0 def __eq__(self, other): """Articles with the same usenet address are the same""" return self.article == other.article def __hash__(self): """Required because we implement eq. Articles with the same usenet address can appear in different NZF's. So we make every article object unique, even though it is bad practice. """ return id(self) def __repr__(self): return "" % (self.article, self.bytes, self.art_id) ############################################################################## # NzbFile ############################################################################## NzbFileSaver = ( "date", "filename", "filename_checked", "filepath", "type", "is_par2", "vol", "blocks", "setname", "articles", "decodetable", "bytes", "bytes_left", "nzo", "nzf_id", "deleted", "valid", "import_finished", "crc32", "assembled", "md5of16k", ) class NzbFile(TryList): """Representation of one file consisting of multiple articles""" # Pre-define attributes to save memory __slots__ = NzbFileSaver + ("first_article",) def __init__(self, date, subject, raw_article_db, file_bytes, nzo): """Setup object""" super().__init__() self.date: datetime.datetime = date self.type: Optional[str] = None self.filename: str = sanitize_filename(name_extractor(subject)) self.filename_checked = False self.filepath: Optional[str] = None # Identifiers for par2 files self.is_par2: bool = False self.vol: Optional[int] = None self.blocks: Optional[int] = None self.setname: Optional[str] = None # Articles are removed from "articles" after being fetched self.articles: List[Article] = [] self.decodetable: List[Article] = [] self.bytes: int = file_bytes self.bytes_left: int = file_bytes self.nzo: NzbObject = nzo self.nzf_id: str = get_new_id("nzf", nzo.admin_path) self.deleted = False self.import_finished = False self.crc32: Optional[int] = 0 self.assembled: bool = False self.md5of16k: Optional[bytes] = None self.valid: bool = bool(raw_article_db) # Temporarily hold the first article during import self.first_article: Optional[Article] = None if self.valid and self.nzf_id: # Save first article separate, so we can deobfuscate-during-download # We process the first_file in nzo.add_nzf because if this NZF turns # out to be a duplicate file inside the NZB, the first article would # otherwise become a ghost article. self.first_article = self.add_article(raw_article_db.pop(0)) self.first_article.lowest_partnum = True # Any articles left? if raw_article_db: # Save the rest save_data(raw_article_db, self.nzf_id, nzo.admin_path) else: # All imported self.import_finished = True def finish_import(self): """Load the article objects from disk""" logging.debug("Finishing import on %s", self.filename) if raw_article_db := load_data(self.nzf_id, self.nzo.admin_path, remove=False): for raw_article in raw_article_db: self.add_article(raw_article) # Make sure we have labeled the lowest part number # Also when DirectUnpack is disabled we need to know self.decodetable[0].lowest_partnum = True # Mark safe to continue self.import_finished = True def add_article(self, article_info): """Add article to object database and return article object""" article = Article(article_info[0], article_info[1], self) self.articles.append(article) self.decodetable.append(article) return article def remove_article(self, article: Article, success: bool) -> int: """Handle completed article, possibly end of file""" if article in self.articles: self.articles.remove(article) if success: self.bytes_left -= article.bytes return len(self.articles) def set_par2(self, setname, vol, blocks): """Designate this this file as a par2 file""" self.is_par2 = True self.setname = setname self.vol = vol self.blocks = int_conv(blocks) def update_crc32(self, crc32: Optional[int], length: int) -> None: if self.crc32 is None or crc32 is None: self.crc32 = None else: self.crc32 = sabctools.crc32_combine(self.crc32, crc32, length) def get_articles(self, server: Server, servers: List[Server], fetch_limit: int) -> List[Article]: """Get next articles to be downloaded""" articles = [] for article in self.articles: if article := article.get_article(server, servers): articles.append(article) if len(articles) >= fetch_limit: return articles self.add_to_try_list(server) return articles def reset_all_try_lists(self): """Clear all lists of visited servers""" for art in self.articles: art.reset_try_list() self.reset_try_list() def prepare_filepath(self): """Do all checks before making the final path""" if not self.filepath: self.nzo.verify_nzf_filename(self) filename = sanitize_filename(self.filename) self.filepath = get_unique_filename(os.path.join(self.nzo.download_path, filename)) self.filename = get_filename(self.filepath) return self.filepath @property def completed(self): """Is this file completed?""" return self.import_finished and not bool(self.articles) def remove_admin(self): """Remove article database from disk (sabnzbd_nzf_)""" try: logging.debug("Removing article database for %s", self.nzf_id) remove_file(os.path.join(self.nzo.admin_path, self.nzf_id)) except: pass def __getstate__(self): """Save to pickle file, selecting attributes""" dict_ = {} for item in NzbFileSaver: dict_[item] = getattr(self, item) dict_["try_list"] = super().__getstate__() return dict_ def __setstate__(self, dict_): """Load from pickle file, selecting attributes""" for item in NzbFileSaver: try: setattr(self, item, dict_[item]) except KeyError: # Handle new attributes setattr(self, item, None) super().__setstate__(dict_.get("try_list", [])) def __eq__(self, other: "NzbFile"): """Assume it's the same file if the number bytes and first article are the same or if there are no articles left, use the filenames. Some NZB's are just a mess and report different sizes for the same article. """ if other and (self.bytes == other.bytes or len(self.decodetable) == len(other.decodetable)): if self.decodetable and other.decodetable: return self.decodetable[0] == other.decodetable[0] # Fallback to filename comparison return self.filename == other.filename return False def __hash__(self): """Required because we implement eq. The same file can be spread over multiple NZO's so we make every NZF unique. Even though it's considered bad practice. """ return id(self) def __repr__(self): return "" % (self.filename, self.bytes, self.nzf_id) ############################################################################## # NzbObject ############################################################################## class NzbEmpty(Exception): pass class NzbRejected(Exception): pass class NzbRejectToHistory(Exception): def __init__(self, nzo, fail_msg): self.nzo: NzbObject = nzo self.nzo.fail_msg = fail_msg super().__init__() NzbObjectSaver = ( "filename", "work_name", "final_name", "bytes", "bytes_downloaded", "bytes_tried", "bytes_missing", "bytes_par2", "repair", "unpack", "delete", "script", "cat", "url", "groups", "avg_date", "propagation_delay", "md5of16k", "extrapars", "par2packs", "files", "files_table", "finished_files", "status", "avg_bps_freq", "avg_bps_total", "priority", "saved_articles", "nzo_id", "futuretype", "removed_from_queue", "action_line", "unpack_info", "fail_msg", "nzo_info", "custom_name", "password", "correct_password", "next_save", "save_timeout", "encrypted", "bad_articles", "duplicate", "duplicate_key", "oversized", "precheck", "incomplete", "reuse", "meta", "first_articles", "first_articles_count", "md5sum", "download_path", "servercount", "unwanted_ext", "renames", ) NzoAttributeSaver = ("cat", "pp", "script", "priority", "final_name", "password", "url") # Lock to prevent errors when saving the NZO data NZO_LOCK = threading.RLock() class NzbObject(TryList): def __init__( self, filename: str, pp: Optional[int] = None, script: Optional[str] = None, nzb_fp: Optional[BinaryIO] = None, futuretype: bool = False, cat: Optional[str] = None, url: Optional[str] = None, priority: Optional[Union[int, str]] = DEFAULT_PRIORITY, password: Optional[str] = None, nzbname: Optional[str] = None, status: str = Status.QUEUED, nzo_info: Optional[Dict[str, Any]] = None, reuse: Optional[str] = None, nzo_id: Optional[str] = None, dup_check: bool = True, ): super().__init__() # Use original filename as basis self.work_name = self.filename = filename # User defined job name if nzbname: self.final_name = self.work_name = nzbname # Extract password if not explicitly set, also on URL-fetches which might have a custom name with password self.password = password if not self.password: # Extract before create_work_name, as it would escape the "/" on Windows self.work_name, self.password = scan_password(self.work_name) # Check for password also in filename if not self.password: _, self.password = scan_password(get_basename(filename)) # Remove trailing .nzb/.par(2) and sanitize self.work_name = create_work_name(self.work_name) self.final_name = self.work_name # Temporary store for custom job name for after URL-fetching self.custom_name = nzbname # Create a record of the input for pp, script, and priority input_pp = pp input_script = script input_priority = priority if priority != DEFAULT_PRIORITY else None # Determine category and find pp/script values based on input # Later will be re-evaluated based on import steps if pp is None: r = u = d = None else: r, u, d = pp_to_opts(pp) self.priority: int = NORMAL_PRIORITY self.set_priority(priority) # Parse priority of input self.repair: bool = r # True if we want to repair this set self.unpack: bool = u # True if we want to unpack this set self.delete: bool = d # True if we want to delete this set self.cat = cat # User-set category self.script: Optional[str] = None # External script for this set if is_valid_script(script): self.script = script # Information fields self.url = url self.groups = [] self.avg_date = datetime.datetime(1970, 1, 1, 1, 0) self.avg_stamp = 0.0 # Avg age in seconds (calculated from avg_age) self.propagation_delay: Optional[float] = None # Set during parsing self.correct_password: Optional[str] = None # Bookkeeping values self.meta = {} self.servercount: Dict[str, int] = {} # Dict to keep bytes per server self.direct_unpacker: Optional[sabnzbd.directunpacker.DirectUnpacker] = None # The DirectUnpacker instance self.bytes: int = 0 # Original bytesize self.bytes_par2: int = 0 # Bytes available for repair self.bytes_downloaded: int = 0 # Downloaded byte self.bytes_tried: int = 0 # Which bytes did we try self.bytes_missing: int = 0 # Bytes missing self.bad_articles: int = 0 # How many bad (non-recoverable) articles self.extrapars: Dict[str, List[NzbFile]] = {} # Holds the extra parfile names for all sets self.par2packs: Dict[str, Dict[str, FilePar2Info]] = {} # Holds the par2info for each file in each set self.md5of16k: Dict[bytes, str] = {} # Holds the md5s of the first-16k of all files in the NZB (hash: name) self.files: List[NzbFile] = [] # List of all NZFs self.files_table: Dict[str, NzbFile] = {} # Dictionary of NZFs indexed using NZF_ID self.renames: Dict[str, str] = {} # Dictionary of all renamed files self.finished_files: List[NzbFile] = [] # List of all finished NZFs # The current status of the nzo eg: # Queued, Downloading, Repairing, Unpacking, Failed, Complete self.status: str = status self.avg_bps_freq = 0 self.avg_bps_total = 0 self.first_articles: List[Article] = [] self.first_articles_count = 0 self.saved_articles: Set[Article] = set() self.nzo_id: Optional[str] = None self.duplicate: Optional[str] = None self.duplicate_key: Optional[str] = None self.futuretype = futuretype self.removed_from_queue = False self.to_be_removed = False self.oversized = False self.precheck = False self.incomplete = False self.unwanted_ext = 0 self.reuse = reuse if self.status == Status.QUEUED and not reuse: self.precheck = cfg.pre_check() if self.precheck: self.status = Status.CHECKING # Store one line responses for filejoin/par2/unrar here for history display self.action_line = "" # Store the results from various filejoin/par2/unrar stages self.unpack_info: Dict[str, List[str]] = {} # Stores one line containing the last failure self.fail_msg = "" # Stores various info about the nzo to be self.nzo_info: Dict[str, Any] = nzo_info or {} self.next_save = None self.save_timeout = None self.encrypted = 0 self.url_wait: Optional[float] = None self.url_tries = 0 self.pp_active = False self.md5sum: Optional[str] = None # Path is empty in case of a future NZB self.download_path = "" # This is a slot for a future NZB, ready now # It can also be a retry of a failed job with no extra NZB-file if nzb_fp is None and not reuse: # For future NZB, check if we don't already have this in the queue or history # based on the custom name supplied by the user or the RSS feed if self.custom_name and dup_check: self.duplicate_check() self.handle_duplicate_action() return # Re-use existing nzo_id, when a "future" job gets it payload if nzo_id: self.nzo_id = nzo_id sabnzbd.NzbQueue.remove(nzo_id, delete_all_data=False) # Apply conversion option to final folder if cfg.replace_spaces(): logging.info("Replacing spaces with underscores in %s", self.final_name) self.final_name = self.final_name.replace(" ", "_") if cfg.replace_underscores(): logging.info("Replacing underscores with dots in %s", self.final_name) self.final_name = self.final_name.replace("_", ".") if cfg.replace_dots(): logging.info("Replacing dots with spaces in %s", self.final_name) self.final_name = self.final_name.replace(".", " ") # Reuse the existing directory if reuse and os.path.exists(reuse): self.download_path = long_path(reuse) else: # Determine "incomplete" folder self.download_path = os.path.join(cfg.download_dir.get_path(), self.work_name) self.download_path = get_unique_dir(self.download_path, create_dir=True) if not self.download_path: raise NzbEmpty self.download_path = long_path(self.download_path) set_permissions(self.download_path) # Always create the admin-directory, just to be sure admin_dir = os.path.join(self.download_path, JOB_ADMIN) if not os.path.exists(admin_dir): create_all_dirs(admin_dir) _, self.work_name = os.path.split(self.download_path) # When doing a retry or repair, remove old cache-files if reuse: remove_all(admin_dir, "SABnzbd_nz?_*", keep_folder=True) remove_all(admin_dir, "SABnzbd_article_*", keep_folder=True) if nzb_fp: full_nzb_path = save_compressed(admin_dir, filename, nzb_fp) try: sabnzbd.nzbparser.nzbfile_parser(full_nzb_path, self) except Exception as err: self.incomplete = True logging.warning(T("Invalid NZB file %s, skipping (error: %s)"), filename, err) logging.info("Traceback: ", exc_info=True) # Some people want to keep the broken files if cfg.allow_incomplete_nzb(): self.pause() else: self.purge_data() raise NzbEmpty # Check against identical checksum or series/season/episode if not repair # Have to check for duplicate before saving the backup, as it will # trigger the duplicate-detection based on the backup if not reuse and dup_check and not self.duplicate and self.priority != REPAIR_PRIORITY: self.duplicate_check() # Copy to backup backup_nzb(full_nzb_path) if not self.files and not reuse: self.purge_data() if self.url: logging.warning(T("Empty NZB file %s") + " [%s]", filename, self.url) else: logging.warning(T("Empty NZB file %s"), filename) raise NzbEmpty if cat is None: for metacat in self.meta.get("category", ()): if metacat := cat_convert(metacat): cat = metacat break if cat is None: for grp in self.groups: if cat := cat_convert(grp): break # Pickup backed-up attributes when re-using if reuse: cat, pp, script = self.load_attribs() # Determine category and find pp/script values self.cat, pp_tmp, self.script, priority = cat_to_opts(cat, pp, script, self.priority) self.set_priority(priority) self.repair, self.unpack, self.delete = pp_to_opts(pp_tmp) # Show first meta-password (if any), when there's no explicit password if not self.password and self.meta.get("password"): self.password = self.meta.get("password", [None])[0] # Check if we expect propagation delay if (propagation_delay := self.avg_stamp + float(cfg.propagation_delay() * 60)) > time.time(): self.propagation_delay = propagation_delay # Run user pre-queue script if set and valid if not reuse and make_script_path(cfg.pre_script()): # Call the script accept, name, pq_pp, pq_cat, pq_script, pq_priority, pq_group = sabnzbd.newsunpack.pre_queue(self, pp, cat) if pq_cat: # An explicit pp/script/priority set upon adding the job takes precedence # over an implicit setting based on the category set by pre-queue if input_priority and not pq_priority: pq_priority = input_priority if input_pp and not pq_pp: pq_pp = input_pp if input_script and not pq_script: pq_script = input_script # Accept or reject accept = int_conv(accept) if accept < 1: self.purge_data() raise NzbRejected if accept == 2: raise NzbRejectToHistory(self, T("Pre-queue script marked job as failed")) # Process all options, only over-write if set by script # Beware that cannot do "if priority/pp", because those can # also have a valid value of 0, which shouldn't be ignored if name: self.set_final_name_and_scan_password(name) self.duplicate_check(repeat=True) try: pp = int(pq_pp) except: pp = None if pq_cat: cat = pq_cat try: priority = int(pq_priority) except: priority = DEFAULT_PRIORITY if pq_script and is_valid_script(pq_script): script = pq_script if pq_group: self.groups = [str(pq_group)] # Re-evaluate results from pre-queue script self.cat, pp, self.script, priority = cat_to_opts(cat, pp, script, priority) self.set_priority(priority) self.repair, self.unpack, self.delete = pp_to_opts(pp) # Pause if requested by the NZB-adding or the pre-queue script if self.priority == PAUSED_PRIORITY: self.pause() self.set_stateless_priority(self.cat) # Pause job when above size limit limit = cfg.size_limit.get_int() if not reuse and abs(limit) > 0.5 and self.bytes > limit: logging.info("Job too large, forcing low prio and paused (%s)", self.final_name) self.pause() self.oversized = True self.priority = LOW_PRIORITY # Take action on the duplicate status self.handle_duplicate_action() # Check if there is any unwanted extension in plain sight in the NZB itself if cfg.action_on_unwanted_extensions(): for nzf in self.files: if has_unwanted_extension(nzf.filename): logging.warning(T("Unwanted Extension in file %s (%s)"), nzf.filename, self.final_name) # Pause, or Abort: if cfg.action_on_unwanted_extensions() == 1: logging.debug("Unwanted extension ... pausing") self.unwanted_ext = 1 self.pause() if cfg.action_on_unwanted_extensions() == 2: logging.debug("Unwanted extension ... aborting") raise NzbRejectToHistory(self, T("Aborted, unwanted extension detected")) if reuse: self.check_existing_files(self.download_path) # Sort the files in the queue self.sort_nzfs() # Copy meta fields to nzo_info, if not already set for kw in self.meta: if not self.nzo_info.get(kw): self.nzo_info[kw] = self.meta[kw][0] logging.debug("NZB nzo-info = %s", self.nzo_info) # Set nzo save-delay to minimum 120 seconds self.save_timeout = max(120, min(6.0 * self.bytes / GIGI, 300.0)) def update_download_stats(self, bps, serverid, bytes_received): if bps: self.avg_bps_total += bps / 1024 self.avg_bps_freq += 1 if serverid in self.servercount: self.servercount[serverid] += bytes_received else: self.servercount[serverid] = bytes_received def add_nzf(self, nzf: NzbFile): """Bookkeeping when adding new files Only used during import, so not locked""" self.files.append(nzf) self.files_table[nzf.nzf_id] = nzf self.bytes += nzf.bytes # Only now add first article to the list self.first_articles.append(nzf.first_article) self.first_articles_count += 1 nzf.first_article = None # Count how many bytes are available for repair if sabnzbd.par2file.is_parfile(nzf.filename): self.bytes_par2 += nzf.bytes logging.info("File %s added to queue", nzf.filename) @synchronized(NZO_LOCK) def remove_nzf(self, nzf: NzbFile) -> bool: if nzf in self.files: self.files.remove(nzf) if nzf not in self.finished_files: self.finished_files.append(nzf) nzf.import_finished = True nzf.deleted = True return not bool(self.files) def sort_nzfs(self): """Sort the files in the NZO based on name and type and then optimize for unwanted extensions search. """ self.files.sort(key=functools.cmp_to_key(nzf_cmp_name)) # In the hunt for Unwanted Extensions: # The file with the unwanted extension often is in the first or the last rar file # So put the last rar immediately after the first rar file so that it gets detected early if cfg.unwanted_extensions(): # ... only useful if there are unwanted extensions defined and there is no sorting on date logging.debug("Unwanted Extension: putting last rar after first rar") firstrarpos = lastrarpos = 0 for nzfposcounter, nzf in enumerate(self.files): if RE_RAR.search(nzf.filename.lower()): # a NZF found with '.rar' in the name if firstrarpos == 0: # this is the first .rar found, so remember this position firstrarpos = nzfposcounter lastrarpos = nzfposcounter lastrarnzf = nzf # The NZF itself if firstrarpos != lastrarpos: # at least two different .rar's found logging.debug("Unwanted Extension: First rar at %s, Last rar at %s", firstrarpos, lastrarpos) logging.debug("Unwanted Extension: Last rar is %s", lastrarnzf.filename) try: # Remove and add it back after the position of the first rar self.files.remove(lastrarnzf) self.files.insert(firstrarpos + 1, lastrarnzf) except: logging.debug("The lastrar swap did not go well") def reset_all_try_lists(self): for nzf in self.files: nzf.reset_all_try_lists() self.reset_try_list() @synchronized(NZO_LOCK) def postpone_pars(self, parset: str): """Move all vol-par files matching 'parset' to the extrapars table""" # Create new extrapars if it didn't already exist # For example if created when the first par2 file was missing if parset not in self.extrapars: self.extrapars[parset] = [] lparset = parset.lower() for xnzf in self.files[:]: # Move only when not current NZF and filename was extractable from subject if xnzf.filename: setname, vol, block = sabnzbd.par2file.analyse_par2(xnzf.filename) # Don't postpone header-only-files, so we can extract all # possible md5of16k and par2packs's even if the filenames are bad # Usually they are all downloaded as first_articles if setname and block and matcher(lparset, setname.lower()): xnzf.set_par2(parset, vol, block) # Don't postpone if all par2 are desired and should be kept or not repairing if self.repair and not (cfg.enable_all_par() and not cfg.enable_par_cleanup()): self.extrapars[parset].append(xnzf) self.files.remove(xnzf) # Already count these bytes as done self.bytes_tried += xnzf.bytes_left # Sort the sets for setname in self.extrapars: self.extrapars[setname].sort(key=lambda x: x.blocks) # Also re-parse all filenames in case par2 came after first articles self.verify_all_filenames_and_resort() @synchronized(NZO_LOCK) def handle_par2(self, nzf: NzbFile, filepath): """Check if file is a par2 and build up par2 collection""" # Need to remove it from the other set it might be in self.remove_extrapar(nzf) # Reparse setname, vol, block = sabnzbd.par2file.analyse_par2(nzf.filename, filepath) nzf.set_par2(setname, vol, block) # Parse the file contents for hashes set_id, pack = sabnzbd.par2file.parse_par2_file(filepath, nzf.nzo.md5of16k) # If we couldn't parse it, we ignore it if set_id and pack: if pack not in self.par2packs.values(): logging.debug("Got par2pack for set %s", nzf.setname) # Verify that we are not over-writing existing set with the same name, but different values if setname in self.par2packs: logging.debug("Found duplicate par2pack-setname: %s, using set ID: %s", setname, set_id) setname = set_id self.par2packs[setname] = pack # See if we need to postpone some pars self.postpone_pars(setname) else: # Need to add this to the set, first need setname for setname in self.par2packs: if self.par2packs[setname] == pack: break # Change the properties nzf.set_par2(setname, vol, block) logging.debug("Got additional par2pack for set %s", nzf.setname) # Make sure it exists, could be removed by newsunpack if setname not in self.extrapars: self.extrapars[setname] = [] self.extrapars[setname].append(nzf) elif self.repair: # For some reason this par2 file is broken but we still want repair self.promote_par2(nzf) # Is it an obfuscated file? if get_ext(nzf.filename) != ".par2": # Do cheap renaming so it gets better picked up by par2 # Only basename has to be the same new_fname = get_unique_filename(os.path.join(self.download_path, "%s.par2" % setname)) renamer(filepath, new_fname) self.renamed_file(get_filename(new_fname), nzf.filename) nzf.filename = get_filename(new_fname) @synchronized(NZO_LOCK) def promote_par2(self, nzf: NzbFile): """In case of a broken par2 or missing par2, move another of the same set to the top (if we can find it) """ setname, vol, block = sabnzbd.par2file.analyse_par2(nzf.filename) # Now we need to identify if we have more in this set if setname and self.repair: # Maybe it was the first one if setname not in self.extrapars: self.postpone_pars(setname) # Get the next one for new_nzf in self.extrapars[setname]: if self.add_parfile(new_nzf): # Add it to the top self.files.remove(new_nzf) self.files.insert(0, new_nzf) break def get_extra_blocks(self, setname: str, needed_blocks: int) -> int: """We want par2-files of all sets that are similar to this one So that we also can handle multi-sets with duplicate filenames Returns number of added blocks in case they are available In case of duplicate files for the same set, we might add too little par2 on the first add-run, but that's a risk we need to take. """ logging.info("Need %s more blocks, checking blocks", needed_blocks) avail_blocks = 0 block_list = [] for setname_search in self.extrapars: # Do it for our set, or highlight matching one # We might catch too many par2's, but that's okay if setname_search == setname or difflib.SequenceMatcher(None, setname, setname_search).ratio() > 0.85: for nzf in self.extrapars[setname_search]: # Don't count extrapars that are completed already if nzf.completed or nzf in self.finished_files: continue block_list.append(nzf) avail_blocks += nzf.blocks # Sort the smallest blocks first block_list.sort(key=lambda x: x.blocks, reverse=False) logging.info("%s blocks available", avail_blocks) # Enough? if avail_blocks >= needed_blocks: added_blocks = 0 for new_nzf in block_list: if self.add_parfile(new_nzf): added_blocks += new_nzf.blocks if added_blocks >= needed_blocks: break else: # End of block_list reached with insufficient blocks added return 0 logging.info("Added %s blocks to %s", added_blocks, self.final_name) return added_blocks else: # Not enough return 0 @synchronized(NZO_LOCK) def remove_article(self, article: Article, success: bool): """Remove article from the NzbFile and do check if it can succeed""" job_can_succeed = True nzf = article.nzf # Update all statistics # Ignore bytes from par2 files that were postponed if nzf in self.files: self.bytes_tried += article.bytes if not success: # Increase missing bytes counter self.bytes_missing += article.bytes # Add extra parfiles when there was a damaged article and not pre-checking if self.extrapars and not self.precheck: self.prospective_add(nzf) # Sometimes a few CRC errors are still fine, abort otherwise if self.bad_articles > MAX_BAD_ARTICLES: self.abort_direct_unpacker() else: # Increase counter of actually finished bytes self.bytes_downloaded += article.bytes # First or regular article? if article.lowest_partnum and self.first_articles and article in self.first_articles: self.first_articles.remove(article) # All first articles done? if not self.first_articles: # Do we have rename information from par2 if self.md5of16k: self.verify_all_filenames_and_resort() # Check the availability of these first articles if cfg.fail_hopeless_jobs() and cfg.fast_fail(): job_can_succeed = self.check_first_article_availability() # Remove from file-tracking articles_left = nzf.remove_article(article, success) file_done = not articles_left # Only on fully loaded files we can know if it's really done if not nzf.import_finished: file_done = False # File completed, remove and do checks if file_done: self.remove_nzf(nzf) # Check if we can succeed when we have missing articles # Skip check if retry or first articles already deemed it hopeless if not success and job_can_succeed and not self.reuse and cfg.fail_hopeless_jobs(): job_can_succeed, _ = self.check_availability_ratio() # Abort the job due to failure if not job_can_succeed: self.fail_msg = T("Aborted, cannot be completed") + " - https://sabnzbd.org/not-complete" self.set_unpack_info("Download", self.fail_msg, unique=False) logging.debug('Abort job "%s", due to impossibility to complete it', self.final_name) return True, True, True # Check if there are any files left here, so the check is inside the NZO_LOCK return articles_left, file_done, not self.files def check_existing_files(self, wdir: str): """Check if downloaded files already exits, for these set NZF to complete""" fix_unix_encoding(wdir) # Get a list of already present files, ignore folders existing_files = globber(wdir, "*.*") # Substitute renamed files if renames := load_data(RENAMES_FILE, self.admin_path, remove=True): for name in renames: if name in existing_files or renames[name] in existing_files: if name in existing_files: existing_files.remove(name) existing_files.append(renames[name]) self.renames = renames # Looking for the longest name first, minimizes the chance on a mismatch existing_files.sort(key=len) # The NZFs should be tried shortest first, to improve the chance on a proper match nzfs = self.files[:] nzfs.sort(key=lambda x: len(x.filename)) # Flag files from NZB that already exist as finished for existing_filename in existing_files[:]: for nzf in nzfs: if existing_filename in nzf.filename: logging.info("Matched file %s to %s of %s", existing_filename, nzf.filename, self.final_name) nzf.filename = existing_filename nzf.bytes_left = 0 self.remove_nzf(nzf) nzfs.remove(nzf) existing_files.remove(existing_filename) # Set bytes correctly nzf.bytes_left = 0 self.bytes_tried += nzf.bytes self.bytes_downloaded += nzf.bytes break # Create an NZF for each remaining existing file try: for existing_filename in existing_files: # Create NZF's using basic information filepath = os.path.join(wdir, existing_filename) logging.info("Existing file %s added to %s", existing_filename, self.final_name) tup = os.stat(filepath) tm = datetime.datetime.fromtimestamp(tup.st_mtime) nzf = NzbFile(tm, existing_filename, [], tup.st_size, self) self.files.append(nzf) self.files_table[nzf.nzf_id] = nzf nzf.filename = existing_filename self.remove_nzf(nzf) # Set bytes correctly nzf.bytes_left = 0 self.bytes += nzf.bytes self.bytes_tried += nzf.bytes self.bytes_downloaded += nzf.bytes except: logging.error(T("Error importing %s"), self.final_name) logging.info("Traceback: ", exc_info=True) # Process all the par2 files in one go, because handle_par2 # otherwise updates the byte-counters incorrectly. for nzf in self.finished_files: filepath = os.path.join(wdir, nzf.filename) if sabnzbd.par2file.is_parfile(filepath): self.handle_par2(nzf, filepath) self.bytes_par2 += nzf.bytes @property def pp(self) -> Optional[int]: if self.repair is None: return None else: return opts_to_pp(self.repair, self.unpack, self.delete) @property def propagation_delay_left(self) -> int: """Returns number of propagation minutes remaining, if any. It could return seconds, but the numerical value is only used in the queue.""" if self.propagation_delay: if (time_left := self.propagation_delay - time.time()) > 0: return int(time_left / 60 + 0.5) # We can remove the value, to skip any further calculations self.propagation_delay = None return 0 def set_pp(self, value: int): self.repair, self.unpack, self.delete = pp_to_opts(value) logging.info("Set pp=%s for job %s", value, self.final_name) # Abort unpacking if not desired anymore if not self.unpack: self.abort_direct_unpacker() def set_priority(self, value: Optional[Union[int, str]]): """Check if this is a valid priority""" # When unknown (0 is a known one), set to DEFAULT if value == "" or value is None: self.priority = DEFAULT_PRIORITY return # Convert input value = int_conv(value) if value in ( REPAIR_PRIORITY, FORCE_PRIORITY, HIGH_PRIORITY, NORMAL_PRIORITY, LOW_PRIORITY, DEFAULT_PRIORITY, PAUSED_PRIORITY, STOP_PRIORITY, ): self.priority = value return # Invalid value, set to normal priority self.priority = NORMAL_PRIORITY def set_stateless_priority(self, category: str): """Find a priority that doesn't set a job state, starting from the given category, for jobs to fall back to after their priority was set to PAUSED or DUP. The fallback priority cannot be another state-setting priority or FORCE; the latter could override the job state immediately after it was set.""" cat_options = [category] if category != "*": cat_options.append("default") for cat in cat_options: prio = cat_to_opts(cat)[3] if prio not in (PAUSED_PRIORITY, FORCE_PRIORITY): self.priority = prio break else: self.priority = NORMAL_PRIORITY @property def labels(self): """Return (translated) labels of job""" labels = [] if self.duplicate in (DuplicateStatus.DUPLICATE, DuplicateStatus.SMART_DUPLICATE): labels.append(T("DUPLICATE")) if self.duplicate in ( DuplicateStatus.DUPLICATE_ALTERNATIVE, DuplicateStatus.SMART_DUPLICATE_ALTERNATIVE, ): labels.append(T("ALTERNATIVE")) if self.encrypted > 0: labels.append(T("ENCRYPTED")) if self.oversized: labels.append(T("TOO LARGE")) if self.incomplete: labels.append(T("INCOMPLETE")) if self.unwanted_ext: labels.append(T("UNWANTED")) # Waiting for URL fetching if isinstance(self.url_wait, float): dif = int(self.url_wait - time.time() + 0.5) if dif > 0: labels.append(T("WAIT %s sec") % dif) # Propagation delay label if self.propagation_delay_left and self.priority != FORCE_PRIORITY: labels.append(T("PROPAGATING %s min") % self.propagation_delay_left) # Queue indicator: propagation of post return labels @property def final_name_with_password(self): if self.password: return "%s / %s" % (self.final_name, self.password) else: return self.final_name def set_final_name_and_scan_password(self, name, password=None): if isinstance(name, str): if password is not None: self.password = password else: name, password = scan_password(name) if password is not None: self.password = password self.final_name = sanitize_foldername(name) self.save_to_disk() @property def direct_unpack_progress(self) -> Optional[str]: """Report status of current Direct Unpack, if one is active""" if self.direct_unpacker and self.direct_unpacker.active_instance: return self.direct_unpacker.get_formatted_stats() @property def pp_or_finished(self): """We don't want any more articles if we are post-processing or in the final state""" return self.pp_active or self.status in (Status.COMPLETED, Status.DELETED, Status.FAILED) def pause(self): self.status = Status.PAUSED # Prevent loss of paused state when terminated if self.nzo_id and not self.removed_from_queue: self.save_to_disk() def resume(self): self.status = Status.QUEUED if self.encrypted > 0: # If user resumes after encryption warning, no more auto-pauses self.encrypted = 2 # If user resumes after warning, reset duplicate/oversized/incomplete/unwanted indicators self.oversized = False self.incomplete = False if self.unwanted_ext: # If user resumes after "unwanted" warning, no more auto-pauses self.unwanted_ext = 2 if self.duplicate: self.duplicate = DuplicateStatus.DUPLICATE_IGNORED @synchronized(NZO_LOCK) def add_parfile(self, parfile: NzbFile) -> bool: """Add parfile to the files to be downloaded Resets trylist just to be sure Adjust download-size accordingly Returns False when the file couldn't be added """ if not parfile.completed and parfile not in self.files and parfile not in self.finished_files: parfile.reset_try_list() self.files.append(parfile) self.bytes_tried -= parfile.bytes_left return True return False @synchronized(NZO_LOCK) def remove_extrapar(self, parfile: NzbFile): """Remove par file from any/all sets""" for parset in list(self.extrapars): if parfile in self.extrapars[parset]: self.extrapars[parset].remove(parfile) # Remove empty sets, when we found (based on md5of16k pack) # that all par2 files actually belong to a different set if not self.extrapars[parset]: self.extrapars.pop(parset) @synchronized(NZO_LOCK) def prospective_add(self, nzf: NzbFile): """Add par2 files to compensate for missing articles""" # Get some blocks! if not nzf.is_par2: for parset in self.extrapars: # Due to strong obfuscation on article-level the parset could have a different name # than the files. Because of that we just add the required number of par2-blocks # from all the sets. This probably means we get too much par2, but it's worth it. blocks_new = 0 for new_nzf in self.extrapars[parset]: if self.add_parfile(new_nzf): blocks_new += new_nzf.blocks # Enough now? if blocks_new >= self.bad_articles: logging.info("Prospectively added %s repair blocks to %s", blocks_new, self.final_name) break # Reset NZO TryList self.reset_try_list() def add_to_direct_unpacker(self, nzf: NzbFile): """Start or add to DirectUnpacker""" if not self.direct_unpacker: sabnzbd.directunpacker.DirectUnpacker(self) self.direct_unpacker.add(nzf) def abort_direct_unpacker(self): """Abort any running DirectUnpackers""" # During nzo creation the property doesn't exist yet if hasattr(self, "direct_unpacker") and self.direct_unpacker: self.direct_unpacker.abort() def check_availability_ratio(self) -> Tuple[bool, float]: """Determine if we are still meeting the required ratio""" availability_ratio = req_ratio = cfg.req_completion_rate() # Rare case where the NZB only consists of par2 files if self.bytes > self.bytes_par2: # Calculate ratio based on byte-statistics availability_ratio = 100 * (self.bytes - self.bytes_missing) / (self.bytes - self.bytes_par2) logging.debug( "Availability ratio=%.2f, bad articles=%d, total bytes=%d, missing bytes=%d, par2 bytes=%d", availability_ratio, self.bad_articles, self.bytes, self.bytes_missing, self.bytes_par2, ) # When there is no or little par2, we allow a few bad articles # This way RAR-only jobs might still succeed if self.bad_articles <= MAX_BAD_ARTICLES: return True, req_ratio # Check based on availability ratio return availability_ratio >= req_ratio, availability_ratio def check_first_article_availability(self) -> bool: """Use the first articles to see if it's likely the job will succeed """ # Ignore this check on retry if not self.reuse: # Ignore undamaged or small downloads if self.bad_articles and self.first_articles_count >= 10: # We need a float-division, see if more than 80% is there if self.bad_articles / self.first_articles_count >= 0.8: return False return True @synchronized(NZO_LOCK) def set_download_report(self): """Format the stats for the history information""" # Pretty-format the per-server stats if self.servercount: # Sort the servers first servers = config.get_servers() server_names = sorted( servers, key=lambda svr: "%02d%s" % (servers[svr].priority(), servers[svr].displayname().lower()), ) msgs = [ "%s=%sB" % (servers[server_name].displayname(), to_units(self.servercount[server_name])) for server_name in server_names if server_name in self.servercount ] self.set_unpack_info("Servers", ", ".join(msgs), unique=True) # In case there were no bytes available at all of this download # we list the number of bytes we used while trying if not self.bytes_downloaded: self.bytes_downloaded = sum(self.servercount.values()) # Format information about the download itself download_msgs = [] if self.avg_bps_total and self.bytes_downloaded and self.avg_bps_freq: # Get the seconds it took to complete the download avg_bps = self.avg_bps_total / self.avg_bps_freq download_time = int_conv(self.bytes_downloaded / (avg_bps * 1024)) self.nzo_info["download_time"] = download_time # Format the total time the download took, in days, hours, and minutes, or seconds. complete_time = format_time_string(download_time) download_msgs.append( T("Downloaded in %s at an average of %sB/s") % (complete_time, to_units(avg_bps * 1024)) ) download_msgs.append(T("Age") + ": " + calc_age(self.avg_date, True)) bad = self.nzo_info.get("bad_articles", 0) miss = self.nzo_info.get("missing_articles", 0) dups = self.nzo_info.get("duplicate_articles", 0) if bad: download_msgs.append(T("%s articles were malformed") % bad) if miss: download_msgs.append(T("%s articles were missing") % miss) if dups: download_msgs.append(T("%s articles had non-matching duplicates") % dups) self.set_unpack_info("Download", "
".join(download_msgs), unique=True) # Add RSS source if rss_feed := self.nzo_info.get("RSS"): self.set_unpack_info("RSS", rss_feed, unique=True) self.set_unpack_info("Source", self.url or self.filename, unique=True) @synchronized(NZO_LOCK) def increase_bad_articles_counter(self, bad_article_type: str): """Record information about bad articles""" if bad_article_type not in self.nzo_info: self.nzo_info[bad_article_type] = 0 self.nzo_info[bad_article_type] += 1 self.bad_articles += 1 def get_articles(self, server: Server, servers: List[Server], fetch_limit: int) -> List[Article]: articles = [] nzf_remove_list = [] # Did we go through all first-articles? if self.first_articles: for article_test in self.first_articles: article = article_test.get_article(server, servers) if not article: break articles.append(article) if len(articles) >= fetch_limit: break # Move on to next ones if not articles: for nzf in self.files: if nzf.deleted: logging.debug("Skipping existing file %s", nzf.filename) else: # Don't try to get an article if server is in try_list of nzf if not nzf.server_in_try_list(server): if not nzf.import_finished: # Only load NZF when it's a primary server # or when it's a backup server without active primaries if sabnzbd.Downloader.highest_server(server): nzf.finish_import() # Still not finished? Something went wrong... if not nzf.import_finished and not self.removed_from_queue: logging.error(T("Error importing %s"), nzf) nzf_remove_list.append(nzf) nzf.nzo.status = Status.PAUSED continue else: break if articles := nzf.get_articles(server, servers, fetch_limit): break # Remove all files for which admin could not be read for nzf in nzf_remove_list: nzf.deleted = True self.files.remove(nzf) # If cleanup emptied the active files list, end this job if nzf_remove_list and not self.files: sabnzbd.NzbQueue.end_job(self) if not articles: # No articles for this server, block for next time self.add_to_try_list(server) return articles @synchronized(NZO_LOCK) def move_top_bulk(self, nzf_ids: List[str]): self.cleanup_nzf_ids(nzf_ids) if nzf_ids: target = list(range(len(nzf_ids))) while 1: self.move_up_bulk(nzf_ids, cleanup=False) pos_nzf_table = self.build_pos_nzf_table(nzf_ids) keys = list(pos_nzf_table) keys.sort() if target == keys: break @synchronized(NZO_LOCK) def move_bottom_bulk(self, nzf_ids): self.cleanup_nzf_ids(nzf_ids) if nzf_ids: target = list(range(len(self.files) - len(nzf_ids), len(self.files))) while 1: self.move_down_bulk(nzf_ids, cleanup=False) pos_nzf_table = self.build_pos_nzf_table(nzf_ids) keys = list(pos_nzf_table) keys.sort() if target == keys: break @synchronized(NZO_LOCK) def move_up_bulk(self, nzf_ids, cleanup=True): if cleanup: self.cleanup_nzf_ids(nzf_ids) if nzf_ids: pos_nzf_table = self.build_pos_nzf_table(nzf_ids) while pos_nzf_table: pos = min(pos_nzf_table) nzf = pos_nzf_table.pop(pos) if pos > 0: tmp_nzf = self.files[pos - 1] if tmp_nzf.nzf_id not in nzf_ids: self.files[pos - 1] = nzf self.files[pos] = tmp_nzf @synchronized(NZO_LOCK) def move_down_bulk(self, nzf_ids, cleanup=True): if cleanup: self.cleanup_nzf_ids(nzf_ids) if nzf_ids: pos_nzf_table = self.build_pos_nzf_table(nzf_ids) while pos_nzf_table: pos = max(pos_nzf_table) nzf = pos_nzf_table.pop(pos) if pos < len(self.files) - 1: tmp_nzf = self.files[pos + 1] if tmp_nzf.nzf_id not in nzf_ids: self.files[pos + 1] = nzf self.files[pos] = tmp_nzf def verify_nzf_filename(self, nzf: NzbFile, yenc_filename: Optional[str] = None): """Get filename from par2-info or from yenc""" # Already done? if nzf.filename_checked: return # If writing already started, we can't rename anymore if nzf.filepath: return # If we have the md5, use it to rename if nzf.md5of16k and self.md5of16k: # Don't check again, even if no match nzf.filename_checked = True # Find the match and rename if nzf.md5of16k in self.md5of16k: new_filename = self.md5of16k[nzf.md5of16k] # Was it even new? if new_filename != nzf.filename: logging.info("Detected filename based on par2: %s -> %s", nzf.filename, new_filename) self.renamed_file(new_filename, nzf.filename) nzf.filename = new_filename return # Fallback to yenc/nzb name (also when there is no partnum=1) # We also keep the NZB name in case it ends with ".par2" (usually correct) if ( yenc_filename and yenc_filename != nzf.filename and not is_probably_obfuscated(yenc_filename) and not nzf.filename.endswith(".par2") ): logging.info("Detected filename from yenc or uu: %s -> %s", nzf.filename, yenc_filename) self.renamed_file(yenc_filename, nzf.filename) nzf.filename = yenc_filename @synchronized(NZO_LOCK) def verify_all_filenames_and_resort(self): """Verify all filenames based on par2 info and then re-sort files. Locked so all files are verified at once without interruptions. """ logging.info("Checking all filenames for %s", self.final_name) for nzf_verify in self.files: self.verify_nzf_filename(nzf_verify) logging.info("Re-sorting %s after getting filename information", self.final_name) self.sort_nzfs() # Also trigger it again for Direct Unpack, if it's active if self.direct_unpacker: self.direct_unpacker.set_volumes_for_nzo() @synchronized(NZO_LOCK) def renamed_file(self, name_set, old_name=None): """Save renames at various stages (Download/PP) to be used on Retry. Accepts strings and dicts. """ if not old_name: # Add to dict self.renames.update(name_set) else: self.renames[name_set] = old_name @property def admin_path(self): """Return the full path for my job-admin folder""" return long_path(get_admin_path(self.work_name, self.futuretype)) @property def group(self): if self.groups: return self.groups[0] else: return None @property def remaining(self): """Return remaining bytes""" return self.bytes - self.bytes_tried @synchronized(NZO_LOCK) def purge_data(self, delete_all_data=True): """Remove (all) job data""" logging.info( "[%s] Purging data for job %s (delete_all_data=%s)", caller_name(), self.final_name, delete_all_data ) # Abort DirectUnpack and let it remove files self.abort_direct_unpacker() # Remove all cached files sabnzbd.ArticleCache.purge_articles(self.saved_articles) # Delete all, or just basic files if self.futuretype: # If duplicate is discarded during URL-fetches, no nzo_id is known yet if self.nzo_id: # Remove temporary file left from URL-fetches remove_data(self.nzo_id, self.admin_path) elif delete_all_data: remove_all(self.download_path, recursive=True) else: # We remove any saved articles and save the renames file remove_all(self.download_path, "SABnzbd_nz?_*", keep_folder=True) remove_all(self.download_path, "SABnzbd_article_*", keep_folder=True) save_data(self.renames, RENAMES_FILE, self.admin_path, silent=True) def get_nzf_by_id(self, nzf_id: str) -> NzbFile: if nzf_id in self.files_table: return self.files_table[nzf_id] @synchronized(NZO_LOCK) def set_unpack_info(self, key: str, msg: str, setname: Optional[str] = None, unique: bool = False): """Builds a dictionary containing the stage name (key) and a message If unique is present, it will only have a single line message """ # Make sure all messages are strings msg = str(msg) # Add name of the set if setname: msg = "[%s] %s" % (setname, msg) # Unique messages allow only one line per stage(key) if not unique: if key not in self.unpack_info: self.unpack_info[key] = [] self.unpack_info[key].append(msg) else: self.unpack_info[key] = [msg] def set_action_line(self, action: Optional[str] = None, msg: Optional[str] = None): if action and msg: self.action_line = "%s: %s" % (action, msg.strip()) else: self.action_line = "" # Make sure it's updated in the interface sabnzbd.misc.history_updated() @synchronized(NZO_LOCK) def save_to_disk(self): """Save job's admin to disk""" self.save_attribs() if self.nzo_id and not self.removed_from_queue: save_data(self, self.nzo_id, self.admin_path) def save_attribs(self): """Save specific attributes for Retry""" attribs = {} for attrib in NzoAttributeSaver: attribs[attrib] = getattr(self, attrib) logging.debug("Saving attributes %s for %s", attribs, self.final_name) save_data(attribs, ATTRIB_FILE, self.admin_path, silent=True) def load_attribs(self) -> Tuple[Optional[str], Optional[int], Optional[str]]: """Load saved attributes and return them to be parsed""" attribs = load_data(ATTRIB_FILE, self.admin_path, remove=False) logging.debug("Loaded attributes %s for %s", attribs, self.final_name) # If attributes file somehow does not exist if not attribs: return None, None, None # Only a subset we want to apply directly to the NZO for attrib in ("final_name", "priority", "url"): # Only set if it is present and has a value if attribs.get(attrib): setattr(self, attrib, attribs[attrib]) # Only set password if it wasn't already set if not self.password and attribs.get("password"): self.password = attribs["password"] # Rest is to be used directly in the NZO-init flow return attribs["cat"], attribs["pp"], attribs["script"] @synchronized(NZO_LOCK) def build_pos_nzf_table(self, nzf_ids: List[str]) -> Dict[int, NzbFile]: pos_nzf_table = {} for nzf_id in nzf_ids: if nzf_id in self.files_table: nzf = self.files_table[nzf_id] pos = self.files.index(nzf) pos_nzf_table[pos] = nzf return pos_nzf_table @synchronized(NZO_LOCK) def cleanup_nzf_ids(self, nzf_ids: List[str]): for nzf_id in nzf_ids[:]: if nzf_id in self.files_table: if self.files_table[nzf_id] not in self.files: nzf_ids.remove(nzf_id) else: nzf_ids.remove(nzf_id) def set_duplicate_key(self): """Shorthand to set the key once""" if not self.duplicate_key: show_analysis = sabnzbd.sorting.BasicAnalyzer(self.final_name) # We can only set a duplicate key for these types if show_analysis.type not in ("tv", "movie", "date"): return # The key always includes the title, for movies we don't add anything else duplicate_key_items = [show_analysis.info.get("title", "")] if show_analysis.type == "tv": # For TV-shows we add the season and episode duplicate_key_items.append(str(show_analysis.info.get("season_num", ""))) duplicate_key_items.append(str(show_analysis.info.get("episode_num", ""))) elif show_analysis.type == "date": # Add date duplicate_key_items.append(str(show_analysis.info.get("year", ""))) duplicate_key_items.append(str(show_analysis.info.get("month", ""))) duplicate_key_items.append(str(show_analysis.info.get("day", ""))) # We allow 1 proper result to bypass the detection, if desired if show_analysis.is_proper() and cfg.dupes_propercheck(): duplicate_key_items.append("proper") self.duplicate_key = "/".join(duplicate_key_items).lower() def duplicate_check(self, repeat: bool = False): """Set the correct duplicate status""" if not cfg.no_dupes() and not cfg.no_smart_dupes(): return # Reset status in case of a repeat analysis if repeat: self.duplicate = None self.duplicate_key = None duplicate_in_history = smart_duplicate_in_history = False duplicate_in_queue = smart_duplicate_in_queue = False with HistoryDB() as history_db: # Dupe check off just name or nzb contents if cfg.no_dupes(): logging.debug("Duplicate checking NZB %s (md5sum=%s)", self.final_name, self.md5sum) duplicate_in_history = history_db.have_name_or_md5sum(self.final_name, self.md5sum) logging.debug("Duplicate in history: %s", duplicate_in_history) duplicate_in_queue = sabnzbd.NzbQueue.have_name_or_md5sum(self.final_name, self.md5sum) logging.debug("Duplicate in queue: %s", duplicate_in_queue) # The nzb can already be in the backup while the job is still in the queue, so skip on repeat if not repeat and not duplicate_in_history and not duplicate_in_queue and cfg.backup_for_duplicates(): duplicate_in_history = backup_exists(self.filename) logging.debug("Duplicate in backup: %s", duplicate_in_history) # Dupe check off nzb filename if not duplicate_in_history and not duplicate_in_queue and cfg.no_smart_dupes(): self.set_duplicate_key() logging.debug("Smart duplicate checking (%s): %s", self.final_name, self.duplicate_key) if self.duplicate_key: smart_duplicate_in_history = history_db.have_duplicate_key(self.duplicate_key) logging.debug("Duplicate in history: %s", smart_duplicate_in_history) smart_duplicate_in_queue = sabnzbd.NzbQueue.have_duplicate_key(self.duplicate_key) logging.debug("Duplicate in queue: %s", smart_duplicate_in_queue) else: logging.debug("Unknown type, skipping smart duplicate check") # Set the correct status if smart_duplicate_in_queue: self.duplicate = DuplicateStatus.SMART_DUPLICATE_ALTERNATIVE elif duplicate_in_queue: self.duplicate = DuplicateStatus.DUPLICATE_ALTERNATIVE elif smart_duplicate_in_history: self.duplicate = DuplicateStatus.SMART_DUPLICATE elif duplicate_in_history: self.duplicate = DuplicateStatus.DUPLICATE def handle_duplicate_action(self): """Handle duplicate detection action""" # If the job is set Force in any way, ignore results of duplicate check if self.priority == FORCE_PRIORITY: self.duplicate = None # Take a direct action # 1 = Discard # 2 = Pause # 3 = Fail (move to History) # 4 = Tag if self.duplicate in (DuplicateStatus.DUPLICATE, DuplicateStatus.SMART_DUPLICATE): smart_duplicate = self.duplicate == DuplicateStatus.SMART_DUPLICATE if (not smart_duplicate and cfg.no_dupes() == 1) or (smart_duplicate and cfg.no_smart_dupes() == 1): # Discard duplicate_warning(T('Ignoring duplicate NZB "%s"'), self.final_name) self.purge_data() raise NzbRejected elif (not smart_duplicate and cfg.no_dupes() == 3) or (smart_duplicate and cfg.no_smart_dupes() == 3): # Fail (move to History) duplicate_warning(T('Failing duplicate NZB "%s"'), self.final_name) raise NzbRejectToHistory(self, T("Duplicate NZB")) elif (not smart_duplicate and cfg.no_dupes() == 2) or (smart_duplicate and cfg.no_smart_dupes() == 2): # Pause duplicate_warning(T('Pausing duplicate NZB "%s"'), self.final_name) self.pause() else: # Tag job duplicate_warning('%s: "%s"', T("Duplicate NZB"), self.final_name) # In case of alternative, just pause (unless only tagging is desired) if (self.duplicate == DuplicateStatus.DUPLICATE_ALTERNATIVE and cfg.no_dupes() != 4) or ( self.duplicate == DuplicateStatus.SMART_DUPLICATE_ALTERNATIVE and cfg.no_smart_dupes() != 4 ): logging.info("Pausing duplicate alternative %s", self.final_name) self.pause() def __getstate__(self): """Save to pickle file, selecting attributes""" dict_ = {} for item in NzbObjectSaver: dict_[item] = getattr(self, item) dict_["try_list"] = super().__getstate__() return dict_ def __setstate__(self, dict_): """Load from pickle file, selecting attributes""" for item in NzbObjectSaver: try: setattr(self, item, dict_[item]) except KeyError: # Handle new attributes setattr(self, item, None) super().__setstate__(dict_.get("try_list", [])) # Set non-transferable values self.pp_active = False self.avg_stamp = time.mktime(self.avg_date.timetuple()) self.url_wait = None self.url_tries = 0 self.to_be_removed = False self.direct_unpacker = None # Attributes added since 3.0.0 if self.bytes_par2 is None: self.bytes_par2 = 0 for nzf in self.files + self.finished_files: if sabnzbd.par2file.is_parfile(nzf.filename): self.bytes_par2 += nzf.bytes if self.download_path is None: self.download_path = long_path(os.path.join(cfg.download_dir.get_path(), self.work_name)) if self.par2packs is None: self.par2packs = {} if not isinstance(self.saved_articles, set): # Converted from list to set self.saved_articles = set(self.saved_articles) def __repr__(self): return "" % (self.filename, self.bytes, self.nzo_id) def nzf_cmp_name(nzf1: NzbFile, nzf2: NzbFile): # The comparison will sort .par2 files to the top of the queue followed by .rar files, # they will then be sorted by name. nzf1_name = nzf1.filename.lower() nzf2_name = nzf2.filename.lower() # Determine vol-pars is_par1 = ".vol" in nzf1_name and ".par2" in nzf1_name is_par2 = ".vol" in nzf2_name and ".par2" in nzf2_name # mini-par2 in front if not is_par1 and nzf1_name.endswith(".par2"): return -1 if not is_par2 and nzf2_name.endswith(".par2"): return 1 # vol-pars go to the back if is_par1 and not is_par2: return 1 if is_par2 and not is_par1: return -1 # Prioritize .rar files above any other type of file (other than vol-par) m1 = RE_RAR.search(nzf1_name) m2 = RE_RAR.search(nzf2_name) if m1 and not (is_par2 or m2): return -1 elif m2 and not (is_par1 or m1): return 1 # Force .rar to come before 'r00' if m1 and m1.group(1) == ".rar": nzf1_name = nzf1_name.replace(".rar", ".r//") if m2 and m2.group(1) == ".rar": nzf2_name = nzf2_name.replace(".rar", ".r//") return cmp(nzf1_name, nzf2_name) def create_work_name(name: str) -> str: """Remove ".nzb" and ".par(2)" and sanitize, skip URL's""" if name.find("://") < 0: # Invalid charters need to be removed before and after (see unit-tests) return sanitize_foldername(strip_extensions(sanitize_foldername(name))) else: return name.strip() def scan_password(name: str) -> Tuple[str, Optional[str]]: """Get password (if any) from the title""" if "http://" in name or "https://" in name: return name, None # Strip any unwanted usenet-related extensions name = strip_extensions(name) # Identify any braces braces = name[1:].find("{{") if braces < 0: braces = len(name) else: braces += 1 slash = name.find("/") # Look for name/password, but make sure that '/' comes before any {{ if 0 < slash < braces and "password=" not in name: # Is it maybe in 'name / password' notation? if slash == name.find(" / ") + 1 and name[: slash - 1].strip(". "): # Remove the extra space after name and before password return name[: slash - 1].strip(". "), name[slash + 2 :] if name[:slash].strip(". "): return name[:slash].strip(". "), name[slash + 1 :] # Look for "name password=password" pw = name.find("password=") if pw > 0 and name[:pw].strip(". "): return name[:pw].strip(". "), name[pw + 9 :] # Look for name{{password}} if braces < len(name): closing_braces = name.rfind("}}") if closing_braces > braces and name[:braces].strip(". "): return name[:braces].strip(". "), name[braces + 2 : closing_braces] # Look again for name/password if slash > 0 and name[:slash].strip(". "): return name[:slash].strip(". "), name[slash + 1 :] # No password found return name, None def name_extractor(subject: str) -> str: """Try to extract a file name from a subject line, return `subject` if in doubt""" # Filename nicely wrapped in quotes for name in re.findall(RE_SUBJECT_FILENAME_QUOTES, subject): if name := name.strip(' "'): return name # Found nothing? Try a basic filename-like search for name in re.findall(RE_SUBJECT_BASIC_FILENAME, subject): if name := name.strip(): return name # Return the subject return subject def matcher(pattern, txt): """Return True if `pattern` is sufficiently equal to `txt`""" if txt.endswith(pattern): txt = txt[: txt.rfind(pattern)].strip() return (not txt) or txt.endswith('"') else: return False ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1716993699.44822 SABnzbd-4.3.2/sabnzbd/happyeyeballs.py0000644000000000000000000001766414625637243017100 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.happyeyeballs - Python implementation of RFC 6555 / Happy Eyeballs: find the quickest IPv4/IPv6 connection """ # Python implementation of RFC 6555/8305 (Happy Eyeballs): find the quickest IPv4/IPv6 connection # See https://tools.ietf.org/html/rfc6555 # See https://tools.ietf.org/html/rfc8305 import socket import threading import time import logging import queue import functools from dataclasses import dataclass from typing import Tuple, Union, Optional from more_itertools import roundrobin import sabnzbd.cfg as cfg from sabnzbd.constants import DEF_TIMEOUT from sabnzbd.decorators import cache_maintainer # How long to delay between connection attempts? The RFC suggests 250ms, but this is # quite long and might give us a slow host that just happened to be on top of the list. # The absolute minium specified in RFC 8305 is 10ms, so we use that. CONNECTION_ATTEMPT_DELAY = 0.01 # While providers are afraid to add IPv6 to their standard hostnames # we map a number of well known hostnames to their IPv6 alternatives. # WARNING: Only add if the SSL-certificate allows both hostnames! IPV6_MAPPING = { "news.eweka.nl": "news6.eweka.nl", "news.xlned.com": "news6.xlned.com", "news.easynews.com": "news6.easynews.com", "news.tweaknews.nl": "news6.tweaknews.nl", "news.tweaknews.eu": "news6.tweaknews.eu", "news.astraweb.com": "news6.astraweb.com", "news.pureusenet.nl": "news6.pureusenet.nl", "news.sunnyusenet.com": "news6.sunnyusenet.com", "news.newshosting.com": "news6.newshosting.com", "news.usenetserver.com": "news6.usenetserver.com", "news.frugalusenet.com": "news-v6.frugalusenet.com", "eunews.frugalusenet.com": "eunews-v6.frugalusenet.com", } # For typing and convenience! @dataclass class AddrInfo: family: socket.AddressFamily type: socket.SocketKind proto: int canonname: str sockaddr: Union[Tuple[str, int], Tuple[str, int, int, int]] ipaddress: str = "" def __post_init__(self): # For easy access self.ipaddress = self.sockaddr[0] def family_type(family) -> str: """Human-readable socket type""" if family not in (socket.AF_INET, socket.AF_INET6, socket.AF_UNSPEC): raise ValueError("Invalid family") if family == socket.AF_INET: return "IPv4-only" elif family == socket.AF_INET6: return "IPv6-only" return "IPv4 or IPv6" # Called by each thread def do_socket_connect(result_queue: queue.Queue, addrinfo: AddrInfo, timeout: int): """Connect to the ip, and put the result into the queue""" try: start = time.time() s = socket.socket(addrinfo.family, addrinfo.type) s.settimeout(timeout) try: s.connect(addrinfo.sockaddr) result_queue.put(addrinfo) logging.debug( "Happy Eyeballs connected to %s (%s) in %dms", addrinfo.ipaddress, addrinfo.canonname, 1000 * (time.time() - start), ) except socket.error: logging.debug( "Happy Eyeballs failed to connect to %s (%s) in %dms", addrinfo.ipaddress, addrinfo.canonname, 1000 * (time.time() - start), ) finally: s.close() except: pass @cache_maintainer(clear_time=10) @functools.lru_cache(maxsize=None) def happyeyeballs(host: str, port: int, timeout: int = DEF_TIMEOUT, family=socket.AF_UNSPEC) -> Optional[AddrInfo]: """Return the fastest result of getaddrinfo() based on RFC 6555/8305 (Happy Eyeballs), including IPv6 addresses if desired. Returns None in case no addresses were returned by getaddrinfo or if no connection could be made to any of the addresses. If family is specified, only that family is tried""" try: # See if we can add a IPv6 alternative check_hosts = [host] if cfg.ipv6_staging() and host in IPV6_MAPPING: check_hosts.append(IPV6_MAPPING[host]) logging.info("Added alternative IPv6 address: %s", IPV6_MAPPING[host]) ipv4_addrinfo = [] ipv6_addrinfo = [] last_canonname = "" for check_host in check_hosts: try: for addrinfo in socket.getaddrinfo( check_host, port, family, socket.SOCK_STREAM, flags=socket.AI_CANONNAME ): # Convert to AddrInfo addrinfo = AddrInfo(*addrinfo) # The canonname is only reported once per alias if addrinfo.canonname: last_canonname = addrinfo.canonname elif last_canonname: addrinfo.canonname = last_canonname # Put it in the right list for further processing # But prevent adding duplicate items to the lists if addrinfo not in ipv6_addrinfo and addrinfo not in ipv4_addrinfo: if addrinfo.family == socket.AddressFamily.AF_INET6: ipv6_addrinfo.append(addrinfo) else: ipv4_addrinfo.append(addrinfo) except: # Did we fail on the first getaddrinfo already? # Otherwise, we failed on the IPv6 alternative address, and those failures can be ignored if not ipv4_addrinfo and not ipv6_addrinfo: raise logging.debug( "Available addresses for %s (port=%d, %s): %d IPv4 and %d IPv6", host, port, family_type(family), len(ipv4_addrinfo), len(ipv6_addrinfo), ) # To optimize success, the RFC states to alternate between trying the # IPv6 and IPv4 results, starting with IPv6 since it is the preferred method. result_queue: queue.Queue[AddrInfo] = queue.Queue() addr_tried = 0 result: Optional[AddrInfo] = None for addrinfo in roundrobin(ipv6_addrinfo, ipv4_addrinfo): threading.Thread(target=do_socket_connect, args=(result_queue, addrinfo, timeout), daemon=True).start() addr_tried += 1 try: result = result_queue.get(timeout=CONNECTION_ATTEMPT_DELAY) break except queue.Empty: # Start a thread for the next address in the list if the previous # connection attempt did not complete in time or if it wasn't a success continue # If we had no results, we might just need to give it more time if not result: try: # Reduce waiting time by time already spent result = result_queue.get(timeout=timeout - addr_tried * CONNECTION_ATTEMPT_DELAY) except queue.Empty: raise ConnectionError("No addresses could be resolved") logging.info( "Quickest IP address for %s (port=%d, %s): %s (%s)", host, port, family_type(family), result.ipaddress, result.canonname, ) return result except Exception as e: logging.debug("Failed Happy Eyeballs lookup: %s", e) return None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4483075 SABnzbd-4.3.2/sabnzbd/nzbparser.py0000644000000000000000000004246714625637243016243 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2008-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.nzbparser - Parse and import NZB files """ import os import bz2 import gzip import time import logging import hashlib import xml.etree.ElementTree import datetime import zipfile import tempfile import cherrypy._cpreqbody from typing import Optional, Dict, Any, Union, List, Tuple import sabnzbd from sabnzbd import nzbstuff from sabnzbd.encoding import utob, correct_cherrypy_encoding from sabnzbd.filesystem import ( get_filename, is_valid_script, get_ext, clip_path, remove_file, remove_data, ) from sabnzbd.misc import name_to_cat, cat_pp_script_sanitizer from sabnzbd.constants import DEFAULT_PRIORITY, VALID_ARCHIVES, AddNzbFileResult from sabnzbd.utils import rarfile def add_nzbfile( nzbfile: Union[str, cherrypy._cpreqbody.Part], pp: Optional[Union[int, str]] = None, script: Optional[str] = None, cat: Optional[str] = None, catdir: Optional[str] = None, priority: Optional[Union[int, str]] = DEFAULT_PRIORITY, nzbname: Optional[str] = None, nzo_info=None, url: Optional[str] = None, keep: Optional[bool] = None, reuse: Optional[str] = None, password: Optional[str] = None, nzo_id: Optional[str] = None, dup_check: bool = True, ): """Add file, either a single NZB-file or an archive. All other parameters are passed to the NZO-creation. """ # Base conversion of input cat, pp, script = cat_pp_script_sanitizer(cat, pp, script) if isinstance(nzbfile, str): # File coming from queue repair or local file-path path = nzbfile filename = os.path.basename(path) keep_default = True if not sabnzbd.WIN32: # If windows client sends file to Unix server backslashes may # be included, so convert these path = path.replace("\\", "/") logging.info("Attempting to add %s [%s]", filename, path) else: # File from file-upload object # CherryPy mangles unicode-filenames: https://github.com/cherrypy/cherrypy/issues/1766 filename = correct_cherrypy_encoding(nzbfile.filename) logging.info("Attempting to add %s", filename) keep_default = False try: # We have to create a copy, because we can't re-use the CherryPy temp-file # Just to be sure we add the extension to detect file type later on nzb_temp_file, path = tempfile.mkstemp(suffix=get_ext(filename)) os.write(nzb_temp_file, nzbfile.file.read()) os.close(nzb_temp_file) except OSError: logging.error(T("Cannot create temp file for %s"), filename) logging.info("Traceback: ", exc_info=True) return None finally: # Close the CherryPy reference nzbfile.file.close() # Externally defined if we should keep the file? if keep is None: keep = keep_default if get_ext(filename) in VALID_ARCHIVES: return process_nzb_archive_file( filename, path=path, pp=pp, script=script, cat=cat, catdir=catdir, priority=priority, nzbname=nzbname, keep=keep, reuse=reuse, nzo_info=nzo_info, url=url, password=password, nzo_id=nzo_id, dup_check=dup_check, ) else: return process_single_nzb( filename, path=path, pp=pp, script=script, cat=cat, catdir=catdir, priority=priority, nzbname=nzbname, keep=keep, reuse=reuse, nzo_info=nzo_info, url=url, password=password, nzo_id=nzo_id, dup_check=dup_check, ) def process_nzb_archive_file( filename: str, path: str, pp: Optional[int] = None, script: Optional[str] = None, cat: Optional[str] = None, catdir: Optional[str] = None, keep: bool = False, priority: Optional[Union[int, str]] = None, nzbname: Optional[str] = None, reuse: Optional[str] = None, nzo_info: Optional[Dict[str, Any]] = None, url: Optional[str] = None, password: Optional[str] = None, nzo_id: Optional[str] = None, dup_check: bool = True, ) -> Tuple[AddNzbFileResult, List[str]]: """Analyse archive and create job(s). Accepts archive files with ONLY nzb/nfo/folder files in it. """ nzo_ids = [] if catdir is None: catdir = cat filename, cat = name_to_cat(filename, catdir) try: if zipfile.is_zipfile(path): zf = zipfile.ZipFile(path) elif rarfile.is_rarfile(path): zf = rarfile.RarFile(path) elif sabnzbd.newsunpack.is_sevenfile(path): zf = sabnzbd.newsunpack.SevenZip(path) else: logging.info("File %s is not a supported archive!", filename) return AddNzbFileResult.ERROR, [] except: logging.info(T("Cannot read %s"), path, exc_info=True) return AddNzbFileResult.RETRY, [] status: AddNzbFileResult = AddNzbFileResult.NO_FILES_FOUND names = zf.namelist() nzbcount = 0 for name in names: name = name.lower() if name.endswith(".nzb"): status = AddNzbFileResult.OK nzbcount += 1 if status == AddNzbFileResult.OK: if nzbcount != 1: nzbname = None for name in names: if name.lower().endswith(".nzb"): try: datap = zf.open(name) except OSError: logging.error(T("Cannot read %s"), name, exc_info=True) zf.close() return AddNzbFileResult.ERROR, [] name = get_filename(name) if datap: nzo = None try: nzo = nzbstuff.NzbObject( name, pp=pp, script=script, nzb_fp=datap, cat=cat, url=url, priority=priority, password=password, nzbname=nzbname, nzo_info=nzo_info, reuse=reuse, nzo_id=nzo_id, dup_check=dup_check, ) except (sabnzbd.nzbstuff.NzbEmpty, sabnzbd.nzbstuff.NzbRejected): # Empty or fully rejected pass except sabnzbd.nzbstuff.NzbRejectToHistory as err: # Duplicate or unwanted extension directed to history sabnzbd.NzbQueue.fail_to_history(err.nzo) nzo_ids.append(err.nzo.nzo_id) except: # Something else is wrong, show error logging.error(T("Error while adding %s, removing"), name, exc_info=True) finally: datap.close() if nzo: # We can only use existing nzo_id once nzo_id = None nzo_ids.append(sabnzbd.NzbQueue.add(nzo)) # Close the pointer to the compressed file zf.close() try: if not keep: remove_file(path) except OSError: logging.error(T("Error removing %s"), clip_path(path)) logging.info("Traceback: ", exc_info=True) else: zf.close() # If all were rejected/empty/etc, update status if not nzo_ids: status = AddNzbFileResult.NO_FILES_FOUND return status, nzo_ids def process_single_nzb( filename: str, path: str, pp: Optional[int] = None, script: Optional[str] = None, cat: Optional[str] = None, catdir: Optional[str] = None, keep: bool = False, priority: Optional[Union[int, str]] = None, nzbname: Optional[str] = None, reuse: Optional[str] = None, nzo_info: Optional[Dict[str, Any]] = None, url: Optional[str] = None, password: Optional[str] = None, nzo_id: Optional[str] = None, dup_check: bool = True, ) -> Tuple[AddNzbFileResult, List[str]]: """Analyze file and create a job from it Supports NZB, NZB.BZ2, NZB.GZ and GZ.NZB-in-disguise """ if catdir is None: catdir = cat try: with open(path, "rb") as nzb_file: check_bytes = nzb_file.read(2) if check_bytes == b"\x1f\x8b": # gzip file or gzip in disguise filename = filename.replace(".nzb.gz", ".nzb") nzb_fp = gzip.GzipFile(path, "rb") elif check_bytes == b"BZ": # bz2 file or bz2 in disguise filename = filename.replace(".nzb.bz2", ".nzb") nzb_fp = bz2.BZ2File(path, "rb") else: nzb_fp = open(path, "rb") except OSError: logging.warning(T("Cannot read %s"), clip_path(path)) logging.info("Traceback: ", exc_info=True) return AddNzbFileResult.RETRY, [] if filename: filename, cat = name_to_cat(filename, catdir) # The name is used as the name of the folder, so sanitize it using folder specific sanitization if not nzbname: # Prevent embedded password from being damaged by sanitize and trimming nzbname = get_filename(filename) # Parse the data result: AddNzbFileResult = AddNzbFileResult.OK nzo = None nzo_ids = [] try: nzo = nzbstuff.NzbObject( filename, pp=pp, script=script, nzb_fp=nzb_fp, cat=cat, url=url, priority=priority, password=password, nzbname=nzbname, nzo_info=nzo_info, reuse=reuse, nzo_id=nzo_id, dup_check=dup_check, ) except sabnzbd.nzbstuff.NzbEmpty: # Malformed or might not be an NZB file result = AddNzbFileResult.NO_FILES_FOUND except sabnzbd.nzbstuff.NzbRejected: # Rejected as duplicate or by pre-queue script result = AddNzbFileResult.ERROR except sabnzbd.nzbstuff.NzbRejectToHistory as err: # Duplicate or unwanted extension directed to history sabnzbd.NzbQueue.fail_to_history(err.nzo) nzo_ids.append(err.nzo.nzo_id) except: # Something else is wrong, show error logging.error(T("Error while adding %s, removing"), filename, exc_info=True) result = AddNzbFileResult.ERROR finally: nzb_fp.close() if nzo: nzo_ids.append(sabnzbd.NzbQueue.add(nzo, quiet=bool(reuse))) try: if not keep and result in {AddNzbFileResult.ERROR, AddNzbFileResult.OK}: remove_file(path) except OSError: # Job was still added to the queue, so throw error but don't report failed add logging.error(T("Error removing %s"), clip_path(path)) logging.info("Traceback: ", exc_info=True) return result, nzo_ids def nzbfile_parser(full_nzb_path: str, nzo): # For type-hinting nzo: sabnzbd.nzbstuff.NzbObject # Hash for dupe-checking md5sum = hashlib.md5() # Average date avg_age_sum = 0 # In case of failing timestamps and failing files time_now = time.time() skipped_files = 0 valid_files = 0 # Use nzb.gz file from admin dir with gzip.open(full_nzb_path) as nzb_fh: for _, element in xml.etree.ElementTree.iterparse(nzb_fh): # For type-hinting element: xml.etree.ElementTree.Element # Ignore namespace _, has_namespace, postfix = element.tag.partition("}") if has_namespace: element.tag = postfix # Parse the header if element.tag.lower() == "head": for meta in element.iter("meta"): meta_type = meta.attrib.get("type") if meta_type and meta.text: # Meta tags can occur multiple times if meta_type not in nzo.meta: nzo.meta[meta_type] = [] nzo.meta[meta_type].append(meta.text) element.clear() logging.debug("NZB file meta-data = %s", nzo.meta) continue # Parse the files if element.tag.lower() == "file": # Get subject and date # Don't fail, if subject is missing file_name = "unknown" if element.attrib.get("subject"): file_name = element.attrib.get("subject") # Don't fail if no date present try: file_date = datetime.datetime.fromtimestamp(int(element.attrib.get("date"))) file_timestamp = int(element.attrib.get("date")) except: file_date = datetime.datetime.fromtimestamp(time_now) file_timestamp = time_now # Get group for group in element.iter("group"): if group.text not in nzo.groups: nzo.groups.append(group.text) # Get segments raw_article_db = {} file_bytes = 0 if len(element.find("segments")): for segment in element.find("segments").iter("segment"): try: article_id = segment.text segment_size = int(segment.attrib.get("bytes")) partnum = int(segment.attrib.get("number")) # Update hash md5sum.update(utob(article_id)) # Duplicate parts? if partnum in raw_article_db: if article_id != raw_article_db[partnum][0]: logging.info( "Duplicate part %s, but different ID-s (%s // %s)", partnum, raw_article_db[partnum][0], article_id, ) nzo.increase_bad_articles_counter("duplicate_articles") else: logging.info("Skipping duplicate article (%s)", article_id) elif segment_size <= 0 or segment_size >= 2**23: # Perform sanity check (not negative, 0 or larger than 8MB) on article size logging.info("Skipping article %s due to strange size (%s)", article_id, segment_size) nzo.increase_bad_articles_counter("bad_articles") else: raw_article_db[partnum] = (article_id, segment_size) file_bytes += segment_size except: # In case of missing attributes pass # Sort the articles by part number, compatible with Python 3.5 raw_article_db_sorted = [raw_article_db[partnum] for partnum in sorted(raw_article_db)] # Create NZF nzf = sabnzbd.nzbstuff.NzbFile(file_date, file_name, raw_article_db_sorted, file_bytes, nzo) # Check if we already have this exact NZF (see custom eq-checks) if nzf in nzo.files: logging.info("File %s occurred twice in NZB, skipping", nzf.filename) remove_data(nzf.nzf_id, nzo.admin_path) continue # Add valid NZF's if file_name and nzf.valid and nzf.nzf_id: nzo.add_nzf(nzf) valid_files += 1 avg_age_sum += file_timestamp else: logging.info("Error importing %s, skipping", file_name) if nzf.nzf_id: remove_data(nzf.nzf_id, nzo.admin_path) skipped_files += 1 element.clear() # Final bookkeeping nr_files = max(1, valid_files) nzo.avg_stamp = avg_age_sum / nr_files nzo.avg_date = datetime.datetime.fromtimestamp(avg_age_sum / nr_files) nzo.md5sum = md5sum.hexdigest() if skipped_files: logging.warning(T("Failed to import %s files from %s"), skipped_files, nzo.filename) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.448413 SABnzbd-4.3.2/sabnzbd/newsunpack.py0000644000000000000000000024763014625637243016412 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.newsunpack """ import os import sys import re import subprocess import logging import time import io import shutil import functools from typing import Tuple, List, BinaryIO, Optional, Dict, Any, Union, Set import sabnzbd from sabnzbd.encoding import correct_unknown_encoding, ubtou import sabnzbd.utils.rarfile as rarfile from sabnzbd.misc import ( format_time_string, find_on_path, int_conv, get_all_passwords, calc_age, cmp, run_command, build_and_run_command, format_time_left, is_none, ) from sabnzbd.filesystem import ( make_script_path, real_path, globber, globber_full, renamer, clip_path, long_path, remove_file, listdir_full, setname_from_path, get_ext, TS_RE, build_filelists, get_filename, SEVENMULTI_RE, is_size, get_basename, ) from sabnzbd.nzbstuff import NzbObject import sabnzbd.cfg as cfg from sabnzbd.constants import Status, JOB_ADMIN # Regex globals RAR_V3_RE = re.compile(r"\.(?Ppart\d*)$", re.I) RAR_EXTRACTFROM_RE = re.compile(r"^Extracting\sfrom\s(.+)") RAR_EXTRACTED_RE = re.compile(r"^(Extracting|Creating|...)\s+(.*?)\s+OK\s*$") SEVENZIP_PATH_RE = re.compile("^Path = (.+)") PAR2_TARGET_RE = re.compile(r'^(?:File|Target): "(.+)" -') PAR2_BLOCK_FOUND_RE = re.compile(r'File: "([^"]+)" - found \d+ of \d+ data blocks from "([^"]+)"') PAR2_IS_MATCH_FOR_RE = re.compile(r'File: "([^"]+)" - is a match for "([^"]+)"') PAR2_FILENAME_RE = re.compile(r'"([^"]+)"') # Constants SEVENZIP_ID = b"7z\xbc\xaf'\x1c" PAR2_COMMAND = None MULTIPAR_COMMAND = None RAR_COMMAND = None NICE_COMMAND = None SEVENZIP_COMMAND = None IONICE_COMMAND = None RAR_PROBLEM = False PAR2_TURBO = True RAR_VERSION = 0 SEVENZIP_VERSION = "" def find_programs(curdir: str): """Find external programs""" def check(path: str, program: str) -> Optional[str]: p = os.path.abspath(os.path.join(path, program)) if os.access(p, os.X_OK): return p else: return None if sabnzbd.MACOS: if sabnzbd.MACOSARM64: # M1 (ARM64) versions sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, "osx/par2/arm64/par2-turbo") sabnzbd.newsunpack.RAR_COMMAND = check(curdir, "osx/unrar/arm64/unrar") else: # Regular x64 versions sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, "osx/par2/par2-turbo") sabnzbd.newsunpack.RAR_COMMAND = check(curdir, "osx/unrar/unrar") # The 7zip binary is universal2 sabnzbd.newsunpack.SEVENZIP_COMMAND = check(curdir, "osx/7zip/7zz") if sabnzbd.WIN32: if sabnzbd.WIN64: # 64 bit versions sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, "win/par2/x64/par2.exe") sabnzbd.newsunpack.MULTIPAR_COMMAND = check(curdir, "win/multipar/par2j64.exe") sabnzbd.newsunpack.RAR_COMMAND = check(curdir, "win/unrar/x64/UnRAR.exe") else: # 32 bit versions sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, "win/par2/par2.exe") sabnzbd.newsunpack.MULTIPAR_COMMAND = check(curdir, "win/multipar/par2j.exe") sabnzbd.newsunpack.RAR_COMMAND = check(curdir, "win/unrar/UnRAR.exe") # We just use the 32 bit version sabnzbd.newsunpack.SEVENZIP_COMMAND = check(curdir, "win/7zip/7za.exe") else: if not sabnzbd.newsunpack.PAR2_COMMAND: sabnzbd.newsunpack.PAR2_COMMAND = find_on_path("par2") if not sabnzbd.newsunpack.RAR_COMMAND: sabnzbd.newsunpack.RAR_COMMAND = find_on_path( ( "unrar", "rar", "unrar3", "rar3", ) ) sabnzbd.newsunpack.NICE_COMMAND = find_on_path("nice") sabnzbd.newsunpack.IONICE_COMMAND = find_on_path("ionice") # p7zip is the old Linux port of 7-Zip, now unmaintained. # Therefore the official filenames are different for Linux: # # 7zz (7-Zip) - full version of 7-Zip that supports all formats. # 7zzs (7-Zip) - full version of 7-Zip that supports all formats (static linked). # # 7z (p7zip) - older linux port that requires 7z.so shared library, supports all formats via 7z.so. # 7za (p7zip) - older linux port that supports some main formats: # 7z, xz, lzma, zip, bzip2, gzip, tar, cab, ppmd and split. if not sabnzbd.newsunpack.SEVENZIP_COMMAND: sabnzbd.newsunpack.SEVENZIP_COMMAND = find_on_path( ( "7zz", "7zzs", "7za", "7z", ) ) if not (sabnzbd.WIN32 or sabnzbd.MACOS): # Run check on rar version version, original = unrar_check(sabnzbd.newsunpack.RAR_COMMAND) sabnzbd.newsunpack.RAR_PROBLEM = not original or version < sabnzbd.constants.REC_RAR_VERSION sabnzbd.newsunpack.RAR_VERSION = version # Run check on 7zip sabnzbd.newsunpack.SEVENZIP_VERSION = sevenzip_check(sabnzbd.newsunpack.SEVENZIP_COMMAND) # Run check on par2-multicore sabnzbd.newsunpack.PAR2_TURBO = par2_turbo_check(sabnzbd.newsunpack.PAR2_COMMAND) # Set the path for rarfile rarfile.UNRAR_TOOL = sabnzbd.newsunpack.RAR_COMMAND ENV_NZO_FIELDS = [ "bytes", "bytes_downloaded", "bytes_tried", "cat", "correct_password", "duplicate", "duplicate_key", "encrypted", "fail_msg", "filename", "final_name", "group", "nzo_id", "oversized", "password", "pp", "priority", "repair", "script", "status", "unpack", "unwanted_ext", "url", ] def external_processing( extern_proc: str, nzo: NzbObject, complete_dir: str, nicename: str, status: int ) -> Tuple[str, int]: """Run a user postproc script, return console output and exit value""" failure_url = nzo.nzo_info.get("failure", "") # Items can be bool or null, causing POpen to fail command = [ str(extern_proc), str(complete_dir), str(nzo.filename), str(nicename), "", str(nzo.cat), str(nzo.group), str(status), str(failure_url), ] # Add path to original NZB nzb_paths = globber_full(nzo.admin_path, "*.gz") # Fields not in the NZO directly extra_env_fields = { "failure_url": failure_url, "complete_dir": complete_dir, "pp_status": status, "download_time": nzo.nzo_info.get("download_time", ""), "avg_bps": int(nzo.avg_bps_total / nzo.avg_bps_freq) if nzo.avg_bps_freq else 0, "age": calc_age(nzo.avg_date), "orig_nzb_gz": clip_path(nzb_paths[0]) if nzb_paths else "", } # Make sure that if we run a Python script it's output is unbuffered, so we can show it to the user if extern_proc.endswith(".py"): extra_env_fields["pythonunbuffered"] = True try: p = build_and_run_command(command, env=create_env(nzo, extra_env_fields)) sabnzbd.PostProcessor.external_process = p # Follow the output, so we can abort it lines = [] while 1: line = p.stdout.readline() if not line: break line = line.strip() lines.append(line) # Show current line in history nzo.set_action_line(T("Running script"), line) except: logging.debug("Failed script %s, Traceback: ", extern_proc, exc_info=True) return "Cannot run script %s\r\n" % extern_proc, -1 output = "\n".join(lines) ret = p.wait() return output, ret def unpacker( nzo: NzbObject, workdir_complete: str, one_folder: bool, joinables: List[str] = [], rars: List[str] = [], sevens: List[str] = [], ts: List[str] = [], depth: int = 0, ) -> Tuple[Union[int, bool], List[str]]: """Do a recursive unpack from all archives in 'download_path' to 'workdir_complete'""" if depth > 2: # Prevent going to deep down the rabbit-hole nzo.set_unpack_info("Unpack", T("Unpack nesting too deep [%s]") % nzo.final_name) logging.info(T("Unpack nesting too deep [%s]"), nzo.final_name) return False, [] depth += 1 if depth == 1: # First time, ignore anything in workdir_complete xjoinables, xrars, xsevens, xts = build_filelists(nzo.download_path) else: xjoinables, xrars, xsevens, xts = build_filelists(nzo.download_path, workdir_complete, check_both=nzo.delete) force_rerun = False newfiles = [] error = None new_joins = new_ts = None if cfg.enable_filejoin(): new_joins = [jn for jn in xjoinables if jn not in joinables] if new_joins: logging.info("Filejoin starting on %s", nzo.download_path) error, newf = file_join(nzo, workdir_complete, new_joins) if newf: newfiles.extend(newf) logging.info("Filejoin finished on %s", nzo.download_path) if cfg.enable_unrar(): new_rars = [rar for rar in xrars if rar not in rars] if new_rars: logging.info("Unrar starting on %s", nzo.download_path) error, newf = rar_unpack(nzo, workdir_complete, one_folder, new_rars) if newf: newfiles.extend(newf) logging.info("Unrar finished on %s", nzo.download_path) if cfg.enable_7zip() and SEVENZIP_COMMAND: new_sevens = [seven for seven in xsevens if seven not in sevens] if new_sevens: logging.info("7za starting on %s", nzo.download_path) error, newf = unseven(nzo, workdir_complete, one_folder, new_sevens) if newf: newfiles.extend(newf) logging.info("7za finished on %s", nzo.download_path) if cfg.enable_tsjoin(): new_ts = [_ts for _ts in xts if _ts not in ts] if new_ts: logging.info("TS Joining starting on %s", nzo.download_path) error, newf = file_join(nzo, workdir_complete, new_ts) if newf: newfiles.extend(newf) logging.info("TS Joining finished on %s", nzo.download_path) # Refresh history and set output nzo.set_action_line() # Only re-run if something was unpacked and it was success rerun = error in (False, 0) # During a Retry we might miss files in the complete folder # that failed during recursive unpack in the first run if nzo.reuse and depth == 1 and any(build_filelists(workdir=None, workdir_complete=workdir_complete)): rerun = True # We can't recursive unpack on long paths on Windows # See: https://github.com/sabnzbd/sabnzbd/pull/771 if sabnzbd.WIN32 and len(workdir_complete) > 256: rerun = False # Double-check that we didn't miss any files in workdir # But only if dele=True, otherwise of course there will be files left if rerun and nzo.delete and depth == 1 and any(build_filelists(nzo.download_path)): force_rerun = True # Clear lists to force re-scan of files xjoinables, xrars, xsevens, xts = ([], [], [], []) if rerun and (cfg.enable_recursive() or new_ts or new_joins or force_rerun): z, y = unpacker(nzo, workdir_complete, one_folder, xjoinables, xrars, xsevens, xts, depth) if z: error = z if y: newfiles.extend(y) return error, newfiles ############################################################################## # Filejoin Functions ############################################################################## def match_ts(file: str) -> Tuple[str, int]: """Return True if file is a joinable TS file""" match = TS_RE.search(file) if not match: return "", 0 num = int(match.group(1)) try: setname = file[: match.start()] setname += ".ts" except: setname = "" return setname, num def clean_up_joinables(names: List[str]): """Remove joinable files and their .1 backups""" for name in names: if os.path.exists(name): try: remove_file(name) except: pass name1 = name + ".1" if os.path.exists(name1): try: remove_file(name1) except: pass def get_seq_number(name: str) -> int: """Return sequence number if name as an int""" head, tail = os.path.splitext(name) if tail == ".ts": _, num = match_ts(name) else: num = tail[1:] if num.isdigit(): return int(num) else: return 0 def file_join(nzo: NzbObject, workdir_complete: str, joinables: List[str]) -> Tuple[bool, List[str]]: """Join and joinable files in 'workdir' to 'workdir_complete' and when successful, delete originals """ newfiles = [] bufsize = 24 * 1024 * 1024 # Create matching sets from the list of files joinable_sets = {} joinable_set = None for joinable in joinables: head, tail = os.path.splitext(joinable) if tail == ".ts": head, _ = match_ts(joinable) if head not in joinable_sets: joinable_sets[head] = [] joinable_sets[head].append(joinable) logging.debug("joinable_sets: %s", joinable_sets) try: # Handle each set for joinable_set in joinable_sets: current = joinable_sets[joinable_set] joinable_sets[joinable_set].sort() # If par2 already did the work, just remove the files if os.path.exists(joinable_set): logging.debug("file_join(): Skipping %s, (probably) joined by par2", joinable_set) if nzo.delete: clean_up_joinables(current) # done, go to next set continue # Only join when there is more than one file size = len(current) if size < 2: continue # Prepare joined file filename = joinable_set if workdir_complete: filename = filename.replace(nzo.download_path, workdir_complete) logging.debug("file_join(): Assembling %s", filename) # Join the segments with open(filename, "ab") as joined_file: n = get_seq_number(current[0]) seq_error = n > 1 for joinable in current: if get_seq_number(joinable) != n: seq_error = True perc = (100.0 / size) * n logging.debug("Processing %s", joinable) nzo.set_action_line(T("Joining"), "%.0f%%" % perc) with open(joinable, "rb") as f: shutil.copyfileobj(f, joined_file, bufsize) if nzo.delete: remove_file(joinable) n += 1 # Remove any remaining .1 files clean_up_joinables(current) # Finish up newfiles.append(filename) setname = setname_from_path(joinable_set) if seq_error: msg = T("Incomplete sequence of joinable files") nzo.fail_msg = T("File join of %s failed") % setname nzo.set_unpack_info("Filejoin", T('[%s] Error "%s" while joining files') % (setname, msg)) logging.error(T('Error "%s" while running file_join on %s'), msg, nzo.final_name) return True, [] else: msg = T("[%s] Joined %s files") % (joinable_set, size) nzo.set_unpack_info("Filejoin", msg, setname) except: msg = sys.exc_info()[1] nzo.fail_msg = T("File join of %s failed") % msg nzo.set_unpack_info( "Filejoin", T('[%s] Error "%s" while joining files') % (setname_from_path(joinable_set), msg) ) logging.error(T('Error "%s" while running file_join on %s'), msg, nzo.final_name) return True, [] return False, newfiles ############################################################################## # (Un)Rar Functions ############################################################################## def rar_unpack(nzo: NzbObject, workdir_complete: str, one_folder: bool, rars: List[str]) -> Tuple[int, List[str]]: """Unpack multiple sets 'rars' of RAR files from 'download_path' to 'workdir_complete. When 'delete' is set, originals will be deleted. When 'one_folder' is set, all files will be in a single folder """ fail = 0 newfiles = extracted_files = [] rar_sets = {} for rar in rars: rar_set = setname_from_path(rar) if RAR_V3_RE.search(rar_set): # Remove the ".partXX" part rar_set = get_basename(rar_set) if rar_set not in rar_sets: rar_sets[rar_set] = [] rar_sets[rar_set].append(rar) logging.debug("Rar_sets: %s", rar_sets) for rar_set in rar_sets: # Run the RAR extractor rar_sets[rar_set].sort(key=functools.cmp_to_key(rar_sort)) rarpath = rar_sets[rar_set][0] if workdir_complete and rarpath.startswith(nzo.download_path): extraction_path = workdir_complete else: extraction_path = os.path.split(rarpath)[0] # Is the direct-unpacker still running? We wait for it if nzo.direct_unpacker: wait_count = 0 last_stats = nzo.direct_unpacker.get_formatted_stats() while nzo.direct_unpacker.is_alive(): logging.debug("DirectUnpacker still alive for %s: %s", nzo.final_name, last_stats) # Bump the file-lock in case it's stuck with nzo.direct_unpacker.next_file_lock: nzo.direct_unpacker.next_file_lock.notify() time.sleep(2) # Did something change? Might be stuck if last_stats == nzo.direct_unpacker.get_formatted_stats(): wait_count += 1 if wait_count > 60: # We abort after 2 minutes of no changes nzo.direct_unpacker.abort() else: wait_count = 0 last_stats = nzo.direct_unpacker.get_formatted_stats() # Did we already direct-unpack it? Not when recursive-unpacking if nzo.direct_unpacker and rar_set in nzo.direct_unpacker.success_sets: logging.info("Set %s completed by DirectUnpack", rar_set) fail = 0 success = True rars, newfiles = nzo.direct_unpacker.success_sets.pop(rar_set) else: logging.info("Extracting rarfile %s (belonging to %s) to %s", rarpath, rar_set, extraction_path) try: fail, newfiles, rars = rar_extract( rarpath, len(rar_sets[rar_set]), one_folder, nzo, rar_set, extraction_path ) success = not fail except: success = False fail = 1 msg = sys.exc_info()[1] nzo.fail_msg = T("Unpacking failed, %s") % msg setname = nzo.final_name nzo.set_unpack_info("Unpack", T('[%s] Error "%s" while unpacking RAR files') % (setname, msg)) logging.error(T('Error "%s" while running rar_unpack on %s'), msg, setname) logging.debug("Traceback: ", exc_info=True) if success: logging.debug("rar_unpack(): Rars: %s", rars) logging.debug("rar_unpack(): Newfiles: %s", newfiles) extracted_files.extend(newfiles) # Do not fail if this was a recursive unpack if fail and rarpath.startswith(workdir_complete): # Do not delete the files, leave it to user! logging.info("Ignoring failure to do recursive unpack of %s", rarpath) fail = 0 success = True newfiles = [] # Do not fail if this was maybe just some duplicate fileset # Multipar and par2tbb will detect and log them, par2cmdline will not if fail and rar_set.endswith((".1", ".2")): # Just in case, we leave the raw files logging.info("Ignoring failure of unpack for possible duplicate file %s", rarpath) fail = 0 success = True newfiles = [] # Delete the old files if we have to if success and nzo.delete and newfiles: for rar in rars: try: remove_file(rar) except OSError: if os.path.exists(rar): logging.warning(T("Deleting %s failed!"), rar) brokenrar = "%s.1" % rar if os.path.exists(brokenrar): logging.info("Deleting %s", brokenrar) try: remove_file(brokenrar) except OSError: if os.path.exists(brokenrar): logging.warning(T("Deleting %s failed!"), brokenrar) return fail, extracted_files def rar_extract( rarfile_path: str, numrars: int, one_folder: bool, nzo: NzbObject, setname: str, extraction_path: str ) -> Tuple[int, List[str], List[str]]: """Unpack single rar set 'rarfile' to 'extraction_path', with password tries Return fail==0(ok)/fail==1(error)/fail==2(wrong password)/fail==3(crc-error), new_files, rars """ fail = 0 new_files = [] rars = [] passwords = get_all_passwords(nzo) for password in passwords: if password: logging.debug('Trying unrar with password "%s"', password) msg = T('Trying unrar with password "%s"') % password nzo.set_unpack_info("Unpack", msg, setname) fail, new_files, rars = rar_extract_core( rarfile_path, numrars, one_folder, nzo, setname, extraction_path, password ) if fail != 2: break return fail, new_files, rars def rar_extract_core( rarfile_path: str, numrars: int, one_folder: bool, nzo: NzbObject, setname: str, extraction_path: str, password: str ) -> Tuple[int, List[str], List[str]]: """Unpack single rar set 'rarfile_path' to 'extraction_path' Return fail==0(ok)/fail==1(error)/fail==2(wrong password)/fail==3(crc-error), new_files, rars """ start = time.time() logging.debug("rar_extract(): Extractionpath: %s", extraction_path) if password: password_command = "-p%s" % password else: password_command = "-p-" ############################################################################ if one_folder or cfg.flat_unpack(): action = "e" else: action = "x" if cfg.overwrite_files(): overwrite = "-o+" # Enable overwrite rename = "-o+" # Dummy else: overwrite = "-o-" # Disable overwrite rename = "-or" # Auto renaming if sabnzbd.WIN32: # On Windows, UnRar uses a custom argument parser # See: https://github.com/sabnzbd/sabnzbd/issues/1043 # The -scf forces the output to be UTF8 command = [ RAR_COMMAND, action, "-idp", "-scf", overwrite, rename, "-ai", password_command, rarfile_path, "%s\\" % long_path(extraction_path), ] elif RAR_PROBLEM: # Use only oldest options, specifically no "-or" or "-scf" command = [ RAR_COMMAND, action, "-idp", overwrite, password_command, rarfile_path, "%s/" % extraction_path, ] else: # The -scf forces the output to be UTF8 command = [ RAR_COMMAND, action, "-idp", "-scf", overwrite, rename, "-ai", password_command, rarfile_path, "%s/" % extraction_path, ] if cfg.ignore_unrar_dates(): command.insert(3, "-tsm-") # Get list of all the volumes part of this set logging.debug("Analyzing rar file ... %s found", rarfile.is_rarfile(rarfile_path)) p = build_and_run_command(command, windows_unrar_command=True) sabnzbd.PostProcessor.external_process = p nzo.set_action_line(T("Unpacking"), "00/%02d" % numrars) # Loop over the output from rar! curr = 0 extracted = [] rarfiles = [] fail = 0 inrecovery = False lines = [] while 1: line = p.stdout.readline() if not line: break # Skip empty lines line = line.strip() if not line: continue lines.append(line) if line.startswith("Extracting from"): filename = re.search(RAR_EXTRACTFROM_RE, line).group(1) if filename not in rarfiles: rarfiles.append(filename) curr += 1 perc = (curr / numrars) * 100 nzo.set_action_line(T("Unpacking"), "%02d/%02d %s" % (curr, numrars, add_time_left(perc, start))) elif line.find("recovery volumes found") > -1: inrecovery = True # and thus start ignoring "Cannot find volume" for a while logging.debug("unrar recovery start: %s" % line) elif line.startswith("Reconstruct"): # end of reconstruction: 'Reconstructing... 100%' or 'Reconstructing... ' (both success), or 'Reconstruction impossible' inrecovery = False logging.debug("unrar recovery result: %s" % line) elif line.startswith("Cannot find volume") and not inrecovery: filename = os.path.basename(line[19:]) msg = T("Unpacking failed, unable to find %s") % filename nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 1 elif line.endswith("- CRC failed"): msg = T("Unpacking failed, CRC error") nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 2 # Older unrar versions report a wrong password as a CRC error elif line.startswith("File too large"): msg = T("Unpacking failed, file too large for filesystem (FAT?)") nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 1 elif line.startswith("Write error"): msg = "%s %s" % (T("Unpacking failed, write error or disk is full?"), line[11:]) nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 1 elif line.startswith("Cannot create"): line2 = p.stdout.readline() if "must not exceed 260" in line2: msg = "%s: %s" % (T("Unpacking failed, path is too long"), line[13:]) else: msg = "%s %s" % (T("Unpacking failed, write error or disk is full?"), line[13:]) nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 1 # Kill the process (can stay in endless loop on Windows Server) p.kill() elif line.startswith("ERROR: "): nzo.fail_msg = line nzo.set_unpack_info("Unpack", line, setname) fail = 1 elif ( "The specified password is incorrect" in line or "Incorrect password" in line or ("ncrypted file" in line and (("CRC failed" in line) or ("Checksum error" in line))) ): # unrar 3.x: "Encrypted file: CRC failed in oLKQfrcNVivzdzSG22a2xo7t001.part1.rar (password incorrect ?)" # unrar 4.x: "CRC failed in the encrypted file oLKQfrcNVivzdzSG22a2xo7t001.part1.rar. Corrupt file or wrong password." # unrar 5.x: "Checksum error in the encrypted file oLKQfrcNVivzdzSG22a2xo7t001.part1.rar. Corrupt file or wrong password." # unrar 5.01: "The specified password is incorrect." # unrar 5.80: "Incorrect password for oLKQfrcNVivzdzSG22a2xo7t001.part1.rar" msg = T("Unpacking failed, archive requires a password") nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 2 elif "is not RAR archive" in line: # Unrecognizable RAR file msg = T("Unusable RAR file") nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 3 elif "checksum error" in line or "Unexpected end of archive" in line: # Corrupt archive or passworded, we can't know # packed data checksum error in volume FILE msg = T("Corrupt RAR file") nzo.fail_msg = msg nzo.set_unpack_info("Unpack", msg, setname) fail = 3 elif m := re.search(RAR_EXTRACTED_RE, line): # In case of flat-unpack, UnRar still prints the whole path (?!) unpacked_file = m.group(2) if cfg.flat_unpack(): unpacked_file = os.path.basename(unpacked_file) extracted.append(real_path(extraction_path, unpacked_file)) if fail: if p.stdout: p.stdout.close() p.wait() logging.debug("UNRAR output: \n%s", "\n".join(lines)) return fail, [], [] if p.stdout: p.stdout.close() p.wait() # Which files did we use to extract this? rarfiles = rar_volumelist(rarfile_path, password, rarfiles) logging.debug("UNRAR output: \n%s", "\n".join(lines)) msg = T("Unpacked %s files/folders in %s") % (len(extracted), format_time_string(time.time() - start)) nzo.set_unpack_info("Unpack", msg, setname) logging.info(msg) return 0, extracted, rarfiles ############################################################################## # 7Zip Functions ############################################################################## def unseven(nzo: NzbObject, workdir_complete: str, one_folder: bool, sevens: List[str]): """Unpack multiple sets '7z' of 7Zip files from 'download_path' to 'workdir_complete. When 'delete' is set, originals will be deleted. """ unseven_failed = False new_files = [] # Find multi-volume sets, because 7zip will not provide actual set members seven_sets = {} for seven in sevens: setname = setname_from_path(seven) if SEVENMULTI_RE.search(setname): # Remove the ".001" part setname = get_basename(setname) if setname not in seven_sets: seven_sets[setname] = [] seven_sets[setname].append(seven) # Unpack each set for seven_set in seven_sets: logging.info("Starting extract on 7zip set/file: %s ", seven_set) nzo.set_action_line(T("Unpacking"), setname_from_path(seven_set)) # Sort, so that x.001 is the first one seven_sets[seven_set].sort() seven_path = seven_sets[seven_set][0] if workdir_complete and seven_path.startswith(nzo.download_path): extraction_path = workdir_complete else: extraction_path = os.path.split(seven_path)[0] res, new_files_set = seven_extract(nzo, seven_path, seven_set, extraction_path, one_folder) if res: unseven_failed = True elif nzo.delete: for seven in seven_sets[seven_set]: try: remove_file(seven) except: logging.warning(T("Deleting %s failed!"), seven) new_files.extend(new_files_set) return unseven_failed, new_files def seven_extract( nzo: NzbObject, seven_path: str, seven_set: str, extraction_path: str, one_folder: bool ) -> Tuple[int, List[str]]: """Unpack single set 'sevenset' to 'extraction_path', with password tries Return fail==0(ok)/fail==1(error)/fail==2(wrong password), new_files, sevens """ fail = 0 new_files = [] passwords = get_all_passwords(nzo) for password in passwords: if password: msg = T('Trying 7zip with password "%s"') % password logging.debug(msg) nzo.set_unpack_info("Unpack", msg, seven_set) fail, new_files = seven_extract_core(nzo, seven_path, extraction_path, seven_set, one_folder, password) if fail != 2: # anything else than a password problem (so: OK, or disk problem): break return fail, new_files def seven_extract_core( nzo: NzbObject, seven_path: str, extraction_path: str, seven_set: str, one_folder: bool, password: str ) -> Tuple[int, List[str]]: """Unpack single 7Z set 'sevenset' to 'extraction_path' Return fail==0(ok)/fail==1(error)/fail==2(wrong password), new_files, message """ start = time.time() if one_folder or cfg.flat_unpack(): method = "e" # Unpack without folders else: method = "x" # Unpack with folders if sabnzbd.WIN32 or sabnzbd.MACOS: case = "-ssc-" # Case insensitive else: case = "-ssc" # Case sensitive if cfg.overwrite_files(): overwrite = "-aoa" else: overwrite = "-aou" if password: password = "-p%s" % password else: password = "-p" # For file-bookkeeping orig_dir_content = listdir_full(extraction_path) command = [SEVENZIP_COMMAND, method, "-y", overwrite, case, password, "-o%s" % extraction_path, seven_path] p = build_and_run_command(command) sabnzbd.PostProcessor.external_process = p output = p.stdout.read() logging.debug("7za output: %s", output) # ret contains the 7z/7za exit code: 0 = Normal, 1 = Warning, 2 = Fatal error, etc ret = p.wait() # What's new? Use symmetric difference new_files = list(set(orig_dir_content) ^ set(listdir_full(extraction_path))) # Anything else than 0 as RC: 7z unpack had a problem if ret > 0: # Let's try to find the cause: if "Data Error in encrypted file. Wrong password?" in output: msg = T("Unpacking failed, archive requires a password") elif "Disk full." in output or "No space left on device" in output: # note: the above does not work with 7z version 16.02, and does work with 7z 19.00 and higher ret = 1 msg = T("Unpacking failed, write error or disk is full?") elif "ERROR: CRC Failed" in output: ret = 1 msg = T("Unpacking failed, CRC error") else: # Default message msg = T("Unpacking failed, %s") % T("see logfile") logging.info("7za return code: %s", ret) nzo.fail_msg = msg nzo.status = Status.FAILED else: msg = T("Unpacked %s files/folders in %s") % (len(new_files), format_time_string(time.time() - start)) nzo.set_unpack_info("Unpack", msg, seven_set) logging.info(msg) return ret, new_files ############################################################################## # PAR2 Functions ############################################################################## def par2_repair(nzo: NzbObject, setname: str) -> Tuple[bool, bool]: """Try to repair a set, return readd and correctness""" # Check which of the files exists for new_par in nzo.extrapars[setname]: test_parfile = os.path.join(nzo.download_path, new_par.filename) if os.path.exists(test_parfile): parfile_nzf = new_par break else: # No file was found, we assume this set already finished logging.info("No par2 files found on disk for set %s", setname) return False, True parfile = os.path.join(nzo.download_path, parfile_nzf.filename) old_dir_content = os.listdir(nzo.download_path) used_joinables = () joinables = () used_for_repair = () result = readd = False # Need to copy now, gets pop-ed during repair setpars = nzo.extrapars[setname][:] # Start QuickCheck nzo.status = Status.QUICK_CHECK nzo.set_action_line(T("Repair"), T("Quick Checking")) qc_result = quick_check_set(setname, nzo) if qc_result: logging.info("Quick-check for %s is OK, skipping repair", setname) nzo.set_unpack_info("Repair", T("[%s] Quick Check OK") % setname) result = True if not result and cfg.enable_all_par(): # Download all par2 files that haven't been downloaded yet readd = False for extrapar in nzo.extrapars[setname][:]: # Make sure we only get new par2 files if nzo.add_parfile(extrapar): readd = True if readd: return readd, result if not result: nzo.status = Status.REPAIRING result = False readd = False try: nzo.set_action_line(T("Repair"), T("Starting Repair")) logging.info('Scanning "%s"', parfile) joinables, _, _, _ = build_filelists(nzo.download_path, check_rar=False) # Multipar on Windows, par2cmdline on the other platforms if cfg.enable_multipar() and sabnzbd.WIN32: finished, readd, used_joinables, used_for_repair = multipar_verify(parfile, nzo, setname, joinables) else: finished, readd, used_joinables, used_for_repair = par2cmdline_verify(parfile, nzo, setname, joinables) if finished: result = True logging.info("Par verify finished ok on %s!", parfile) else: logging.info("Par verify failed on %s!", parfile) return readd, False except: msg = sys.exc_info()[1] nzo.fail_msg = T("Repairing failed, %s") % msg logging.error(T("Error %s while running par2_repair on set %s"), msg, setname) logging.info("Traceback: ", exc_info=True) return readd, result try: if cfg.enable_par_cleanup(): deletables = [] new_dir_content = os.listdir(nzo.download_path) # If Multipar or par2cmdline repairs a broken part of a joinable, it doesn't list it as such. # So we need to manually add all joinables of the set to the list of used joinables. # We assume at least 1 of them was not broken, so we can use it as a base to find the rest. if used_joinables: for used_jn in used_joinables[:]: for jn in joinables: if get_filename(jn).startswith(setname_from_path(used_jn)) and jn not in used_joinables: used_joinables.append(jn) # Remove extra files created during repair and par2 base files for path in new_dir_content: if get_ext(path) == ".1" and path not in old_dir_content: deletables.append(os.path.join(nzo.download_path, path)) deletables.append(os.path.join(nzo.download_path, setname + ".par2")) deletables.append(os.path.join(nzo.download_path, setname + ".PAR2")) deletables.append(parfile) # Add output of par2-repair to remove deletables.extend(used_joinables) deletables.extend([os.path.join(nzo.download_path, f) for f in used_for_repair]) # Delete pars of the set deletables.extend([os.path.join(nzo.download_path, nzf.filename) for nzf in setpars]) for filepath in deletables: if filepath in joinables: joinables.remove(filepath) if os.path.exists(filepath): try: remove_file(filepath) except OSError: logging.warning(T("Deleting %s failed!"), filepath) except: msg = sys.exc_info()[1] nzo.fail_msg = T("Repairing failed, %s") % msg logging.error(T('Error "%s" while running par2_repair on set %s'), msg, setname, exc_info=True) return readd, result def par2cmdline_verify( parfile: str, nzo: NzbObject, setname: str, joinables: List[str] ) -> Tuple[bool, bool, List[str], List[str]]: """Run par2 on par-set""" used_joinables = [] used_for_repair = [] # set the current nzo status to "Verifying...". Used in History nzo.status = Status.VERIFYING start = time.time() # Long-path notation isn't supported by par2cmdline if sabnzbd.WIN32: parfile = clip_path(parfile) # Build command and add extra options command = [str(PAR2_COMMAND), "r", parfile] if options := cfg.par_option().strip().split(): for option in options: command.insert(2, option) # Append the wildcard for this set parfolder = os.path.split(parfile)[0] if len(nzo.extrapars) == 1 or len(globber(parfolder, setname + "*")) < 2: # Support bizarre naming conventions wildcard = "*" else: # Normal case, everything is named after set wildcard = setname + "*" if sabnzbd.MACOS or sabnzbd.WIN32: command.append(os.path.join(parfolder, wildcard)) else: # For Unix systems, remove folders, due to bug in some par2cmdline versions flist = [item for item in globber_full(parfolder, wildcard) if os.path.isfile(item)] command.extend(flist) # We need to check for the bad par2cmdline that skips blocks # Or the one that complains about basepath par2text = run_command([command[0], "-h"]) if "No data skipping" in par2text: logging.info("Detected par2cmdline version that skips blocks, adding -N parameter") command.insert(2, "-N") if "Set the basepath" in par2text: logging.info("Detected par2cmdline version that needs basepath, adding -B parameter") command.insert(2, "-B") command.insert(3, parfolder) # Run the external command p = build_and_run_command(command) sabnzbd.PostProcessor.external_process = p # Set up our variables lines = [] renames = {} reconstructed = [] finished = False readd = False verifynum = 0 verifytotal = 0 verified = 0 perc = 0 in_verify = False in_extra_files = False in_verify_repaired = False # Loop over the output, whee while 1: line = p.stdout.readline() if not line: break # Skip empty lines line = line.strip() if not line: continue if not line.startswith(("Repairing:", "Scanning:", "Loading:", "Solving:", "Constructing:")): lines.append(line) if line.startswith(("Invalid option specified", "Invalid thread option", "Cannot specify recovery file count")): msg = T("[%s] PAR2 received incorrect options, check your Config->Switches settings") % setname nzo.set_unpack_info("Repair", msg) nzo.status = Status.FAILED logging.error(msg) elif line.startswith("All files are correct"): msg = T("[%s] Verified in %s, all files correct") % (setname, format_time_string(time.time() - start)) nzo.set_unpack_info("Repair", msg) logging.info("Verified in %s, all files correct", format_time_string(time.time() - start)) finished = True elif line.startswith("Repair is required"): msg = T("[%s] Verified in %s, repair is required") % (setname, format_time_string(time.time() - start)) nzo.set_unpack_info("Repair", msg) logging.info("Verified in %s, repair is required", format_time_string(time.time() - start)) start = time.time() verified = 1 # Reset to use them again for verification of repair verifytotal = 0 verifynum = 0 elif line.startswith("Main packet not found") or "The recovery file does not exist" in line: # Initialparfile probably didn't decode properly or bad user parameters # We will try to get another par2 file, but 99% of time it's user parameters msg = T("Invalid par2 files or invalid PAR2 parameters, cannot verify or repair") logging.info(msg) logging.info("Extra pars = %s", nzo.extrapars[setname]) # Look for the smallest par2file block_table = {} for nzf in nzo.extrapars[setname]: if not nzf.completed: block_table[nzf.blocks] = nzf if block_table: nzf = block_table[min(block_table)] logging.info("Found new par2file %s", nzf.filename) # Move from extrapar list to files to be downloaded # and remove it from the extrapars list nzo.add_parfile(nzf) readd = True else: nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED elif line.startswith("You need"): # We need more blocks, but are they available? chunks = line.split() needed_blocks = int(chunks[2]) # Check if we have enough blocks added_blocks = nzo.get_extra_blocks(setname, needed_blocks) if added_blocks: msg = T("Fetching %s blocks...") % str(added_blocks) nzo.set_action_line(T("Fetching"), msg) readd = True else: # Failed msg = T("Repair failed, not enough repair blocks (%s short)") % str(needed_blocks) nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED elif line.startswith("Repair is possible"): start = time.time() nzo.set_action_line(T("Repairing"), "%2d%%" % 0) elif line.startswith(("Repairing:", "Processing:")): # "Processing" is shown when it is only joining files without repairing chunks = line.split() new_perc = float(chunks[-1][:-1]) # Only send updates for whole-percentage updates if new_perc - perc > 1: perc = new_perc nzo.set_action_line(T("Repairing"), "%2d%% %s" % (perc, add_time_left(perc, start))) nzo.status = Status.REPAIRING elif line.startswith("Repair complete"): msg = T("[%s] Repaired in %s") % (setname, format_time_string(time.time() - start)) nzo.set_unpack_info("Repair", msg) logging.info("Repaired in %s", format_time_string(time.time() - start)) finished = True elif verified and line.endswith(("are missing.", "exist but are damaged.")): # Files that will later be verified after repair chunks = line.split() verifytotal += int(chunks[0]) elif line.startswith("Verifying repaired files"): in_verify_repaired = True elif in_verify_repaired and line.startswith("Target"): verifynum += 1 if verifynum <= verifytotal: nzo.set_action_line(T("Verifying repair"), "%02d/%02d" % (verifynum, verifytotal)) elif "Could not write" in line and "at offset 0:" in line: # If there are joinables, this error will only happen in case of 100% complete files # We can just skip the retry, because par2cmdline will fail in those cases # because it refuses to scan the ".001" file if joinables: finished = True used_joinables = [] elif " cannot be renamed to " in line: msg = line.strip() nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED elif "There is not enough space on the disk" in line: # Oops, disk is full! msg = T("Repairing failed, %s") % T("Disk full") nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED elif "No details available for recoverable file" in line: msg = line.strip() nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED elif line.startswith("Repair Failed."): # Unknown repair problem msg = T("Repairing failed, %s") % line nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED finished = False elif not verified: if line.startswith("Scanning:"): pass if in_extra_files: if "is a match for" in line or line.find("data blocks from") > 0: # Baldy named ones if m_rename := PAR2_IS_MATCH_FOR_RE.search(line): old_name = m_rename.group(1) new_name = m_rename.group(2) logging.debug('PAR2 will rename "%s" to "%s"', old_name, new_name) renames[new_name] = old_name # Obfuscated and also damaged if m_block := PAR2_BLOCK_FOUND_RE.search(line): workdir = os.path.split(parfile)[0] old_name = m_block.group(1) new_name = m_block.group(2) if joinables: # Find out if a joinable file has been used for joining for jn in joinables: if get_filename(jn) == old_name: used_joinables.append(jn) break # Special case of joined RAR files, the "of" and "from" must both be RAR files # This prevents the joined rars files from being seen as an extra rar-set if ".rar" in old_name.lower() and ".rar" in new_name.lower(): used_joinables.append(os.path.join(workdir, old_name)) else: logging.debug('PAR2 will reconstruct "%s" from "%s"', new_name, old_name) reconstructed.append(os.path.join(workdir, old_name)) renames[new_name] = old_name if m_block or m_rename: # Show progress verifynum += 1 nzo.set_action_line(T("Checking extra files"), "%02d" % verifynum) elif not in_verify: # Total number to verify if m := re.match(r"There are (\d+) recoverable files", line): verifytotal = int(m.group(1)) if line.startswith("Verifying source files:"): in_verify = True nzo.status = Status.VERIFYING elif line.startswith("Scanning extra files:"): in_verify = False in_extra_files = True verifynum = 0 else: # Target files for verification m = PAR2_TARGET_RE.match(line) if m: verifynum += 1 nzo.set_action_line(T("Verifying"), "%02d/%02d" % (verifynum, verifytotal)) # Remove redundant extra files that are just duplicates of original ones if "duplicate data blocks" in line: used_for_repair.append(m.group(1)) p.wait() # Also log what is shown to user in history if nzo.fail_msg: logging.info(nzo.fail_msg) logging.debug("par2cmdline output was:\n%s", "\n".join(lines)) # If successful, add renamed files to the collection if finished and renames: nzo.renamed_file(renames) # If successful and files were reconstructed, remove incomplete original files if finished and reconstructed: # Use 'used_joinables' as a vehicle to get rid of the files used_joinables.extend(reconstructed) return finished, readd, used_joinables, used_for_repair def multipar_verify( parfile: str, nzo: NzbObject, setname: str, joinables: List[str] ) -> Tuple[bool, bool, List[str], List[str]]: """Run par2 on par-set""" parfolder = os.path.split(parfile)[0] used_joinables = [] used_for_repair = [] # set the current nzo status to "Verifying...". Used in History nzo.status = Status.VERIFYING start = time.time() # Caching of verification implemented by adding -vs/-vd # But not really required due to prospective-par2 # Force output of utf-8 by adding -uo command = [str(MULTIPAR_COMMAND), "r", "-uo", "-vs2", "-vd%s" % nzo.admin_path, parfile] # Only add user-options if supplied options = cfg.par_option().strip().split() if options: for option in options: # We wrongly instructed users to use /x parameter style instead of -x option = option.replace("/", "-", 1) command.insert(2, option) # Support bizarre naming conventions by scanning all files if len(nzo.extrapars) == 1 or len(globber(parfolder, setname + "*")) < 2: command.insert(2, "-vl2") # Run MultiPar p = build_and_run_command(command) sabnzbd.PostProcessor.external_process = p # Set up our variables lines = [] renames = {} reconstructed = [] finished = False readd = False verifynum = 0 verifytotal = 0 verifyextratotal = 0 in_check = False in_verify = False in_repair = False in_verify_repaired = False misnamed_files = False old_name = None # Loop over the output, whee while 1: line = p.stdout.readline() if not line: break # Skip empty lines line = line.strip() if not line: continue # Save it all lines.append(line) # ----------------- Startup if line.startswith("invalid option"): # Option error msg = T("[%s] PAR2 received incorrect options, check your Config->Switches settings") % setname nzo.set_unpack_info("Repair", msg) nzo.status = Status.FAILED logging.error(msg) elif line.startswith("valid file is not found"): # Initialparfile probably didn't decode properly, or bad user parameters # We will try to get another par2 file, but 99% of time it's user parameters msg = T("Invalid par2 files or invalid PAR2 parameters, cannot verify or repair") logging.info(msg) logging.info("Extra pars = %s", nzo.extrapars[setname]) # Look for the smallest par2file block_table = {} for nzf in nzo.extrapars[setname]: if not nzf.completed: block_table[nzf.blocks] = nzf if block_table: nzf = block_table[min(block_table)] logging.info("Found new par2file %s", nzf.filename) # Move from extrapar list to files to be downloaded # and remove it from the extrapars list nzo.add_parfile(nzf) readd = True else: nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED elif line.startswith("There is not enough space on the disk"): msg = T("Repairing failed, %s") % T("Disk full") nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED # ----------------- Start check/verify stage elif line.startswith("Recovery Set ID"): # Remove files were MultiPar stores verification result when repaired successful recovery_id = line.split()[-1] used_for_repair.append(os.path.join(JOB_ADMIN, "2_%s.bin" % recovery_id)) used_for_repair.append(os.path.join(JOB_ADMIN, "2_%s.ini" % recovery_id)) elif line.startswith("Input File total count"): # How many files will it try to find? verifytotal = int(line.split()[-1]) # ----------------- Misnamed-detection stage # Misnamed files elif line.startswith("Searching misnamed file"): # We are in the misnamed files block # How many misnamed files will it try to find? verifyextratotal = int(line.split()[-1]) verifynum = 0 misnamed_files = True elif misnamed_files and "Found" in line: # First it reports the current filename if m := PAR2_FILENAME_RE.search(line): verifynum += 1 nzo.set_action_line(T("Checking extra files"), "%02d/%02d" % (verifynum, verifyextratotal)) old_name = m.group(1) elif misnamed_files and "Misnamed" in line: # Then it finds the actual m = PAR2_FILENAME_RE.search(line) if m and old_name: new_name = m.group(1) logging.debug('MultiPar will rename "%s" to "%s"', old_name, new_name) renames[new_name] = old_name # New name is also part of data! reconstructed.append(old_name) # ----------------- Checking stage # Checking input files elif line.startswith("Complete file count"): in_check = False verifynum = 0 old_name = None elif line.startswith("Verifying Input File"): in_check = True nzo.status = Status.VERIFYING elif in_check: if m := PAR2_FILENAME_RE.search(line): # Only increase counter if it was really the detection line if line.startswith("= ") or "%" not in line: verifynum += 1 nzo.set_action_line(T("Checking"), "%02d/%02d" % (verifynum, verifytotal)) old_name = m.group(1) # ----------------- Verify stage # Which files need extra verification? elif line.startswith("Damaged file count"): verifytotal = int(line.split()[-1]) elif line.startswith("Missing file count"): verifytotal += int(line.split()[-1]) # Actual verification elif line.startswith("Input File Slice found"): # End of verification AND end of misnamed file search in_verify = False misnamed_files = False old_name = None elif line.startswith("Finding available slice"): # The actual scanning of the files in_verify = True verifynum = 0 elif in_verify: if m := PAR2_FILENAME_RE.search(line): # It prints the filename couple of times, so we save it to check nzo.status = Status.VERIFYING if line.split()[1] in ("Damaged", "Found"): verifynum += 1 # Set old_name in case it was misnamed and found (not when we are joining) old_name = None if line.split()[1] == "Found" and not joinables: old_name = m.group(1) # Sometimes we don't know the total (filejoin) if verifytotal <= 1 or verifynum > verifytotal: nzo.set_action_line(T("Verifying"), "%02d" % verifynum) else: nzo.set_action_line(T("Verifying"), "%02d/%02d" % (verifynum, verifytotal)) elif old_name and old_name != m.group(1): # Hey we found another misnamed one! new_name = m.group(1) logging.debug('MultiPar will rename "%s" to "%s"', old_name, new_name) renames[new_name] = old_name # Need to remove the old file after repair (Multipar keeps it) used_for_repair.append(old_name) # Need to reset it to avoid collision old_name = None if joinables: # Find out if a joinable file has been used for joining for jn in joinables: if get_filename(jn) == m.group(1): used_joinables.append(jn) break elif line.startswith("Need"): # We need more blocks, but are they available? chunks = line.split() needed_blocks = int(chunks[1]) # Check if we have enough blocks added_blocks = nzo.get_extra_blocks(setname, needed_blocks) if added_blocks: msg = T("Fetching %s blocks...") % str(added_blocks) nzo.set_action_line(T("Fetching"), msg) readd = True else: # Failed msg = T("Repair failed, not enough repair blocks (%s short)") % str(needed_blocks) nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED # MultiPar can say 'PAR File(s) Incomplete' also when it needs more blocks # But the Need-more-blocks message is always last, so force failure finished = False # Result of verification elif line.startswith("All Files Complete") or line.endswith("PAR File(s) Incomplete"): # 'PAR File(s) Incomplete' is also reported for success when there are very similar filenames in the folder # See: https://github.com/Yutaka-Sawada/MultiPar/issues/54 # Check if there was damage, by inspecting the number of missing blocks if "Input File Slice lost" in lines[-2] and int(lines[-2].split()[-1]) == 0: # Completed without damage! msg = T("[%s] Verified in %s, all files correct") % (setname, format_time_string(time.time() - start)) nzo.set_unpack_info("Repair", msg) logging.info("Verified in %s, all files correct", format_time_string(time.time() - start)) finished = True elif line.startswith(("Ready to repair", "Ready to rejoin")): # Ready to repair! # Or we are re-joining a split file when there's no damage but takes time msg = T("[%s] Verified in %s, repair is required") % (setname, format_time_string(time.time() - start)) nzo.set_unpack_info("Repair", msg) logging.info("Verified in %s, repair is required", format_time_string(time.time() - start)) start = time.time() # Set message for user in case of joining if line.startswith("Ready to rejoin"): # There is no status-update when it is joining nzo.set_action_line(T("Joining"), "%2d" % len(used_joinables)) # ----------------- Repair stage elif "Recovering slice" in line: # Before this it will calculate matrix, here is where it starts start = time.time() in_repair = True nzo.set_action_line(T("Repairing"), "%2d%%" % 0) elif line.startswith("Verifying repair"): in_repair = False in_verify_repaired = True # How many will be checked? verifytotal = int(line.split()[-1]) verifynum = 0 elif in_repair: try: # Line with percentage of repair (nothing else) perc = float(line[:-1]) nzo.set_action_line(T("Repairing"), "%2d%% %s" % (perc, add_time_left(perc, start))) nzo.status = Status.REPAIRING except: # Checksum error if "checksum" in line: # Failed due to checksum error of multipar msg = T("Repairing failed, %s") % line nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED else: # Not sure, log error logging.info("Traceback: ", exc_info=True) elif line.startswith("Repaired successfully"): msg = T("[%s] Repaired in %s") % (setname, format_time_string(time.time() - start)) nzo.set_unpack_info("Repair", msg) logging.info("Repaired in %s", format_time_string(time.time() - start)) finished = True elif in_verify_repaired and line.startswith("Repaired :"): # Track verification of repaired files (can sometimes take a while) verifynum += 1 nzo.set_action_line(T("Verifying repair"), "%02d/%02d" % (verifynum, verifytotal)) elif line.startswith("Failed to repair") and not readd: # Unknown repair problem msg = T("Repairing failed, %s") % line nzo.fail_msg = msg nzo.set_unpack_info("Repair", msg, setname) nzo.status = Status.FAILED finished = True p.wait() # Also log what is shown to user in history if nzo.fail_msg: logging.info(nzo.fail_msg) logging.debug("MultiPar output:\n%s", "\n".join(lines)) # Add renamed files to the collection # MultiPar always automatically renames whatever it can in the 'Searching misnamed file:'-section # Even if the repair did not complete fully it will rename those! # But the ones in 'Finding available slices'-section will only be renamed after successful repair if renames: # If success, we also remove the possibly previously renamed ones if finished: reconstructed.extend(list(renames.values())) # Adding to the collection nzo.renamed_file(renames) # Remove renamed original files workdir = os.path.split(parfile)[0] used_joinables.extend([os.path.join(workdir, name) for name in reconstructed]) return finished, readd, used_joinables, used_for_repair def create_env(nzo: Optional[NzbObject] = None, extra_env_fields: Dict[str, Any] = {}) -> Optional[Dict[str, Any]]: """Modify the environment for pp-scripts with extra information macOS: Return copy of environment without PYTHONPATH and PYTHONHOME other: return None """ env = os.environ.copy() # Are we adding things? if nzo: # Add basic info for field in ENV_NZO_FIELDS: try: field_value = getattr(nzo, field) # Special filters for Python types if field_value is None: env["SAB_" + field.upper()] = "" elif isinstance(field_value, bool): env["SAB_" + field.upper()] = str(field_value * 1) else: env["SAB_" + field.upper()] = str(field_value) except: # Catch key errors pass # Always supply basic info extra_env_fields.update( { "program_dir": sabnzbd.DIR_PROG, "api_key": cfg.api_key(), "api_url": f"{sabnzbd.BROWSER_URL}/api", "par2_command": sabnzbd.newsunpack.PAR2_COMMAND, "multipar_command": sabnzbd.newsunpack.MULTIPAR_COMMAND, "rar_command": sabnzbd.newsunpack.RAR_COMMAND, "7zip_command": sabnzbd.newsunpack.SEVENZIP_COMMAND, "version": sabnzbd.__version__, } ) # Add extra fields for field in extra_env_fields: try: if extra_env_fields[field] is not None: env["SAB_" + field.upper()] = str(extra_env_fields[field]) else: env["SAB_" + field.upper()] = "" except: # Catch key errors pass if sabnzbd.MACOS: if "PYTHONPATH" in env: del env["PYTHONPATH"] if "PYTHONHOME" in env: del env["PYTHONHOME"] return env def rar_volumelist(rarfile_path: str, password: str, known_volumes: List[str]) -> List[str]: """List volumes that are part of this rarset and merge them with parsed paths list, removing duplicates. We assume RarFile is right and use parsed paths as backup. """ # UnRar is required to read some RAR files # RarFile can fail in special cases try: zf = rarfile.RarFile(rarfile_path) # setpassword can fail due to bugs in RarFile if password: try: zf.setpassword(password) except: pass zf_volumes = zf.volumelist() except: zf_volumes = [] # Remove duplicates zf_volumes_base = [os.path.basename(vol) for vol in zf_volumes] for known_volume in known_volumes: if os.path.basename(known_volume) not in zf_volumes_base: # Long-path notation just to be sure zf_volumes.append(long_path(known_volume)) return zf_volumes # Sort the various RAR filename formats properly :\ def rar_sort(a: str, b: str) -> int: """Define sort method for rar file names""" aext = a.split(".")[-1] bext = b.split(".")[-1] if aext == "rar" and bext == "rar": return cmp(a, b) elif aext == "rar": return -1 elif bext == "rar": return 1 else: return cmp(a, b) def quick_check_set(setname: str, nzo: NzbObject) -> bool: """Check all on-the-fly crc32s of a set""" par2pack = nzo.par2packs.get(setname) if par2pack is None: return False # We use bitwise assignment (&=) so False always wins in case of failure # This way the renames always get saved! result = True nzf_list = nzo.finished_files renames = {} found_paths: Set[str] = set() # Files to ignore ignore_ext = cfg.quick_check_ext_ignore() for file in par2pack: par2info = par2pack[file] found = False file_to_ignore = get_ext(file).replace(".", "") in ignore_ext for nzf in nzf_list: # Do a simple filename based check if file == nzf.filename: found = True found_paths.add(nzf.filepath) if ( nzf.crc32 is not None and nzf.crc32 == par2info.filehash and is_size(nzf.filepath, par2info.filesize) ): logging.debug("Quick-check of file %s OK", file) result &= True elif file_to_ignore: # We don't care about these files logging.debug("Quick-check ignoring file %s", file) result &= True else: logging.info("Quick-check of file %s failed!", file) result = False break # Now let's do obfuscation check if ( nzf.filepath not in found_paths and nzf.crc32 is not None and nzf.crc32 == par2info.filehash and is_size(nzf.filepath, par2info.filesize) ): try: logging.debug("Quick-check will rename %s to %s", nzf.filename, file) # Note: file can and is allowed to be in a subdirectory. # Subdirectories in par2 always contain "/", not "\" so we need to normalize file = os.path.normpath(file) renamer( os.path.join(nzo.download_path, nzf.filename), os.path.join(nzo.download_path, file), create_local_directories=True, ) renames[file] = nzf.filename nzf.filename = file result &= True found = True found_paths.add(nzf.filepath) break except IOError: # Renamed failed for some reason, probably already done break if not found: if file_to_ignore: # We don't care about these files logging.debug("Quick-check ignoring missing file %s", file) continue logging.info("Cannot Quick-check missing file %s!", file) result = False # Save renames if renames: nzo.renamed_file(renames) return result def unrar_check(rar: str) -> Tuple[int, bool]: """Return version number of unrar, where "5.01" returns 501 Also return whether an original version is found (version, original) """ version = 0 original = False if rar: try: version = run_command([rar]) except: return version, original original = "Alexander Roshal" in version if m := re.search(r"RAR\s(\d+)\.(\d+)", version): version = int(m.group(1)) * 100 + int(m.group(2)) else: version = 0 return version, original def sevenzip_check(sevenzip: str) -> str: """Return version of 7zip, currently as a string""" if sevenzip: try: seven_command_output = run_command([sevenzip]) # Example: 7-Zip (z) 21.06 (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-11-24 # 7-Zip (a) 24.03 (x86) : Copyright (c) 1999-2024 Igor Pavlov : 2024-03-23 return re.search(r"(\d+\.\d+).*Copyright", seven_command_output).group(1) except: pass return "" def par2_turbo_check(par2_path: str) -> bool: """Detect if we have the turbo par2 variant""" try: if "par2cmdline-turbo" in run_command([par2_path, "-V"]): return True except: pass return False def is_sfv_file(myfile: str) -> bool: """Checks if given file is a SFV file, and returns result as boolean""" # based on https://stackoverflow.com/a/7392391/5235502 textchars = bytearray({7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100)) - {0x7F}) is_ascii_string = lambda input_bytes: not bool(input_bytes.translate(None, textchars)) # first check if it's plain text (ASCII or Unicode) try: with open(myfile, "rb") as f: # get first 10000 bytes to check myblock = f.read(10000) if is_ascii_string(myblock): # ASCII, so store lines for further inspection try: lines = ubtou(myblock).split("\n") except UnicodeDecodeError: return False else: # non-ASCII, so not SFV return False except: # the with-open() went wrong, so not an existing file, so certainly not a SFV file return False sfv_info_line_counter = 0 for line in lines: line = line.strip() if re.search(r"^[^;].*\ +[A-Fa-f0-9]{8}$", line): # valid, useful SFV line: some text, then one or more space, and a 8-digit hex number sfv_info_line_counter += 1 if sfv_info_line_counter >= 10: # with 10 valid, useful lines we're confident enough # (note: if we find less lines (even just 1 line), with no negatives, it is OK. See below) break elif not line or line.startswith(";"): # comment line or just spaces, so continue to next line continue else: # not a valid SFV line, so not a SFV file: return False # if we get here, no negatives were found, and at least 1 valid line is OK return sfv_info_line_counter >= 1 def sfv_check(sfvs: List[str], nzo: NzbObject) -> bool: """Verify files using SFV files""" # Update status nzo.status = Status.VERIFYING nzo.set_action_line(T("Trying SFV verification"), "...") # We use bitwise assignment (&=) so False always wins in case of failure # This way the renames always get saved! result = True nzf_list = nzo.finished_files renames = {} # Files to ignore ignore_ext = cfg.quick_check_ext_ignore() # We need the crc32 of all files calculated_crc32 = {} verifytotal = len(nzo.finished_files) verifynum = 0 for nzf in nzf_list: if nzf.crc32 is not None: verifynum += 1 nzo.set_action_line(T("Verifying"), "%02d/%02d" % (verifynum, verifytotal)) calculated_crc32[nzf.filename] = b"%08x" % (nzf.crc32 & 0xFFFFFFFF) sfv_parse_results = {} nzo.set_action_line(T("Trying SFV verification"), "...") for sfv in sfvs: setname = setname_from_path(sfv) nzo.set_unpack_info("Repair", T("Trying SFV verification"), setname) # Parse the sfv and add to the already found results # Duplicates will be replaced sfv_parse_results.update(parse_sfv(sfv)) for file in sfv_parse_results: found = False file_to_ignore = get_ext(file).replace(".", "") in ignore_ext for nzf in nzf_list: # Do a simple filename based check if file == nzf.filename: found = True if calculated_crc32.get(nzf.filename, "") == sfv_parse_results[file]: logging.debug("SFV-check of file %s OK", file) result &= True elif file_to_ignore: # We don't care about these files logging.debug("SFV-check ignoring file %s", file) result &= True else: logging.info("SFV-check of file %s failed!", file) result = False break # Now lets do obfuscation check if calculated_crc32.get(nzf.filename, "") == sfv_parse_results[file]: try: logging.debug("SFV-check will rename %s to %s", nzf.filename, file) renamer(os.path.join(nzo.download_path, nzf.filename), os.path.join(nzo.download_path, file)) renames[file] = nzf.filename nzf.filename = file result &= True found = True break except IOError: # Renamed failed for some reason, probably already done break if not found: if file_to_ignore: # We don't care about these files logging.debug("SFV-check ignoring missing file %s", file) continue logging.info("Cannot SFV-check missing file %s!", file) result = False # Save renames if renames: nzo.renamed_file(renames) return result def parse_sfv(sfv_filename): """Parse SFV file and return dictionary of crc32's and filenames""" results = {} with open(sfv_filename, mode="rb") as sfv_list: for sfv_item in sfv_list: sfv_item = sfv_item.strip() # Ignore comment-lines if sfv_item.startswith(b";"): continue # Parse out the filename and crc32 filename, expected_crc32 = sfv_item.strip().rsplit(maxsplit=1) # We don't know what encoding is used when it was created results[correct_unknown_encoding(filename)] = expected_crc32.lower() return results def add_time_left(perc: float, start_time: Optional[float] = None, time_used: Optional[float] = None) -> str: """Calculate time left based on current progress, if it is taking more than 10 seconds""" if not time_used: time_used = time.time() - start_time if time_used > 10: return " - %s %s" % (format_time_left(int((100 - perc) / (perc / time_used)), short_format=True), T("left")) return "" def pre_queue(nzo: NzbObject, pp, cat): """Run pre-queue script (if any) and process results. pp and cat are supplied separate since they can change. """ def fix(p): # If added via API, some items can still be "None" (as a string) if is_none(p): return "" return str(p) values = [1, nzo.final_name_with_password, pp, cat, nzo.script, nzo.priority, None] script_path = make_script_path(cfg.pre_script()) if script_path: # Basic command-line parameters command = [ script_path, nzo.final_name_with_password, pp, cat, nzo.script, nzo.priority, str(nzo.bytes), " ".join(nzo.groups), ] command = [fix(arg) for arg in command] # Fields not in the NZO directly show_analysis = sabnzbd.sorting.BasicAnalyzer(nzo.final_name) extra_env_fields = { "groups": " ".join(nzo.groups), "title": show_analysis.info.get("title", ""), "season": show_analysis.info.get("season_num", ""), "episode": show_analysis.info.get("episode_num", ""), "episode_name": show_analysis.info.get("ep_name", ""), "is_proper": show_analysis.is_proper(), "resolution": show_analysis.info.get("resolution", ""), "decade": show_analysis.info.get("decade", ""), "year": show_analysis.info.get("year", ""), "month": show_analysis.info.get("month", ""), "day": show_analysis.info.get("day", ""), "job_type": show_analysis.type, } try: p = build_and_run_command(command, env=create_env(nzo, extra_env_fields)) except: logging.debug("Failed script %s, Traceback: ", script_path, exc_info=True) return values output = p.stdout.read() ret = p.wait() logging.info("Pre-queue script returned %s and output=\n%s", ret, output) if ret == 0: split_output = output.splitlines() try: # Extract category line from pre-queue output pre_queue_category = split_output[3].strip(" '\"") except IndexError: pre_queue_category = None for index, line in enumerate(split_output): line = line.strip(" '\"") if index < len(values): if line: values[index] = line elif pre_queue_category and index in (2, 4, 5): # Preserve empty pp, script, and priority lines to prevent # pre-existing values from overriding category-based settings values[index] = "" accept = int_conv(values[0]) if accept < 1: logging.info("Pre-Q refuses %s", nzo.final_name) elif accept == 2: logging.info("Pre-Q accepts&fails %s", nzo.final_name) else: logging.info("Pre-Q accepts %s", nzo.final_name) return values def is_sevenfile(path: str) -> bool: """Return True if path has 7Zip-signature and 7Zip is detected""" with open(path, "rb") as sevenzip: if sevenzip.read(6) == SEVENZIP_ID: return bool(SEVENZIP_COMMAND) return False class SevenZip: """Minimal emulation of ZipFile class for 7Zip""" def __init__(self, path: str): self.path = path # Check if it's actually a 7Zip-file if not is_sevenfile(self.path): raise TypeError("File is not a 7zip file") def namelist(self) -> List[str]: """Return list of names in 7Zip""" names = [] command = [SEVENZIP_COMMAND, "l", "-p", "-y", "-slt", "-sccUTF-8", self.path] output = run_command(command) for line in output.split("\n"): if m := SEVENZIP_PATH_RE.search(line): names.append(m.group(1).strip("\r")) if names: # Remove name of archive itself del names[0] return names def open(self, name: str) -> BinaryIO: """Read named file from 7Zip and return data""" command = [SEVENZIP_COMMAND, "e", "-p", "-y", "-so", self.path, name] # Ignore diagnostic output, otherwise it will be appended to content with build_and_run_command(command, text_mode=False, stderr=subprocess.DEVNULL) as p: data = io.BytesIO(p.stdout.read()) p.wait() return data def close(self): """Close file""" pass ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.448578 SABnzbd-4.3.2/sabnzbd/directunpacker.py0000644000000000000000000005514314625637243017233 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.directunpacker """ import os import re import subprocess import time import threading import logging from typing import Optional, Dict, List, Tuple import sabnzbd import sabnzbd.cfg as cfg from sabnzbd.misc import int_conv, format_time_string, build_and_run_command from sabnzbd.filesystem import long_path, remove_all, real_path, remove_file, get_basename from sabnzbd.nzbstuff import NzbObject, NzbFile from sabnzbd.encoding import platform_btou from sabnzbd.decorators import synchronized from sabnzbd.newsunpack import RAR_EXTRACTFROM_RE, RAR_EXTRACTED_RE, rar_volumelist, add_time_left from sabnzbd.postproc import prepare_extraction_path from sabnzbd.utils.rarfile import RarFile from sabnzbd.utils.diskspeed import diskspeedmeasure # Need a lock to make sure start and stop is handled correctly # Otherwise we could stop while the thread was still starting START_STOP_LOCK = threading.RLock() ACTIVE_UNPACKERS = [] RAR_NR = re.compile(r"(.*?)(\.part(\d*).rar|\.r(\d*))$", re.IGNORECASE) class DirectUnpacker(threading.Thread): def __init__(self, nzo: NzbObject): super().__init__() self.nzo: NzbObject = nzo self.active_instance: Optional[subprocess.Popen] = None self.killed: bool = False self.next_file_lock = threading.Condition(threading.RLock()) self.unpack_dir_info = None self.rarfile_nzf: Optional[NzbFile] = None self.cur_setname: Optional[str] = None self.cur_volume: int = 0 self.total_volumes: Dict[str, int] = {} self.unpack_time: float = 0.0 self.success_sets: Dict[str, Tuple[List[str], List[str]]] = {} self.next_sets: List[NzbFile] = [] self.duplicate_lines: int = 0 nzo.direct_unpacker = self def stop(self): pass def save(self): pass def reset_active(self): # make sure the process and file handlers are closed nicely: try: if self.active_instance: self.active_instance.stdout.close() self.active_instance.stdin.close() self.active_instance.wait(timeout=2) except: logging.debug("Exception in reset_active()", exc_info=True) pass self.active_instance = None self.cur_setname = None self.cur_volume = 0 self.rarfile_nzf = None def check_requirements(self): if ( not cfg.enable_unrar() or not cfg.direct_unpack() or self.killed or self.nzo.first_articles or not self.nzo.unpack or self.nzo.bad_articles or sabnzbd.newsunpack.RAR_PROBLEM ): return False return True def set_volumes_for_nzo(self): """Loop over all files to detect the names""" logging.debug("Parsing setname and volume information for %s" % self.nzo.final_name) none_counter = 0 found_counter = 0 for nzf in self.nzo.files + self.nzo.finished_files: nzf.setname, nzf.vol = analyze_rar_filename(nzf.filename) # We matched? if nzf.setname: found_counter += 1 if nzf.setname not in self.total_volumes: self.total_volumes[nzf.setname] = 0 self.total_volumes[nzf.setname] = max(self.total_volumes[nzf.setname], nzf.vol) else: none_counter += 1 # Too much not found? Obfuscated, ignore results if none_counter > found_counter: self.total_volumes = {} @synchronized(START_STOP_LOCK) def add(self, nzf: NzbFile): """Add jobs and start instance of DirectUnpack""" if not cfg.direct_unpack_tested(): test_disk_performance() # Stop if something is wrong or we shouldn't start yet if not self.check_requirements(): return # Is this the first set? if not self.cur_setname: self.set_volumes_for_nzo() self.cur_setname = nzf.setname # Analyze updated filenames nzf.setname, nzf.vol = analyze_rar_filename(nzf.filename) # Are we doing this set? if self.cur_setname and self.cur_setname == nzf.setname: logging.debug("DirectUnpack queued %s for %s", nzf.filename, self.cur_setname) # Is this the first one of the first set? if not self.active_instance and not self.is_alive() and self.have_next_volume(): # Too many runners already? if len(ACTIVE_UNPACKERS) >= cfg.direct_unpack_threads(): logging.info("Too many DirectUnpackers currently to start %s", self.cur_setname) return # Start the unrar command and the loop self.create_unrar_instance() self.start() elif not any(test_nzf.setname == nzf.setname for test_nzf in self.next_sets): # Need to store this for the future, only once per set! self.next_sets.append(nzf) # Wake up the thread to see if this is good to go with self.next_file_lock: self.next_file_lock.notify() def run(self): # Input and output linebuf = b"" last_volume_linebuf = b"" unrar_log = [] rarfiles = [] extracted = [] start_time = time.time() # Need to read char-by-char because there's no newline after new-disk message while 1: # We need to lock, so we don't crash if unpacker is deleted while we read with START_STOP_LOCK: if not self.active_instance or not self.active_instance.stdout: break while 1: # Keep reading until reaching space or end of line # to prevent continuous locking and unlocking char = self.active_instance.stdout.read(1) linebuf += char if char in (b" ", b"\n", b""): break # End of program if not char: break # Handle whole lines if char == b"\n": # When reaching end-of-line, we can safely convert and add to the log linebuf_encoded = platform_btou(linebuf.strip()) linebuf = b"" # Skip empty lines if not linebuf_encoded: continue unrar_log.append(linebuf_encoded) # Error? Let PP-handle this job if any( error_text in linebuf_encoded for error_text in ( "ERROR: ", "Cannot create", "in the encrypted file", "CRC failed", "checksum failed", "You need to start extraction from a previous volume", "password is incorrect", "Incorrect password", "Write error", "checksum error", "Cannot open", "start extraction from a previous volume", "Unexpected end of archive", ) ): logging.info("Error in DirectUnpack of %s: %s", self.cur_setname, linebuf_encoded) self.abort() elif linebuf_encoded.startswith("All OK"): # Did we reach the end? # Stop timer and finish self.unpack_time += time.time() - start_time ACTIVE_UNPACKERS.remove(self) # Take note of the correct password if self.nzo.password and not self.nzo.correct_password: self.nzo.correct_password = self.nzo.password # Add to success rarfile_path = os.path.join(self.nzo.download_path, self.rarfile_nzf.filename) self.success_sets[self.cur_setname] = ( rar_volumelist(rarfile_path, self.nzo.correct_password, rarfiles), extracted, ) logging.info("DirectUnpack completed for %s", self.cur_setname) self.nzo.set_action_line(T("Direct Unpack"), T("Completed")) # List success in history-info msg = T("Unpacked %s files/folders in %s") % (len(extracted), format_time_string(self.unpack_time)) msg = "%s - %s" % (T("Direct Unpack"), msg) self.nzo.set_unpack_info("Unpack", msg, self.cur_setname) # Write current log and clear logging.debug("DirectUnpack Unrar output: \n%s", "\n".join(unrar_log)) unrar_log = [] rarfiles = [] extracted = [] # Are there more files left? while not self.nzo.removed_from_queue and not self.next_sets: logging.debug("Direct Unpack for %s waiting for more sets", self.nzo.final_name) with self.next_file_lock: self.next_file_lock.wait() # Is there another set to do? logging.debug( "Direct Unpack for %s continuing: killed=%s, cur_setname=%s, next_sets=%s", self.nzo.final_name, self.killed, self.cur_setname, self.next_sets, ) if self.next_sets: # Start new instance nzf = self.next_sets.pop(0) self.reset_active() self.cur_setname = nzf.setname # Wait for the 1st volume to appear self.wait_for_next_volume() self.create_unrar_instance() start_time = time.time() else: self.killed = True break elif linebuf_encoded.startswith("Extracting from"): # List files we used filename = re.search(RAR_EXTRACTFROM_RE, linebuf_encoded).group(1) if filename not in rarfiles: rarfiles.append(filename) elif m := re.search(RAR_EXTRACTED_RE, linebuf_encoded): # List files we extracted # In case of flat-unpack, UnRar still prints the whole path (?!) unpacked_file = m.group(2) if cfg.flat_unpack(): unpacked_file = os.path.basename(unpacked_file) extracted.append(real_path(self.unpack_dir_info[0], unpacked_file)) if linebuf.endswith(b"[C]ontinue, [Q]uit "): # Stop timer self.unpack_time += time.time() - start_time # Wait for the next one.. self.wait_for_next_volume() # Possible that the instance was deleted while locked if not self.killed: # Sometimes the assembler is still working on the file, resulting in "Unexpected end of archive". # So we delay a tiny bit before we continue. This is not the cleanest solution, but it works. time.sleep(0.1) # If unrar stopped or is killed somehow, writing will cause a crash try: # Give unrar some time to do its thing self.active_instance.stdin.write(b"C\n") start_time = time.time() time.sleep(0.1) except IOError: self.abort() break # Did we unpack a new volume? Sometimes UnRar hangs on 1 volume if not last_volume_linebuf or last_volume_linebuf != linebuf: # Next volume self.cur_volume += 1 self.nzo.set_action_line(T("Direct Unpack"), self.get_formatted_stats(include_time_left=True)) logging.info("DirectUnpacked volume %s for %s", self.cur_volume, self.cur_setname) # If lines did not change and we don't have the next volume, this download is missing files! # In rare occasions we can get stuck forever with repeating lines if last_volume_linebuf == linebuf: if not self.have_next_volume() or self.duplicate_lines > 10: logging.info("DirectUnpack failed due to missing files %s", self.cur_setname) self.abort() else: logging.debug('Duplicate output line detected: "%s"', platform_btou(last_volume_linebuf)) self.duplicate_lines += 1 else: self.duplicate_lines = 0 last_volume_linebuf = linebuf # Add last line and write any new output if linebuf: unrar_log.append(platform_btou(linebuf.strip())) if unrar_log: logging.debug("DirectUnpack Unrar output: \n%s", "\n".join(unrar_log)) # Make more space self.reset_active() if self in ACTIVE_UNPACKERS: ACTIVE_UNPACKERS.remove(self) logging.debug("Closing DirectUnpack for %s", self.nzo.final_name) # Set the thread to killed so it never gets restarted by accident self.killed = True def have_next_volume(self): """Check if next volume of set is available, start from the end of the list where latest completed files are Make sure that files are 100% written to disk by checking nzf.assembled """ for nzf_search in reversed(self.nzo.finished_files): if ( nzf_search.setname == self.cur_setname and nzf_search.vol == (self.cur_volume + 1) and nzf_search.assembled ): return nzf_search return False def wait_for_next_volume(self): """Wait for the correct volume to appear but stop if it was killed or the NZB is in post-processing and no new files will be downloaded. """ while not self.have_next_volume() and not self.killed and not self.nzo.pp_active: with self.next_file_lock: self.next_file_lock.wait() @synchronized(START_STOP_LOCK) def create_unrar_instance(self): """Start the unrar instance using the user's options""" # Generate extraction path and save for post-proc if not self.unpack_dir_info: try: self.unpack_dir_info = prepare_extraction_path(self.nzo) except: # Prevent fatal crash if directory creation fails self.abort() return # Get the information extraction_path, _, _, one_folder, _ = self.unpack_dir_info # Set options if self.nzo.correct_password: password_command = "-p%s" % self.nzo.correct_password elif self.nzo.password: password_command = "-p%s" % self.nzo.password else: password_command = "-p-" if one_folder or cfg.flat_unpack(): action = "e" else: action = "x" # The first NZF self.rarfile_nzf = self.have_next_volume() # Ignore if maybe this set is not there anymore # This can happen due to race/timing issues when creating the sets if not self.rarfile_nzf: return # Generate command rarfile_path = os.path.join(self.nzo.download_path, self.rarfile_nzf.filename) if sabnzbd.WIN32: # On Windows, UnRar uses a custom argument parser # See: https://github.com/sabnzbd/sabnzbd/issues/1043 # The -scf forces the output to be UTF8 command = [ sabnzbd.newsunpack.RAR_COMMAND, action, "-vp", "-idp", "-scf", "-o+", "-ai", password_command, rarfile_path, "%s\\" % long_path(extraction_path), ] else: # The -scf forces the output to be UTF8 command = [ sabnzbd.newsunpack.RAR_COMMAND, action, "-vp", "-idp", "-scf", "-o+", "-ai", password_command, rarfile_path, "%s/" % extraction_path, ] if cfg.ignore_unrar_dates(): command.insert(3, "-tsm-") # Let's start from the first one! self.cur_volume = 1 # Need to disable buffer to have direct feedback self.active_instance = build_and_run_command( command, windows_unrar_command=True, text_mode=False, stdin=subprocess.PIPE ) # Add to runners ACTIVE_UNPACKERS.append(self) # Doing the first logging.info("DirectUnpacked volume %s for %s", self.cur_volume, self.cur_setname) @synchronized(START_STOP_LOCK) def abort(self): """Abort running instance and delete generated files""" if not self.killed and self.cur_setname: logging.info("Aborting DirectUnpack for %s", self.cur_setname) self.killed = True # Save reference to the first rarfile rarfile_nzf = self.rarfile_nzf # Abort Unrar if self.active_instance: # First we try to abort gracefully try: self.active_instance.stdin.write(b"Q\n") time.sleep(0.2) except IOError: pass # Now force kill and give it a bit of time try: self.active_instance.kill() time.sleep(0.2) except AttributeError: # Already killed by the Quit command pass # Wake up the thread with self.next_file_lock: self.next_file_lock.notify() # No new sets self.next_sets = [] self.success_sets = {} # Remove files if self.unpack_dir_info: extraction_path, _, _, one_folder, _ = self.unpack_dir_info # In case of flat-unpack we need to remove the files manually if one_folder: # RarFile can fail for mysterious reasons try: rar_contents = RarFile( os.path.join(self.nzo.download_path, rarfile_nzf.filename), single_file_check=True ).filelist() for rm_file in rar_contents: # Flat-unpack, so remove foldername from RarFile output f = os.path.join(extraction_path, os.path.basename(rm_file)) remove_file(f) except: # The user will have to remove it themselves logging.info( "Failed to clean Direct Unpack after aborting %s", rarfile_nzf.filename, exc_info=True ) else: # We can just remove the whole path remove_all(extraction_path, recursive=True) # Remove dir-info self.unpack_dir_info = None # Reset settings self.reset_active() def get_formatted_stats(self, include_time_left: bool = False) -> str: """Get percentage or number of rar's done""" if self.cur_setname and self.cur_setname in self.total_volumes: # This won't work on obfuscated posts if self.total_volumes[self.cur_setname] >= self.cur_volume and self.cur_volume: formatted_stats = "%02d/%02d" % (self.cur_volume, self.total_volumes[self.cur_setname]) if include_time_left: formatted_stats += add_time_left( (self.cur_volume / self.total_volumes[self.cur_setname]) * 100, time_used=self.unpack_time ) return formatted_stats return str(self.cur_volume) def analyze_rar_filename(filename): """Extract volume number and setname from rar-filenames Both ".part01.rar" and ".r01" """ if m := RAR_NR.search(filename): if m.group(4): # Special since starts with ".rar", ".r00" return m.group(1), int_conv(m.group(4)) + 2 return m.group(1), int_conv(m.group(3)) else: # Detect if first of "rxx" set if filename.endswith(".rar"): return get_basename(filename), 1 return None, None def abort_all(): """Abort all running DirectUnpackers""" logging.info("Aborting all DirectUnpackers") for direct_unpacker in ACTIVE_UNPACKERS: direct_unpacker.abort() def test_disk_performance(): """Test the incomplete-dir performance and enable Direct Unpack if good enough (> 100MB/s) """ if diskspeedmeasure(sabnzbd.cfg.download_dir.get_path()) > 100: cfg.direct_unpack.set(True) logging.warning( T("Direct Unpack was automatically enabled.") + " " + T( "Jobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair." ) ) else: logging.info("Direct Unpack was not enabled, incomplete folder disk speed below 40MB/s") cfg.direct_unpack_tested.set(True) sabnzbd.config.save_config() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.448673 SABnzbd-4.3.2/sabnzbd/nzbqueue.py0000644000000000000000000012270514625637243016065 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.nzbqueue - nzb queue """ import os import logging import time import cherrypy._cpreqbody from typing import List, Dict, Union, Tuple, Optional import sabnzbd from sabnzbd.nzbstuff import NzbObject, Article from sabnzbd.misc import exit_sab, cat_to_opts, int_conv, caller_name, safe_lower, duplicate_warning from sabnzbd.filesystem import get_admin_path, remove_all, globber_full, remove_file, is_valid_script from sabnzbd.nzbparser import process_single_nzb from sabnzbd.panic import panic_queue from sabnzbd.decorators import NzbQueueLocker from sabnzbd.constants import ( QUEUE_FILE_NAME, QUEUE_VERSION, FUTURE_Q_FOLDER, JOB_ADMIN, LOW_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY, STOP_PRIORITY, VERIFIED_FILE, Status, IGNORED_FILES_AND_FOLDERS, DuplicateStatus, ) import sabnzbd.cfg as cfg from sabnzbd.downloader import Server import sabnzbd.notifier as notifier class NzbQueue: """Singleton NzbQueue""" def __init__(self): self.__top_only: bool = cfg.top_only() self.__nzo_list: List[NzbObject] = [] self.__nzo_table: Dict[str, NzbObject] = {} def read_queue(self, repair: int): """Read queue from disk, supporting repair modes 0 = no repairs 1 = use existing queue, add missing "incomplete" folders 2 = Discard all queue admin, reconstruct from "incomplete" folders """ nzo_ids = [] if repair < 2: # Try to process the queue file try: data = sabnzbd.filesystem.load_admin(QUEUE_FILE_NAME) if data: queue_vers, nzo_ids, _ = data if not queue_vers == QUEUE_VERSION: nzo_ids = [] logging.error(T("Incompatible queuefile found, cannot proceed")) if not repair: panic_queue(os.path.join(cfg.admin_dir.get_path(), QUEUE_FILE_NAME)) exit_sab(2) except: nzo_ids = [] logging.error( T("Error loading %s, corrupt file detected"), os.path.join(cfg.admin_dir.get_path(), QUEUE_FILE_NAME), ) # First handle jobs in the queue file folders = [] for nzo_id in nzo_ids: folder, _id = os.path.split(nzo_id) path = get_admin_path(folder, future=False) # Try as normal job nzo = sabnzbd.filesystem.load_data(_id, path, remove=False) if not nzo: # Try as future job path = get_admin_path(folder, future=True) nzo = sabnzbd.filesystem.load_data(_id, path) if nzo: self.add(nzo, save=False, quiet=True) folders.append(folder) # Scan for any folders in "incomplete" that are not yet in the queue if repair: logging.info("Starting queue repair") self.scan_jobs(not folders) # Handle any lost future jobs for item in globber_full(os.path.join(cfg.admin_dir.get_path(), FUTURE_Q_FOLDER)): path, nzo_id = os.path.split(item) if nzo_id not in self.__nzo_table: if nzo_id.startswith("SABnzbd_nzo"): nzo = sabnzbd.filesystem.load_data(nzo_id, path, remove=True) if nzo: self.add(nzo, save=True) else: try: remove_file(item) except: pass @NzbQueueLocker def scan_jobs(self, all_jobs: bool = False, action: bool = True) -> List[str]: """Scan "incomplete" for missing folders, 'all' is True: Include active folders 'action' is True, do the recovery action returns list of orphaned folders """ result = [] # Folders from the download queue if all_jobs: registered = [] else: registered = [nzo.work_name for nzo in self.__nzo_list] # Retryable folders from History items = sabnzbd.api.build_history()[0] # Anything waiting or active or retryable is a known item registered.extend( [ os.path.basename(item["path"]) for item in items if item["retry"] or item["loaded"] or item["status"] == Status.QUEUED ] ) # Repair unregistered folders for folder in globber_full(cfg.download_dir.get_path()): name = os.path.basename(folder) if os.path.isdir(folder) and name not in registered and name not in IGNORED_FILES_AND_FOLDERS: if action: logging.info("Repairing job %s", folder) self.repair_job(folder) result.append(os.path.basename(folder)) else: if action: logging.info("Skipping repair for job %s", folder) return result def repair_job( self, repair_folder: str, new_nzb: Optional[cherrypy._cpreqbody.Part] = None, password: Optional[str] = None ) -> Optional[str]: """Reconstruct admin for a single job folder, optionally with new NZB""" # Check if folder exists if not repair_folder or not os.path.exists(repair_folder): return None name = os.path.basename(repair_folder) admin_path = os.path.join(repair_folder, JOB_ADMIN) # If Retry was used and a new NZB was uploaded if getattr(new_nzb, "filename", None): remove_all(admin_path, "*.gz", keep_folder=True) logging.debug("Repair job %s with new NZB (%s)", name, new_nzb.filename) _, nzo_ids = sabnzbd.nzbparser.add_nzbfile(new_nzb, nzbname=name, reuse=repair_folder, password=password) else: # Was this file already post-processed? verified = sabnzbd.filesystem.load_data(VERIFIED_FILE, admin_path, remove=False) filenames = [] if not verified or not all(verified[x] for x in verified): filenames = globber_full(admin_path, "*.gz") if filenames: logging.debug("Repair job %s by re-parsing stored NZB", name) _, nzo_ids = sabnzbd.nzbparser.add_nzbfile( filenames[0], nzbname=name, reuse=repair_folder, password=password ) else: try: logging.debug("Repair job %s without stored NZB", name) nzo = NzbObject(name, password=password, nzbname=name, reuse=repair_folder) self.add(nzo) nzo_ids = [nzo.nzo_id] except: # NzoObject can throw exceptions if duplicate or unwanted etc logging.info("Skipping %s due to exception", name, exc_info=True) nzo_ids = [] # Return None if we could not add anything if nzo_ids: return nzo_ids[0] return None @NzbQueueLocker def send_back(self, old_nzo: NzbObject): """Send back job to queue after successful pre-check""" try: nzb_path = globber_full(old_nzo.admin_path, "*.gz")[0] except: logging.info("Failed to find NZB file after pre-check (%s)", old_nzo.nzo_id) return # Store old position and create new NZO old_position = self.__nzo_list.index(old_nzo) res, nzo_ids = process_single_nzb( old_nzo.filename, nzb_path, keep=True, reuse=old_nzo.download_path, nzo_id=old_nzo.nzo_id ) if res == 0 and nzo_ids: # Swap to old position new_nzo = self.get_nzo(nzo_ids[0]) self.__nzo_list.remove(new_nzo) self.__nzo_list.insert(old_position, new_nzo) # Reset reuse flag to make pause/abort on encryption possible self.__nzo_table[nzo_ids[0]].reuse = None @NzbQueueLocker def save(self, save_nzo: Union[NzbObject, None, bool] = None): """Save queue, all nzo's or just the specified one""" logging.info("Saving queue") nzo_ids = [] # Aggregate nzo_ids and save each nzo for nzo in self.__nzo_list[:]: if not nzo.removed_from_queue: nzo_ids.append(os.path.join(nzo.work_name, nzo.nzo_id)) if save_nzo is None or nzo is save_nzo: if not nzo.futuretype: # Also includes save_data for NZO nzo.save_to_disk() else: sabnzbd.filesystem.save_data(nzo, nzo.nzo_id, nzo.admin_path) sabnzbd.filesystem.save_admin((QUEUE_VERSION, nzo_ids, []), QUEUE_FILE_NAME) def set_top_only(self, value): self.__top_only = value def change_opts(self, nzo_ids: List[str], pp: int) -> int: result = 0 for nzo_id in nzo_ids: if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].set_pp(pp) result += 1 return result def change_script(self, nzo_ids: List[str], script: str) -> int: result = 0 if (script is None) or is_valid_script(script): for nzo_id in nzo_ids: if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].script = script logging.info("Set script=%s for job %s", script, self.__nzo_table[nzo_id].final_name) result += 1 return result def change_cat(self, nzo_ids: List[str], cat: str) -> int: result = 0 for nzo_id in nzo_ids: if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzo.cat, pp, nzo.script, prio = cat_to_opts(cat) logging.info("Set cat=%s for job %s", cat, nzo.final_name) nzo.set_pp(pp) self.set_priority([nzo_id], prio) # Abort any ongoing unpacking if the category changed nzo.abort_direct_unpacker() result += 1 return result def change_name(self, nzo_id: str, name: str, password: str = None) -> bool: if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] logging.info("Renaming %s to %s", nzo.final_name, name) # Abort any ongoing unpacking if the name changed (dirs change) nzo.abort_direct_unpacker() if not nzo.futuretype: nzo.set_final_name_and_scan_password(name, password) else: # Reset url fetch wait time nzo.url_wait = None nzo.url_tries = 0 return True else: return False def get_nzo(self, nzo_id) -> Optional[NzbObject]: if nzo_id in self.__nzo_table: return self.__nzo_table[nzo_id] else: return None @NzbQueueLocker def add(self, nzo: NzbObject, save: bool = True, quiet: bool = False) -> str: # Can already be set for future jobs if not nzo.nzo_id: nzo.nzo_id = sabnzbd.filesystem.get_new_id("nzo", nzo.admin_path, self.__nzo_table) # If no files are to be downloaded anymore, send to postproc if not nzo.files and not nzo.futuretype: self.end_job(nzo) return nzo.nzo_id # Reset try_lists, markers and evaluate the scheduling settings nzo.reset_try_list() nzo.removed_from_queue = False priority = nzo.priority if sabnzbd.Scheduler.analyse(False, priority): nzo.status = Status.PAUSED self.__nzo_table[nzo.nzo_id] = nzo if priority > HIGH_PRIORITY: # Top and repair priority items are added to the top of the queue self.__nzo_list.insert(0, nzo) elif priority == LOW_PRIORITY: self.__nzo_list.append(nzo) else: # for high priority we need to add the item at the bottom # of any other high priority items above the normal priority # for normal priority we need to add the item at the bottom # of the normal priority items above the low priority if self.__nzo_list: pos = 0 added = False for position in self.__nzo_list: if position.priority < priority: self.__nzo_list.insert(pos, nzo) added = True break pos += 1 if not added: # if there are no other items classed as a lower priority # then it will be added to the bottom of the queue self.__nzo_list.append(nzo) else: # if the queue is empty then simple append the item to the bottom self.__nzo_list.append(nzo) if save: self.save(nzo) if not (quiet or nzo.status == Status.FETCHING): notifier.send_notification(T("NZB added to queue"), nzo.filename, "download", nzo.cat) if not quiet and cfg.auto_sort(): try: field, direction = cfg.auto_sort().split() self.sort_queue(field, direction) except ValueError: pass return nzo.nzo_id @NzbQueueLocker def remove(self, nzo_id: str, cleanup: bool = True, delete_all_data: bool = True) -> Optional[NzbObject]: """Remove NZO from queue. It can be added to history directly. Or, we do some clean-up, sometimes leaving some data. """ if nzo_id in self.__nzo_table: nzo = self.__nzo_table.pop(nzo_id) logging.info("[%s] Removing job %s", caller_name(), nzo.final_name) # Set statuses nzo.removed_from_queue = True self.__nzo_list.remove(nzo) if cleanup: nzo.status = Status.DELETED nzo.purge_data(delete_all_data=delete_all_data) self.save(False) return nzo @NzbQueueLocker def remove_multiple(self, nzo_ids: List[str], delete_all_data=True) -> List[str]: """Remove multiple jobs from the queue. Also triggers duplicate handling and downloader-disconnect, so intended for external use only!""" removed = [] for nzo_id in nzo_ids: if nzo := self.remove(nzo_id, delete_all_data=delete_all_data): removed.append(nzo_id) # Start an alternative, if available self.handle_duplicate_alternatives(nzo, success=False) # Any files left? Otherwise let's disconnect if not self.actives(grabs=False) and cfg.autodisconnect(): # This was the last job, close server connections sabnzbd.Downloader.disconnect() return removed @NzbQueueLocker def remove_all(self, search: Optional[str] = None) -> List[str]: """Remove NZO's that match the search-pattern""" nzo_ids = [] search = safe_lower(search) for nzo_id, nzo in self.__nzo_table.items(): if not search or search in nzo.final_name.lower(): nzo_ids.append(nzo_id) return self.remove_multiple(nzo_ids) def remove_nzfs(self, nzo_id: str, nzf_ids: List[str]) -> List[str]: removed = [] if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] for nzf_id in nzf_ids: nzf = nzo.get_nzf_by_id(nzf_id) if nzf: removed.append(nzf_id) nzo.abort_direct_unpacker() post_done = nzo.remove_nzf(nzf) if post_done: if nzo.finished_files: self.end_job(nzo) else: self.remove(nzo_id) else: # Force-remove all trace and update counters nzo.bytes -= nzf.bytes nzo.bytes_tried -= nzf.bytes - nzf.bytes_left if nzf.is_par2 or sabnzbd.par2file.is_parfile(nzf.filename): nzo.bytes_par2 -= nzf.bytes del nzo.files_table[nzf_id] nzo.finished_files.remove(nzf) logging.info("Removed NZFs %s from job %s", removed, nzo.final_name) return removed def pause_multiple_nzo(self, nzo_ids: List[str]) -> List[str]: handled = [] for nzo_id in nzo_ids: self.pause_nzo(nzo_id) handled.append(nzo_id) return handled def pause_nzo(self, nzo_id: str) -> List[str]: handled = [] if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzo.pause() logging.info("Paused nzo: %s", nzo_id) handled.append(nzo_id) return handled def resume_multiple_nzo(self, nzo_ids: List[str]) -> List[str]: handled = [] for nzo_id in nzo_ids: self.resume_nzo(nzo_id) handled.append(nzo_id) return handled @NzbQueueLocker def resume_nzo(self, nzo_id: str) -> List[str]: handled = [] if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzo.resume() logging.info("Resumed nzo: %s", nzo_id) handled.append(nzo_id) return handled @NzbQueueLocker def switch(self, item_id_1: str, item_id_2: str) -> Tuple[int, int]: try: # Allow an index as second parameter, easier for some skins i = int(item_id_2) item_id_2 = self.__nzo_list[i].nzo_id except: pass try: nzo1 = self.__nzo_table[item_id_1] nzo2 = self.__nzo_table[item_id_2] except KeyError: # One or both jobs missing return -1, 0 if nzo1 == nzo2: return -1, 0 # get the priorities of the two items nzo1_priority = nzo1.priority nzo2_priority = nzo2.priority try: # get the item id of the item below to use in priority changing item_id_3 = self.__nzo_list[i + 1].nzo_id # if there is an item below the id1 and id2 then we need that too # to determine whether to change the priority nzo3 = self.__nzo_table[item_id_3] nzo3_priority = nzo3.priority # if id1 is surrounded by items of a different priority then change it's pririty to match if nzo2_priority != nzo1_priority and nzo3_priority != nzo1_priority or nzo2_priority > nzo1_priority: nzo1.priority = nzo2_priority except: nzo1.priority = nzo2_priority item_id_pos1 = -1 item_id_pos2 = -1 for i in range(len(self.__nzo_list)): if item_id_1 == self.__nzo_list[i].nzo_id: item_id_pos1 = i elif item_id_2 == self.__nzo_list[i].nzo_id: item_id_pos2 = i if (item_id_pos1 > -1) and (item_id_pos2 > -1): item = self.__nzo_list[item_id_pos1] logging.info( "Switching job [%s] %s => [%s] %s", item_id_pos1, item.final_name, item_id_pos2, self.__nzo_list[item_id_pos2].final_name, ) del self.__nzo_list[item_id_pos1] self.__nzo_list.insert(item_id_pos2, item) return item_id_pos2, nzo1.priority # If moving failed/no movement took place return -1, nzo1.priority @NzbQueueLocker def move_nzf_up_bulk(self, nzo_id: str, nzf_ids: List[str], size: int): if nzo_id in self.__nzo_table: for _ in range(size): self.__nzo_table[nzo_id].move_up_bulk(nzf_ids) @NzbQueueLocker def move_nzf_top_bulk(self, nzo_id: str, nzf_ids: List[str]): if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].move_top_bulk(nzf_ids) @NzbQueueLocker def move_nzf_down_bulk(self, nzo_id: str, nzf_ids: List[str], size: int): if nzo_id in self.__nzo_table: for _ in range(size): self.__nzo_table[nzo_id].move_down_bulk(nzf_ids) @NzbQueueLocker def move_nzf_bottom_bulk(self, nzo_id: str, nzf_ids: List[str]): if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].move_bottom_bulk(nzf_ids) @NzbQueueLocker def sort_queue(self, field: str, direction: Optional[str] = None): """Sort queue by field: "name", "size" or "avg_age" or by percentage remaining Direction is specified as "desc" or "asc" """ field = field.lower() reverse = False if safe_lower(direction) == "desc": reverse = True if field == "name": logging.info("Sorting by name (reversed: %s)", reverse) sort_function = lambda nzo: nzo.final_name.lower() elif field == "size" or field == "bytes": logging.info("Sorting by size (reversed: %s)", reverse) sort_function = lambda nzo: nzo.bytes elif field == "avg_age": reverse = not reverse logging.info("Sorting by average date... (reversed: %s)", reverse) sort_function = lambda nzo: nzo.avg_date elif field == "remaining": if self.__nzo_list: logging.debug("Sorting by percentage downloaded...") sort_function = lambda nzo: nzo.remaining / nzo.bytes if nzo.bytes else 1 else: logging.debug("Sort: %s not recognized", field) return # Apply sort by requested order, then restore priority ordering self.__nzo_list.sort(key=sort_function, reverse=reverse) self.__nzo_list.sort(key=lambda nzo: nzo.priority, reverse=True) def update_sort_order(self): """Resorts the queue if it is useful for the selected sort method""" auto_sort = cfg.auto_sort() if auto_sort and auto_sort.startswith("remaining"): self.sort_queue("remaining") @NzbQueueLocker def __set_priority(self, nzo_id: str, priority: Union[int, str]) -> Optional[int]: """Sets the priority on the nzo and places it in the queue at the appropriate position""" try: priority = int_conv(priority) nzo = self.__nzo_table[nzo_id] nzo_id_pos1 = -1 pos = -1 # If priority == STOP_PRIORITY, then send to queue if priority == STOP_PRIORITY: self.end_job(nzo) return # Get the current position in the queue for i in range(len(self.__nzo_list)): if nzo_id == self.__nzo_list[i].nzo_id: nzo_id_pos1 = i break # Don't change priority and order if priority is the same as asked if priority == self.__nzo_list[nzo_id_pos1].priority: return nzo_id_pos1 nzo.set_priority(priority) if sabnzbd.Scheduler.analyse(False, priority) and nzo.status in ( Status.CHECKING, Status.DOWNLOADING, Status.QUEUED, ): nzo.status = Status.PAUSED elif nzo.status == Status.PAUSED: nzo.status = Status.QUEUED nzo.save_to_disk() if nzo_id_pos1 != -1: del self.__nzo_list[nzo_id_pos1] if priority == FORCE_PRIORITY: # A top priority item (usually a completed download fetching pars) # is added to the top of the queue self.__nzo_list.insert(0, nzo) pos = 0 elif priority == LOW_PRIORITY: pos = len(self.__nzo_list) self.__nzo_list.append(nzo) else: # for high priority we need to add the item at the bottom # of any other high priority items above the normal priority # for normal priority we need to add the item at the bottom # of the normal priority items above the low priority if self.__nzo_list: p = 0 added = False for position in self.__nzo_list: if position.priority < priority: self.__nzo_list.insert(p, nzo) pos = p added = True break p += 1 if not added: # if there are no other items classed as a lower priority # then it will be added to the bottom of the queue pos = len(self.__nzo_list) self.__nzo_list.append(nzo) else: # if the queue is empty then simple append the item to the bottom self.__nzo_list.append(nzo) pos = 0 logging.info( "Set priority=%s for job %s => position=%s ", priority, self.__nzo_table[nzo_id].final_name, pos ) return pos except: return -1 @NzbQueueLocker def set_priority(self, nzo_ids: List[str], priority: int) -> int: try: n = -1 for nzo_id in nzo_ids: n = self.__set_priority(nzo_id, priority) return n except: return -1 @staticmethod def reset_try_lists(article: Article, remove_fetcher_from_trylist: bool = True): """Let article get new fetcher and reset trylists""" if remove_fetcher_from_trylist: article.remove_from_try_list(article.fetcher) article.fetcher = None article.tries = 0 article.nzf.reset_try_list() article.nzf.nzo.reset_try_list() def has_forced_jobs(self) -> bool: """Check if the queue contains any Forced Priority jobs to download while paused """ for nzo in self.__nzo_list: if nzo.priority == FORCE_PRIORITY and nzo.status not in (Status.PAUSED, Status.GRABBING): return True # Each time the priority of a job is changed the queue is sorted, so we can # assume that if we reach a job below Force priority we can continue if nzo.priority < FORCE_PRIORITY: return False return False def get_articles(self, server: Server, servers: List[Server], fetch_limit: int) -> List[Article]: """Get next article for jobs in the queue Not locked for performance, since it only reads the queue """ for nzo in self.__nzo_list: # Not when queue paused, individually paused, or when waiting for propagation # Force items will always download if ( not sabnzbd.Downloader.paused and nzo.status not in (Status.PAUSED, Status.GRABBING) and not nzo.propagation_delay_left ) or nzo.priority == FORCE_PRIORITY: if not nzo.server_in_try_list(server): if articles := nzo.get_articles(server, servers, fetch_limit): return articles # Stop after first job that wasn't paused/propagating/etc if self.__top_only: return [] return [] def register_article(self, article: Article, success: bool = True): """Register the articles we tried Not locked for performance, since it only modifies individual NZOs """ nzf = article.nzf nzo = nzf.nzo if nzo.pp_or_finished or nzf.deleted: logging.debug("Discarding article for file %s: deleted or already post-processing", nzf.filename) # If this file is needed later (par2 file added back to queue), it would be damaged because # we discard this article. So we reset it to be picked up again if needed. # But not reset all articles, as it could cause problems for articles still attached to a server. article.reset_try_list() nzf.reset_try_list() return articles_left, file_done, post_done = nzo.remove_article(article, success) # Write data if file is done or at trigger time # Skip if the file is already queued, since all available articles will then be written if ( file_done or (article.lowest_partnum and nzf.filename_checked and not nzf.import_finished) or (articles_left and (articles_left % sabnzbd.ArticleCache.assembler_write_trigger) == 0) ): if not nzo.precheck: # Only start decoding if we have a filename and type # The type is only set if sabctools could decode the article if nzf.filename and nzf.type: sabnzbd.Assembler.process(nzo, nzf, file_done) elif nzf.filename.lower().endswith(".par2"): # Broken par2 file, try to get another one nzo.promote_par2(nzf) # Save bookkeeping in case of crash if file_done and (nzo.next_save is None or time.time() > nzo.next_save): nzo.save_to_disk() sabnzbd.BPSMeter.save() if nzo.save_timeout is None: nzo.next_save = None else: nzo.next_save = time.time() + nzo.save_timeout # Remove post from Queue if post_done: nzo.set_download_report() self.end_job(nzo) @NzbQueueLocker def end_job(self, nzo: NzbObject): """Send NZO to the post-processing queue""" # Notify assembler to call postprocessor if not nzo.removed_from_queue: logging.info("[%s] Ending job %s", caller_name(), nzo.final_name) nzo.removed_from_queue = True if nzo.precheck: nzo.save_to_disk() # Check result enough, _ = nzo.check_availability_ratio() if enough: # Enough data present, do real download self.send_back(nzo) return else: # Not enough data, let postprocessor show it as failed pass sabnzbd.Assembler.process(nzo) def fail_to_history(self, nzo: NzbObject): """Fail to history, with all the steps in between""" if not nzo.nzo_id: self.add(nzo, quiet=True) self.remove(nzo.nzo_id, cleanup=False) sabnzbd.PostProcessor.process(nzo) def actives(self, grabs: bool = True) -> int: """Return amount of non-paused jobs, optionally with 'grabbing' items Not locked for performance, only reads the queue """ n = 0 for nzo in self.__nzo_list: # Ignore any items that are paused if grabs and nzo.status == Status.GRABBING: n += 1 elif nzo.status not in (Status.PAUSED, Status.GRABBING): n += 1 return n def queue_info( self, search: Optional[str] = None, categories: Optional[List[str]] = None, priorities: Optional[List[str]] = None, statuses: Optional[List[str]] = None, nzo_ids: Optional[List[str]] = None, start: int = 0, limit: int = 0, ) -> Tuple[int, int, int, List[NzbObject], int, int]: """Return list of queued jobs, optionally filtered and limited by start and limit. Not locked for performance, only reads the queue """ if search: search = search.lower() bytes_left = 0 bytes_total = 0 bytes_left_previous_page = 0 q_size = 0 nzo_list = [] nzos_matched = 0 for nzo in self.__nzo_list: if nzo.status not in (Status.PAUSED, Status.CHECKING) or nzo.priority == FORCE_PRIORITY: b_left = nzo.remaining bytes_total += nzo.bytes bytes_left += b_left q_size += 1 # We need the number of bytes before the current page if nzos_matched < start: bytes_left_previous_page += b_left # Conditions split up for readability if search and search not in nzo.final_name.lower(): continue if categories and nzo.cat not in categories: continue if priorities and nzo.priority not in priorities: continue if statuses and nzo.status not in statuses: # Propagation status is set only by the API-code, so has to be filtered specially if not (Status.PROPAGATING in statuses and nzo.propagation_delay_left): continue if nzo_ids and nzo.nzo_id not in nzo_ids: continue if not limit or start <= nzos_matched < start + limit: nzo_list.append(nzo) nzos_matched += 1 if not search and not nzo_ids: nzos_matched = len(self.__nzo_list) return bytes_total, bytes_left, bytes_left_previous_page, nzo_list, q_size, nzos_matched def remaining(self) -> int: """Return bytes left in the queue by non-paused items Not locked for performance, only reads the queue """ bytes_left = 0 for nzo in self.__nzo_list: if nzo.status != Status.PAUSED: bytes_left += nzo.remaining return bytes_left def is_empty(self) -> bool: for nzo in self.__nzo_list: if not nzo.futuretype and nzo.status != Status.PAUSED: return False return True def stop_idle_jobs(self): """Detect jobs that have zero files left and send them to post processing""" # Only check servers that are active active_servers = [server for server in sabnzbd.Downloader.servers[:] if server.active] nr_servers = len(active_servers) empty = [] if nr_servers <= 0: logging.debug("Skipping stop_idle_jobs because no servers are active") return for nzo in self.__nzo_list: if not nzo.futuretype and not nzo.files and nzo.status not in (Status.PAUSED, Status.GRABBING): logging.info("Found idle job %s", nzo.final_name) empty.append(nzo) # Stall prevention by checking if all servers are in the trylist # This is a CPU-cheaper alternative to prevent stalling if len(nzo.try_list) >= nr_servers: # Maybe the NZF's need a reset too? for nzf in nzo.files: if nzo.removed_from_queue: break if len(nzf.try_list) >= nr_servers: # Check for articles where all active servers have already been tried for article in nzf.articles[:]: if article.all_servers_in_try_list(active_servers): sabnzbd.NzbQueue.register_article(article, success=False) nzo.increase_bad_articles_counter("missing_articles") logging.info("Resetting bad trylist for file %s in job %s", nzf.filename, nzo.final_name) nzf.reset_try_list() # Reset main trylist, minimal performance impact logging.info("Resetting bad trylist for job %s", nzo.final_name) nzo.reset_try_list() for nzo in empty: self.end_job(nzo) def pause_on_prio(self, priority: int): for nzo in self.__nzo_list: if nzo.priority == priority: nzo.pause() @NzbQueueLocker def resume_on_prio(self, priority: int): for nzo in self.__nzo_list: if nzo.priority == priority: # Don't use nzo.resume() to avoid resetting job warning flags nzo.status = Status.QUEUED def pause_on_cat(self, cat: str): for nzo in self.__nzo_list: if nzo.cat == cat: nzo.pause() @NzbQueueLocker def resume_on_cat(self, cat: str): for nzo in self.__nzo_list: if nzo.cat == cat: # Don't use nzo.resume() to avoid resetting job warning flags nzo.status = Status.QUEUED def get_urls(self) -> List[Tuple[str, NzbObject]]: """Return list of future-types needing URL""" lst = [] for nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] if nzo.futuretype: url = nzo.url if nzo.futuretype and url.lower().startswith("http"): lst.append((url, nzo)) return lst @NzbQueueLocker def have_name_or_md5sum(self, name: str, md5sum: str) -> bool: """Check whether this name or md5sum is already in the queue or the post-processing queue""" lname = name.lower() for nzo in self.__nzo_list + sabnzbd.PostProcessor.get_queue(): # Skip any jobs already marked as duplicate, to prevent double-triggers # URL's do not have an MD5! if not nzo.duplicate and ( nzo.final_name.lower() == lname or (nzo.md5sum and md5sum and nzo.md5sum == md5sum) ): return True return False @NzbQueueLocker def have_duplicate_key(self, duplicate_key: str) -> bool: """Check whether this duplicate key is already in the queue or the post-processing queue""" for nzo in self.__nzo_list + sabnzbd.PostProcessor.get_queue(): # Skip any jobs already marked as duplicate, to prevent double-triggers if not nzo.duplicate and nzo.duplicate_key == duplicate_key: return True return False @NzbQueueLocker def handle_duplicate_alternatives(self, finished_nzo: NzbObject, success: bool): """Remove matching duplicates if the first job succeeded, or start the next alternative if the job failed""" if not cfg.no_dupes() and not cfg.no_smart_dupes(): return # Unfortunately we need a copy, since we might remove items from the list for nzo in self.__nzo_list[:]: if not nzo.duplicate or nzo.duplicate == DuplicateStatus.DUPLICATE_IGNORED: continue # URL's do not have an MD5! if ( nzo.final_name.lower() == finished_nzo.final_name.lower() or (nzo.md5sum and finished_nzo.md5sum and nzo.md5sum == finished_nzo.md5sum) ) or (nzo.duplicate_key and finished_nzo.duplicate_key and nzo.duplicate_key == finished_nzo.duplicate_key): # Start the next alternative if not success: # Don't just resume if only set to tag if (nzo.duplicate == DuplicateStatus.DUPLICATE_ALTERNATIVE and cfg.no_dupes() != 4) or ( nzo.duplicate == DuplicateStatus.SMART_DUPLICATE_ALTERNATIVE and cfg.no_smart_dupes() != 4 ): logging.info("Resuming duplicate alternative %s for ", nzo.final_name, finished_nzo.final_name) nzo.resume() nzo.duplicate = None return # Take action on the alternatives to the duplicate # 1 = Discard # 2 = Pause # 3 = Fail (move to History) # 4 = Tag smart_duplicate = nzo.duplicate == DuplicateStatus.SMART_DUPLICATE_ALTERNATIVE if (not smart_duplicate and cfg.no_dupes() == 1) or (smart_duplicate and cfg.no_smart_dupes() == 1): duplicate_warning(T('Ignoring duplicate NZB "%s"'), nzo.final_name) self.remove(nzo.nzo_id) elif (not smart_duplicate and cfg.no_dupes() == 3) or (smart_duplicate and cfg.no_smart_dupes() == 3): duplicate_warning(T('Failing duplicate NZB "%s"'), nzo.final_name) nzo.fail_msg = T("Duplicate NZB") self.fail_to_history(nzo) else: # Action set to Pause or Tag, so only adjust the label on the first matching job logging.info("Re-tagging duplicate alternative %s for %s", nzo.final_name, finished_nzo.final_name) if nzo.duplicate == DuplicateStatus.DUPLICATE_ALTERNATIVE: nzo.duplicate = DuplicateStatus.DUPLICATE else: nzo.duplicate = DuplicateStatus.SMART_DUPLICATE return def __repr__(self): return "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4487557 SABnzbd-4.3.2/sabnzbd/emailer.py0000644000000000000000000002363714625637243015651 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.emailer - Send notification emails """ import smtplib import logging import re import time import glob import os from Cheetah.Template import Template from email.message import EmailMessage import sabnzbd from sabnzbd.constants import DEF_EMAIL_TMPL, CHEETAH_DIRECTIVES from sabnzbd.misc import to_units, split_host, time_format from sabnzbd.notifier import check_cat import sabnzbd.cfg as cfg RE_HEADER = re.compile(r"^([^:]+):(.*)") def errormsg(msg): logging.error(msg) return msg def get_email_date(): """Return un-localized date string for the Date: field""" # Get locale independent date/time string: "Sun May 22 20:15:12 2011" day, month, dayno, hms, year = time.asctime(time.gmtime()).split() return "%s, %s %s %s %s +0000" % (day, dayno, month, year, hms) def send_email(message, email_to, test=None): """Send message if message non-empty and email-parms are set""" # we should not use CFG if we are testing. we should use values # from UI instead. # email_to is replaced at send_with_template, since it can be an array if test: email_server = test.get("email_server") email_from = test.get("email_from") email_account = test.get("email_account") email_pwd = test.get("email_pwd") if email_pwd and not email_pwd.replace("*", ""): # If all stars, get stored password instead email_pwd = cfg.email_pwd() else: email_server = cfg.email_server() email_from = cfg.email_from() email_account = cfg.email_account() email_pwd = cfg.email_pwd() if not message.strip("\n\r\t "): return "Skipped empty message" # Prepare the email email_message = _prepare_message(message) if email_server and email_to and email_from: server, port = split_host(email_server) if not port: port = 25 logging.debug("Connecting to server %s:%s", server, port) try: mailconn = smtplib.SMTP_SSL(server, port) mailconn.ehlo() logging.debug("Connected to server %s:%s", server, port) except: # Non SSL mail server logging.debug("Non-SSL mail server detected reconnecting to server %s:%s", server, port) try: mailconn = smtplib.SMTP(server, port) mailconn.ehlo() except: logging.info("Traceback: ", exc_info=True) return errormsg(T("Failed to connect to mail server")) # TLS support if mailconn.ehlo_resp and re.search(b"STARTTLS", mailconn.ehlo_resp, re.IGNORECASE): logging.debug("TLS mail server detected") try: mailconn.starttls() mailconn.ehlo() except: logging.info("Traceback: ", exc_info=True) return errormsg(T("Failed to initiate TLS connection")) # Authentication if (email_account != "") and (email_pwd != ""): try: mailconn.login(email_account, email_pwd) except smtplib.SMTPHeloError: return errormsg(T("The server didn't reply properly to the helo greeting")) except smtplib.SMTPAuthenticationError: return errormsg(T("Failed to authenticate to mail server")) except smtplib.SMTPException: return errormsg(T("No suitable authentication method was found")) except: logging.info("Traceback: ", exc_info=True) return errormsg(T("Unknown authentication failure in mail server")) try: mailconn.sendmail(email_from, email_to, email_message) msg = None except smtplib.SMTPHeloError: msg = errormsg("The server didn't reply properly to the helo greeting.") except smtplib.SMTPRecipientsRefused: msg = errormsg("The server rejected ALL recipients (no mail was sent).") except smtplib.SMTPSenderRefused: msg = errormsg("The server didn't accept the from_addr.") except smtplib.SMTPDataError: msg = errormsg("The server replied with an unexpected error code (other than a refusal of a recipient).") except: logging.info("Traceback: ", exc_info=True) msg = errormsg(T("Failed to send e-mail")) try: mailconn.close() except: logging.info("Traceback: ", exc_info=True) errormsg(T("Failed to close mail connection")) if msg: return msg else: logging.info("Notification e-mail successfully sent") return T("Email succeeded") else: return T("Cannot send, missing required data") def send_with_template(prefix, parm, test=None): """Send an email using template""" parm["from"] = cfg.email_from() parm["date"] = get_email_date() ret = None email_templates = [] path = cfg.email_dir.get_path() if path and os.path.exists(path): try: email_templates = glob.glob(os.path.join(path, "%s-*.tmpl" % prefix)) except: logging.error(T("Cannot find email templates in %s"), path) else: path = os.path.join(sabnzbd.DIR_PROG, DEF_EMAIL_TMPL) tpath = os.path.join(path, "%s-%s.tmpl" % (prefix, cfg.language())) if os.path.exists(tpath): email_templates = [tpath] else: email_templates = [os.path.join(path, "%s-en.tmpl" % prefix)] for template_file in email_templates: logging.debug("Trying to send email using template %s", template_file) if os.access(template_file, os.R_OK): if test: recipients = [test.get("email_to")] else: recipients = cfg.email_to() if len(recipients): for recipient in recipients: # Force-open as UTF-8, otherwise Cheetah breaks it with open(template_file, "r", encoding="utf-8") as template_fp: parm["to"] = recipient message = Template(file=template_fp, searchList=[parm], compilerSettings=CHEETAH_DIRECTIVES) ret = send_email(message.respond(), recipient, test) else: ret = T("No recipients given, no email sent") else: # Can't open or read file, stop return errormsg(T("Cannot read %s") % template_file) # Did we send any emails at all? if not ret: ret = T("No email templates found") return ret def endjob( filename, cat, status, path, bytes_downloaded, fail_msg, stages, script, script_output, script_ret, test=None ): """Send end-of-job email""" # Is it allowed? if not check_cat("misc", cat, keyword="email") and not test: return None # Translate the stage names tr = sabnzbd.api.Ttemplate if not status and fail_msg: xstages = {tr("stage-fail"): (fail_msg,)} else: xstages = {} for stage in stages: lines = [] for line in stages[stage]: if "\n" in line or "
" in line: lines.extend(line.replace("
", "\n").split("\n")) else: lines.append(line) xstages[tr("stage-" + stage.lower())] = lines parm = {} parm["status"] = status parm["name"] = filename parm["path"] = path parm["msgid"] = "" parm["stages"] = xstages parm["script"] = script parm["script_output"] = script_output parm["script_ret"] = script_ret parm["cat"] = cat parm["size"] = "%sB" % to_units(bytes_downloaded) parm["end_time"] = time.strftime(time_format("%Y-%m-%d %H:%M:%S")) return send_with_template("email", parm, test) def rss_mail(feed, jobs): """Send notification email containing list of files""" parm = {"amount": len(jobs), "feed": feed, "jobs": jobs} return send_with_template("rss", parm) def badfetch_mail(msg, url): """Send notification email about failed NZB fetch""" parm = {"url": url, "msg": msg} return send_with_template("badfetch", parm) def diskfull_mail(): """Send email about disk full, no templates""" if cfg.email_full(): return send_email( T( """To: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. """ ) % (cfg.email_to.get_string(), cfg.email_from(), get_email_date()), cfg.email_to(), ) else: return "" def _prepare_message(txt): """Parse the headers in the template to real headers""" msg = EmailMessage() payload = [] body = False header = False for line in txt.split("\n"): if header and not line: body = True if body: payload.append(line) elif m := RE_HEADER.search(line): # If we match a header header = True keyword = m.group(1).strip() value = m.group(2).strip() msg[keyword] = value msg.set_content("\n".join(payload)) return msg.as_bytes(policy=msg.policy.clone(linesep="\r\n")) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4488273 SABnzbd-4.3.2/sabnzbd/getipaddress.py0000644000000000000000000001270314625637243016701 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.getipaddress """ import functools import logging import socket import time import urllib.error import urllib.request from typing import Callable import socks import sabnzbd import sabnzbd.cfg from sabnzbd.encoding import ubtou from sabnzbd.happyeyeballs import happyeyeballs, family_type def timeout(max_timeout: float): """Timeout decorator, parameter in seconds.""" def timeout_decorator(item: Callable) -> Callable: """Wrap the original function.""" @functools.wraps(item) def func_wrapper(*args, **kwargs): """Closure for function.""" # Raises a TimeoutError if execution exceeds max_timeout # Raises a RuntimeError is SABnzbd is already shutting down when called try: return sabnzbd.THREAD_POOL.submit(item, *args, **kwargs).result(max_timeout) except (TimeoutError, RuntimeError): return None return func_wrapper return timeout_decorator @timeout(3.0) def addresslookup(myhost): return socket.getaddrinfo(myhost, 80) @timeout(3.0) def addresslookup4(myhost): return socket.getaddrinfo(myhost, 80, socket.AF_INET) @timeout(3.0) def addresslookup6(myhost): return socket.getaddrinfo(myhost, 80, socket.AF_INET6) def active_socks5_proxy(): """Return the active proxy""" if socket.socket == socks.socksocket: return "%s:%s" % socks.socksocket.default_proxy[1:3] return None def dnslookup(): """Perform a basic DNS lookup""" start = time.time() try: addresslookup(sabnzbd.cfg.selftest_host()) result = True except: result = False logging.debug("DNS Lookup = %s (in %.2f seconds)", result, time.time() - start) return result def local_ipv4(): try: with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s_ipv4: # Option: use 100.64.1.1 (IANA-Reserved IPv4 Prefix for Shared Address Space) s_ipv4.connect(("10.255.255.255", 80)) ipv4 = s_ipv4.getsockname()[0] except socket.error: ipv4 = None logging.debug("Local IPv4 address = %s", ipv4) return ipv4 def public_ip(family=socket.AF_UNSPEC): """ Reports the client's public IP address (IPv4 or IPv6, if specified by family), as reported by selftest host """ start = time.time() if resolvehostaddress := happyeyeballs(sabnzbd.cfg.selftest_host(), port=443, family=family): resolvehostip = resolvehostaddress.ipaddress else: logging.debug("Error resolving my IP address: resolvehost not found") return None if sabnzbd.misc.is_ipv4_addr(resolvehostip): resolveurl = f"http://{resolvehostip}/?ipv4test" elif sabnzbd.misc.is_ipv6_addr(resolvehostip): resolveurl = f"http://[{resolvehostip}]/?ipv6test" # including square brackets else: logging.debug("Error resolving public IP address: no valid IPv4 or IPv6 address found") return None try: req = urllib.request.Request(resolveurl) req.add_header("Host", sabnzbd.cfg.selftest_host()) req.add_header("User-Agent", "SABnzbd/%s" % sabnzbd.__version__) with urllib.request.urlopen(req, timeout=2) as open_req: client_ip = ubtou(open_req.read().strip()) # Make sure it's a valid IPv4 or IPv6 address if not sabnzbd.misc.is_ipv4_addr(client_ip) and not sabnzbd.misc.is_ipv6_addr(client_ip): raise ValueError except: logging.debug( "Failed to get public address from %s (%s)", sabnzbd.cfg.selftest_host(), family_type(family), exc_info=True, ) return None # If text is updated, make sure to update log-anonymization logging.debug("Public address %s = %s (in %.2f seconds)", family_type(family), client_ip, time.time() - start) return client_ip def public_ipv4(): return public_ip(family=socket.AF_INET) def local_ipv6(): """ return IPv6 address on local LAN interface. So a first check if there is IPv6 connectivity """ try: with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s_ipv6: # IPv6 prefix for documentation purpose s_ipv6.connect(("2001:db8::8080", 80)) ipv6_address = s_ipv6.getsockname()[0] except: ipv6_address = None # If text is updated, make sure to update log-anonymization logging.debug("Local IPv6 address = %s", ipv6_address) return ipv6_address def public_ipv6(): if local_address := local_ipv6(): if public_address := public_ip(family=socket.AF_INET6): return public_address elif not sabnzbd.misc.is_lan_addr(local_address): return local_address ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4489048 SABnzbd-4.3.2/sabnzbd/scheduler.py0000644000000000000000000004657114625637243016213 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.scheduler - Event Scheduler """ import random import logging import time from typing import Optional import sabnzbd.utils.kronos as kronos import sabnzbd.downloader import sabnzbd.misc import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.filesystem import diskspace from sabnzbd.constants import LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY DAILY_RANGE = list(range(1, 8)) class Scheduler: def __init__(self): self.scheduler = kronos.ThreadedScheduler() self.pause_end: Optional[float] = None # Moment when pause will end self.resume_task: Optional[kronos.Task] = None self.restart_scheduler = False self.pp_pause_event = False self.load_schedules() def start(self): """Start the scheduler""" self.scheduler.start() def stop(self): """Stop the scheduler, destroy instance""" logging.debug("Stopping scheduler") self.scheduler.stop() def restart(self, plan_restart=True): """Stop and start scheduler""" if plan_restart: self.restart_scheduler = True elif self.restart_scheduler: logging.debug("Restarting scheduler") self.restart_scheduler = False self.scheduler.stop() self.scheduler.start() self.analyse(sabnzbd.Downloader.paused) self.load_schedules() def abort(self): """Emergency stop, just set the running attribute false so we don't have to wait the full scheduler-check cycle before it really stops""" self.scheduler.running = False def is_alive(self): """Thread-like check if we are doing fine""" if self.scheduler.thread: return self.scheduler.thread.is_alive() return False def load_schedules(self): rss_planned = False for schedule in cfg.schedules(): arguments = [] argument_list = None try: enabled, m, h, d, action_name = schedule.split() except: try: enabled, m, h, d, action_name, argument_list = schedule.split(None, 5) except: continue # Bad schedule, ignore if argument_list: arguments = argument_list.split() action_name = action_name.lower() try: m = int(m) h = int(h) except: logging.warning(T("Bad schedule %s at %s:%s"), action_name, m, h) continue if d.isdigit(): d = [int(i) for i in d] else: d = DAILY_RANGE if action_name == "resume": action = self.scheduled_resume arguments = [] elif action_name == "pause": action = sabnzbd.Downloader.pause arguments = [] elif action_name == "pause_all": action = sabnzbd.downloader.pause_all arguments = [] elif action_name == "shutdown": action = sabnzbd.shutdown_program arguments = [] elif action_name == "restart": action = restart_program arguments = [] elif action_name == "pause_post": action = pp_pause elif action_name == "resume_post": action = pp_resume elif action_name == "speedlimit" and arguments != []: action = sabnzbd.Downloader.limit_speed elif action_name == "enable_server" and arguments != []: action = enable_server elif action_name == "disable_server" and arguments != []: action = disable_server elif action_name == "scan_folder": action = sabnzbd.DirScanner.scan elif action_name == "rss_scan": action = sabnzbd.RSSReader.run rss_planned = True elif action_name == "create_backup": action = sabnzbd.config.create_config_backup elif action_name == "remove_failed": action = sabnzbd.api.history_remove_failed elif action_name == "remove_completed": action = sabnzbd.api.history_remove_completed elif action_name == "enable_quota": action = sabnzbd.BPSMeter.set_status arguments = [True] elif action_name == "disable_quota": action = sabnzbd.BPSMeter.set_status arguments = [False] elif action_name == "pause_all_low": action = sabnzbd.NzbQueue.pause_on_prio arguments = [LOW_PRIORITY] elif action_name == "pause_all_normal": action = sabnzbd.NzbQueue.pause_on_prio arguments = [NORMAL_PRIORITY] elif action_name == "pause_all_high": action = sabnzbd.NzbQueue.pause_on_prio arguments = [HIGH_PRIORITY] elif action_name == "resume_all_low": action = sabnzbd.NzbQueue.resume_on_prio arguments = [LOW_PRIORITY] elif action_name == "resume_all_normal": action = sabnzbd.NzbQueue.resume_on_prio arguments = [NORMAL_PRIORITY] elif action_name == "resume_all_high": action = sabnzbd.NzbQueue.resume_on_prio arguments = [HIGH_PRIORITY] elif action_name == "pause_cat": action = sabnzbd.NzbQueue.pause_on_cat arguments = [argument_list] elif action_name == "resume_cat": action = sabnzbd.NzbQueue.resume_on_cat arguments = [argument_list] else: logging.warning(T("Unknown action: %s"), action_name) continue if enabled == "1": logging.info("Scheduling %s(%s) on days %s at %02d:%02d", action_name, arguments, d, h, m) self.scheduler.add_daytime_task(action, action_name, d, None, (h, m), args=arguments) else: logging.debug("Skipping %s(%s) on days %s at %02d:%02d", action_name, arguments, d, h, m) # Set RSS check interval if not rss_planned: interval = cfg.rss_rate() delay = random.randint(0, interval - 1) logging.info("Scheduling RSS interval task every %s min (delay=%s)", interval, delay) sabnzbd.RSSReader.next_run = time.time() + delay * 60 self.scheduler.add_interval_task(sabnzbd.RSSReader.run, "RSS", delay * 60, interval * 60) self.scheduler.add_single_task(sabnzbd.RSSReader.run, "RSS", 15) if cfg.version_check(): # Check for new release daily at a random time m = random.randint(0, 59) h = random.randint(0, 23) logging.info("Scheduling version check in 10 minutes and daily at %s:%s", h, m) self.scheduler.add_single_task(sabnzbd.misc.check_latest_version, "version_check", 10 * 60) self.scheduler.add_daytime_task( sabnzbd.misc.check_latest_version, "recurring_version_check", DAILY_RANGE, None, (h, m), ) action, hour, minute = sabnzbd.BPSMeter.get_quota() if action: logging.info("Setting schedule for quota check daily at %s:%s", hour, minute) self.scheduler.add_daytime_task(action, "quota_reset", DAILY_RANGE, None, (hour, minute)) logging.info("Setting schedule for midnight auto history-purge") self.scheduler.add_daytime_task( sabnzbd.database.scheduled_history_purge, "midnight_history_purge", DAILY_RANGE, None, (0, 0), ) logging.info("Setting schedule for midnight BPS reset") self.scheduler.add_daytime_task( sabnzbd.BPSMeter.update, "midnight_bps", DAILY_RANGE, None, (0, 0), ) logging.info("Setting schedule for midnight server expiration check") self.scheduler.add_daytime_task( sabnzbd.downloader.check_server_expiration, "check_server_expiration", DAILY_RANGE, None, (0, 0), ) logging.info("Setting schedule for server quota check") self.scheduler.add_interval_task( sabnzbd.downloader.check_server_quota, "check_server_quota", 0, 10 * 60, ) # Subscribe to special schedule changes cfg.rss_rate.callback(self.scheduler_restart_guard) def analyse(self, was_paused=False, priority=None): """Determine what pause/resume state we would have now. 'priority': evaluate only effect for given priority, return True for paused """ self.pp_pause_event = False paused = None paused_all = False pause_post = False pause_low = pause_normal = pause_high = False speedlimit = None quota = True servers = {} for ev in sort_schedules(all_events=True): if priority is None: logging.debug("Schedule check result = %s", ev) # Skip if disabled if ev[4] == "0": continue action = ev[1] try: value = ev[2] except: value = None if action == "pause": paused = True elif action == "pause_all": paused_all = True self.pp_pause_event = True elif action == "resume": paused = False paused_all = False elif action == "pause_post": pause_post = True self.pp_pause_event = True elif action == "resume_post": pause_post = False self.pp_pause_event = True elif action == "speedlimit" and value is not None: speedlimit = ev[2] elif action == "pause_all_low": pause_low = True elif action == "pause_all_normal": pause_normal = True elif action == "pause_all_high": pause_high = True elif action == "resume_all_low": pause_low = False elif action == "resume_all_normal": pause_normal = False elif action == "resume_all_high": pause_high = False elif action == "enable_quota": quota = True elif action == "disable_quota": quota = False elif action == "enable_server": try: servers[value] = 1 except: logging.warning(T("Schedule for non-existing server %s"), value) elif action == "disable_server": try: servers[value] = 0 except: logging.warning(T("Schedule for non-existing server %s"), value) # Special case, a priority was passed, so evaluate only that and return state if priority == LOW_PRIORITY: return pause_low if priority == NORMAL_PRIORITY: return pause_normal if priority == HIGH_PRIORITY: return pause_high if priority is not None: return False # Normal analysis if not was_paused: if paused_all: sabnzbd.downloader.pause_all() else: sabnzbd.downloader.unpause_all() sabnzbd.Downloader.set_paused_state(paused or paused_all) sabnzbd.PostProcessor.paused = pause_post if speedlimit is not None: sabnzbd.Downloader.limit_speed(speedlimit) sabnzbd.BPSMeter.set_status(quota, action=False) for serv in servers: try: item = config.get_config("servers", serv) value = servers[serv] if bool(item.enable()) != bool(value): item.enable.set(value) sabnzbd.Downloader.init_server(serv, serv) except: pass config.save_config() def scheduler_restart_guard(self): """Set flag for scheduler restart""" self.restart_scheduler = True def scheduled_resume(self): """Scheduled resume, only when no oneshot resume is active""" if self.pause_end is None: sabnzbd.downloader.unpause_all() def __oneshot_resume(self, when): """Called by delayed resume schedule Only resumes if call comes at the planned time """ if self.pause_end is not None and (when > self.pause_end - 5) and (when < self.pause_end + 55): self.pause_end = None logging.debug("Resume after pause-interval") sabnzbd.downloader.unpause_all() else: logging.debug("Ignoring cancelled resume") def plan_resume(self, interval): """Set a scheduled resume after the interval""" if interval > 0: self.pause_end = time.time() + (interval * 60) logging.debug("Schedule resume at %s", self.pause_end) self.scheduler.add_single_task(self.__oneshot_resume, "", interval * 60, args=[self.pause_end]) sabnzbd.Downloader.pause() else: self.pause_end = None sabnzbd.downloader.unpause_all() def __check_diskspace(self, full_dir: str, required_space: float): """Resume if there is sufficient available space""" if not cfg.fulldisk_autoresume(): self.cancel_resume_task() return disk_free = diskspace(force=True)[full_dir][1] if disk_free > required_space: logging.info("Resuming, %s has %d GB free, needed %d GB", full_dir, disk_free, required_space) sabnzbd.Downloader.resume() else: logging.info("%s has %d GB free, need %d GB to resume", full_dir, disk_free, required_space) # Remove scheduled task if user manually resumed or we auto-resumed if not sabnzbd.Downloader.paused: self.cancel_resume_task() def plan_diskspace_resume(self, full_dir: str, required_space: float): """Create regular check for free disk space""" self.cancel_resume_task() logging.info("Will resume when %s has more than %d GB free space", full_dir, required_space) self.resume_task = self.scheduler.add_interval_task( self.__check_diskspace, "check_diskspace", 5 * 60, 9 * 60, "threaded", args=[full_dir, required_space] ) def plan_required_server_resume(self, interval: int = 5): """Create task for resuming downloading""" if not sabnzbd.Downloader.paused: self.plan_resume(interval) def cancel_resume_task(self): """Cancel the current auto resume task""" if self.resume_task: logging.debug("Cancelling existing resume_task '%s'", self.resume_task.name) self.scheduler.cancel(self.resume_task) self.resume_task = None def pause_int(self) -> str: """Return minutes:seconds until pause ends""" if self.pause_end is None: return "0" else: val = self.pause_end - time.time() if val < 0: sign = "-" val = abs(val) else: sign = "" mins = int(val / 60) sec = int(val - mins * 60) return "%s%d:%02d" % (sign, mins, sec) def pause_check(self): """Unpause when time left is negative, compensate for missed schedule""" if self.pause_end is not None and (self.pause_end - time.time()) < 0: self.pause_end = None logging.debug("Force resume, negative timer") sabnzbd.downloader.unpause_all() def plan_server(self, action, parms, interval): """Plan to re-activate server after 'interval' minutes""" self.scheduler.add_single_task(action, "", interval * 60, args=parms) def force_rss(self): """Add a one-time RSS scan, one second from now""" self.scheduler.add_single_task(sabnzbd.RSSReader.run, "RSS", 1) def sort_schedules(all_events, now=None): """Sort the schedules, based on order of happening from now `all_events=True`: Return an event for each active day `all_events=False`: Return only first occurring event of the week `now` : for testing: simulated localtime() """ day_min = 24 * 60 week_min = 7 * day_min events = [] now = now or time.localtime() now_hm = now[3] * 60 + now[4] now = now[6] * day_min + now_hm for schedule in cfg.schedules(): parms = None try: # Note: the last parameter can have spaces (category name)! enabled, m, h, dd, action, parms = schedule.split(None, 5) except: try: enabled, m, h, dd, action = schedule.split(None, 4) except: continue # Bad schedule, ignore action = action.strip() if dd == "*": dd = "1234567" if not dd.isdigit(): continue # Bad schedule, ignore for d in dd: then = (int(d) - 1) * day_min + int(h) * 60 + int(m) dif = then - now if all_events and dif < 0: # Expired event will occur again after a week dif = dif + week_min events.append((dif, action, parms, schedule, enabled)) if not all_events: break events.sort(key=lambda x: x[0]) return events def pp_pause(): sabnzbd.PostProcessor.paused = True def pp_resume(): sabnzbd.PostProcessor.paused = False def enable_server(server): """Enable server (scheduler only)""" try: config.get_config("servers", server).enable.set(1) except: logging.warning(T("Trying to set status of non-existing server %s"), server) return config.save_config() sabnzbd.Downloader.update_server(server, server) def disable_server(server): """Disable server (scheduler only)""" try: config.get_config("servers", server).enable.set(0) except: logging.warning(T("Trying to set status of non-existing server %s"), server) return config.save_config() sabnzbd.Downloader.update_server(server, server) def restart_program(): """Restart program (used by scheduler)""" logging.info("Scheduled restart request") # Just set the stop flag, because stopping CherryPy from # the scheduler is not reliable sabnzbd.TRIGGER_RESTART = True ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4490116 SABnzbd-4.3.2/sabnzbd/deobfuscate_filenames.py0000644000000000000000000003130414625637243020530 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ Deobfuscation post-processing script: Will check in the completed job folder if maybe there are par2 files, for example "rename.par2", and use those to rename the files. If there is no "rename.par2" available, it will rename large, not-excluded files to the job-name in the queue if the filename looks obfuscated Based on work by P1nGu1n """ import hashlib import logging import os import re import sabnzbd from sabnzbd.filesystem import get_unique_filename, renamer, get_ext, get_basename from sabnzbd.par2file import is_parfile, parse_par2_file import sabnzbd.utils.file_extension as file_extension from sabnzbd.misc import match_str from sabnzbd.constants import IGNORED_MOVIE_FOLDERS from typing import List # Files to exclude and minimal file size for renaming EXCLUDED_FILE_EXTS = (".vob", ".rar", ".par2", ".mts", ".m2ts", ".cpi", ".clpi", ".mpl", ".mpls", ".bdm", ".bdmv") MIN_FILE_SIZE = 10 * 1024 * 1024 def decode_par2(parfile: str) -> List[str]: """Parse a par2 file and rename files listed in the par2 to their real name. Return list of generated files""" # Check if really a par2 file if not is_parfile(parfile): logging.info("Par2 file %s was not really a par2 file") return [] # Parse the par2 file md5of16k = {} parse_par2_file(parfile, md5of16k) # Parse all files in the folder dirname = os.path.dirname(parfile) new_files = [] # list of new files generated for fn in os.listdir(dirname): filepath = os.path.join(dirname, fn) # Only check files if os.path.isfile(filepath): with open(filepath, "rb") as fileToMatch: first16k_data = fileToMatch.read(16384) # Check if we have this hash and the filename is different file_md5of16k = hashlib.md5(first16k_data).digest() if file_md5of16k in md5of16k and fn != md5of16k[file_md5of16k]: new_path = os.path.join(dirname, md5of16k[file_md5of16k]) # Make sure it's a unique name unique_filename = get_unique_filename(new_path) renamer(filepath, unique_filename) new_files.append(unique_filename) return new_files def recover_par2_names(filelist: List[str]) -> List[str]: """Find par2 files and use them for renaming""" # Check that files exists filelist = [f for f in filelist if os.path.isfile(f)] # Search for par2 files in the filelist par2_files = [f for f in filelist if f.endswith(".par2")] # Found any par2 files we can use? if not par2_files: logging.debug("No additional par2 files found to process") else: # Run par2 from SABnzbd on them for par2_file in par2_files: # Analyse data and analyse result logging.debug("Deobfuscate par2: handling %s", par2_file) new_files = decode_par2(par2_file) if new_files: logging.debug("Deobfuscate par2 repair/verify finished") filelist += new_files filelist = [f for f in filelist if os.path.isfile(f)] else: logging.debug("Deobfuscate par2 repair/verify did not find anything to rename") return filelist def is_probably_obfuscated(myinputfilename: str) -> bool: """Returns boolean if filename is likely obfuscated. Default: True, so obfuscated myinputfilename (string) can be a plain file name, or a full path""" # Find filebasename path, filename = os.path.split(myinputfilename) filebasename, fileextension = os.path.splitext(filename) logging.debug("Checking: %s", filebasename) # First: the patterns that are certainly obfuscated: # ...blabla.H.264/b082fa0beaa644d3aa01045d5b8d0b36.mkv is certainly obfuscated if re.findall(r"^[a-f0-9]{32}$", filebasename): logging.debug("Obfuscated: 32 hex digit") # exactly 32 hex digits, so: return True # 0675e29e9abfd2.f7d069dab0b853283cc1b069a25f82.6547 if re.findall(r"^[a-f0-9.]{40,}$", filebasename): logging.debug("Obfuscated: starting with 40+ lower case hex digits and/or dots") return True # "[BlaBla] something [More] something 5937bc5e32146e.bef89a622e4a23f07b0d3757ad5e8a.a02b264e [Brrr]" # So: square brackets plus 30+ hex digit if re.findall(r"[a-f0-9]{30}", filebasename) and len(re.findall(r"\[\w+\]", filebasename)) >= 2: logging.debug("Obfuscated: square brackets plus a 30+ hex") return True # /some/thing/abc.xyz.a4c567edbcbf27.BLA is certainly obfuscated if re.findall(r"^abc\.xyz", filebasename): logging.debug("Obfuscated: starts with 'abc.xyz'") # ... which we consider as obfuscated: return True # Then: patterns that are not obfuscated but typical, clear names: # these are signals for the obfuscation versus non-obfuscation decimals = sum(1 for c in filebasename if c.isnumeric()) upperchars = sum(1 for c in filebasename if c.isupper()) lowerchars = sum(1 for c in filebasename if c.islower()) spacesdots = sum(1 for c in filebasename if c == " " or c == "." or c == "_") # space-like symbols # Example: "Great Distro" if upperchars >= 2 and lowerchars >= 2 and spacesdots >= 1: logging.debug("Not obfuscated: upperchars >= 2 and lowerchars >= 2 and spacesdots >= 1") return False # Example: "this is a download" if spacesdots >= 3: logging.debug("Not obfuscated: spacesdots >= 3") return False # Example: "Beast 2020" if (upperchars + lowerchars >= 4) and decimals >= 4 and spacesdots >= 1: logging.debug("Not obfuscated: (upperchars + lowerchars >= 4) and decimals > 3 and spacesdots > 1") return False # Example: "Catullus", starts with a capital, and most letters are lower case if filebasename[0].isupper() and lowerchars > 2 and upperchars / lowerchars <= 0.25: logging.debug("Not obfuscated: starts with a capital, and most letters are lower case") return False # Finally: default to obfuscated: logging.debug("Obfuscated (default)") return True # default is obfuscated def first_file_is_much_bigger(filelist): # returns True if first file is much bigger than second file # Note: input parameter filelist must ordered on size! try: factor = os.path.getsize(filelist[0]) / os.path.getsize(filelist[1]) if factor > 3: return True else: return False except: # no second file at all return True def deobfuscate(nzo, filelist: List[str], usefulname: str): """ For files in filelist: 1. if a file has no meaningful extension, add it (for example ".txt" or ".png") 2. pick biggest file (and its lookalikes), and deobfuscate (if needed), to usefulname Typical cases for step 2: Case 1: bla.iso (1000MB, so much bigger than next biggest file) bla-sample.iso (100MB) bla.txt (1MB) something.txt (1MB) Because "bla" (of biggest file bla.iso) looks meaningless / obfuscated, we rename these files to Nice_Name_1234.iso Nice_Name_1234-sample.iso Nice_Name_1234.txt something.txt (no renaming) Case 2: one.bin (10MB) two.bin (12MB) three.bin (8MB) No renaming, because the biggest file (12MB) is not much bigger than the second biggest file (10MB) Case 3: Great_File_1969.iso (1000MB) No renaming because the filename looks OK already (not obfuscated) """ # Can't be imported directly due to circular import nzo: sabnzbd.nzbstuff.NzbObject # to be sure, only keep really existing files and remove any duplicates: filelist = set(f for f in filelist if os.path.isfile(f)) # Do not deobfuscate/rename anything if there is a typical DVD or Bluray directory: ignored_movie_folders_with_dir_sep = tuple(os.path.sep + f + os.path.sep for f in IGNORED_MOVIE_FOLDERS) match_ignored_movie_folders = [f for f in filelist if match_str(f, ignored_movie_folders_with_dir_sep)] if match_ignored_movie_folders: logging.info( "Skipping deobfuscation because of DVD/Bluray directory name(s), like: %s", str(match_ignored_movie_folders)[:200], ) nzo.set_unpack_info("Deobfuscate", T("Deobfuscate skipped due to DVD/Bluray directories")) return # If needed, add a useful extension (by looking at file contents) # Example: if 'kjladsflkjadf.adsflkjads' is probably a PNG, rename to 'kjladsflkjadf.adsflkjads.png' newlist = [] nr_ext_renamed = 0 for file in filelist: if file_extension.has_popular_extension(file): # common extension, like .doc or .iso, so assume OK and change nothing logging.debug("Extension of %s looks common", file) newlist.append(file) else: # uncommon (so: obfuscated) extension new_extension_to_add = file_extension.what_is_most_likely_extension(file) if new_extension_to_add: new_name = get_unique_filename("%s%s" % (file, new_extension_to_add)) logging.info("Deobfuscate renaming (adding extension) %s to %s", file, new_name) renamer(file, new_name) newlist.append(new_name) nr_ext_renamed += 1 else: # no new extension found newlist.append(file) if nr_ext_renamed: nzo.set_unpack_info("Deobfuscate", T("Deobfuscate corrected the extension of %d file(s)") % nr_ext_renamed) filelist = newlist logging.debug("Trying to see if there are qualifying files to be deobfuscated") nr_files_renamed = 0 # We pick the biggest file ... probably the most important file # so sort filelist on size: filelist = sorted(filelist, key=os.path.getsize, reverse=True) if filelist: biggest_file = filelist[0] else: biggest_file = None if not biggest_file or not os.path.isfile(biggest_file): # no file found, which is weird logging.info("No file given, or not found (%s)", biggest_file) return logging.debug("Deobfuscate inspecting biggest file%s", biggest_file) if not first_file_is_much_bigger(filelist): logging.debug("%s excluded from deobfuscation because it is not much bigger than other file(s)", biggest_file) return if get_ext(biggest_file) in EXCLUDED_FILE_EXTS: logging.debug("%s excluded from deobfuscation because of excluded extension", biggest_file) return if not is_probably_obfuscated(biggest_file): logging.debug("%s excluded from deobfuscation because filename does not look obfuscated", biggest_file) return # if we get here, the biggest_file is relatively big, has no excluded extension, and is obfuscated # Rename the biggest_file and make sure the new filename is unique path, file = os.path.split(biggest_file) # construct new_name: new_name = get_unique_filename("%s%s" % (os.path.join(path, usefulname), get_ext(biggest_file))) logging.info("Deobfuscate renaming %s to %s", biggest_file, new_name) renamer(biggest_file, new_name) nr_files_renamed += 1 # Now find other files with the same basename in filelist, and rename them in the same way: basedirfile = get_basename(biggest_file) # something like "/home/this/myiso" for otherfile in filelist: if otherfile.startswith(basedirfile) and os.path.isfile(otherfile): # yes, same basedirfile, only different ending remaining_ending = otherfile.replace(basedirfile, "") # might be long ext, like ".dut.srt" or "-sample.iso" new_name = get_unique_filename("%s%s" % (os.path.join(path, usefulname), remaining_ending)) logging.info("Deobfuscate renaming %s to %s", otherfile, new_name) # Rename and make sure the new filename is unique renamer(otherfile, new_name) nr_files_renamed += 1 if nr_files_renamed: nzo.set_unpack_info("Deobfuscate", T("Deobfuscate renamed %d file(s)") % nr_files_renamed) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4490979 SABnzbd-4.3.2/sabnzbd/osxmenu.py0000644000000000000000000005672114625637243015731 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.osxmenu - macOS Top Menu """ import os import sys import time import logging from typing import Optional from objc import YES, NO, lookUpClass from Foundation import ( NSObject, NSDate, NSTimer, NSRunLoop, NSDefaultRunLoopMode, NSColor, NSFont, NSImage, NSAttributedString, NSUserNotification, NSUserNotificationCenter, ) from AppKit import ( NSStatusBar, NSMenu, NSMenuItem, NSAlternateKeyMask, NSTerminateNow, NSEventTrackingRunLoopMode, NSVariableStatusItemLength, NSForegroundColorAttributeName, NSFontAttributeName, NSOnState, NSOffState, NSBaselineOffsetAttributeName, NSParagraphStyleAttributeName, NSMutableParagraphStyle, NSParagraphStyle, NSCenterTextAlignment, ) import sabnzbd import sabnzbd.cfg from sabnzbd.filesystem import diskspace from sabnzbd.misc import to_units from sabnzbd.constants import VALID_ARCHIVES, VALID_NZB_FILES, MEBI, Status from sabnzbd.panic import launch_a_browser from sabnzbd.api import fast_queue import sabnzbd.config as config DefaultUserNotificationCenter = NSUserNotificationCenter.defaultUserNotificationCenter() status_icons = { "idle": "icons/sabnzbd_osx_idle.tiff", "pause": "icons/sabnzbd_osx_pause.tiff", "clicked": "icons/sabnzbd_osx_clicked.tiff", } start_time = NSDate.date() class SABnzbdDelegate(NSObject): icons = {} status_bar = None history_db = None def awakeFromNib(self): # Wait for SABnzbd to be ready, otherwise tray_icon might not be read from config yet while not sabnzbd.WEBUI_READY and not sabnzbd.SABSTOP: time.sleep(0.5) # Set this thread as default handler for notification actions DefaultUserNotificationCenter.setDelegate_(self) # Do we want the menu if sabnzbd.cfg.tray_icon(): # Status Bar initialize self.buildMenu() # Timer for updating menu self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_( start_time, 3.0, self, "updateAction:", None, True ) NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode) NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSEventTrackingRunLoopMode) self.timer.fire() def buildMenu(self): # logging.info("building menu") status_bar = NSStatusBar.systemStatusBar() self.status_item = status_bar.statusItemWithLength_(NSVariableStatusItemLength) for icon in status_icons: icon_path = status_icons[icon] if hasattr(sys, "frozen"): # Path is modified for the binary icon_path = os.path.join(os.path.dirname(sys.executable), "..", "Resources", status_icons[icon]) self.icons[icon] = NSImage.alloc().initByReferencingFile_(icon_path) self.icons[icon].setTemplate_(YES) self.status_item.setImage_(self.icons["idle"]) self.status_item.setAlternateImage_(self.icons["clicked"]) self.status_item.setHighlightMode_(1) self.status_item.setToolTip_("SABnzbd") self.status_item.setEnabled_(YES) # Variables self.state = "Idle" self.speed = 0 # Menu construction self.menu = NSMenu.alloc().init() # Warnings Item self.warnings_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Warnings"), "openBrowserAction:", "" ) self.warnings_menu_item.setHidden_(YES) self.menu.addItem_(self.warnings_menu_item) # State Item self.state_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Idle"), "openBrowserAction:", "" ) self.menu.addItem_(self.state_menu_item) # Queue Item self.menu_queue = None self.queue_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Queue"), "openBrowserAction:", "" ) self.menu.addItem_(self.queue_menu_item) # Purge Queue Item self.purgequeue_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Purge Queue"), "purgeAction:", "" ) self.purgequeue_menu_item.setRepresentedObject_("queue") self.purgequeue_menu_item.setAlternate_(YES) self.purgequeue_menu_item.setKeyEquivalentModifierMask_(NSAlternateKeyMask) self.menu.addItem_(self.purgequeue_menu_item) # History Item self.menu_history = None self.history_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("History"), "openBrowserAction:", "" ) self.menu.addItem_(self.history_menu_item) # Purge History Item self.purgehistory_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Purge History"), "purgeAction:", "" ) self.purgehistory_menu_item.setRepresentedObject_("history") self.purgehistory_menu_item.setAlternate_(YES) self.purgehistory_menu_item.setKeyEquivalentModifierMask_(NSAlternateKeyMask) self.menu.addItem_(self.purgehistory_menu_item) self.menu.addItem_(NSMenuItem.separatorItem()) # Limit Speed Item & Submenu self.speed_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Limit Speed"), "", "") self.menu_speed = NSMenu.alloc().init() for speed in range(10, 101, 10): menu_speed_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( "%s%%" % speed, "speedlimitAction:", "" ) menu_speed_item.setRepresentedObject_("%s" % speed) self.menu_speed.addItem_(menu_speed_item) self.speed_menu_item.setSubmenu_(self.menu_speed) self.menu.addItem_(self.speed_menu_item) # Pause Item & Submenu self.pause_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Pause"), "pauseAction:", "") self.pause_menu_item.setRepresentedObject_("0") self.menu_pause = NSMenu.alloc().init() for i in range(6): menu_pause_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( "%s %s" % ((i + 1) * 10, T("min")), "pauseAction:", "" ) menu_pause_item.setRepresentedObject_("%s" % ((i + 1) * 10)) self.menu_pause.addItem_(menu_pause_item) self.pause_menu_item.setSubmenu_(self.menu_pause) self.menu.addItem_(self.pause_menu_item) # Resume Item self.resume_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Resume"), "resumeAction:", "") self.resume_menu_item.setHidden_(YES) self.menu.addItem_(self.resume_menu_item) # Watched folder Item if sabnzbd.cfg.dirscan_dir(): self.watched_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Scan watched folder"), "watchedFolderAction:", "" ) self.menu.addItem_(self.watched_menu_item) # Read RSS feeds if config.get_rss(): self.rss_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Read all RSS feeds"), "rssAction:", "" ) self.menu.addItem_(self.rss_menu_item) self.menu.addItem_(NSMenuItem.separatorItem()) # Complete Folder Item self.completefolder_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Complete Folder"), "openFolderAction:", "" ) self.completefolder_menu_item.setRepresentedObject_(sabnzbd.cfg.complete_dir.get_path()) self.menu.addItem_(self.completefolder_menu_item) # Incomplete Folder Item self.incompletefolder_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Incomplete Folder"), "openFolderAction:", "" ) self.incompletefolder_menu_item.setRepresentedObject_(sabnzbd.cfg.download_dir.get_path()) self.menu.addItem_(self.incompletefolder_menu_item) self.menu.addItem_(NSMenuItem.separatorItem()) # Set diagnostic menu self.diagnostic_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Troubleshoot"), "", "") self.menu_diagnostic = NSMenu.alloc().init() diag_items = ( (T("Restart"), "restartAction:"), (T("Restart") + " - 127.0.0.1:8080", "restartSafeHost:"), (T("Restart without login"), "restartNoLogin:"), ) for item in diag_items: menu_diag_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(item[0], item[1], "") menu_diag_item.setRepresentedObject_(item[0]) self.menu_diagnostic.addItem_(menu_diag_item) self.diagnostic_menu_item.setSubmenu_(self.menu_diagnostic) self.menu.addItem_(self.diagnostic_menu_item) # Quit Item menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Quit"), "terminate:", "") self.menu.addItem_(menu_item) # Add menu to Status Item self.status_item.setMenu_(self.menu) def updateAction_(self, notification): try: self.warningsUpdate() self.queueUpdate() self.historyUpdate() self.stateUpdate() self.pauseUpdate() self.speedlimitUpdate() self.diskspaceUpdate() except: logging.info("[osx] Exception", exc_info=True) def queueUpdate(self): try: queue_bytes_total, queue_bytes_left, _, nzo_list, _, queue_fullsize = sabnzbd.NzbQueue.queue_info(limit=10) bytesleftprogess = 0 self.info = "" if not self.menu_queue: self.menu_queue = NSMenu.alloc().init() self.menu_queue.removeAllItems() if nzo_list: menu_queue_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("Queue First 10 Items"), "", "" ) self.menu_queue.addItem_(menu_queue_item) self.menu_queue.addItem_(NSMenuItem.separatorItem()) for nzo in nzo_list: bytesleft = nzo.remaining / MEBI bytesleftprogess += nzo.remaining bytes_total = nzo.bytes / MEBI timeleft = sabnzbd.api.calc_timeleft(bytesleftprogess, sabnzbd.BPSMeter.bps) job = "%s\t(%d/%d MB) %s" % (nzo.filename, bytesleft, bytes_total, timeleft) self.menu_queue.addItem_(NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(job, "", "")) self.info = "%d nzb(s)\t(%d / %d MB)" % ( queue_fullsize, (queue_bytes_left / MEBI), (queue_bytes_total / MEBI), ) else: menu_queue_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Empty"), "", "") self.menu_queue.addItem_(menu_queue_item) self.queue_menu_item.setSubmenu_(self.menu_queue) except: logging.info("[osx] queueUpdate Exception", exc_info=True) def historyUpdate(self): try: # Fetch history items if not self.history_db: self.history_db = sabnzbd.database.HistoryDB() items = self.history_db.fetch_history(limit=10)[0] if not self.menu_history: self.menu_history = NSMenu.alloc().init() self.menu_history.removeAllItems() menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( T("History Last 10 Items"), "", "" ) self.menu_history.addItem_(menu_history_item) self.menu_history.addItem_(NSMenuItem.separatorItem()) if items: for history in items: if os.path.isdir(history["storage"]): menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( history["name"], "openFolderAction:", "" ) else: menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( history["name"], "", "" ) if history["status"] != Status.COMPLETED: jobfailed = NSAttributedString.alloc().initWithString_attributes_( history["name"], { NSForegroundColorAttributeName: NSColor.redColor(), NSFontAttributeName: NSFont.menuFontOfSize_(14.0), }, ) menu_history_item.setAttributedTitle_(jobfailed) menu_history_item.setRepresentedObject_(history["storage"]) self.menu_history.addItem_(menu_history_item) else: menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T("Empty"), "", "") self.menu_history.addItem_(menu_history_item) self.history_menu_item.setSubmenu_(self.menu_history) except: logging.info("[osx] historyUpdate Exception", exc_info=True) def warningsUpdate(self): try: warnings = sabnzbd.GUIHANDLER.count() if warnings: warningsAttributes = { NSForegroundColorAttributeName: NSColor.redColor(), NSFontAttributeName: NSFont.menuFontOfSize_(14.0), } warningsTitle = NSAttributedString.alloc().initWithString_attributes_( "%s : %s" % (T("Warnings"), warnings), warningsAttributes ) self.warnings_menu_item.setAttributedTitle_(warningsTitle) self.warnings_menu_item.setHidden_(NO) else: self.warnings_menu_item.setTitle_("%s : 0" % (T("Warnings"))) self.warnings_menu_item.setHidden_(YES) except: logging.info("[osx] warningsUpdate Exception", exc_info=True) def stateUpdate(self): try: paused, bytes_left, bpsnow, time_left = fast_queue() if paused: self.state = T("Paused") if sabnzbd.Scheduler.pause_int() != "0": self.setMenuTitle_("\n%s\n%s\n" % (T("Paused"), sabnzbd.Scheduler.pause_int())) else: self.setMenuTitle_("") elif bytes_left > 0: self.state = "" speed = to_units(bpsnow) # "10.1 MB/s" doesn't fit, remove space char if "M" in speed and len(speed) > 5: speed = speed.replace(" ", "") time_left = (bpsnow > 10 and time_left) or "------" self.setMenuTitle_("\n\n%s\n%sB/s\n" % (time_left, speed)) else: self.state = T("Idle") self.setMenuTitle_("") if self.state != "" and self.info != "": self.state_menu_item.setTitle_("%s - %s" % (self.state, self.info)) if self.info == "": self.state_menu_item.setTitle_("%s" % self.state) else: self.state_menu_item.setTitle_("%s" % self.info) if not config.get_servers(): self.state_menu_item.setTitle_(T("Go to wizard")) except: logging.info("[osx] stateUpdate Exception", exc_info=True) def pauseUpdate(self): try: if sabnzbd.Downloader.paused: self.status_item.setImage_(self.icons["pause"]) self.resume_menu_item.setHidden_(NO) self.pause_menu_item.setHidden_(YES) else: self.status_item.setImage_(self.icons["idle"]) self.resume_menu_item.setHidden_(YES) self.pause_menu_item.setHidden_(NO) except: logging.info("[osx] pauseUpdate Exception", exc_info=True) def speedlimitUpdate(self): try: if self.speed != sabnzbd.Downloader.bandwidth_perc: self.speed = sabnzbd.Downloader.bandwidth_perc speedsValues = self.menu_speed.numberOfItems() for i in range(speedsValues): menuitem = self.menu_speed.itemAtIndex_(i) if sabnzbd.Downloader.bandwidth_perc == int(menuitem.representedObject()): menuitem.setState_(NSOnState) else: menuitem.setState_(NSOffState) except: logging.info("[osx] speedlimitUpdate Exception", exc_info=True) def diskspaceUpdate(self): try: self.completefolder_menu_item.setTitle_( "%s (%.2f GB)" % (T("Complete Folder"), diskspace()["complete_dir"][1]) ) self.incompletefolder_menu_item.setTitle_( "%s (%.2f GB)" % (T("Incomplete Folder"), diskspace()["download_dir"][1]) ) except: logging.info("[osx] diskspaceUpdate Exception", exc_info=True) def setMenuTitle_(self, text): try: style = NSMutableParagraphStyle.new() style.setParagraphStyle_(NSParagraphStyle.defaultParagraphStyle()) style.setAlignment_(NSCenterTextAlignment) style.setLineSpacing_(0.0) style.setMaximumLineHeight_(9.0) style.setParagraphSpacing_(-3.0) titleAttributes = { NSBaselineOffsetAttributeName: -5.0, NSFontAttributeName: NSFont.menuFontOfSize_(9.0), NSParagraphStyleAttributeName: style, } title = NSAttributedString.alloc().initWithString_attributes_(text, titleAttributes) self.status_item.setAttributedTitle_(title) except: logging.info("[osx] setMenuTitle Exception", exc_info=True) def openBrowserAction_(self, sender): launch_a_browser(sabnzbd.BROWSER_URL, True) def speedlimitAction_(self, sender): # logging.info("[osx] speed limit to %s" % (sender.representedObject())) speed = int(sender.representedObject()) if speed != self.speed: sabnzbd.Downloader.limit_speed("%s%%" % speed) self.speedlimitUpdate() def purgeAction_(self, sender): mode = sender.representedObject() # logging.info("[osx] purge %s" % (mode)) if mode == "queue": sabnzbd.NzbQueue.remove_all() elif mode == "history": if not self.history_db: self.history_db = sabnzbd.database.HistoryDB() self.history_db.remove_with_status(Status.COMPLETED) def pauseAction_(self, sender): minutes = int(sender.representedObject()) # logging.info("[osx] pause for %s" % (minutes)) if minutes: sabnzbd.Scheduler.plan_resume(minutes) else: sabnzbd.Downloader.pause() def resumeAction_(self, sender): sabnzbd.Scheduler.plan_resume(0) def watchedFolderAction_(self, sender): sabnzbd.DirScanner.scan() def rssAction_(self, sender): sabnzbd.Scheduler.force_rss() def openFolderAction_(self, sender): folder2open = sender.representedObject() os.system('open "%s"' % folder2open) def restartAction_(self, sender): self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) logging.info("Restart requested by tray") sabnzbd.trigger_restart() self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) def restartSafeHost_(self, sender): sabnzbd.cfg.cherryhost.set("127.0.0.1") sabnzbd.cfg.cherryport.set("8080") sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config() self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) sabnzbd.trigger_restart() self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) def restartNoLogin_(self, sender): sabnzbd.cfg.username.set("") sabnzbd.cfg.password.set("") sabnzbd.config.save_config() self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) sabnzbd.trigger_restart() self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) def application_openFiles_(self, nsapp, filenames): # logging.info('[osx] file open') # logging.info('[osx] file : %s' % (filenames)) for filename in filenames: logging.info("[osx] receiving from macOS : %s", filename) if os.path.exists(filename): if sabnzbd.filesystem.get_ext(filename) in VALID_ARCHIVES + VALID_NZB_FILES: sabnzbd.nzbparser.add_nzbfile(filename, keep=True) # logging.info('opening done') def applicationShouldTerminate_(self, sender): logging.info("[osx] application terminating") self.setMenuTitle_("\n\n%s\n" % (T("Stopping..."))) self.status_item.setHighlightMode_(NO) sabnzbd.shutdown_program() return NSTerminateNow def send_notification( self, title: str, subtitle: str, msg: str, button_text: Optional[str] = None, button_action: Optional[str] = None, ): """Send a macOS notification, optionally with 1 action button""" notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(subtitle) notification.setInformativeText_(msg) notification.setSoundName_("NSUserNotificationDefaultSoundName") if button_text and button_action: notification.setHasActionButton_(True) notification.set_showsButtons_(True) notification.setActionButtonTitle_(button_text) notification.setUserInfo_({"value": button_action}) else: notification.setHasActionButton_(False) notification.set_showsButtons_(False) notification.setDeliveryDate_(NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date())) DefaultUserNotificationCenter.scheduleNotification_(notification) def userNotificationCenter_didActivateNotification_(self, center, notification): """Handler for the clicks on the notification""" if notification.activationType() == 1: # user clicked on the notification (not on a button) launch_a_browser(sabnzbd.BROWSER_URL, force=True) elif notification.activationType() == 2: # User clicked on the action button if os.path.exists(folder2open := notification.userInfo()["value"]): os.system('open "%s"' % folder2open) # Remove this notification after interaction DefaultUserNotificationCenter._removeDisplayedNotification_(notification) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4491806 SABnzbd-4.3.2/sabnzbd/dirscanner.py0000644000000000000000000002417014625637243016354 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.dirscanner - Scanner for Watched Folder """ import asyncio import os import logging import threading from typing import Generator, Set, Optional, Tuple import sabnzbd from sabnzbd.constants import SCAN_FILE_NAME, VALID_ARCHIVES, VALID_NZB_FILES, AddNzbFileResult import sabnzbd.filesystem as filesystem import sabnzbd.config as config import sabnzbd.cfg as cfg DIR_SCANNER_LOCK = threading.RLock() VALID_EXTENSIONS = set(VALID_NZB_FILES + VALID_ARCHIVES) def compare_stat_tuple(tup1, tup2): """Test equality of two stat-tuples, content-related parts only""" if tup1.st_ino != tup2.st_ino: return False if tup1.st_size != tup2.st_size: return False if tup1.st_mtime != tup2.st_mtime: return False if tup1.st_ctime != tup2.st_ctime: return False return True async def clean_file_list(inp_list, files): """Remove elements of "inp_list" not found in "files" """ for path in set(inp_list.keys()).difference(files): del inp_list[path] class DirScanner(threading.Thread): """Thread that periodically scans a given directory and picks up any valid NZB, NZB.GZ ZIP-with-only-NZB and even NZB.GZ named as .NZB Candidates which turned out wrong, will be remembered and skipped in subsequent scans, unless changed. """ def __init__(self): super().__init__() # Create loop right away, so socks5 proxy doesn't break it self.loop = asyncio.new_event_loop() self.scanner_task: Optional[asyncio.Task] = None self.lock: Optional[asyncio.Lock] = None # Prevents concurrent scans self.error_reported = False # Prevents multiple reporting of missing watched folder self.dirscan_dir = cfg.dirscan_dir.get_path() self.dirscan_speed = cfg.dirscan_speed() cfg.dirscan_dir.callback(self.newdir) cfg.dirscan_speed.callback(self.newspeed) try: dirscan_dir, self.ignored, self.suspected = sabnzbd.filesystem.load_admin(SCAN_FILE_NAME) if dirscan_dir != self.dirscan_dir: self.ignored = {} self.suspected = {} except: self.ignored = {} # Will hold all unusable files and the # successfully processed ones that cannot be deleted self.suspected = {} # Will hold name/attributes of suspected candidates def newdir(self): """We're notified of a dir change""" self.ignored = {} self.suspected = {} self.dirscan_dir = cfg.dirscan_dir.get_path() self.start_scanner() def newspeed(self): """We're notified of a scan speed change""" self.dirscan_speed = cfg.dirscan_speed() self.start_scanner() def stop(self): """Stop the dir scanner""" if self.loop: asyncio.run_coroutine_threadsafe(self.shutdown(), self.loop) def save(self): """Save dir scanner bookkeeping""" sabnzbd.filesystem.save_admin((self.dirscan_dir, self.ignored, self.suspected), SCAN_FILE_NAME) def run(self): """Start the scanner""" logging.info("Dirscanner starting up") try: self.start_scanner() self.loop.run_forever() finally: self.loop.close() def start_scanner(self): """Start the scanner if it is not already running""" with DIR_SCANNER_LOCK: if not self.loop: logging.debug("Can not start scanner because loop not found") return if not self.scanner_task or self.scanner_task.done(): self.scanner_task = asyncio.run_coroutine_threadsafe(self.scanner(), self.loop) def get_suspected_files( self, folder: str, catdir: Optional[str] = None ) -> Generator[Tuple[str, Optional[str], Optional[os.stat_result]], None, None]: """Generator listing possible paths to NZB files""" if catdir is None: cats = config.get_categories() else: cats = {} try: with os.scandir(os.path.join(folder, catdir or "")) as it: for entry in it: path = entry.path if path in self.ignored: # We still need to know that an ignored file is still present when we clean up yield path, catdir, None continue # If the entry is a catdir then recursion if entry.is_dir(): if not catdir and entry.name.lower() in cats: yield from self.get_suspected_files(folder, entry.name) continue if filesystem.get_ext(path) in VALID_EXTENSIONS: try: # https://docs.python.org/3/library/os.html#os.DirEntry.stat # On Windows, the st_ino, st_dev and st_nlink attributes of the stat_result are always set # to zero. Call os.stat() to get these attributes. if sabnzbd.WIN32: stat_tuple = os.stat(path) else: stat_tuple = entry.stat() except OSError: continue else: self.ignored[path] = 1 yield path, catdir, None continue if path in self.suspected: if not compare_stat_tuple(self.suspected[path], stat_tuple): # Suspected file attributes have changed del self.suspected[path] yield path, catdir, stat_tuple except: if not self.error_reported and not catdir: logging.error(T("Cannot read Watched Folder %s"), filesystem.clip_path(folder)) logging.info("Traceback: ", exc_info=True) self.error_reported = True async def when_stable_add_nzbfile(self, path: str, catdir: Optional[str], stat_tuple: os.stat_result): """Try and import the NZB but wait until the attributes are stable for 1 second, but give up after 3 sec""" logging.info("Trying to import %s", path) # Wait until the attributes are stable for 1 second, but give up after 3 sec # This indicates that the file is fully written to disk for n in range(3): await asyncio.sleep(1.0) try: stat_tuple_tmp = os.stat(path) except OSError: continue if compare_stat_tuple(stat_tuple, stat_tuple_tmp): break stat_tuple = stat_tuple_tmp else: # Not stable return # Add the NZB's res, _ = sabnzbd.nzbparser.add_nzbfile(path, catdir=catdir, keep=False) if res is AddNzbFileResult.RETRY or res is AddNzbFileResult.ERROR: # Retry later, for example when we can't read the file self.suspected[path] = stat_tuple elif res is AddNzbFileResult.OK: self.error_reported = False else: self.ignored[path] = 1 def scan(self): """Schedule a scan of the watched folder""" if not self.loop: return if not (dirscan_dir := self.dirscan_dir): return asyncio.run_coroutine_threadsafe(self.scan_async(dirscan_dir), self.loop) async def scan_async(self, dirscan_dir: str): """Do one scan of the watched folder""" # On Python 3.8 we first need an event loop before we can create a asyncio.Lock if not self.lock: with DIR_SCANNER_LOCK: self.lock = asyncio.Lock() async with self.lock: if sabnzbd.PAUSED_ALL: return files: Set[str] = set() futures: Set[asyncio.Task] = set() for path, catdir, stat_tuple in self.get_suspected_files(dirscan_dir): files.add(path) if path in self.ignored or path in self.suspected: continue if stat_tuple.st_size > 0: futures.add(asyncio.create_task(self.when_stable_add_nzbfile(path, catdir, stat_tuple))) await asyncio.sleep(0) # Remove files from the bookkeeping that are no longer on the disk # Wait for the paths found in this scan to finish await asyncio.gather(clean_file_list(self.ignored, files), clean_file_list(self.suspected, files), *futures) async def scanner(self): """Periodically scan the directory and add NZB files to the queue""" while True: if not (dirscan_speed := self.dirscan_speed): break if not (dirscan_dir := self.dirscan_dir): break await self.scan_async(dirscan_dir) await asyncio.sleep(dirscan_speed) async def shutdown(self): """Cancel all tasks and stop the loop""" loop = asyncio.get_event_loop() # Get all tasks except for this one tasks = filter(lambda task: task is not asyncio.current_task(), asyncio.all_tasks()) # Cancel them all for task in tasks: task.cancel() # Wait for the tasks to be done await asyncio.gather(*tasks, return_exceptions=True) loop.stop() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4492424 SABnzbd-4.3.2/sabnzbd/decorators.py0000644000000000000000000000544014625637243016370 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ############################################################################## # Decorators ############################################################################## import time import functools from typing import Union, Callable from threading import Lock, RLock, Condition # All operations that modify the queue need to happen in a lock # Also used when importing NZBs to prevent IO-race conditions # Names of wrapper-functions should be the same in misc.caller_name # The NzbQueueLocker both locks and notifies the Downloader NZBQUEUE_LOCK = RLock() DOWNLOADER_CV = Condition(NZBQUEUE_LOCK) # All operations that modify downloader state need to be locked DOWNLOADER_LOCK = RLock() def synchronized(lock: Union[Lock, RLock]): def wrap(func: Callable): def call_func(*args, **kw): # Using the try/finally approach is 25% faster compared to using "with lock" try: lock.acquire() return func(*args, **kw) finally: lock.release() return call_func return wrap def NzbQueueLocker(func: Callable): global DOWNLOADER_CV def call_func(*params, **kparams): DOWNLOADER_CV.acquire() try: return func(*params, **kparams) finally: DOWNLOADER_CV.notify_all() DOWNLOADER_CV.release() return call_func def cache_maintainer(clear_time: int): """ A function decorator that clears functools.cache or functools.lru_cache clear_time seconds :param clear_time: In seconds, how often to clear cache (only checks when called) """ def inner(func): def wrapper(*args, **kwargs): if hasattr(func, "next_clear"): if time.time() > func.next_clear or kwargs.get("force"): func.cache_clear() func.next_clear = time.time() + clear_time else: func.next_clear = time.time() + clear_time return func(*args, **kwargs) return wrapper return inner ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4494052 SABnzbd-4.3.2/sabnzbd/utils/rarvolinfo.py0000644000000000000000000000751014625637243017544 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.utils.rarvolinfo - Find out volume number and/or original extension of a rar file. Useful with obfuscated files """ import os try: import sabnzbd.utils.rarfile as rarfile except ImportError: import rarfile def get_rar_extension(myrarfile): """ Find out original extension of a rar file. Returns "" in case of file problems So ... returns: "part001.rar", ... "part005.rar" or old number scheme (can only happen for rar3/rar4 files): "rar", r00, ... r89 """ # When things go wrong volumenumber = -1 org_extension = False try: rar_ver = rarfile.is_rarfile(myrarfile) with open(myrarfile, "rb") as fh: if rar_ver.endswith("3"): # As it's rar3, let's first find the numbering scheme: old (rNN) or new (partNN.rar) mybuf = fh.read(100) # first 100 bytes is enough HEAD_FLAGS_LSB = mybuf[10] # LSB = Least Significant Byte newnumbering = HEAD_FLAGS_LSB & 0x10 # For the volume number, At the end of the file, we need about 20 bytes fh.seek(-20, os.SEEK_END) mybuf = fh.read() volumenumber = 1 + mybuf[-9] + 256 * mybuf[-8] if newnumbering: org_extension = "part%02d.rar" % volumenumber else: # 1, 2, 3, 4 resp refers to .rar, .r00, .r01, .r02 ... if volumenumber == 1: org_extension = "rar" else: org_extension = "r%02d" % (volumenumber - 2) elif rar_ver.endswith("5"): mybuf = fh.read(100) # first 100 bytes is enough # Get (and skip) the first 8 + 4 bytes rar5sig, newpos = rarfile.load_bytes(mybuf, 8, 0) # Rar5 signature crc32, newpos = rarfile.load_bytes(mybuf, 4, newpos) # crc32 # Then get the VINT values (with variable size, so parse them all): headersize, newpos = rarfile.load_vint(mybuf, newpos) headertype, newpos = rarfile.load_vint(mybuf, newpos) headerflags, newpos = rarfile.load_vint(mybuf, newpos) extraareasize, newpos = rarfile.load_vint(mybuf, newpos) archiveflags, newpos = rarfile.load_vint(mybuf, newpos) # Now we're ready for the volume number: if archiveflags & 2: value, newpos = rarfile.load_vint(mybuf, newpos) volumenumber = value + 1 else: # first volume, aka 1 volumenumber = 1 # Combine into the extension org_extension = "part%03d.rar" % volumenumber except: pass return volumenumber, org_extension # Main if __name__ == "__main__": import sys try: myfile = sys.argv[1] print("File:", myfile) print("Volume and extension:", get_rar_extension(myfile)) except: print("Please specify rar file as parameter") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4494948 SABnzbd-4.3.2/sabnzbd/utils/apireg.py0000644000000000000000000001023414625637243016627 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ util.apireg - Registration of API connection info """ import winreg def reg_info(user): """Return the reg key for API""" if user: # Normally use the USER part of the registry section = winreg.HKEY_CURRENT_USER keypath = r"Software\SABnzbd" else: # A Windows Service will use the service key instead section = winreg.HKEY_LOCAL_MACHINE keypath = r"SYSTEM\CurrentControlSet\Services\SABnzbd" return section, keypath def get_connection_info(user=True): """Return URL of the API running SABnzbd instance 'user' == True will first try user's registry, otherwise system is used """ section, keypath = reg_info(user) url = None try: hive = winreg.ConnectRegistry(None, section) key = winreg.OpenKey(hive, keypath + r"\api") for i in range(0, winreg.QueryInfoKey(key)[1]): name, value, val_type = winreg.EnumValue(key, i) if name == "url": url = value winreg.CloseKey(key) except OSError: pass finally: winreg.CloseKey(hive) # Nothing in user's registry, try system registry if user and not url: url = get_connection_info(user=False) return url def set_connection_info(url, user=True): """Set API info in register""" section, keypath = reg_info(user) try: hive = winreg.ConnectRegistry(None, section) try: winreg.CreateKey(hive, keypath) except OSError: pass key = winreg.OpenKey(hive, keypath) mykey = winreg.CreateKey(key, "api") winreg.SetValueEx(mykey, "url", None, winreg.REG_SZ, url) winreg.CloseKey(mykey) winreg.CloseKey(key) except OSError: if user: set_connection_info(url, user=False) finally: winreg.CloseKey(hive) def del_connection_info(user=True): """Remove API info from register""" section, keypath = reg_info(user) try: hive = winreg.ConnectRegistry(None, section) key = winreg.OpenKey(hive, keypath) winreg.DeleteKey(key, "api") winreg.CloseKey(key) except OSError: if user: del_connection_info(user=False) finally: winreg.CloseKey(hive) def get_install_lng(): """Return language-code used by the installer""" lng = 0 try: hive = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) key = winreg.OpenKey(hive, r"Software\SABnzbd") for i in range(0, winreg.QueryInfoKey(key)[1]): name, value, val_type = winreg.EnumValue(key, i) if name == "Installer Language": lng = value winreg.CloseKey(key) except OSError: pass finally: winreg.CloseKey(hive) if lng in LanguageMap: return LanguageMap[lng] return "en" # Map from NSIS-codepage to our language-strings LanguageMap = { "1033": "en", "1036": "fr", "1031": "de", "1043": "nl", "1035": "fi", "1045": "pl", "1053": "sv", "1030": "da", "2068": "nb", "1048": "ro", "1034": "es", "1046": "pr_BR", "3098": "sr", "1037": "he", "1049": "ru", "2052": "zh_CN", } if __name__ == "__main__": print("URL = %s" % get_connection_info()) print("Language = %s" % get_install_lng()) # del_connection_info() # set_connection_info('localhost', '8080', 'blabla', user=False) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4495716 SABnzbd-4.3.2/sabnzbd/utils/systrayiconthread.py0000644000000000000000000002432114625637243021141 0ustar00runnerstaff#!/usr/bin/python3 # based on SysTrayIcon.py by Simon Brunning - simon@brunningonline.net # http://www.brunningonline.net/simon/blog/archives/001835.html # http://www.brunningonline.net/simon/blog/archives/SysTrayIcon.py.html # modified on 2011-10-04 by Jan Schejbal to support threading and preload icons # override doUpdates to perform actions inside the icon thread # override click to perform actions when left-clicking the icon import os import pywintypes import win32api import win32con import win32gui import win32gui_struct import timer from threading import Thread from time import sleep class SysTrayIconThread(Thread): QUIT = "QUIT" SPECIAL_ACTIONS = [QUIT] FIRST_ID = 1023 def __init__(self, icon, hover_text, menu_options, on_quit=None, default_menu_index=None, window_class_name=None): super().__init__() self.terminate = False self.icon = icon self.icons = {} self.hover_text = hover_text self.on_quit = on_quit # menu_options = menu_options + (('Quit', None, self.QUIT),) self._next_action_id = self.FIRST_ID self.menu_actions_by_id = set() self.menu_options = self._add_ids_to_menu_options(list(menu_options)) self.menu_actions_by_id = dict(self.menu_actions_by_id) del self._next_action_id self.click_timer = None self.default_menu_index = default_menu_index or 0 self.window_class_name = window_class_name or "SysTrayIconPy" self.start() def initialize(self): # Note that all functions should return True to prevent tracebacks message_map = { win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart, win32con.WM_DESTROY: self.destroy, win32con.WM_COMMAND: self.command, win32con.WM_USER + 20: self.notify, } # Register the Window class. window_class = win32gui.WNDCLASS() hinst = window_class.hInstance = win32gui.GetModuleHandle(None) window_class.lpszClassName = self.window_class_name window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) window_class.hbrBackground = win32con.COLOR_WINDOW window_class.lpfnWndProc = message_map # could also specify a wndproc. classAtom = win32gui.RegisterClass(window_class) # Create the Window. style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU self.hwnd = win32gui.CreateWindow( classAtom, self.window_class_name, style, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, hinst, None, ) win32gui.UpdateWindow(self.hwnd) self.notify_id = None self.refresh_icon() def stop(self): self.terminate = True sleep(0.15) def run(self): self.initialize() while not self.terminate: win32gui.PumpWaitingMessages() self.doUpdates() sleep(0.1) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, (self.hwnd, 0)) # Override this def doUpdates(self): pass # Notification def sendnotification(self, title, msg): hicon = self.get_icon(self.icon) win32gui.Shell_NotifyIcon( win32gui.NIM_MODIFY, (self.hwnd, 0, win32gui.NIF_INFO, win32con.WM_USER + 20, hicon, "Balloon tooltip", msg, 200, title), ) def _add_ids_to_menu_options(self, menu_options): result = [] for menu_option in menu_options: option_text, option_icon, option_action = menu_option if callable(option_action) or option_action in self.SPECIAL_ACTIONS: self.menu_actions_by_id.add((self._next_action_id, option_action)) result.append(menu_option + (self._next_action_id,)) elif non_string_iterable(option_action): result.append( (option_text, option_icon, self._add_ids_to_menu_options(option_action), self._next_action_id) ) elif option_text == "SEPARATOR": # Skip, add separator later result.append(menu_option + (self._next_action_id,)) else: print(("Unknown item", option_text, option_icon, option_action)) self._next_action_id += 1 return result def get_icon(self, path): hicon = self.icons.get(path) if hicon != None: return hicon # Try and find a custom icon hinst = win32gui.GetModuleHandle(None) if os.path.isfile(path): icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE hicon = win32gui.LoadImage(hinst, path, win32con.IMAGE_ICON, 0, 0, icon_flags) else: print("Can't find icon file - using default.") hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) self.icons[path] = hicon return hicon def refresh_icon(self): hicon = self.get_icon(self.icon) if self.notify_id: message = win32gui.NIM_MODIFY else: message = win32gui.NIM_ADD self.notify_id = ( self.hwnd, 0, win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, win32con.WM_USER + 20, hicon, self.hover_text, ) try: win32gui.Shell_NotifyIcon(message, self.notify_id) except: # Timeouts can occur after system comes out of standby/hibernate pass def restart(self, hwnd, msg, wparam, lparam): self.refresh_icon() return True def destroy(self, hwnd, msg, wparam, lparam): if self.on_quit: self.on_quit(self) nid = (self.hwnd, 0) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) win32gui.PostQuitMessage(0) # Terminate the app. return True def notify(self, hwnd, msg, wparam, lparam): # Double click is actually 1 single click followed # by a double-click event, no way to differentiate # So we need a timed callback to cancel if lparam == win32con.WM_LBUTTONDBLCLK: self.execute_menu_option(self.default_menu_index + self.FIRST_ID) self.stop_click_timer() elif lparam == win32con.WM_RBUTTONUP: self.show_menu() elif lparam == win32con.WM_LBUTTONDOWN: # Wrapper of win32api, timeout is in ms # We need to wait at least until what user has defined as double click self.stop_click_timer() self.click_timer = timer.set_timer(win32gui.GetDoubleClickTime() * 2, self.click) return True def show_menu(self): menu = win32gui.CreatePopupMenu() self.create_menu(menu, self.menu_options) # win32gui.SetMenuDefaultItem(menu, 1000, 0) try: pos = win32gui.GetCursorPos() # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp win32gui.SetForegroundWindow(self.hwnd) win32gui.TrackPopupMenu(menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None) win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) except pywintypes.error: # Weird PyWin/win32gui bug, just ignore it for now pass # Override this for left-click action # Need to call the stop-timer in that function! def click(self, *args): pass def stop_click_timer(self): # Stop the timer if self.click_timer: timer.kill_timer(self.click_timer) self.click_timer = None def create_menu(self, menu, menu_options): for option_text, option_icon, option_action, option_id in menu_options[::-1]: if option_icon: option_icon = self.prep_menu_icon(option_icon) if option_id in self.menu_actions_by_id: item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text, hbmpItem=option_icon, wID=option_id) win32gui.InsertMenuItem(menu, 0, 1, item) elif option_text == "SEPARATOR": item, extras = win32gui_struct.PackMENUITEMINFO(fType=win32con.MFT_SEPARATOR) win32gui.InsertMenuItem(menu, 0, 1, item) else: submenu = win32gui.CreatePopupMenu() self.create_menu(submenu, option_action) item, extras = win32gui_struct.PackMENUITEMINFO( text=option_text, hbmpItem=option_icon, hSubMenu=submenu ) win32gui.InsertMenuItem(menu, 0, 1, item) def prep_menu_icon(self, icon): # First load the icon. ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON) ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON) hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE) hdcBitmap = win32gui.CreateCompatibleDC(0) hdcScreen = win32gui.GetDC(0) hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y) hbmOld = win32gui.SelectObject(hdcBitmap, hbm) # Fill the background. brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU) win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush) # unclear if brush needs to be feed. Best clue I can find is: # "GetSysColorBrush returns a cached brush instead of allocating a new # one." - implies no DeleteObject # draw the icon win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL) win32gui.SelectObject(hdcBitmap, hbmOld) win32gui.DeleteDC(hdcBitmap) return hbm def command(self, hwnd, msg, wparam, lparam): self.execute_menu_option(win32gui.LOWORD(wparam)) return True def execute_menu_option(self, id): menu_action = self.menu_actions_by_id[id] if menu_action == self.QUIT: win32gui.DestroyWindow(self.hwnd) else: menu_action(self) def non_string_iterable(obj): try: iter(obj) except TypeError: return False else: return not isinstance(obj, str) ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1716993699.44968 SABnzbd-4.3.2/sabnzbd/utils/pybonjour.py0000644000000000000000000016401514625637243017416 0ustar00runnerstaff################################################################################ # # Copyright (c) 2007-2008 Christopher J. Stawarz # # 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. # ################################################################################ """ Pure-Python interface to Apple Bonjour and compatible DNS-SD libraries pybonjour provides a pure-Python interface (via ctypes) to Apple Bonjour and compatible DNS-SD libraries (such as Avahi). It allows Python scripts to take advantage of Zero Configuration Networking (Zeroconf) to register, discover, and resolve services on both local and wide-area networks. Since pybonjour is implemented in pure Python, scripts that use it can easily be ported to Mac OS X, Windows, Linux, and other systems that run Bonjour. Note on strings: Internally, all strings used in DNS-SD are UTF-8 strings. String arguments passed to the DNS-SD functions provided by pybonjour must be either unicode instances or str instances that can be converted to unicode using the default encoding. (Passing a non-convertible str will result in an exception.) Strings returned from pybonjour (either directly from API functions or passed to application callbacks) are always unicode instances. """ __author__ = "Christopher Stawarz " __version__ = "1.1.1" __revision__ = int("$Revision: 6125 $".split()[1]) import ctypes import os import re import socket import sys ################################################################################ # # Global setup # ################################################################################ class _DummyLock(object): @staticmethod def acquire(): pass @staticmethod def release(): pass _global_lock = _DummyLock() if sys.platform == "win32": # Need to use the stdcall variants _libdnssd = ctypes.windll.dnssd _CFunc = ctypes.WINFUNCTYPE else: if sys.platform == "darwin": _libdnssd = "libSystem.B.dylib" else: _libdnssd = "libdns_sd.so.1" # If libdns_sd is actually Avahi's Bonjour compatibility # layer, silence its annoying warning messages, and use a real # RLock as the global lock, since the compatibility layer # isn't thread safe. try: ctypes.cdll.LoadLibrary("libavahi-client.so.3") except OSError: pass else: os.environ["AVAHI_COMPAT_NOWARN"] = "1" import threading _global_lock = threading.RLock() _libdnssd = ctypes.cdll.LoadLibrary(_libdnssd) _CFunc = ctypes.CFUNCTYPE ################################################################################ # # Constants # ################################################################################ # # General flags # kDNSServiceFlagsMoreComing = 0x1 kDNSServiceFlagsAdd = 0x2 kDNSServiceFlagsDefault = 0x4 kDNSServiceFlagsNoAutoRename = 0x8 kDNSServiceFlagsShared = 0x10 kDNSServiceFlagsUnique = 0x20 kDNSServiceFlagsBrowseDomains = 0x40 kDNSServiceFlagsRegistrationDomains = 0x80 kDNSServiceFlagsLongLivedQuery = 0x100 kDNSServiceFlagsAllowRemoteQuery = 0x200 kDNSServiceFlagsForceMulticast = 0x400 kDNSServiceFlagsReturnCNAME = 0x800 # # Service classes # kDNSServiceClass_IN = 1 # # Service types # kDNSServiceType_A = 1 kDNSServiceType_NS = 2 kDNSServiceType_MD = 3 kDNSServiceType_MF = 4 kDNSServiceType_CNAME = 5 kDNSServiceType_SOA = 6 kDNSServiceType_MB = 7 kDNSServiceType_MG = 8 kDNSServiceType_MR = 9 kDNSServiceType_NULL = 10 kDNSServiceType_WKS = 11 kDNSServiceType_PTR = 12 kDNSServiceType_HINFO = 13 kDNSServiceType_MINFO = 14 kDNSServiceType_MX = 15 kDNSServiceType_TXT = 16 kDNSServiceType_RP = 17 kDNSServiceType_AFSDB = 18 kDNSServiceType_X25 = 19 kDNSServiceType_ISDN = 20 kDNSServiceType_RT = 21 kDNSServiceType_NSAP = 22 kDNSServiceType_NSAP_PTR = 23 kDNSServiceType_SIG = 24 kDNSServiceType_KEY = 25 kDNSServiceType_PX = 26 kDNSServiceType_GPOS = 27 kDNSServiceType_AAAA = 28 kDNSServiceType_LOC = 29 kDNSServiceType_NXT = 30 kDNSServiceType_EID = 31 kDNSServiceType_NIMLOC = 32 kDNSServiceType_SRV = 33 kDNSServiceType_ATMA = 34 kDNSServiceType_NAPTR = 35 kDNSServiceType_KX = 36 kDNSServiceType_CERT = 37 kDNSServiceType_A6 = 38 kDNSServiceType_DNAME = 39 kDNSServiceType_SINK = 40 kDNSServiceType_OPT = 41 kDNSServiceType_TKEY = 249 kDNSServiceType_TSIG = 250 kDNSServiceType_IXFR = 251 kDNSServiceType_AXFR = 252 kDNSServiceType_MAILB = 253 kDNSServiceType_MAILA = 254 kDNSServiceType_ANY = 255 # # Error codes # kDNSServiceErr_NoError = 0 kDNSServiceErr_Unknown = -65537 kDNSServiceErr_NoSuchName = -65538 kDNSServiceErr_NoMemory = -65539 kDNSServiceErr_BadParam = -65540 kDNSServiceErr_BadReference = -65541 kDNSServiceErr_BadState = -65542 kDNSServiceErr_BadFlags = -65543 kDNSServiceErr_Unsupported = -65544 kDNSServiceErr_NotInitialized = -65545 kDNSServiceErr_AlreadyRegistered = -65547 kDNSServiceErr_NameConflict = -65548 kDNSServiceErr_Invalid = -65549 kDNSServiceErr_Firewall = -65550 kDNSServiceErr_Incompatible = -65551 kDNSServiceErr_BadInterfaceIndex = -65552 kDNSServiceErr_Refused = -65553 kDNSServiceErr_NoSuchRecord = -65554 kDNSServiceErr_NoAuth = -65555 kDNSServiceErr_NoSuchKey = -65556 kDNSServiceErr_NATTraversal = -65557 kDNSServiceErr_DoubleNAT = -65558 kDNSServiceErr_BadTime = -65559 # # Other constants # kDNSServiceMaxServiceName = 64 kDNSServiceMaxDomainName = 1005 kDNSServiceInterfaceIndexAny = 0 kDNSServiceInterfaceIndexLocalOnly = -1 ################################################################################ # # Error handling # ################################################################################ class BonjourError(Exception): """ Exception representing an error returned by the DNS-SD library. The errorCode attribute contains the actual integer error code returned. """ _errmsg = { kDNSServiceErr_NoSuchName: "no such name", kDNSServiceErr_NoMemory: "no memory", kDNSServiceErr_BadParam: "bad param", kDNSServiceErr_BadReference: "bad reference", kDNSServiceErr_BadState: "bad state", kDNSServiceErr_BadFlags: "bad flags", kDNSServiceErr_Unsupported: "unsupported", kDNSServiceErr_NotInitialized: "not initialized", kDNSServiceErr_AlreadyRegistered: "already registered", kDNSServiceErr_NameConflict: "name conflict", kDNSServiceErr_Invalid: "invalid", kDNSServiceErr_Firewall: "firewall", kDNSServiceErr_Incompatible: "incompatible", kDNSServiceErr_BadInterfaceIndex: "bad interface index", kDNSServiceErr_Refused: "refused", kDNSServiceErr_NoSuchRecord: "no such record", kDNSServiceErr_NoAuth: "no auth", kDNSServiceErr_NoSuchKey: "no such key", kDNSServiceErr_NATTraversal: "NAT traversal", kDNSServiceErr_DoubleNAT: "double NAT", kDNSServiceErr_BadTime: "bad time", } @classmethod def _errcheck(cls, result, func, args): if result != kDNSServiceErr_NoError: raise cls(result) return args def __init__(self, errorCode): self.errorCode = errorCode Exception.__init__(self, (errorCode, self._errmsg.get(errorCode, "unknown"))) ################################################################################ # # Data types # ################################################################################ class _utf8_char_p(ctypes.c_char_p): @classmethod def from_param(cls, obj): if (obj is not None) and (not isinstance(obj, cls)): if not str(obj): raise TypeError("parameter must be a string type instance") obj = obj.encode("utf-8") return ctypes.c_char_p.from_param(obj) def decode(self): if self.value is None: return None return self.value.decode("utf-8") class _utf8_char_p_non_null(_utf8_char_p): @classmethod def from_param(cls, obj): if obj is None: raise ValueError("parameter cannot be None") return _utf8_char_p.from_param(obj) _DNSServiceFlags = ctypes.c_uint32 _DNSServiceErrorType = ctypes.c_int32 class DNSRecordRef(ctypes.c_void_p): """ A DNSRecordRef pointer. DO NOT CREATE INSTANCES OF THIS CLASS! Only instances returned by the DNS-SD library are valid. Using others will likely cause the Python interpreter to crash. Application code should not use any of the methods of this class. The only valid use of a DNSRecordRef instance is as an argument to a DNS-SD function. To compare two DNSRecordRef instances for equality, use '==' rather than 'is'. """ @classmethod def from_param(cls, obj): if type(obj) is not cls: raise TypeError("expected '%s', got '%s'" % (cls.__name__, type(obj).__name__)) if obj.value is None: raise ValueError("invalid %s instance" % cls.__name__) return obj def __eq__(self, other): return (type(other) is type(self)) and (other.value == self.value) def __ne__(self, other): return not (other == self) def _invalidate(self): self.value = None def _valid(self): return self.value is not None class _DNSRecordRef_or_null(DNSRecordRef): @classmethod def from_param(cls, obj): if obj is None: return obj return DNSRecordRef.from_param(obj) class DNSServiceRef(DNSRecordRef): """ A DNSServiceRef pointer. DO NOT CREATE INSTANCES OF THIS CLASS! Only instances returned by the DNS-SD library are valid. Using others will likely cause the Python interpreter to crash. An instance of this class represents an active connection to the mDNS daemon. The connection remains open until the close() method is called (which also terminates the associated browse, resolve, etc.). Note that this method is *not* called automatically when the instance is deallocated; therefore, application code must be certain to call close() when the connection is no longer needed. The primary use of a DNSServiceRef instance is in conjunction with select() or poll() to determine when a response from the daemon is available. When the file descriptor returned by fileno() is ready for reading, a reply from the daemon is available and should be processed by passing the DNSServiceRef instance to DNSServiceProcessResult(), which will invoke the appropriate application callback function. (Note that the file descriptor should never be read from or written to directly.) The DNSServiceRef class supports the context management protocol introduced in Python 2.5, meaning applications can use the 'with' statement to ensure that DNSServiceRef instances are closed regardless of whether an exception occurs, e.g. sdRef = DNSServiceBrowse(...) with sdRef: # sdRef will be closed regardless of how this block is # exited ... To compare two DNSServiceRef instances for equality, use '==' rather than 'is'. """ def __init__(self, *args, **kwargs): DNSRecordRef.__init__(self, *args, **kwargs) # Since callback functions are called asynchronously, we need # to hold onto references to them for as long as they're in # use. Otherwise, Python could deallocate them before we call # DNSServiceProcessResult(), meaning the Bonjour library would # dereference freed memory when it tried to invoke the # callback. self._callbacks = [] # A DNSRecordRef is invalidated if DNSServiceRefDeallocate() # is called on the corresponding DNSServiceRef, so we need to # keep track of all our record refs and invalidate them when # we're closed. self._record_refs = [] def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() def _add_callback(self, cb): self._callbacks.append(cb) def _add_record_ref(self, ref): self._record_refs.append(ref) def close(self): """ Close the connection to the mDNS daemon and terminate any associated browse, resolve, etc. operations. """ if self._valid(): for ref in self._record_refs: ref._invalidate() del self._record_refs _global_lock.acquire() try: _DNSServiceRefDeallocate(self) finally: _global_lock.release() self._invalidate() del self._callbacks def fileno(self): """ Return the file descriptor associated with this connection. This descriptor should never be read from or written to directly. It should only be passed to select() or poll() to determine when a response from the mDNS daemon is available. """ _global_lock.acquire() try: fd = _DNSServiceRefSockFD(self) finally: _global_lock.release() return fd _DNSServiceDomainEnumReply = _CFunc( None, DNSServiceRef, # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _DNSServiceErrorType, # errorCode _utf8_char_p, # replyDomain ctypes.c_void_p, # context ) _DNSServiceRegisterReply = _CFunc( None, DNSServiceRef, # sdRef _DNSServiceFlags, # flags _DNSServiceErrorType, # errorCode _utf8_char_p, # name _utf8_char_p, # regtype _utf8_char_p, # domain ctypes.c_void_p, # context ) _DNSServiceBrowseReply = _CFunc( None, DNSServiceRef, # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _DNSServiceErrorType, # errorCode _utf8_char_p, # serviceName _utf8_char_p, # regtype _utf8_char_p, # replyDomain ctypes.c_void_p, # context ) _DNSServiceResolveReply = _CFunc( None, DNSServiceRef, # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _DNSServiceErrorType, # errorCode _utf8_char_p, # fullname _utf8_char_p, # hosttarget ctypes.c_uint16, # port ctypes.c_uint16, # txtLen ctypes.c_void_p, # txtRecord (not null-terminated, so c_void_p) ctypes.c_void_p, # context ) _DNSServiceRegisterRecordReply = _CFunc( None, DNSServiceRef, # sdRef DNSRecordRef, # RecordRef _DNSServiceFlags, # flags _DNSServiceErrorType, # errorCode ctypes.c_void_p, # context ) _DNSServiceQueryRecordReply = _CFunc( None, DNSServiceRef, # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _DNSServiceErrorType, # errorCode _utf8_char_p, # fullname ctypes.c_uint16, # rrtype ctypes.c_uint16, # rrclass ctypes.c_uint16, # rdlen ctypes.c_void_p, # rdata ctypes.c_uint32, # ttl ctypes.c_void_p, # context ) ################################################################################ # # Low-level function bindings # ################################################################################ def _create_function_bindings(): ERRCHECK = True NO_ERRCHECK = False OUTPARAM = lambda index: index NO_OUTPARAM = None specs = { #'funcname': # ( # return_type, # errcheck, # outparam, # ( # param_1_type, # param_2_type, # ... # param_n_type, # )), "DNSServiceRefSockFD": (ctypes.c_int, NO_ERRCHECK, NO_OUTPARAM, (DNSServiceRef,)), # sdRef "DNSServiceProcessResult": (_DNSServiceErrorType, ERRCHECK, NO_OUTPARAM, (DNSServiceRef,)), # sdRef "DNSServiceRefDeallocate": (None, NO_ERRCHECK, NO_OUTPARAM, (DNSServiceRef,)), # sdRef "DNSServiceEnumerateDomains": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(0), ( ctypes.POINTER(DNSServiceRef), # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _DNSServiceDomainEnumReply, # callBack ctypes.c_void_p, # context ), ), "DNSServiceRegister": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(0), ( ctypes.POINTER(DNSServiceRef), # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _utf8_char_p, # name _utf8_char_p_non_null, # regtype _utf8_char_p, # domain _utf8_char_p, # host ctypes.c_uint16, # port ctypes.c_uint16, # txtLen ctypes.c_void_p, # txtRecord _DNSServiceRegisterReply, # callBack ctypes.c_void_p, # context ), ), "DNSServiceAddRecord": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(1), ( DNSServiceRef, # sdRef ctypes.POINTER(DNSRecordRef), # RecordRef _DNSServiceFlags, # flags ctypes.c_uint16, # rrtype ctypes.c_uint16, # rdlen ctypes.c_void_p, # rdata ctypes.c_uint32, # ttl ), ), "DNSServiceUpdateRecord": ( _DNSServiceErrorType, ERRCHECK, NO_OUTPARAM, ( DNSServiceRef, # sdRef _DNSRecordRef_or_null, # RecordRef _DNSServiceFlags, # flags ctypes.c_uint16, # rdlen ctypes.c_void_p, # rdata ctypes.c_uint32, # ttl ), ), "DNSServiceRemoveRecord": ( _DNSServiceErrorType, ERRCHECK, NO_OUTPARAM, (DNSServiceRef, DNSRecordRef, _DNSServiceFlags), # sdRef # RecordRef # flags ), "DNSServiceBrowse": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(0), ( ctypes.POINTER(DNSServiceRef), # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _utf8_char_p_non_null, # regtype _utf8_char_p, # domain _DNSServiceBrowseReply, # callBack ctypes.c_void_p, # context ), ), "DNSServiceResolve": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(0), ( ctypes.POINTER(DNSServiceRef), # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _utf8_char_p_non_null, # name _utf8_char_p_non_null, # regtype _utf8_char_p_non_null, # domain _DNSServiceResolveReply, # callBack ctypes.c_void_p, # context ), ), "DNSServiceCreateConnection": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(0), (ctypes.POINTER(DNSServiceRef),), # sdRef ), "DNSServiceRegisterRecord": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(1), ( DNSServiceRef, # sdRef ctypes.POINTER(DNSRecordRef), # RecordRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _utf8_char_p_non_null, # fullname ctypes.c_uint16, # rrtype ctypes.c_uint16, # rrclass ctypes.c_uint16, # rdlen ctypes.c_void_p, # rdata ctypes.c_uint32, # ttl _DNSServiceRegisterRecordReply, # callBack ctypes.c_void_p, # context ), ), "DNSServiceQueryRecord": ( _DNSServiceErrorType, ERRCHECK, OUTPARAM(0), ( ctypes.POINTER(DNSServiceRef), # sdRef _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _utf8_char_p_non_null, # fullname ctypes.c_uint16, # rrtype ctypes.c_uint16, # rrclass _DNSServiceQueryRecordReply, # callBack ctypes.c_void_p, # context ), ), "DNSServiceReconfirmRecord": ( None, # _DNSServiceErrorType in more recent versions NO_ERRCHECK, NO_OUTPARAM, ( _DNSServiceFlags, # flags ctypes.c_uint32, # interfaceIndex _utf8_char_p_non_null, # fullname ctypes.c_uint16, # rrtype ctypes.c_uint16, # rrclass ctypes.c_uint16, # rdlen ctypes.c_void_p, # rdata ), ), "DNSServiceConstructFullName": ( ctypes.c_int, ERRCHECK, OUTPARAM(0), ( ctypes.c_char * kDNSServiceMaxDomainName, # fullName _utf8_char_p, # service _utf8_char_p_non_null, # regtype _utf8_char_p_non_null, # domain ), ), } for name, (restype, errcheck, outparam, argtypes) in specs.items(): prototype = _CFunc(restype, *argtypes) paramflags = [1] * len(argtypes) if outparam is not None: paramflags[outparam] = 2 paramflags = tuple((val,) for val in paramflags) func = prototype((name, _libdnssd), paramflags) if errcheck: func.errcheck = BonjourError._errcheck globals()["_" + name] = func # Only need to do this once _create_function_bindings() del _create_function_bindings ################################################################################ # # Internal utility types and functions # ################################################################################ class _NoDefault(object): def __repr__(self): return "" def check(self, obj): if obj is self: raise ValueError("required parameter value missing") _NO_DEFAULT = _NoDefault() def _string_to_length_and_void_p(string): if isinstance(string, TXTRecord): string = str(string) void_p = ctypes.cast(ctypes.c_char_p(string), ctypes.c_void_p) return len(string), void_p def _length_and_void_p_to_string(length, void_p): char_p = ctypes.cast(void_p, ctypes.POINTER(ctypes.c_char)) return "".join(char_p[i].decode("utf-8") for i in range(length)) ################################################################################ # # High-level functions # ################################################################################ def DNSServiceProcessResult( sdRef, ): """ Read a reply from the daemon, calling the appropriate application callback. This call will block until the daemon's response is received. Use sdRef in conjunction with select() or poll() to determine the presence of a response from the server before calling this function to process the reply without blocking. Call this function at any point if it is acceptable to block until the daemon's response arrives. Note that the client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is a reply from the daemon; the daemon may terminate its connection with a client that does not process the daemon's responses. sdRef: A DNSServiceRef returned by any of the DNSService calls that take a callback parameter. """ _global_lock.acquire() try: _DNSServiceProcessResult(sdRef) finally: _global_lock.release() def DNSServiceEnumerateDomains(flags, interfaceIndex=kDNSServiceInterfaceIndexAny, callBack=None): """ Asynchronously enumerate domains available for browsing and registration. The enumeration MUST be cancelled by closing the returned DNSServiceRef when no more domains are to be found. flags: Possible values are: kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing. kDNSServiceFlagsRegistrationDomains to enumerate domains recommended for registration. interfaceIndex: If non-zero, specifies the interface on which to look for domains. Most applications will pass kDNSServiceInterfaceIndexAny (0) to enumerate domains on all interfaces. callBack: The function to be called when a domain is found or the call asynchronously fails. Its signature should be callBack(sdRef, flags, interfaceIndex, errorCode, replyDomain). return value: A DNSServiceRef instance. Callback Parameters: sdRef: The DNSServiceRef returned by DNSServiceEnumerateDomains(). flags: Possible values are: kDNSServiceFlagsMoreComing kDNSServiceFlagsAdd kDNSServiceFlagsDefault interfaceIndex: Specifies the interface on which the domain exists. errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise indicates the failure that occurred (in which case other parameters are undefined). replyDomain: The name of the domain. """ @_DNSServiceDomainEnumReply def _callback(sdRef, flags, interfaceIndex, errorCode, replyDomain, context): if callBack is not None: callBack(sdRef, flags, interfaceIndex, errorCode, replyDomain.decode()) _global_lock.acquire() try: sdRef = _DNSServiceEnumerateDomains(flags, interfaceIndex, _callback, None) finally: _global_lock.release() sdRef._add_callback(_callback) return sdRef def DNSServiceRegister( flags=0, interfaceIndex=kDNSServiceInterfaceIndexAny, name=None, regtype=_NO_DEFAULT, domain=None, host=None, port=_NO_DEFAULT, txtRecord="", callBack=None, ): """ Register a service that is discovered via DNSServiceBrowse() and DNSServiceResolve() calls. flags: Indicates the renaming behavior on name conflict. Most applications will pass 0. interfaceIndex: If non-zero, specifies the interface on which to register the service. Most applications will pass kDNSServiceInterfaceIndexAny (0) to register on all available interfaces. name: If not None, specifies the service name to be registered. Most applications will not specify a name, in which case the computer name is used. (This name is communicated to the client via the callback.) If a name is specified, it must be 1-63 bytes of UTF-8 text. If the name is longer than 63 bytes, it will be automatically truncated to a legal length, unless the flag kDNSServiceFlagsNoAutoRename is set, in which case a BonjourError exception will be thrown. regtype: The service type followed by the protocol, separated by a dot (e.g. "_ftp._tcp"). The service type must be an underscore, followed by 1-14 characters, which may be letters, digits, or hyphens. The transport protocol must be "_tcp" or "_udp". New service types should be registered at . domain: If not None, specifies the domain on which to advertise the service. Most applications will not specify a domain, instead automatically registering in the default domain(s). host: If not None, specifies the SRV target host name. Most applications will not specify a host, instead automatically using the machine's default host name(s). Note that specifying a host name does NOT create an address record for that host; the application is responsible for ensuring that the appropriate address record exists, or creating it via DNSServiceRegisterRecord(). port: The port, in host (not network) byte order, on which the service accepts connections. Pass 0 for a "placeholder" service (i.e. a service that will not be discovered by browsing, but will cause a name conflict if another client tries to register that same name). Most clients will not use placeholder services. txtRecord: The TXT record rdata. If not None, txtRecord must be either a TXTRecord instance or a string containing a properly formatted DNS TXT record, i.e. ... callBack: The function to be called when the registration completes or asynchronously fails. Its signature should be callBack(sdRef, flags, errorCode, name, regtype, domain). The client MAY pass None for the callback, in which case the client will NOT be notified of the default values picked on its behalf, and the client will NOT be notified of any asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration of the service. The client may NOT pass the flag kDNSServiceFlagsNoAutoRename if the callback is None. The client may still deregister the service at any time by closing the returned DNSServiceRef. return value: A DNSServiceRef instance. The registration will remain active indefinitely until the client terminates it by closing the DNSServiceRef. Callback Parameters: sdRef: The DNSServiceRef returned by DNSServiceRegister(). flags: Currently unused, reserved for future use. errorCode: Will be kDNSServiceErr_NoError on success, otherwise will indicate the failure that occurred (including name conflicts, if the kDNSServiceFlagsNoAutoRename flag was used when registering). Other parameters are undefined if an error occurred. name: The service name registered. (If the application did not specify a name in DNSServiceRegister(), this indicates what name was automatically chosen.) regtype: The type of service registered, as it was passed to the callout. domain: The domain on which the service was registered. (If the application did not specify a domain in DNSServiceRegister(), this indicates the default domain on which the service was registered.) """ _NO_DEFAULT.check(regtype) _NO_DEFAULT.check(port) port = socket.htons(port) # From here on txtRecord has to be a bytes type, so convert what # we have: if type(txtRecord) == TXTRecord: txtRecord = str(txtRecord).encode("utf-8") elif type(txtRecord) == str: txtRecord = txtRecord.encode("utf-8") else: raise TypeError("txtRecord is unhandlable type: {type}".format(type=type(txtRecord))) if not txtRecord: txtLen, txtRecord = 1, "\0" else: txtLen, txtRecord = _string_to_length_and_void_p(txtRecord) @_DNSServiceRegisterReply def _callback(sdRef, flags, errorCode, name, regtype, domain, context): if callBack is not None: callBack(sdRef, flags, errorCode, name.decode(), regtype.decode(), domain.decode()) _global_lock.acquire() try: sdRef = _DNSServiceRegister( flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, _callback, None ) finally: _global_lock.release() sdRef._add_callback(_callback) return sdRef def DNSServiceAddRecord(sdRef, flags=0, rrtype=_NO_DEFAULT, rdata=_NO_DEFAULT, ttl=0): """ Add a record to a registered service. The name of the record will be the same as the registered service's name. The record can later be updated or deregistered by passing the DNSRecordRef returned by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord(). Note that DNSServiceAddRecord/UpdateRecord/RemoveRecord are NOT thread-safe with respect to a single DNSServiceRef. If you plan to have multiple threads in your program simultaneously add, update, or remove records from the same DNSServiceRef, then it's the caller's responsibility to use a lock or take similar appropriate precautions to serialize those calls. sdRef: A DNSServiceRef returned by DNSServiceRegister(). flags: Currently ignored, reserved for future use. rrtype: The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc.). rdata: A string containing the raw rdata to be contained in the added resource record. ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value. return value: A DNSRecordRef instance, which may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord(). If sdRef is closed, the DNSRecordRef is also invalidated and may not be used further. """ _NO_DEFAULT.check(rrtype) _NO_DEFAULT.check(rdata) rdlen, rdata = _string_to_length_and_void_p(rdata) _global_lock.acquire() try: RecordRef = _DNSServiceAddRecord(sdRef, flags, rrtype, rdlen, rdata, ttl) finally: _global_lock.release() sdRef._add_record_ref(RecordRef) return RecordRef def DNSServiceUpdateRecord(sdRef, RecordRef=None, flags=0, rdata=_NO_DEFAULT, ttl=0): """ Update a registered resource record. The record must either be: - The primary txt record of a service registered via DNSServiceRegister(), or - A record added to a registered service via DNSServiceAddRecord(), or - An individual record registered by DNSServiceRegisterRecord() sdRef: A DNSServiceRef returned by DNSServiceRegister() or DNSServiceCreateConnection(). RecordRef: A DNSRecordRef returned by DNSServiceAddRecord(), or None to update the service's primary txt record. flags: Currently ignored, reserved for future use. rdata: A string containing the new rdata to be contained in the updated resource record. ttl: The time to live of the updated resource record, in seconds. """ _NO_DEFAULT.check(rdata) rdlen, rdata = _string_to_length_and_void_p(rdata) _global_lock.acquire() try: _DNSServiceUpdateRecord(sdRef, RecordRef, flags, rdlen, rdata, ttl) finally: _global_lock.release() def DNSServiceRemoveRecord(sdRef, RecordRef, flags=0): """ Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister a record registered individually via DNSServiceRegisterRecord(). sdRef: A DNSServiceRef returned by DNSServiceRegister() (if the record being removed was registered via DNSServiceAddRecord()) or by DNSServiceCreateConnection() (if the record being removed was registered via DNSServiceRegisterRecord()). recordRef: A DNSRecordRef returned by DNSServiceAddRecord() or DNSServiceRegisterRecord(). flags: Currently ignored, reserved for future use. """ _global_lock.acquire() try: _DNSServiceRemoveRecord(sdRef, RecordRef, flags) finally: _global_lock.release() RecordRef._invalidate() def DNSServiceBrowse( flags=0, interfaceIndex=kDNSServiceInterfaceIndexAny, regtype=_NO_DEFAULT, domain=None, callBack=None ): """ Browse for instances of a service. flags: Currently ignored, reserved for future use. interfaceIndex: If non-zero, specifies the interface on which to browse for services. Most applications will pass kDNSServiceInterfaceIndexAny (0) to browse on all available interfaces. regtype: The service type being browsed for followed by the protocol, separated by a dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp". domain: If not None, specifies the domain on which to browse for services. Most applications will not specify a domain, instead browsing on the default domain(s). callBack: The function to be called when an instance of the service being browsed for is found, or if the call asynchronously fails. Its signature should be callBack(sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain). return value: A DNSServiceRef instance. The browse operation will run indefinitely until the client terminates it by closing the DNSServiceRef. Callback Parameters: sdRef: The DNSServiceRef returned by DNSServiceBrowse(). flags: Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd. interfaceIndex: The interface on which the service is advertised. This index should be passed to DNSServiceResolve() when resolving the service. errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will indicate the failure that occurred. Other parameters are undefined if an error occurred. serviceName: The discovered service name. This name should be displayed to the user and stored for subsequent use in the DNSServiceResolve() call. regtype: The service type, which is usually (but not always) the same as was passed to DNSServiceBrowse(). One case where the discovered service type may not be the same as the requested service type is when using subtypes: The client may want to browse for only those ftp servers that allow anonymous connections. The client will pass the string "_ftp._tcp,_anon" to DNSServiceBrowse(), but the type of the service that's discovered is simply "_ftp._tcp". The regtype for each discovered service instance should be stored along with the name, so that it can be passed to DNSServiceResolve() when the service is later resolved. replyDomain: The domain of the discovered service instance. This may or may not be the same as the domain that was passed to DNSServiceBrowse(). The domain for each discovered service instance should be stored along with the name, so that it can be passed to DNSServiceResolve() when the service is later resolved. """ _NO_DEFAULT.check(regtype) @_DNSServiceBrowseReply def _callback(sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain, context): if callBack is not None: callBack( sdRef, flags, interfaceIndex, errorCode, serviceName.decode(), regtype.decode(), replyDomain.decode() ) _global_lock.acquire() try: sdRef = _DNSServiceBrowse(flags, interfaceIndex, regtype, domain, _callback, None) finally: _global_lock.release() sdRef._add_callback(_callback) return sdRef def DNSServiceResolve( flags=0, interfaceIndex=_NO_DEFAULT, name=_NO_DEFAULT, regtype=_NO_DEFAULT, domain=_NO_DEFAULT, callBack=None ): """ Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and txt record. Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring; use DNSServiceQueryRecord() instead, as it is more efficient for this task. Note: When the desired results have been returned, the client MUST terminate the resolve by closing the returned DNSServiceRef. Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record and a single TXT record. To resolve non-standard services with multiple SRV or TXT records, DNSServiceQueryRecord() should be used. flags: Currently ignored, reserved for future use. interfaceIndex: The interface on which to resolve the service. If this resolve call is as a result of a currently active DNSServiceBrowse() operation, then the interfaceIndex should be the index reported in the browse callback. If this resolve call is using information previously saved (e.g. in a preference file) for later use, then use kDNSServiceInterfaceIndexAny (0), because the desired service may now be reachable via a different physical interface. name: The name of the service instance to be resolved, as reported to the DNSServiceBrowse() callback. regtype: The type of the service instance to be resolved, as reported to the DNSServiceBrowse() callback. domain: The domain of the service instance to be resolved, as reported to the DNSServiceBrowse() callback. callBack: The function to be called when a result is found, or if the call asynchronously fails. Its signature should be callBack(sdRef, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtRecord). return value: A DNSServiceRef instance. The resolve operation will run indefinitely until the client terminates it by closing the DNSServiceRef. Callback Parameters: sdRef: The DNSServiceRef returned by DNSServiceResolve(). flags: Currently unused, reserved for future use. interfaceIndex: The interface on which the service was resolved. errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will indicate the failure that occurred. Other parameters are undefined if an error occurred. fullname: The full service domain name, in the form ... hosttarget: The target hostname of the machine providing the service. port: The port, in host (not network) byte order, on which connections are accepted for this service. txtRecord: A string containing the service's primary txt record, in standard txt record format. """ _NO_DEFAULT.check(interfaceIndex) _NO_DEFAULT.check(name) _NO_DEFAULT.check(regtype) _NO_DEFAULT.check(domain) @_DNSServiceResolveReply def _callback(sdRef, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtLen, txtRecord, context): if callBack is not None: port = socket.ntohs(port) txtRecord = _length_and_void_p_to_string(txtLen, txtRecord) callBack(sdRef, flags, interfaceIndex, errorCode, fullname.decode(), hosttarget.decode(), port, txtRecord) _global_lock.acquire() try: sdRef = _DNSServiceResolve(flags, interfaceIndex, name, regtype, domain, _callback, None) finally: _global_lock.release() sdRef._add_callback(_callback) return sdRef def DNSServiceCreateConnection(): """ Create a connection to the daemon allowing efficient registration of multiple individual records. return value: A DNSServiceRef instance. Closing it severs the connection and deregisters all records registered on this connection. """ _global_lock.acquire() try: sdRef = _DNSServiceCreateConnection() finally: _global_lock.release() return sdRef def DNSServiceRegisterRecord( sdRef, flags, interfaceIndex=kDNSServiceInterfaceIndexAny, fullname=_NO_DEFAULT, rrtype=_NO_DEFAULT, rrclass=kDNSServiceClass_IN, rdata=_NO_DEFAULT, ttl=0, callBack=None, ): """ Register an individual resource record on a connected DNSServiceRef. Note that name conflicts occurring for records registered via this call must be handled by the client in the callback. sdRef: A DNSServiceRef returned by DNSServiceCreateConnection(). flags: Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique. interfaceIndex: If non-zero, specifies the interface on which to register the record. Passing kDNSServiceInterfaceIndexAny (0) causes the record to be registered on all interfaces. fullname: The full domain name of the resource record. rrtype: The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc.). rrclass: The class of the resource record (usually kDNSServiceClass_IN). rdata: A string containing the raw rdata, as it is to appear in the DNS record. ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value. callBack: The function to be called when a result is found, or if the call asynchronously fails (e.g. because of a name conflict). Its signature should be callBack(sdRef, RecordRef, flags, errorCode). return value: A DNSRecordRef instance, which may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord(). (To deregister ALL records registered on a single connected DNSServiceRef and deallocate each of their corresponding DNSRecordRefs, close the DNSServiceRef.) Callback Parameters: sdRef: The connected DNSServiceRef returned by DNSServiceCreateConnection(). RecordRef: The DNSRecordRef returned by DNSServiceRegisterRecord(). flags: Currently unused, reserved for future use. errorCode: Will be kDNSServiceErr_NoError on success, otherwise will indicate the failure that occurred (including name conflicts). Other parameters are undefined if an error occurred. """ _NO_DEFAULT.check(fullname) _NO_DEFAULT.check(rrtype) _NO_DEFAULT.check(rdata) rdlen, rdata = _string_to_length_and_void_p(rdata) @_DNSServiceRegisterRecordReply def _callback(sdRef, RecordRef, flags, errorCode, context): if callBack is not None: callBack(sdRef, RecordRef, flags, errorCode) _global_lock.acquire() try: RecordRef = _DNSServiceRegisterRecord( sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata, ttl, _callback, None ) finally: _global_lock.release() sdRef._add_callback(_callback) sdRef._add_record_ref(RecordRef) return RecordRef def DNSServiceQueryRecord( flags=0, interfaceIndex=kDNSServiceInterfaceIndexAny, fullname=_NO_DEFAULT, rrtype=_NO_DEFAULT, rrclass=kDNSServiceClass_IN, callBack=None, ): """ Query for an arbitrary DNS record. flags: Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast query in a non-local domain. Without setting this flag, unicast queries will be one-shot; that is, only answers available at the time of the call will be returned. By setting this flag, answers (including Add and Remove events) that become available after the initial call is made will generate callbacks. This flag has no effect on link-local multicast queries. interfaceIndex: If non-zero, specifies the interface on which to issue the query. Passing kDNSServiceInterfaceIndexAny (0) causes the name to be queried for on all interfaces. fullname: The full domain name of the resource record to be queried for. rrtype: The numerical type of the resource record to be queried for (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc.). rrclass: The class of the resource record (usually kDNSServiceClass_IN). callBack: The function to be called when a result is found, or if the call asynchronously fails. Its signature should be callBack(sdRef, flags, interfaceIndex, errorCode, fullname, rrtype, rrclass, rdata, ttl). return value: A DNSServiceRef instance. The query operation will run indefinitely until the client terminates it by closing the DNSServiceRef. Callback Parameters: sdRef: The DNSServiceRef returned by DNSServiceQueryRecord(). flags: Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd. The Add flag is NOT set for PTR records with a ttl of 0, i.e. "Remove" events. interfaceIndex: The interface on which the query was resolved. errorCode: Will be kDNSServiceErr_NoError on success, otherwise will indicate the failure that occurred. Other parameters are undefined if an error occurred. fullname: The resource record's full domain name. rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc.). rrclass: The class of the resource record (usually kDNSServiceClass_IN). rdata: A string containing the raw rdata of the resource record. ttl: The resource record's time to live, in seconds. """ _NO_DEFAULT.check(fullname) _NO_DEFAULT.check(rrtype) @_DNSServiceQueryRecordReply def _callback(sdRef, flags, interfaceIndex, errorCode, fullname, rrtype, rrclass, rdlen, rdata, ttl, context): if callBack is not None: rdata = _length_and_void_p_to_string(rdlen, rdata) callBack(sdRef, flags, interfaceIndex, errorCode, fullname.decode(), rrtype, rrclass, rdata, ttl) _global_lock.acquire() try: sdRef = _DNSServiceQueryRecord(flags, interfaceIndex, fullname, rrtype, rrclass, _callback, None) finally: _global_lock.release() sdRef._add_callback(_callback) return sdRef def DNSServiceReconfirmRecord( flags=0, interfaceIndex=kDNSServiceInterfaceIndexAny, fullname=_NO_DEFAULT, rrtype=_NO_DEFAULT, rrclass=kDNSServiceClass_IN, rdata=_NO_DEFAULT, ): """ Instruct the daemon to verify the validity of a resource record that appears to be out of date (e.g. because tcp connection to a service's target failed). Causes the record to be flushed from the daemon's cache (as well as all other daemons' caches on the network) if the record is determined to be invalid. flags: Currently unused, reserved for future use. interfaceIndex: If non-zero, specifies the interface of the record in question. Passing kDNSServiceInterfaceIndexAny (0) causes all instances of this record to be reconfirmed. fullname: The resource record's full domain name. rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc.). rrclass: The class of the resource record (usually kDNSServiceClass_IN). rdata: A string containing the raw rdata of the resource record. """ _NO_DEFAULT.check(fullname) _NO_DEFAULT.check(rrtype) _NO_DEFAULT.check(rdata) rdlen, rdata = _string_to_length_and_void_p(rdata) _global_lock.acquire() try: _DNSServiceReconfirmRecord(flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata) finally: _global_lock.release() def DNSServiceConstructFullName(service=None, regtype=_NO_DEFAULT, domain=_NO_DEFAULT): r""" Concatenate a three-part domain name (as returned by a callback function) into a properly-escaped full domain name. Note that callback functions already escape strings where necessary. service: The service name; any dots or backslashes must NOT be escaped. May be None (to construct a PTR record name, e.g. "_ftp._tcp.apple.com."). regtype: The service type followed by the protocol, separated by a dot (e.g. "_ftp._tcp"). domain: The domain name, e.g. "apple.com.". Literal dots or backslashes, if any, must be escaped, e.g. "1st\. Floor.apple.com." return value: The resulting full domain name. """ _NO_DEFAULT.check(regtype) _NO_DEFAULT.check(domain) _global_lock.acquire() try: fullName = _DNSServiceConstructFullName(service, regtype, domain) finally: _global_lock.release() return fullName.value.decode("utf-8") ################################################################################ # # TXTRecord class # ################################################################################ class TXTRecord(object): """ A mapping representing a DNS TXT record. The TXT record's name=value entries are stored as key/value pairs in the mapping. Although keys can be accessed in a case-insensitive fashion (meaning txt['foo'] and txt['FoO'] refer to the same value), key case is preserved in the wire representation of the record (so txt['FoO'] = 'bar' will generate a FoO=bar entry in the TXT record). Key order is also preserved, so keys appear in the wire format in the order in which they were created. Note that in addition to being valid as a txtRecord parameter to DNSServiceRegister(), a TXTRecord instance can be used in place of a resource record data string (i.e. rdata parameter) with any function that accepts one. """ def __init__(self, items={}, strict=True): """ Create a new TXTRecord instance, initializing it with the contents of items. If strict is true, then strict conformance to the DNS TXT record format will be enforced, and attempts to add a name containing invalid characters or a name/value pair whose wire representation is longer than 255 bytes will raise a ValueError exception. """ self.strict = strict self._names = [] self._items = {} for name, value in items.items(): self[name] = value def __contains__(self, name): "Return True if name is a key in the record, False otherwise" return name.lower() in self._items def __iter__(self): "Return an iterator over name/value pairs" for name in self._names: yield self._items[name] def __len__(self): "Return the number of name/value pairs" return len(self._names) def __bool__(self): "Return False if the record is empty, True otherwise" return bool(self._items) def __str__(self): """ Return the wire representation of the TXT record as a string. If self.strict is false, any name/value pair whose wire length if greater than 255 bytes will be truncated to 255 bytes. If the record is empty, '\\0' is returned. """ if not self: return "\0" parts = [] for name, value in self: if value is None: item = name else: item = "%s=%s" % (name, value) if (not self.strict) and (len(item) > 255): item = item[:255] parts.append(chr(len(item))) parts.append(item) return "".join(parts) def __getitem__(self, name): """ Return the value associated with name. The value is either None (meaning name has no associated value) or an str instance (which may be of length 0). Raises KeyError if name is not a key. """ return self._items[name.lower()][1] # Require one or more printable ASCII characters (0x20-0x7E), # excluding '=' (0x3D) _valid_name_re = re.compile(r"^[ -<>-~]+$") def __setitem__(self, name, value): """ Add a name/value pair to the record. If value is None, then name will have no associated value. If value is a unicode instance, it will be encoded as a UTF-8 string. Otherwise, value will be converted to an str instance. """ stored_name = name name = name.lower() length = len(name) if value is not None: value = str(value) length += 1 + len(value) if self.strict and (length > 255): raise ValueError("name=value string must be 255 bytes or less") if name not in self._items: if self.strict and (self._valid_name_re.match(stored_name) is None): raise ValueError("invalid name: '%s'" % stored_name) self._names.append(name) self._items[name] = (stored_name, value) def __delitem__(self, name): """ Remove name and its corresponding value from the record. Raises KeyError if name is not a key. """ name = name.lower() del self._items[name] self._names.remove(name) @classmethod def parse(cls, data, strict=False): """ Given a string data containing the wire representation of a DNS TXT record, parse it and return a TXTRecord instance. The strict parameter is passed to the TXTRecord constructor. """ txt = cls(strict=strict) while data: length = ord(data[0]) item = data[1 : length + 1].split("=", 1) # Add the item only if the name is non-empty and there are # no existing items with the same name if item[0] and (item[0] not in txt): if len(item) == 1: txt[item[0]] = None else: txt[item[0]] = item[1] data = data[length + 1 :] return txt ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4497576 SABnzbd-4.3.2/sabnzbd/utils/__init__.py0000644000000000000000000000004414625637243017115 0ustar00runnerstaff# Needed so the import always works ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4498417 SABnzbd-4.3.2/sabnzbd/utils/diskspeed.py0000644000000000000000000000461614625637243017342 0ustar00runnerstaff#!/usr/bin/python3 """ Measure writing speed of disk specified (or working directory if not specified)""" import os import sys import logging import time _DUMP_DATA_SIZE = 10 * 1024 * 1024 def diskspeedmeasure(dirname: str) -> float: """Returns writing speed to my_dirname in MB/s method: keep writing a file, until certain time is passed. Then divide bytes written by time passed In case of problems (ie non-writable dir or file), return 0.0 """ dump_data = os.urandom(_DUMP_DATA_SIZE) start = time.time() maxtime = 0.5 # sec total_written = 0 filename = os.path.join(dirname, "outputTESTING.txt") try: # Use low-level I/O try: fp_testfile = os.open(filename, os.O_CREAT | os.O_WRONLY | os.O_BINARY, 0o777) except AttributeError: fp_testfile = os.open(filename, os.O_CREAT | os.O_WRONLY, 0o777) # Start looping total_time = 0.0 while total_time < maxtime: start = time.time() os.write(fp_testfile, dump_data) os.fsync(fp_testfile) total_time += time.time() - start total_written += _DUMP_DATA_SIZE # Have to use low-level close os.close(fp_testfile) # Remove the file os.remove(filename) except OSError: # Could not write, so ... report 0.0 logging.debug("Failed to measure disk speed on %s", dirname) return 0.0 megabyte_per_second = round(total_written / total_time / 1024 / 1024, 1) logging.debug("Disk speed of %s = %.2f MB/s (in %.2f seconds)", dirname, megabyte_per_second, time.time() - start) return megabyte_per_second if __name__ == "__main__": print("Let's go") if len(sys.argv) >= 2: DIRNAME = sys.argv[1] if not os.path.isdir(DIRNAME): print("Specified argument is not a directory. Bailing out") sys.exit(1) else: # no argument, so use current working directory DIRNAME = os.getcwd() print("Using current working directory") try: SPEED = max(diskspeedmeasure(DIRNAME), diskspeedmeasure(DIRNAME)) if SPEED: print("Disk writing speed: %.2f Mbytes per second" % SPEED) else: print("No measurement possible. Check that directory is writable.") except: print("Something went wrong. I don't know what") raise print("Done") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4499707 SABnzbd-4.3.2/sabnzbd/utils/certgen.py0000644000000000000000000000632614625637243017016 0ustar00runnerstaff#!/usr/bin/python3 """ Adapted from the docs of cryptography Creates a key and self-signed certificate for local use """ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import rsa from cryptography import x509 from cryptography.x509.oid import NameOID import datetime import socket from sabnzbd.getipaddress import local_ipv4 def generate_key(key_size=2048, output_file="key.pem"): """Generate the private-key file for the self-signed certificate Ported from cryptography docs/x509/tutorial.rst (set with no encryption) """ # Generate our key private_key = rsa.generate_private_key(public_exponent=65537, key_size=key_size, backend=default_backend()) # Write our key to disk for safe keeping with open(output_file, "wb") as f: f.write( private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption(), ) ) return private_key def generate_local_cert(private_key, days_valid=3560, output_file="cert.cert", LN="SABnzbd", ON="SABnzbd"): """Generate a certificate, using basic information. Ported from cryptography docs/x509/tutorial.rst """ # Various details about who we are. For a self-signed certificate the # subject and issuer are always the same. subject = issuer = x509.Name( [ x509.NameAttribute(NameOID.LOCALITY_NAME, LN), x509.NameAttribute(NameOID.ORGANIZATION_NAME, ON), # x509.NameAttribute(NameOID.COMMON_NAME, CN), ] ) # build Subject Alternate Names (aka SAN) list # First the host names, add with x509.DNSName(): san_list = [x509.DNSName("localhost"), x509.DNSName(str(socket.gethostname()))] # Then the host IP addresses, add with x509.IPAddress() # Inside a try-except, just to be sure try: import ipaddress san_list.append(x509.IPAddress(ipaddress.IPv4Address("127.0.0.1"))) san_list.append(x509.IPAddress(ipaddress.IPv6Address("::1"))) # append local v4 ip mylocalipv4 = local_ipv4() if mylocalipv4: san_list.append(x509.IPAddress(ipaddress.IPv4Address(str(mylocalipv4)))) except: pass cert = ( x509.CertificateBuilder() .subject_name(subject) .issuer_name(issuer) .public_key(private_key.public_key()) .not_valid_before(datetime.datetime.now(datetime.timezone.utc)) .not_valid_after(datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=days_valid)) .serial_number(x509.random_serial_number()) .add_extension(x509.SubjectAlternativeName(san_list), critical=True) .sign(private_key, hashes.SHA256(), default_backend()) ) # Write our certificate out to disk. with open(output_file, "wb") as f: f.write(cert.public_bytes(serialization.Encoding.PEM)) return cert if __name__ == "__main__": print("Making key") private_key = generate_key() print("Making cert") cert = generate_local_cert(private_key) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4500546 SABnzbd-4.3.2/sabnzbd/utils/kronos.py0000644000000000000000000004500214625637243016674 0ustar00runnerstaff#!/usr/bin/python3 """Module that provides a cron-like task scheduler. This task scheduler is designed to be used from inside your own program. You can schedule Python functions to be called at specific intervals or days. It uses the standard 'sched' module for the actual task scheduling, but provides much more: * repeated tasks (at intervals, or on specific days) * error handling (exceptions in tasks don't kill the scheduler) * optional to run scheduler in its own thread or separate process * optional to run a task in its own thread or separate process If the threading module is available, you can use the various Threaded variants of the scheduler and associated tasks. If threading is not available, you could still use the forked variants. If fork is also not available, all processing is done in a single process, sequentially. There are three Scheduler classes: Scheduler ThreadedScheduler ForkedScheduler You usually add new tasks to a scheduler using the add_interval_task or add_daytime_task methods, with the appropriate processmethod argument to select sequential, threaded or forked processing. NOTE: it is impossible to add new tasks to a ForkedScheduler, after the scheduler has been started! For more control you can use one of the following Task classes and use schedule_task or schedule_task_abs: IntervalTask ThreadedIntervalTask ForkedIntervalTask SingleTask ThreadedSingleTask ForkedSingleTask WeekdayTask ThreadedWeekdayTask ForkedWeekdayTask MonthdayTask ThreadedMonthdayTask ForkedMonthdayTask Kronos is the Greek God of Time. Kronos scheduler (c) Irmen de Jong. This version has been extracted from the Turbogears source repository and slightly changed to be completely stand-alone again. Also some fixes have been made to make it work on Python 2.6 (sched module changes). The version in Turbogears is based on the original stand-alone Kronos. This is open-source software, released under the MIT Software License: http://www.opensource.org/licenses/mit-license.php Adapted to work on Python 3 by the SABnzbd-Team. """ __version__ = "2.1" __all__ = [ "DayTaskRescheduler", "ForkedIntervalTask", "ForkedMonthdayTask", "ForkedScheduler", "ForkedSingleTask", "ForkedTaskMixin", "ForkedWeekdayTask", "IntervalTask", "MonthdayTask", "Scheduler", "SingleTask", "Task", "ThreadedIntervalTask", "ThreadedMonthdayTask", "ThreadedScheduler", "ThreadedSingleTask", "ThreadedTaskMixin", "ThreadedWeekdayTask", "WeekdayTask", "method", ] import os import sched import time import weakref import logging import threading class method: sequential = "sequential" forked = "forked" threaded = "threaded" class Scheduler: """The Scheduler itself.""" def __init__(self): self.running = True self.sched = sched.scheduler(time.time, self.__delayfunc) def __delayfunc(self, delay): # This delay function is basically a time.sleep() that is # divided up, so that we can check the self.running flag while delaying. # there is an additional check in here to ensure that the top item of # the queue hasn't changed if delay < 10: time.sleep(delay) else: toptime = self._getqueuetoptime() endtime = time.time() + delay period = 5 stoptime = endtime - period while self.running and stoptime > time.time() and self._getqueuetoptime() == toptime: time.sleep(period) if not self.running or self._getqueuetoptime() != toptime: return now = time.time() if endtime > now: time.sleep(endtime - now) def _acquire_lock(self): pass def _release_lock(self): pass def add_interval_task( self, action, taskname, initialdelay, interval, processmethod=method.sequential, args=None, kw=None ): """Add a new Interval Task to the schedule. A very short initialdelay or one of zero cannot be honored, you will see a slight delay before the task is first executed. This is because the scheduler needs to pick it up in its loop. """ if initialdelay < 0 or interval < 1: raise ValueError("Delay or interval must be >0") # Select the correct IntervalTask class. Not all types may be available! if processmethod == method.sequential: TaskClass = IntervalTask elif processmethod == method.threaded: TaskClass = ThreadedIntervalTask elif processmethod == method.forked: TaskClass = ForkedIntervalTask else: raise ValueError("Invalid processmethod") if not args: args = [] if not kw: kw = {} task = TaskClass(taskname, interval, action, args, kw) self.schedule_task(task, initialdelay) return task def add_single_task(self, action, taskname, initialdelay, processmethod=method.sequential, args=None, kw=None): """Add a new task to the scheduler that will only be executed once.""" if initialdelay < 0: raise ValueError("Delay must be >0") # Select the correct SingleTask class. Not all types may be available! if processmethod == method.sequential: TaskClass = SingleTask elif processmethod == method.threaded: TaskClass = ThreadedSingleTask elif processmethod == method.forked: TaskClass = ForkedSingleTask else: raise ValueError("Invalid processmethod") if not args: args = [] if not kw: kw = {} task = TaskClass(taskname, action, args, kw) self.schedule_task(task, initialdelay) return task def add_daytime_task( self, action, taskname, weekdays, monthdays, timeonday, processmethod=method.sequential, args=None, kw=None ): """Add a new Day Task (Weekday or Monthday) to the schedule.""" if weekdays and monthdays: raise ValueError("You can only specify weekdays or monthdays, " "not both") if not args: args = [] if not kw: kw = {} if weekdays: # Select the correct WeekdayTask class. # Not all types may be available! if processmethod == method.sequential: TaskClass = WeekdayTask elif processmethod == method.threaded: TaskClass = ThreadedWeekdayTask elif processmethod == method.forked: TaskClass = ForkedWeekdayTask else: raise ValueError("Invalid processmethod") task = TaskClass(taskname, weekdays, timeonday, action, args, kw) if monthdays: # Select the correct MonthdayTask class. # Not all types may be available! if processmethod == method.sequential: TaskClass = MonthdayTask elif processmethod == method.threaded: TaskClass = ThreadedMonthdayTask elif processmethod == method.forked: TaskClass = ForkedMonthdayTask else: raise ValueError("Invalid processmethod") task = TaskClass(taskname, monthdays, timeonday, action, args, kw) firsttime = task.get_schedule_time(True) self.schedule_task_abs(task, firsttime) return task def schedule_task(self, task, delay): """Add a new task to the scheduler with the given delay (seconds). Low-level method for internal use. """ if self.running: # lock the sched queue, if needed self._acquire_lock() try: task.event = self.sched.enter(delay, 0, task, (weakref.ref(self),)) finally: self._release_lock() else: task.event = self.sched.enter(delay, 0, task, (weakref.ref(self),)) def schedule_task_abs(self, task, abstime): """Add a new task to the scheduler for the given absolute time value. Low-level method for internal use. """ if self.running: # lock the sched queue, if needed self._acquire_lock() try: task.event = self.sched.enterabs(abstime, 0, task, (weakref.ref(self),)) finally: self._release_lock() else: task.event = self.sched.enterabs(abstime, 0, task, (weakref.ref(self),)) def start(self): """Start the scheduler.""" self._run() def stop(self): """Remove all pending tasks and stop the Scheduler.""" self.running = False self._clearschedqueue() def cancel(self, task): """Cancel given scheduled task.""" try: self.sched.cancel(task.event) except ValueError: # Ignore if the task was already removed from the queue pass def _getqueuetoptime(self): try: return self.sched._queue[0].time except IndexError: return 0.0 def _clearschedqueue(self): self.sched._queue[:] = [] def _run(self): # Low-level run method to do the actual scheduling loop. self.running = True while self.running: try: self.sched.run() except Exception as x: logging.error("Error during scheduler execution: %s" % str(x), exc_info=True) # queue is empty; sleep a short while before checking again if self.running: time.sleep(5) class Task: """Abstract base class of all scheduler tasks""" def __init__(self, name, action, args, kw): """This is an abstract class!""" self.name = name self.action = action self.args = args self.kw = kw def __call__(self, schedulerref): """Execute the task action in the scheduler's thread.""" try: self.execute() except Exception as x: self.handle_exception(x) self.reschedule(schedulerref()) def reschedule(self, scheduler): """This method should be defined in one of the sub classes!""" raise NotImplementedError("You're using the abstract base class 'Task'," " use a concrete class instead") def execute(self): """Execute the actual task.""" self.action(*self.args, **self.kw) def handle_exception(self, exc): """Handle any exception that occurred during task execution.""" logging.error("Error during scheduler execution: %s" % str(exc), exc_info=True) class SingleTask(Task): """A task that only runs once.""" def reschedule(self, scheduler): pass class IntervalTask(Task): """A repeated task that occurs at certain intervals (in seconds).""" def __init__(self, name, interval, action, args=None, kw=None): Task.__init__(self, name, action, args, kw) self.interval = interval def reschedule(self, scheduler): """Reschedule this task according to its interval (in seconds).""" scheduler.schedule_task(self, self.interval) class DayTaskRescheduler: """A mixin class that contains the reschedule logic for the DayTasks.""" def __init__(self, timeonday): self.timeonday = timeonday def get_schedule_time(self, today): """Calculate the time value at which this task is to be scheduled.""" now = list(time.localtime()) if today: # schedule for today. let's see if that is still possible if (now[3], now[4]) >= self.timeonday: # too bad, it will be tomorrow now[2] += 1 else: # tomorrow now[2] += 1 # set new time on day (hour,minute) now[3], now[4] = self.timeonday # seconds now[5] = 0 return time.mktime(tuple(now)) def reschedule(self, scheduler): """Reschedule this task according to the daytime for the task. The task is scheduled for tomorrow, for the given daytime. """ # (The execute method in the concrete Task classes will check # if the current day is a day on which the task must run). abstime = self.get_schedule_time(False) scheduler.schedule_task_abs(self, abstime) class WeekdayTask(DayTaskRescheduler, Task): """A task that is called at specific days in a week (1-7), at a fixed time on the day. """ def __init__(self, name, weekdays, timeonday, action, args=None, kw=None): if type(timeonday) not in (list, tuple) or len(timeonday) != 2: raise TypeError("timeonday must be a 2-tuple (hour,minute)") if type(weekdays) not in (list, tuple): raise TypeError("weekdays must be a sequence of weekday numbers " "1-7 (1 is Monday)") DayTaskRescheduler.__init__(self, timeonday) Task.__init__(self, name, action, args, kw) self.days = weekdays def execute(self): # This is called every day, at the correct time. We only need to # check if we should run this task today (this day of the week). weekday = time.localtime().tm_wday + 1 if weekday in self.days: self.action(*self.args, **self.kw) class MonthdayTask(DayTaskRescheduler, Task): """A task that is called at specific days in a month (1-31), at a fixed time on the day. """ def __init__(self, name, monthdays, timeonday, action, args=None, kw=None): if type(timeonday) not in (list, tuple) or len(timeonday) != 2: raise TypeError("timeonday must be a 2-tuple (hour,minute)") if type(monthdays) not in (list, tuple): raise TypeError("monthdays must be a sequence of monthdays numbers " "1-31") DayTaskRescheduler.__init__(self, timeonday) Task.__init__(self, name, action, args, kw) self.days = monthdays def execute(self): # This is called every day, at the correct time. We only need to # check if we should run this task today (this day of the month). if time.localtime().tm_mday in self.days: self.action(*self.args, **self.kw) class ThreadedScheduler(Scheduler): """A Scheduler that runs in its own thread.""" def __init__(self): super().__init__() # we require a lock around the task queue self._lock = threading.Lock() def start(self): """Splice off a thread in which the scheduler will run.""" self.thread = threading.Thread(target=self._run) self.thread.daemon = True self.thread.start() def stop(self): """Stop the scheduler and wait for the thread to finish.""" Scheduler.stop(self) try: self.thread.join() except AttributeError: pass def _acquire_lock(self): """Lock the thread's task queue.""" self._lock.acquire() def _release_lock(self): """Release the lock on th ethread's task queue.""" self._lock.release() class ThreadedTaskMixin: """A mixin class to make a Task execute in a separate thread.""" def __call__(self, schedulerref): """Execute the task action in its own thread.""" threading.Thread(target=self.threadedcall).start() self.reschedule(schedulerref()) def threadedcall(self): # This method is run within its own thread, so we have to # # do the execute() call and exception handling here. try: self.execute() except Exception as x: self.handle_exception(x) class ThreadedIntervalTask(ThreadedTaskMixin, IntervalTask): """Interval Task that executes in its own thread.""" pass class ThreadedSingleTask(ThreadedTaskMixin, SingleTask): """Single Task that executes in its own thread.""" pass class ThreadedWeekdayTask(ThreadedTaskMixin, WeekdayTask): """Weekday Task that executes in its own thread.""" pass class ThreadedMonthdayTask(ThreadedTaskMixin, MonthdayTask): """Monthday Task that executes in its own thread.""" pass if hasattr(os, "fork"): import signal class ForkedScheduler(Scheduler): """A Scheduler that runs in its own forked process.""" def __del__(self): if hasattr(self, "childpid"): os.kill(self.childpid, signal.SIGKILL) def start(self): """Fork off a new process in which the scheduler will run.""" pid = os.fork() if pid == 0: # we are the child signal.signal(signal.SIGUSR1, self.signalhandler) self._run() os._exit(0) else: # we are the parent self.childpid = pid # can no longer insert in the scheduler queue del self.sched def stop(self): """Stop the scheduler and wait for the process to finish.""" os.kill(self.childpid, signal.SIGUSR1) os.waitpid(self.childpid, 0) def signalhandler(self, sig, stack): Scheduler.stop(self) class ForkedTaskMixin: """A mixin class to make a Task execute in a separate process.""" def __call__(self, schedulerref): """Execute the task action in its own process.""" pid = os.fork() if pid == 0: # we are the child try: self.execute() except Exception as x: self.handle_exception(x) os._exit(0) else: # we are the parent self.reschedule(schedulerref()) class ForkedIntervalTask(ForkedTaskMixin, IntervalTask): """Interval Task that executes in its own process.""" pass class ForkedSingleTask(ForkedTaskMixin, SingleTask): """Single Task that executes in its own process.""" pass class ForkedWeekdayTask(ForkedTaskMixin, WeekdayTask): """Weekday Task that executes in its own process.""" pass class ForkedMonthdayTask(ForkedTaskMixin, MonthdayTask): """Monthday Task that executes in its own process.""" pass if __name__ == "__main__": def testaction(arg): print((">>>TASK", arg, "sleeping 3 seconds")) time.sleep(3) print(("<< 100: EnumParOut = Ident1 else: EnumParOut = Ident4 elif EnumParIn == Ident3: EnumParOut = Ident2 elif EnumParIn == Ident4: pass elif EnumParIn == Ident5: EnumParOut = Ident3 return EnumParOut def Proc7(IntParI1, IntParI2): IntLoc = IntParI1 + 2 IntParOut = IntParI2 + IntLoc return IntParOut def Proc8(Array1Par, Array2Par, IntParI1, IntParI2): global IntGlob IntLoc = IntParI1 + 5 Array1Par[IntLoc] = IntParI2 Array1Par[IntLoc + 1] = Array1Par[IntLoc] Array1Par[IntLoc + 30] = IntLoc for IntIndex in range(IntLoc, IntLoc + 2): Array2Par[IntLoc][IntIndex] = IntLoc Array2Par[IntLoc][IntLoc - 1] = Array2Par[IntLoc][IntLoc - 1] + 1 Array2Par[IntLoc + 20][IntLoc] = Array1Par[IntLoc] IntGlob = 5 def Func1(CharPar1, CharPar2): CharLoc1 = CharPar1 CharLoc2 = CharLoc1 if CharLoc2 != CharPar2: return Ident1 else: return Ident2 def Func2(StrParI1, StrParI2): IntLoc = 1 while IntLoc <= 1: if Func1(StrParI1[IntLoc], StrParI2[IntLoc + 1]) == Ident1: CharLoc = "A" IntLoc = IntLoc + 1 if "W" <= CharLoc <= "Z": IntLoc = 7 if CharLoc == "X": return TRUE else: if StrParI1 > StrParI2: IntLoc = IntLoc + 7 return TRUE else: return FALSE def Func3(EnumParIn): EnumLoc = EnumParIn if EnumLoc == Ident3: return TRUE return FALSE if __name__ == "__main__": import sys def error(msg): print(msg, end=" ", file=sys.stderr) print("usage: %s [number_of_loops]" % sys.argv[0], file=sys.stderr) sys.exit(100) nargs = len(sys.argv) - 1 if nargs > 1: error("%d arguments are too many;" % nargs) elif nargs == 1: try: loops = int(sys.argv[1]) except ValueError: error("Invalid argument %r;" % sys.argv[1]) else: loops = LOOPS main(loops) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4502106 SABnzbd-4.3.2/sabnzbd/utils/sleepless.py0000644000000000000000000000402014625637243017353 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.utils.sleepless - Keep macOS awake by setting power assertions """ import objc from Foundation import NSBundle # https://developer.apple.com/documentation/iokit/iopowersources.h?language=objc IOKit = NSBundle.bundleWithIdentifier_("com.apple.framework.IOKit") functions = [ ("IOPMAssertionCreateWithName", b"i@i@o^i"), ("IOPMAssertionRelease", b"vi"), ] objc.loadBundleFunctions(IOKit, globals(), functions) # Keep track of the assertion ID at the module-level assertion_id = None def keep_awake(reason): """Tell OS to stay awake. One argument: text to send to OS. Stays in effect until next 'allow_sleep' call. Multiple calls allowed. """ global assertion_id # Each assertion needs to be released, so make sure to only set it once if not assertion_id: kIOPMAssertionTypeNoIdleSleep = "NoIdleSleepAssertion" kIOPMAssertionLevelOn = 255 errcode, assertion_id = IOPMAssertionCreateWithName( kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reason, None ) return errcode == 0 return True def allow_sleep(): """Allow OS to go to sleep""" global assertion_id if assertion_id: IOPMAssertionRelease(assertion_id) assertion_id = None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4502976 SABnzbd-4.3.2/sabnzbd/utils/rarfile.py0000644000000000000000000025070214625637243017012 0ustar00runnerstaff# rarfile.py # # Copyright (c) 2005-2016 Marko Kreen # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. r"""RAR archive reader. This is Python module for Rar archive reading. The interface is made as :mod:`zipfile`-like as possible. Basic logic: - Parse archive structure with Python. - Extract non-compressed files with Python - Extract compressed files with unrar. - Optionally write compressed data to temp file to speed up unrar, otherwise it needs to scan whole archive on each execution. Example:: import rarfile rf = rarfile.RarFile('myarchive.rar') for f in rf.infolist(): print f.filename, f.file_size if f.filename == 'README': print(rf.read(f)) Archive files can also be accessed via file-like object returned by :meth:`RarFile.open`:: import rarfile with rarfile.RarFile('archive.rar') as rf: with rf.open('README') as f: for ln in f: print(ln.strip()) There are few module-level parameters to tune behaviour, here they are with defaults, and reason to change it:: import rarfile # Set to full path of unrar.exe if it is not in PATH rarfile.UNRAR_TOOL = "unrar" # Set to '\\' to be more compatible with old rarfile rarfile.PATH_SEP = '/' For more details, refer to source. """ ## ## Imports and compat - support both Python 2.x and 3.x ## import sys import os import errno import struct from struct import pack, unpack, Struct from binascii import crc32, hexlify from tempfile import mkstemp from subprocess import Popen, PIPE, STDOUT from io import RawIOBase from hashlib import sha1, sha256 from hmac import HMAC from datetime import datetime, timedelta, tzinfo # fixed offset timezone, for UTC try: from datetime import timezone except ImportError: class timezone(tzinfo): """Compat timezone.""" __slots__ = ("_ofs", "_name") _DST = timedelta(0) def __init__(self, offset, name): super(timezone, self).__init__() self._ofs, self._name = offset, name def utcoffset(self, dt): return self._ofs def tzname(self, dt): return self._name def dst(self, dt): return self._DST # only needed for encryped headers try: try: from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf import pbkdf2 class AES_CBC_Decrypt(object): """Decrypt API""" def __init__(self, key, iv): ciph = Cipher(algorithms.AES(key), modes.CBC(iv), default_backend()) self.decrypt = ciph.decryptor().update def pbkdf2_sha256(password, salt, iters): """PBKDF2 with HMAC-SHA256""" ctx = pbkdf2.PBKDF2HMAC(hashes.SHA256(), 32, salt, iters, default_backend()) return ctx.derive(password) except ImportError: from Crypto.Cipher import AES from Crypto.Protocol import KDF class AES_CBC_Decrypt(object): """Decrypt API""" def __init__(self, key, iv): self.decrypt = AES.new(key, AES.MODE_CBC, iv).decrypt def pbkdf2_sha256(password, salt, iters): """PBKDF2 with HMAC-SHA256""" return KDF.PBKDF2(password, salt, 32, iters, hmac_sha256) _have_crypto = 1 except ImportError: _have_crypto = 0 try: from pyblake2 import blake2s _have_blake2 = True except ImportError: _have_blake2 = False # compat with 2.x if sys.hexversion < 0x3000000: def rar_crc32(data, prev=0): """CRC32 with unsigned values.""" if (prev > 0) and (prev & 0x80000000): prev -= 1 << 32 res = crc32(data, prev) if res < 0: res += 1 << 32 return res tohex = hexlify _byte_code = ord else: # pragma: no cover def tohex(data): """Return hex string.""" return hexlify(data).decode("ascii") rar_crc32 = crc32 str = str _byte_code = int # noqa __version__ = "3.0" # export only interesting items __all__ = ["is_rarfile", "RarInfo", "RarFile", "RarExtFile"] ## ## Module configuration. Can be tuned after importing. ## #: default fallback charset DEFAULT_CHARSET = "windows-1252" #: list of encodings to try, with fallback to DEFAULT_CHARSET if none succeed TRY_ENCODINGS = ("utf8", "utf-16le") #: 'unrar', 'rar' or full path to either one UNRAR_TOOL = "unrar" #: Command line args to use for opening file for reading. OPEN_ARGS = ("p", "-inul") #: Command line args to use for extracting file to disk. EXTRACT_ARGS = ("x", "-y", "-idq") #: args for testrar() TEST_ARGS = ("t", "-idq") # # Allow use of tool that is not compatible with unrar. # # By default use 'bsdtar' which is 'tar' program that # sits on top of libarchive. # # Problems with libarchive RAR backend: # - Does not support solid archives. # - Does not support password-protected archives. # ALT_TOOL = "bsdtar" ALT_OPEN_ARGS = ("-x", "--to-stdout", "-f") ALT_EXTRACT_ARGS = ("-x", "-f") ALT_TEST_ARGS = ("-t", "-f") ALT_CHECK_ARGS = ("--help",) #: whether to speed up decompression by using tmp archive USE_EXTRACT_HACK = 0 #: limit the filesize for tmp archive usage HACK_SIZE_LIMIT = 20 * 1024 * 1024 #: Separator for path name components. RAR internally uses '\\'. #: Use '/' to be similar with zipfile. PATH_SEP = "/" ## ## rar constants ## # block types RAR_BLOCK_MARK = 0x72 # r RAR_BLOCK_MAIN = 0x73 # s RAR_BLOCK_FILE = 0x74 # t RAR_BLOCK_OLD_COMMENT = 0x75 # u RAR_BLOCK_OLD_EXTRA = 0x76 # v RAR_BLOCK_OLD_SUB = 0x77 # w RAR_BLOCK_OLD_RECOVERY = 0x78 # x RAR_BLOCK_OLD_AUTH = 0x79 # y RAR_BLOCK_SUB = 0x7A # z RAR_BLOCK_ENDARC = 0x7B # { # flags for RAR_BLOCK_MAIN RAR_MAIN_VOLUME = 0x0001 RAR_MAIN_COMMENT = 0x0002 RAR_MAIN_LOCK = 0x0004 RAR_MAIN_SOLID = 0x0008 RAR_MAIN_NEWNUMBERING = 0x0010 RAR_MAIN_AUTH = 0x0020 RAR_MAIN_RECOVERY = 0x0040 RAR_MAIN_PASSWORD = 0x0080 RAR_MAIN_FIRSTVOLUME = 0x0100 RAR_MAIN_ENCRYPTVER = 0x0200 # flags for RAR_BLOCK_FILE RAR_FILE_SPLIT_BEFORE = 0x0001 RAR_FILE_SPLIT_AFTER = 0x0002 RAR_FILE_PASSWORD = 0x0004 RAR_FILE_COMMENT = 0x0008 RAR_FILE_SOLID = 0x0010 RAR_FILE_DICTMASK = 0x00E0 RAR_FILE_DICT64 = 0x0000 RAR_FILE_DICT128 = 0x0020 RAR_FILE_DICT256 = 0x0040 RAR_FILE_DICT512 = 0x0060 RAR_FILE_DICT1024 = 0x0080 RAR_FILE_DICT2048 = 0x00A0 RAR_FILE_DICT4096 = 0x00C0 RAR_FILE_DIRECTORY = 0x00E0 RAR_FILE_LARGE = 0x0100 RAR_FILE_UNICODE = 0x0200 RAR_FILE_SALT = 0x0400 RAR_FILE_VERSION = 0x0800 RAR_FILE_EXTTIME = 0x1000 RAR_FILE_EXTFLAGS = 0x2000 # flags for RAR_BLOCK_ENDARC RAR_ENDARC_NEXT_VOLUME = 0x0001 RAR_ENDARC_DATACRC = 0x0002 RAR_ENDARC_REVSPACE = 0x0004 RAR_ENDARC_VOLNR = 0x0008 # flags common to all blocks RAR_SKIP_IF_UNKNOWN = 0x4000 RAR_LONG_BLOCK = 0x8000 # Host OS types RAR_OS_MSDOS = 0 RAR_OS_OS2 = 1 RAR_OS_WIN32 = 2 RAR_OS_UNIX = 3 RAR_OS_MACOS = 4 RAR_OS_BEOS = 5 # Compression methods - '0'..'5' RAR_M0 = 0x30 RAR_M1 = 0x31 RAR_M2 = 0x32 RAR_M3 = 0x33 RAR_M4 = 0x34 RAR_M5 = 0x35 # # RAR5 constants # RAR5_BLOCK_MAIN = 1 RAR5_BLOCK_FILE = 2 RAR5_BLOCK_SERVICE = 3 RAR5_BLOCK_ENCRYPTION = 4 RAR5_BLOCK_ENDARC = 5 RAR5_BLOCK_FLAG_EXTRA_DATA = 0x01 RAR5_BLOCK_FLAG_DATA_AREA = 0x02 RAR5_BLOCK_FLAG_SKIP_IF_UNKNOWN = 0x04 RAR5_BLOCK_FLAG_SPLIT_BEFORE = 0x08 RAR5_BLOCK_FLAG_SPLIT_AFTER = 0x10 RAR5_BLOCK_FLAG_DEPENDS_PREV = 0x20 RAR5_BLOCK_FLAG_KEEP_WITH_PARENT = 0x40 RAR5_MAIN_FLAG_ISVOL = 0x01 RAR5_MAIN_FLAG_HAS_VOLNR = 0x02 RAR5_MAIN_FLAG_SOLID = 0x04 RAR5_MAIN_FLAG_RECOVERY = 0x08 RAR5_MAIN_FLAG_LOCKED = 0x10 RAR5_FILE_FLAG_ISDIR = 0x01 RAR5_FILE_FLAG_HAS_MTIME = 0x02 RAR5_FILE_FLAG_HAS_CRC32 = 0x04 RAR5_FILE_FLAG_UNKNOWN_SIZE = 0x08 RAR5_COMPR_SOLID = 0x40 RAR5_ENC_FLAG_HAS_CHECKVAL = 0x01 RAR5_ENDARC_FLAG_NEXT_VOL = 0x01 RAR5_XFILE_ENCRYPTION = 1 RAR5_XFILE_HASH = 2 RAR5_XFILE_TIME = 3 RAR5_XFILE_VERSION = 4 RAR5_XFILE_REDIR = 5 RAR5_XFILE_OWNER = 6 RAR5_XFILE_SERVICE = 7 RAR5_XTIME_UNIXTIME = 0x01 RAR5_XTIME_HAS_MTIME = 0x02 RAR5_XTIME_HAS_CTIME = 0x04 RAR5_XTIME_HAS_ATIME = 0x08 RAR5_XENC_CIPHER_AES256 = 0 RAR5_XENC_CHECKVAL = 0x01 RAR5_XENC_TWEAKED = 0x02 RAR5_XHASH_BLAKE2SP = 0 RAR5_XREDIR_UNIX_SYMLINK = 1 RAR5_XREDIR_WINDOWS_SYMLINK = 2 RAR5_XREDIR_WINDOWS_JUNCTION = 3 RAR5_XREDIR_HARD_LINK = 4 RAR5_XREDIR_FILE_COPY = 5 RAR5_XREDIR_ISDIR = 0x01 RAR5_XOWNER_UNAME = 0x01 RAR5_XOWNER_GNAME = 0x02 RAR5_XOWNER_UID = 0x04 RAR5_XOWNER_GID = 0x08 RAR5_OS_WINDOWS = 0 RAR5_OS_UNIX = 1 ## ## internal constants ## RAR_ID = b"Rar!\x1a\x07\x00" RAR5_ID = b"Rar!\x1a\x07\x01\x00" ZERO = b"\0" EMPTY = b"" UTC = timezone(timedelta(0), "UTC") BSIZE = 32 * 1024 def _get_rar_version(xfile): """Check quickly whether file is rar archive.""" with XFile(xfile) as fd: buf = fd.read(len(RAR5_ID)) if buf.startswith(RAR_ID): return 3 elif buf.startswith(RAR5_ID): return 5 return 0 ## ## Public interface ## def is_rarfile(xfile): """Check quickly whether file is rar archive.""" # SABnzbd-edit: try/except try: rar_ver = _get_rar_version(xfile) if rar_ver: return "RAR%d" % rar_ver except: pass return None class Error(Exception): """Base class for rarfile errors.""" class BadRarFile(Error): """Incorrect data in archive.""" class NotRarFile(Error): """The file is not RAR archive.""" class BadRarName(Error): """Cannot guess multipart name components.""" class NoRarEntry(Error): """File not found in RAR""" class PasswordRequired(Error): """File requires password""" class NeedFirstVolume(Error): """Need to start from first volume.""" class NoCrypto(Error): """Cannot parse encrypted headers - no crypto available.""" class RarExecError(Error): """Problem reported by unrar/rar.""" class RarWarning(RarExecError): """Non-fatal error""" class RarFatalError(RarExecError): """Fatal error""" class RarCRCError(RarExecError): """CRC error during unpacking""" class RarLockedArchiveError(RarExecError): """Must not modify locked archive""" class RarWriteError(RarExecError): """Write error""" class RarOpenError(RarExecError): """Open error""" class RarUserError(RarExecError): """User error""" class RarMemoryError(RarExecError): """Memory error""" class RarCreateError(RarExecError): """Create error""" class RarNoFilesError(RarExecError): """No files that match pattern were found""" class RarUserBreak(RarExecError): """User stop""" class RarWrongPassword(RarExecError): """Incorrect password""" class RarUnknownError(RarExecError): """Unknown exit code""" class RarSignalExit(RarExecError): """Unrar exited with signal""" class RarCannotExec(RarExecError): """Executable not found.""" class RarInfo(object): r"""An entry in rar archive. RAR3 extended timestamps are :class:`datetime.datetime` objects without timezone. RAR5 extended timestamps are :class:`datetime.datetime` objects with UTC timezone. Attributes: filename File name with relative path. Path separator is '/'. Always unicode string. date_time File modification timestamp. As tuple of (year, month, day, hour, minute, second). RAR5 allows archives where it is missing, it's None then. file_size Uncompressed size. compress_size Compressed size. compress_type Compression method: one of :data:`RAR_M0` .. :data:`RAR_M5` constants. extract_version Minimal Rar version needed for decompressing. As (major*10 + minor), so 2.9 is 29. RAR3: 10, 20, 29 RAR5 does not have such field in archive, it's simply set to 50. host_os Host OS type, one of RAR_OS_* constants. RAR3: :data:`RAR_OS_WIN32`, :data:`RAR_OS_UNIX`, :data:`RAR_OS_MSDOS`, :data:`RAR_OS_OS2`, :data:`RAR_OS_BEOS`. RAR5: :data:`RAR_OS_WIN32`, :data:`RAR_OS_UNIX`. mode File attributes. May be either dos-style or unix-style, depending on host_os. mtime File modification time. Same value as :attr:`date_time` but as :class:`datetime.datetime` object with extended precision. ctime Optional time field: creation time. As :class:`datetime.datetime` object. atime Optional time field: last access time. As :class:`datetime.datetime` object. arctime Optional time field: archival time. As :class:`datetime.datetime` object. (RAR3-only) CRC CRC-32 of uncompressed file, unsigned int. RAR5: may be None. blake2sp_hash Blake2SP hash over decompressed data. (RAR5-only) comment Optional file comment field. Unicode string. (RAR3-only) file_redir If not None, file is link of some sort. Contains tuple of (type, flags, target). (RAR5-only) Type is one of constants: :data:`RAR5_XREDIR_UNIX_SYMLINK` unix symlink to target. :data:`RAR5_XREDIR_WINDOWS_SYMLINK` windows symlink to target. :data:`RAR5_XREDIR_WINDOWS_JUNCTION` windows junction. :data:`RAR5_XREDIR_HARD_LINK` hard link to target. :data:`RAR5_XREDIR_FILE_COPY` current file is copy of another archive entry. Flags may contain :data:`RAR5_XREDIR_ISDIR` bit. volume Volume nr, starting from 0. volume_file Volume file name, where file starts. """ # zipfile-compatible fields filename = None file_size = None compress_size = None date_time = None comment = None CRC = None volume = None orig_filename = None # optional extended time fields, datetime() objects. mtime = None ctime = None atime = None extract_version = None mode = None host_os = None compress_type = None # rar3-only fields comment = None arctime = None # rar5-only fields blake2sp_hash = None file_redir = None # internal fields flags = 0 type = None def isdir(self): """Returns True if entry is a directory.""" if self.type == RAR_BLOCK_FILE: return (self.flags & RAR_FILE_DIRECTORY) == RAR_FILE_DIRECTORY return False def needs_password(self): """Returns True if data is stored password-protected.""" if self.type == RAR_BLOCK_FILE: return (self.flags & RAR_FILE_PASSWORD) > 0 return False class RarFile(object): """Parse RAR structure, provide access to files in archive.""" #: Archive comment. Unicode string or None. comment = None def __init__( self, rarfile, mode="r", charset=None, info_callback=None, crc_check=True, errors="stop", single_file_check=False, ): """Open and parse a RAR archive. Parameters: rarfile archive file name mode only 'r' is supported. charset fallback charset to use, if filenames are not already Unicode-enabled. info_callback debug callback, gets to see all archive entries. crc_check set to False to disable CRC checks errors Either "stop" to quietly stop parsing on errors, or "strict" to raise errors. Default is "stop". """ self._rarfile = rarfile self._charset = charset or DEFAULT_CHARSET self._info_callback = info_callback self._crc_check = crc_check self._password = None self._file_parser = None self._single_file_check = single_file_check if errors == "stop": self._strict = False elif errors == "strict": self._strict = True else: raise ValueError("Invalid value for 'errors' parameter.") if mode != "r": raise NotImplementedError("RarFile supports only mode=r") self._parse() def __enter__(self): return self def __exit__(self, typ, value, traceback): self.close() def setpassword(self, password): """Sets the password to use when extracting.""" self._password = password if self._file_parser: if self._file_parser.has_header_encryption(): self._file_parser = None if not self._file_parser: self._parse() else: self._file_parser.setpassword(self._password) def needs_password(self): """Returns True if any archive entries require password for extraction.""" return self._file_parser.needs_password() def namelist(self): """Return list of file and foldernames in archive.""" return [f.filename for f in self.infolist()] def filelist(self): """Return list of filenames in archive.""" return [f.filename for f in self.infolist() if not f.isdir()] def infolist(self): """Return RarInfo objects for all files/directories in archive.""" return self._file_parser.infolist() def volumelist(self): """Returns filenames of archive volumes. In case of single-volume archive, the list contains just the name of main archive file. """ return self._file_parser.volumelist() def getinfo(self, fname): """Return RarInfo for file.""" return self._file_parser.getinfo(fname) def open(self, fname, mode="r", psw=None): """Returns file-like object (:class:`RarExtFile`), from where the data can be read. The object implements :class:`io.RawIOBase` interface, so it can be further wrapped with :class:`io.BufferedReader` and :class:`io.TextIOWrapper`. On older Python where io module is not available, it implements only .read(), .seek(), .tell() and .close() methods. The object is seekable, although the seeking is fast only on uncompressed files, on compressed files the seeking is implemented by reading ahead and/or restarting the decompression. Parameters: fname file name or RarInfo instance. mode must be 'r' psw password to use for extracting. """ if mode != "r": raise NotImplementedError("RarFile.open() supports only mode=r") # entry lookup inf = self.getinfo(fname) if inf.isdir(): raise TypeError("Directory does not have any data: " + inf.filename) # check password if inf.needs_password(): psw = psw or self._password if psw is None: raise PasswordRequired("File %s requires password" % inf.filename) else: psw = None return self._file_parser.open(inf, psw) def read(self, fname, psw=None): """Return uncompressed data for archive entry. For longer files using :meth:`RarFile.open` may be better idea. Parameters: fname filename or RarInfo instance psw password to use for extracting. """ with self.open(fname, "r", psw) as f: return f.read() def close(self): """Release open resources.""" pass def printdir(self): """Print archive file list to stdout.""" for f in self.infolist(): print((f.filename)) def extract(self, member, path=None, pwd=None): """Extract single file into current directory. Parameters: member filename or :class:`RarInfo` instance path optional destination path pwd optional password to use """ if isinstance(member, RarInfo): fname = member.filename else: fname = member self._extract([fname], path, pwd) def extractall(self, path=None, members=None, pwd=None): """Extract all files into current directory. Parameters: path optional destination path members optional filename or :class:`RarInfo` instance list to extract pwd optional password to use """ fnlist = [] if members is not None: for m in members: if isinstance(m, RarInfo): fnlist.append(m.filename) else: fnlist.append(m) self._extract(fnlist, path, pwd) def testrar(self): """Let 'unrar' test the archive.""" # Modified for SABnzbd by clipping paths from sabnzbd.filesystem import clip_path rarpath = clip_path(self._rarfile) cmd = [UNRAR_TOOL] + list(TEST_ARGS) add_password_arg(cmd, self._password) cmd.append("--") with XTempFile(rarpath) as rarfile: cmd.append(rarfile) p = custom_popen(cmd) output = p.communicate()[0] check_returncode(p, output) def strerror(self): """Return error string if parsing failed, or None if no problems. """ if not self._file_parser: return "Not a RAR file" return self._file_parser.strerror() ## ## private methods ## def _parse(self): ver = _get_rar_version(self._rarfile) if ver == 3: p3 = RAR3Parser( self._rarfile, self._password, self._crc_check, self._charset, self._strict, self._info_callback, self._single_file_check, ) self._file_parser = p3 # noqa elif ver == 5: p5 = RAR5Parser( self._rarfile, self._password, self._crc_check, self._charset, self._strict, self._info_callback, self._single_file_check, ) self._file_parser = p5 # noqa else: raise BadRarFile("Not a RAR file") self._file_parser.parse() self.comment = self._file_parser.comment # call unrar to extract a file def _extract(self, fnlist, path=None, psw=None): cmd = [UNRAR_TOOL] + list(EXTRACT_ARGS) # pasoword psw = psw or self._password add_password_arg(cmd, psw) cmd.append("--") # rar file with XTempFile(self._rarfile) as rarfn: cmd.append(rarfn) # file list for fn in fnlist: if os.sep != PATH_SEP: fn = fn.replace(PATH_SEP, os.sep) cmd.append(fn) # destination path if path is not None: cmd.append(path + os.sep) # call p = custom_popen(cmd) output = p.communicate()[0] check_returncode(p, output) # # File format parsing # class CommonParser(object): """Shared parser parts.""" _main = None _hdrenc_main = None _needs_password = False _fd = None _expect_sig = None _parse_error = None _password = None comment = None def __init__(self, rarfile, password, crc_check, charset, strict, info_cb, single_file_check): self._rarfile = rarfile self._password = password self._crc_check = crc_check self._charset = charset self._strict = strict self._single_file_check = single_file_check self._info_callback = info_cb self._info_list = [] self._info_map = {} self._vol_list = [] def has_header_encryption(self): """Returns True if headers are encrypted""" if self._hdrenc_main: return True if self._main: if self._main.flags & RAR_MAIN_PASSWORD: return True return False def setpassword(self, psw): """Set cached password.""" self._password = psw def volumelist(self): """Volume files""" return self._vol_list def needs_password(self): """Is password required""" return self._needs_password def strerror(self): """Last error""" return self._parse_error def infolist(self): """List of RarInfo records.""" return self._info_list def getinfo(self, fname): """Return RarInfo for filename""" # accept both ways here if PATH_SEP == "/": fname2 = fname.replace("\\", "/") else: fname2 = fname.replace("/", "\\") try: return self._info_map[fname] except KeyError: try: return self._info_map[fname2] except KeyError: raise NoRarEntry("No such file: %s" % fname) # read rar def parse(self): """Process file.""" self._fd = None try: self._parse_real() finally: if self._fd: self._fd.close() self._fd = None def _parse_real(self): fd = XFile(self._rarfile) self._fd = fd sig = fd.read(len(self._expect_sig)) if sig != self._expect_sig: if isinstance(self._rarfile, str): raise NotRarFile("Not a Rar archive: {}".format(self._rarfile)) raise NotRarFile("Not a Rar archive") volume = 0 # first vol (.rar) is 0 more_vols = False endarc = False volfile = self._rarfile self._vol_list = [self._rarfile] while 1: if endarc: h = None # don't read past ENDARC else: h = self._parse_header(fd) if not h: if more_vols and not self._single_file_check: volume += 1 fd.close() try: volfile = self._next_volname(volfile) fd = XFile(volfile) except IOError: self._set_error("Cannot open next volume: %s", volfile) break self._fd = fd sig = fd.read(len(self._expect_sig)) if sig != self._expect_sig: self._set_error("Invalid volume sig: %s", volfile) break more_vols = False endarc = False self._vol_list.append(volfile) continue break h.volume = volume h.volume_file = volfile if h.type == RAR_BLOCK_MAIN and not self._main: self._main = h if h.flags & RAR_MAIN_NEWNUMBERING: # RAR 2.x does not set FIRSTVOLUME, # so check it only if NEWNUMBERING is used if not self._single_file_check and (h.flags & RAR_MAIN_FIRSTVOLUME) == 0: raise NeedFirstVolume("Need to start from first volume") if h.flags & RAR_MAIN_PASSWORD: self._needs_password = True if not self._password: break elif h.type == RAR_BLOCK_ENDARC: more_vols = (h.flags & RAR_ENDARC_NEXT_VOLUME) > 0 endarc = True elif h.type == RAR_BLOCK_FILE: # RAR 2.x does not write RAR_BLOCK_ENDARC if h.flags & RAR_FILE_SPLIT_AFTER: more_vols = True # RAR 2.x does not set RAR_MAIN_FIRSTVOLUME if not self._single_file_check and volume == 0 and h.flags & RAR_FILE_SPLIT_BEFORE: raise NeedFirstVolume("Need to start from first volume") if h.needs_password(): self._needs_password = True # store it self.process_entry(fd, h) if self._info_callback: self._info_callback(h) # go to next header if h.add_size > 0: fd.seek(h.data_offset + h.add_size, 0) def process_entry(self, fd, item): """Examine item, add into lookup cache.""" raise NotImplementedError() def _decrypt_header(self, fd): raise NotImplementedError("_decrypt_header") def _parse_block_header(self, fd): raise NotImplementedError("_parse_block_header") def _open_hack(self, inf, psw): raise NotImplementedError("_open_hack") # read single header def _parse_header(self, fd): try: # handle encrypted headers if (self._main and self._main.flags & RAR_MAIN_PASSWORD) or self._hdrenc_main: if not self._password: return fd = self._decrypt_header(fd) # now read actual header return self._parse_block_header(fd) except: # SABnzbd-edit: # Catch all errors self._set_error("Broken header in RAR file") return None # given current vol name, construct next one def _next_volname(self, volfile): if is_filelike(volfile): raise IOError("Working on single FD") if self._main.flags & RAR_MAIN_NEWNUMBERING: return _next_newvol(volfile) return _next_oldvol(volfile) def _set_error(self, msg, *args): if args: msg = msg % args self._parse_error = msg if self._strict: raise BadRarFile(msg) def open(self, inf, psw): """Return stream object for file data.""" if inf.file_redir: # cannot leave to unrar as it expects copied file to exist if inf.file_redir[0] in (RAR5_XREDIR_FILE_COPY, RAR5_XREDIR_HARD_LINK): inf = self.getinfo(inf.file_redir[2]) if not inf: raise BadRarFile("cannot find copied file") if inf.flags & RAR_FILE_SPLIT_BEFORE: raise NeedFirstVolume("Partial file, please start from first volume: " + inf.filename) # is temp write usable? use_hack = 1 if not self._main: use_hack = 0 elif self._main._must_disable_hack(): use_hack = 0 elif inf._must_disable_hack(): use_hack = 0 elif is_filelike(self._rarfile): pass elif inf.file_size > HACK_SIZE_LIMIT: use_hack = 0 elif not USE_EXTRACT_HACK: use_hack = 0 # now extract if inf.compress_type == RAR_M0 and (inf.flags & RAR_FILE_PASSWORD) == 0 and inf.file_redir is None: return self._open_clear(inf) elif use_hack: return self._open_hack(inf, psw) elif is_filelike(self._rarfile): return self._open_unrar_membuf(self._rarfile, inf, psw) else: return self._open_unrar(self._rarfile, inf, psw) def _open_clear(self, inf): return DirectReader(self, inf) def _open_hack_core(self, inf, psw, prefix, suffix): size = inf.compress_size + inf.header_size rf = XFile(inf.volume_file, 0) rf.seek(inf.header_offset) tmpfd, tmpname = mkstemp(suffix=".rar") tmpf = os.fdopen(tmpfd, "wb") try: tmpf.write(prefix) while size > 0: if size > BSIZE: buf = rf.read(BSIZE) else: buf = rf.read(size) if not buf: raise BadRarFile("read failed: " + inf.filename) tmpf.write(buf) size -= len(buf) tmpf.write(suffix) tmpf.close() rf.close() except: rf.close() tmpf.close() os.unlink(tmpname) raise return self._open_unrar(tmpname, inf, psw, tmpname) # write in-memory archive to temp file - needed for solid archives def _open_unrar_membuf(self, memfile, inf, psw): tmpname = membuf_tempfile(memfile) return self._open_unrar(tmpname, inf, psw, tmpname, force_file=True) # extract using unrar def _open_unrar(self, rarfile, inf, psw=None, tmpfile=None, force_file=False): cmd = [UNRAR_TOOL] + list(OPEN_ARGS) add_password_arg(cmd, psw) cmd.append("--") cmd.append(rarfile) # not giving filename avoids encoding related problems if not tmpfile or force_file: fn = inf.filename if PATH_SEP != os.sep: fn = fn.replace(PATH_SEP, os.sep) cmd.append(fn) # read from unrar pipe return PipeReader(self, inf, cmd, tmpfile) # # RAR3 format # class Rar3Info(RarInfo): """RAR3 specific fields.""" extract_version = 15 salt = None add_size = 0 header_crc = None header_size = None header_offset = None data_offset = None _md_class = None _md_expect = None # make sure some rar5 fields are always present file_redir = None blake2sp_hash = None def _must_disable_hack(self): if self.type == RAR_BLOCK_FILE: if self.flags & RAR_FILE_PASSWORD: return True elif self.flags & (RAR_FILE_SPLIT_BEFORE | RAR_FILE_SPLIT_AFTER): return True elif self.type == RAR_BLOCK_MAIN: if self.flags & (RAR_MAIN_SOLID | RAR_MAIN_PASSWORD): return True return False class RAR3Parser(CommonParser): """Parse RAR3 file format.""" _expect_sig = RAR_ID _last_aes_key = (None, None, None) # (salt, key, iv) def _decrypt_header(self, fd): if not _have_crypto: raise NoCrypto("Cannot parse encrypted headers - no crypto") salt = fd.read(8) if self._last_aes_key[0] == salt: key, iv = self._last_aes_key[1:] else: key, iv = rar3_s2k(self._password, salt) self._last_aes_key = (salt, key, iv) return HeaderDecrypt(fd, key, iv) # common header def _parse_block_header(self, fd): h = Rar3Info() h.header_offset = fd.tell() # read and parse base header buf = fd.read(S_BLK_HDR.size) if not buf: return None t = S_BLK_HDR.unpack_from(buf) h.header_crc, h.type, h.flags, h.header_size = t # read full header if h.header_size > S_BLK_HDR.size: hdata = buf + fd.read(h.header_size - S_BLK_HDR.size) else: hdata = buf h.data_offset = fd.tell() # unexpected EOF? if len(hdata) != h.header_size: self._set_error("Unexpected EOF when reading header") return None pos = S_BLK_HDR.size # block has data associated with it? if h.flags & RAR_LONG_BLOCK: h.add_size, pos = load_le32(hdata, pos) else: h.add_size = 0 # parse interesting ones, decide header boundaries for crc if h.type == RAR_BLOCK_MARK: return h elif h.type == RAR_BLOCK_MAIN: pos += 6 if h.flags & RAR_MAIN_ENCRYPTVER: pos += 1 crc_pos = pos if h.flags & RAR_MAIN_COMMENT: self._parse_subblocks(h, hdata, pos) elif h.type == RAR_BLOCK_FILE: pos = self._parse_file_header(h, hdata, pos - 4) crc_pos = pos if h.flags & RAR_FILE_COMMENT: pos = self._parse_subblocks(h, hdata, pos) elif h.type == RAR_BLOCK_SUB: pos = self._parse_file_header(h, hdata, pos - 4) crc_pos = h.header_size elif h.type == RAR_BLOCK_OLD_AUTH: pos += 8 crc_pos = pos elif h.type == RAR_BLOCK_OLD_EXTRA: pos += 7 crc_pos = pos else: crc_pos = h.header_size # check crc if h.type == RAR_BLOCK_OLD_SUB: crcdat = hdata[2:] + fd.read(h.add_size) else: crcdat = hdata[2:crc_pos] calc_crc = rar_crc32(crcdat) & 0xFFFF # return good header if h.header_crc == calc_crc: return h # header parsing failed. self._set_error( "Header CRC error (%02x): exp=%x got=%x (xlen = %d)", h.type, h.header_crc, calc_crc, len(crcdat) ) # instead panicking, send eof return None # read file-specific header def _parse_file_header(self, h, hdata, pos): fld = S_FILE_HDR.unpack_from(hdata, pos) pos += S_FILE_HDR.size h.compress_size = fld[0] h.file_size = fld[1] h.host_os = fld[2] h.CRC = fld[3] h.date_time = parse_dos_time(fld[4]) h.mtime = to_datetime(h.date_time) h.extract_version = fld[5] h.compress_type = fld[6] name_size = fld[7] h.mode = fld[8] h._md_class = CRC32Context h._md_expect = h.CRC if h.flags & RAR_FILE_LARGE: h1, pos = load_le32(hdata, pos) h2, pos = load_le32(hdata, pos) h.compress_size |= h1 << 32 h.file_size |= h2 << 32 h.add_size = h.compress_size name, pos = load_bytes(hdata, name_size, pos) if h.flags & RAR_FILE_UNICODE: nul = name.find(ZERO) h.orig_filename = name[:nul] u = UnicodeFilename(h.orig_filename, name[nul + 1 :]) h.filename = u.decode() # if parsing failed fall back to simple name if u.failed: h.filename = self._decode(h.orig_filename) else: h.orig_filename = name h.filename = self._decode(name) # change separator, if requested if PATH_SEP != "\\": h.filename = h.filename.replace("\\", PATH_SEP) if h.flags & RAR_FILE_SALT: h.salt, pos = load_bytes(hdata, 8, pos) else: h.salt = None # optional extended time stamps if h.flags & RAR_FILE_EXTTIME: pos = _parse_ext_time(h, hdata, pos) else: h.mtime = h.atime = h.ctime = h.arctime = None return pos # find old-style comment subblock def _parse_subblocks(self, h, hdata, pos): while pos < len(hdata): # ordinary block header t = S_BLK_HDR.unpack_from(hdata, pos) ___scrc, stype, sflags, slen = t pos_next = pos + slen pos += S_BLK_HDR.size # corrupt header if pos_next < pos: break # followed by block-specific header if stype == RAR_BLOCK_OLD_COMMENT and pos + S_COMMENT_HDR.size <= pos_next: declen, ver, meth, crc = S_COMMENT_HDR.unpack_from(hdata, pos) pos += S_COMMENT_HDR.size data = hdata[pos:pos_next] cmt = rar3_decompress(ver, meth, data, declen, sflags, crc, self._password) if not self._crc_check: h.comment = self._decode_comment(cmt) elif rar_crc32(cmt) & 0xFFFF == crc: h.comment = self._decode_comment(cmt) pos = pos_next return pos def _read_comment_v3(self, inf, psw=None): # read data with XFile(inf.volume_file) as rf: rf.seek(inf.data_offset) data = rf.read(inf.compress_size) # decompress cmt = rar3_decompress( inf.extract_version, inf.compress_type, data, inf.file_size, inf.flags, inf.CRC, psw, inf.salt ) # check crc if self._crc_check: crc = rar_crc32(cmt) if crc != inf.CRC: return None return self._decode_comment(cmt) def _decode(self, val): for c in TRY_ENCODINGS: try: return val.decode(c) except UnicodeError: pass return val.decode(self._charset, "replace") def _decode_comment(self, val): return self._decode(val) def process_entry(self, fd, item): if item.type == RAR_BLOCK_FILE: # use only first part if (item.flags & RAR_FILE_SPLIT_BEFORE) == 0: self._info_map[item.filename] = item self._info_list.append(item) elif self._single_file_check: # Broken rar-files would lead to double file-listings if item.filename not in self._info_map: self._info_map[item.filename] = item self._info_list.append(item) elif len(self._info_list) > 0: # final crc is in last block old = self._info_list[-1] old.CRC = item.CRC old._md_expect = item._md_expect old.compress_size += item.compress_size # parse new-style comment if item.type == RAR_BLOCK_SUB and item.filename == "CMT": if item.flags & (RAR_FILE_SPLIT_BEFORE | RAR_FILE_SPLIT_AFTER): pass elif item.flags & RAR_FILE_SOLID: # file comment cmt = self._read_comment_v3(item, self._password) if len(self._info_list) > 0: old = self._info_list[-1] old.comment = cmt else: # archive comment cmt = self._read_comment_v3(item, self._password) self.comment = cmt if item.type == RAR_BLOCK_MAIN: if item.flags & RAR_MAIN_COMMENT: self.comment = item.comment if item.flags & RAR_MAIN_PASSWORD: self._needs_password = True # put file compressed data into temporary .rar archive, and run # unrar on that, thus avoiding unrar going over whole archive def _open_hack(self, inf, psw): # create main header: crc, type, flags, size, res1, res2 prefix = RAR_ID + S_BLK_HDR.pack(0x90CF, 0x73, 0, 13) + ZERO * (2 + 4) return self._open_hack_core(inf, psw, prefix, EMPTY) # # RAR5 format # class Rar5Info(RarInfo): """Shared fields for RAR5 records.""" extract_version = 50 header_crc = None header_size = None header_offset = None data_offset = None # type=all block_type = None block_flags = None add_size = 0 block_extra_size = 0 # type=MAIN volume_number = None _md_class = None _md_expect = None def _must_disable_hack(self): return False class Rar5BaseFile(Rar5Info): """Shared struct for file & service record.""" type = -1 file_flags = None file_encryption = (0, 0, 0, EMPTY, EMPTY, EMPTY) file_compress_flags = None file_redir = None file_owner = None file_version = None blake2sp_hash = None def _must_disable_hack(self): if self.flags & RAR_FILE_PASSWORD: return True if self.block_flags & (RAR5_BLOCK_FLAG_SPLIT_BEFORE | RAR5_BLOCK_FLAG_SPLIT_AFTER): return True if self.file_compress_flags & RAR5_COMPR_SOLID: return True if self.file_redir: return True return False class Rar5FileInfo(Rar5BaseFile): """RAR5 file record.""" type = RAR_BLOCK_FILE class Rar5ServiceInfo(Rar5BaseFile): """RAR5 service record.""" type = RAR_BLOCK_SUB class Rar5MainInfo(Rar5Info): """RAR5 archive main record.""" type = RAR_BLOCK_MAIN main_flags = None main_volume_number = None def _must_disable_hack(self): if self.main_flags & RAR5_MAIN_FLAG_SOLID: return True return False class Rar5EncryptionInfo(Rar5Info): """RAR5 archive header encryption record.""" type = RAR5_BLOCK_ENCRYPTION encryption_algo = None encryption_flags = None encryption_kdf_count = None encryption_salt = None encryption_check_value = None def needs_password(self): return True class Rar5EndArcInfo(Rar5Info): """RAR5 end of archive record.""" type = RAR_BLOCK_ENDARC endarc_flags = None class RAR5Parser(CommonParser): """Parse RAR5 format.""" _expect_sig = RAR5_ID _hdrenc_main = None # AES encrypted headers _last_aes256_key = (-1, None, None) # (kdf_count, salt, key) def _gen_key(self, kdf_count, salt): if self._last_aes256_key[:2] == (kdf_count, salt): return self._last_aes256_key[2] if kdf_count > 24: raise BadRarFile("Too large kdf_count") psw = self._password if isinstance(psw, str): psw = psw.encode("utf8") key = pbkdf2_sha256(psw, salt, 1 << kdf_count) self._last_aes256_key = (kdf_count, salt, key) return key def _decrypt_header(self, fd): if not _have_crypto: raise NoCrypto("Cannot parse encrypted headers - no crypto") h = self._hdrenc_main key = self._gen_key(h.encryption_kdf_count, h.encryption_salt) iv = fd.read(16) return HeaderDecrypt(fd, key, iv) # common header def _parse_block_header(self, fd): header_offset = fd.tell() preload = 4 + 3 start_bytes = fd.read(preload) header_crc, pos = load_le32(start_bytes, 0) hdrlen, pos = load_vint(start_bytes, pos) if hdrlen > 2 * 1024 * 1024: return None header_size = pos + hdrlen # SABnzbd-edit: # Python 3 only supports -1 for read(), while Python 2 doesn't care! read_size = max(-1, header_size - len(start_bytes)) # read full header, check for EOF hdata = start_bytes + fd.read(read_size) if len(hdata) != header_size: self._set_error("Unexpected EOF when reading header") return None data_offset = fd.tell() calc_crc = rar_crc32(memoryview(hdata)[4:]) if header_crc != calc_crc: # header parsing failed. self._set_error("Header CRC error: exp=%x got=%x (xlen = %d)", header_crc, calc_crc, len(hdata)) return None block_type, pos = load_vint(hdata, pos) if block_type == RAR5_BLOCK_MAIN: h, pos = self._parse_block_common(Rar5MainInfo(), hdata) h = self._parse_main_block(h, hdata, pos) elif block_type == RAR5_BLOCK_FILE: h, pos = self._parse_block_common(Rar5FileInfo(), hdata) h = self._parse_file_block(h, hdata, pos) elif block_type == RAR5_BLOCK_SERVICE: h, pos = self._parse_block_common(Rar5ServiceInfo(), hdata) h = self._parse_file_block(h, hdata, pos) elif block_type == RAR5_BLOCK_ENCRYPTION: h, pos = self._parse_block_common(Rar5EncryptionInfo(), hdata) h = self._parse_encryption_block(h, hdata, pos) elif block_type == RAR5_BLOCK_ENDARC: h, pos = self._parse_block_common(Rar5EndArcInfo(), hdata) h = self._parse_endarc_block(h, hdata, pos) else: h = None if h: h.header_offset = header_offset h.data_offset = data_offset return h def _parse_block_common(self, h, hdata): h.header_crc, pos = load_le32(hdata, 0) hdrlen, pos = load_vint(hdata, pos) h.header_size = hdrlen + pos h.block_type, pos = load_vint(hdata, pos) h.block_flags, pos = load_vint(hdata, pos) if h.block_flags & RAR5_BLOCK_FLAG_EXTRA_DATA: h.block_extra_size, pos = load_vint(hdata, pos) if h.block_flags & RAR5_BLOCK_FLAG_DATA_AREA: h.add_size, pos = load_vint(hdata, pos) h.compress_size = h.add_size if h.block_flags & RAR5_BLOCK_FLAG_SKIP_IF_UNKNOWN: h.flags |= RAR_SKIP_IF_UNKNOWN if h.block_flags & RAR5_BLOCK_FLAG_DATA_AREA: h.flags |= RAR_LONG_BLOCK return h, pos def _parse_main_block(self, h, hdata, pos): h.main_flags, pos = load_vint(hdata, pos) if h.main_flags & RAR5_MAIN_FLAG_HAS_VOLNR: h.main_volume_number = load_vint(hdata, pos) h.flags |= RAR_MAIN_NEWNUMBERING if h.main_flags & RAR5_MAIN_FLAG_SOLID: h.flags |= RAR_MAIN_SOLID if h.main_flags & RAR5_MAIN_FLAG_ISVOL: h.flags |= RAR_MAIN_VOLUME if h.main_flags & RAR5_MAIN_FLAG_RECOVERY: h.flags |= RAR_MAIN_RECOVERY if self._hdrenc_main: h.flags |= RAR_MAIN_PASSWORD if h.main_flags & RAR5_MAIN_FLAG_HAS_VOLNR == 0: h.flags |= RAR_MAIN_FIRSTVOLUME return h def _parse_file_block(self, h, hdata, pos): h.file_flags, pos = load_vint(hdata, pos) h.file_size, pos = load_vint(hdata, pos) h.mode, pos = load_vint(hdata, pos) if h.file_flags & RAR5_FILE_FLAG_HAS_MTIME: h.mtime, pos = load_unixtime(hdata, pos) h.date_time = h.mtime.timetuple()[:6] if h.file_flags & RAR5_FILE_FLAG_HAS_CRC32: h.CRC, pos = load_le32(hdata, pos) h._md_class = CRC32Context h._md_expect = h.CRC h.file_compress_flags, pos = load_vint(hdata, pos) h.file_host_os, pos = load_vint(hdata, pos) h.orig_filename, pos = load_vstr(hdata, pos) h.filename = h.orig_filename.decode("utf8", "replace") # use compatible values if h.file_host_os == RAR5_OS_WINDOWS: h.host_os = RAR_OS_WIN32 else: h.host_os = RAR_OS_UNIX h.compress_type = RAR_M0 + ((h.file_compress_flags >> 7) & 7) if h.block_extra_size: # allow 1 byte of garbage while pos < len(hdata) - 1: xsize, pos = load_vint(hdata, pos) xdata, pos = load_bytes(hdata, xsize, pos) self._process_file_extra(h, xdata) if h.block_flags & RAR5_BLOCK_FLAG_SPLIT_BEFORE: h.flags |= RAR_FILE_SPLIT_BEFORE if h.block_flags & RAR5_BLOCK_FLAG_SPLIT_AFTER: h.flags |= RAR_FILE_SPLIT_AFTER if h.file_flags & RAR5_FILE_FLAG_ISDIR: h.flags |= RAR_FILE_DIRECTORY if h.file_compress_flags & RAR5_COMPR_SOLID: h.flags |= RAR_FILE_SOLID return h def _parse_endarc_block(self, h, hdata, pos): h.endarc_flags, pos = load_vint(hdata, pos) if h.endarc_flags & RAR5_ENDARC_FLAG_NEXT_VOL: h.flags |= RAR_ENDARC_NEXT_VOLUME return h def _parse_encryption_block(self, h, hdata, pos): h.encryption_algo, pos = load_vint(hdata, pos) h.encryption_flags, pos = load_vint(hdata, pos) h.encryption_kdf_count, pos = load_byte(hdata, pos) h.encryption_salt, pos = load_bytes(hdata, 16, pos) if h.encryption_flags & RAR5_ENC_FLAG_HAS_CHECKVAL: h.encryption_check_value = load_bytes(hdata, 12, pos) if h.encryption_algo != RAR5_XENC_CIPHER_AES256: raise BadRarFile("Unsupported header encryption cipher") self._hdrenc_main = h return h # file extra record def _process_file_extra(self, h, xdata): xtype, pos = load_vint(xdata, 0) if xtype == RAR5_XFILE_TIME: self._parse_file_xtime(h, xdata, pos) elif xtype == RAR5_XFILE_ENCRYPTION: self._parse_file_encryption(h, xdata, pos) elif xtype == RAR5_XFILE_HASH: self._parse_file_hash(h, xdata, pos) elif xtype == RAR5_XFILE_VERSION: self._parse_file_version(h, xdata, pos) elif xtype == RAR5_XFILE_REDIR: self._parse_file_redir(h, xdata, pos) elif xtype == RAR5_XFILE_OWNER: self._parse_file_owner(h, xdata, pos) elif xtype == RAR5_XFILE_SERVICE: pass else: pass # extra block for file time record def _parse_file_xtime(self, h, xdata, pos): tflags, pos = load_vint(xdata, pos) ldr = load_windowstime if tflags & RAR5_XTIME_UNIXTIME: ldr = load_unixtime if tflags & RAR5_XTIME_HAS_MTIME: h.mtime, pos = ldr(xdata, pos) h.date_time = h.mtime.timetuple()[:6] if tflags & RAR5_XTIME_HAS_CTIME: h.ctime, pos = ldr(xdata, pos) if tflags & RAR5_XTIME_HAS_ATIME: h.atime, pos = ldr(xdata, pos) # just remember encryption info def _parse_file_encryption(self, h, xdata, pos): algo, pos = load_vint(xdata, pos) flags, pos = load_vint(xdata, pos) kdf_count, pos = load_byte(xdata, pos) salt, pos = load_bytes(xdata, 16, pos) iv, pos = load_bytes(xdata, 16, pos) checkval = None if flags & RAR5_XENC_CHECKVAL: checkval, pos = load_bytes(xdata, 12, pos) if flags & RAR5_XENC_TWEAKED: h._md_expect = None h._md_class = NoHashContext h.file_encryption = (algo, flags, kdf_count, salt, iv, checkval) h.flags |= RAR_FILE_PASSWORD def _parse_file_hash(self, h, xdata, pos): hash_type, pos = load_vint(xdata, pos) if hash_type == RAR5_XHASH_BLAKE2SP: h.blake2sp_hash, pos = load_bytes(xdata, 32, pos) if _have_blake2 and (h.file_encryption[1] & RAR5_XENC_TWEAKED) == 0: h._md_class = Blake2SP h._md_expect = h.blake2sp_hash def _parse_file_version(self, h, xdata, pos): flags, pos = load_vint(xdata, pos) version, pos = load_vint(xdata, pos) h.file_version = (flags, version) def _parse_file_redir(self, h, xdata, pos): redir_type, pos = load_vint(xdata, pos) redir_flags, pos = load_vint(xdata, pos) redir_name, pos = load_vstr(xdata, pos) redir_name = redir_name.decode("utf8", "replace") h.file_redir = (redir_type, redir_flags, redir_name) def _parse_file_owner(self, h, xdata, pos): user_name = group_name = user_id = group_id = None flags, pos = load_vint(xdata, pos) if flags & RAR5_XOWNER_UNAME: user_name, pos = load_vstr(xdata, pos) if flags & RAR5_XOWNER_GNAME: group_name, pos = load_vstr(xdata, pos) if flags & RAR5_XOWNER_UID: user_id, pos = load_vint(xdata, pos) if flags & RAR5_XOWNER_GID: group_id, pos = load_vint(xdata, pos) h.file_owner = (user_name, group_name, user_id, group_id) def process_entry(self, fd, item): if item.block_type == RAR5_BLOCK_FILE: # use only first part if (item.block_flags & RAR5_BLOCK_FLAG_SPLIT_BEFORE) == 0: self._info_map[item.filename] = item self._info_list.append(item) elif self._single_file_check: # Broken rar-files would lead to double file-listings if item.filename not in self._info_map: self._info_map[item.filename] = item self._info_list.append(item) elif len(self._info_list) > 0: # final crc is in last block old = self._info_list[-1] old.CRC = item.CRC old._md_expect = item._md_expect old.blake2sp_hash = item.blake2sp_hash old.compress_size += item.compress_size elif item.block_type == RAR5_BLOCK_SERVICE: if item.filename == "CMT": self._load_comment(fd, item) def _load_comment(self, fd, item): if item.block_flags & (RAR5_BLOCK_FLAG_SPLIT_BEFORE | RAR5_BLOCK_FLAG_SPLIT_AFTER): return None if item.compress_type != RAR_M0: return None if item.flags & RAR_FILE_PASSWORD: algo, ___flags, kdf_count, salt, iv, ___checkval = item.file_encryption if algo != RAR5_XENC_CIPHER_AES256: return None key = self._gen_key(kdf_count, salt) f = HeaderDecrypt(fd, key, iv) cmt = f.read(item.file_size) else: # archive comment with self._open_clear(item) as cmtstream: cmt = cmtstream.read() # rar bug? - appends zero to comment cmt = cmt.split(ZERO, 1)[0] self.comment = cmt.decode("utf8") def _open_hack(self, inf, psw): # len, type, blk_flags, flags main_hdr = b"\x03\x01\x00\x00" endarc_hdr = b"\x03\x05\x00\x00" main_hdr = S_LONG.pack(rar_crc32(main_hdr)) + main_hdr endarc_hdr = S_LONG.pack(rar_crc32(endarc_hdr)) + endarc_hdr return self._open_hack_core(inf, psw, RAR5_ID + main_hdr, endarc_hdr) ## ## Utility classes ## class UnicodeFilename(object): """Handle RAR3 unicode filename decompression.""" def __init__(self, name, encdata): self.std_name = bytearray(name) self.encdata = bytearray(encdata) self.pos = self.encpos = 0 self.buf = bytearray() self.failed = 0 def enc_byte(self): """Copy encoded byte.""" try: c = self.encdata[self.encpos] self.encpos += 1 return c except IndexError: self.failed = 1 return 0 def std_byte(self): """Copy byte from 8-bit representation.""" try: return self.std_name[self.pos] except IndexError: self.failed = 1 return ord("?") def put(self, lo, hi): """Copy 16-bit value to result.""" self.buf.append(lo) self.buf.append(hi) self.pos += 1 def decode(self): """Decompress compressed UTF16 value.""" hi = self.enc_byte() flagbits = 0 while self.encpos < len(self.encdata): if flagbits == 0: flags = self.enc_byte() flagbits = 8 flagbits -= 2 t = (flags >> flagbits) & 3 if t == 0: self.put(self.enc_byte(), 0) elif t == 1: self.put(self.enc_byte(), hi) elif t == 2: self.put(self.enc_byte(), self.enc_byte()) else: n = self.enc_byte() if n & 0x80: c = self.enc_byte() for _ in range((n & 0x7F) + 2): lo = (self.std_byte() + c) & 0xFF self.put(lo, hi) else: for _ in range(n + 2): self.put(self.std_byte(), 0) return self.buf.decode("utf-16le", "replace") class RarExtFile(RawIOBase): """Base class for file-like object that :meth:`RarFile.open` returns. Provides public methods and common crc checking. Behaviour: - no short reads - .read() and .readinfo() read as much as requested. - no internal buffer, use io.BufferedReader for that. """ #: Filename of the archive entry name = None def __init__(self, parser, inf): super(RarExtFile, self).__init__() # standard io.* properties self.name = inf.filename self.mode = "rb" self._parser = parser self._inf = inf self._fd = None self._remain = 0 self._returncode = 0 self._md_context = None self._open() def _open(self): if self._fd: self._fd.close() md_class = self._inf._md_class or NoHashContext self._md_context = md_class() self._fd = None self._remain = self._inf.file_size def read(self, cnt=None): """Read all or specified amount of data from archive entry.""" # sanitize cnt if cnt is None or cnt < 0: cnt = self._remain elif cnt > self._remain: cnt = self._remain if cnt == 0: return EMPTY # actual read data = self._read(cnt) if data: self._md_context.update(data) self._remain -= len(data) if len(data) != cnt: raise BadRarFile("Failed the read enough data") # done? if not data or self._remain == 0: # self.close() self._check() return data def _check(self): """Check final CRC.""" final = self._md_context.digest() exp = self._inf._md_expect if exp is None: return if final is None: return if self._returncode: check_returncode(self, "") if self._remain != 0: raise BadRarFile("Failed the read enough data") if final != exp: raise BadRarFile("Corrupt file - CRC check failed: %s - exp=%r got=%r" % (self._inf.filename, exp, final)) def _read(self, cnt): """Actual read that gets sanitized cnt.""" def close(self): """Close open resources.""" super(RarExtFile, self).close() if self._fd: self._fd.close() self._fd = None def __del__(self): """Hook delete to make sure tempfile is removed.""" self.close() def readinto(self, buf): """Zero-copy read directly into buffer. Returns bytes read. """ raise NotImplementedError("readinto") def tell(self): """Return current reading position in uncompressed data.""" return self._inf.file_size - self._remain def seek(self, ofs, whence=0): """Seek in data. On uncompressed files, the seeking works by actual seeks so it's fast. On compresses files its slow - forward seeking happends by reading ahead, backwards by re-opening and decompressing from the start. """ # disable crc check when seeking self._md_context = NoHashContext() fsize = self._inf.file_size cur_ofs = self.tell() if whence == 0: # seek from beginning of file new_ofs = ofs elif whence == 1: # seek from current position new_ofs = cur_ofs + ofs elif whence == 2: # seek from end of file new_ofs = fsize + ofs else: raise ValueError("Invalid value for whence") # sanity check if new_ofs < 0: new_ofs = 0 elif new_ofs > fsize: new_ofs = fsize # do the actual seek if new_ofs >= cur_ofs: self._skip(new_ofs - cur_ofs) else: # reopen and seek self._open() self._skip(new_ofs) return self.tell() def _skip(self, cnt): """Read and discard data""" while cnt > 0: if cnt > 8192: buf = self.read(8192) else: buf = self.read(cnt) if not buf: break cnt -= len(buf) def readable(self): """Returns True""" return True def writable(self): """Returns False. Writing is not supported.""" return False def seekable(self): """Returns True. Seeking is supported, although it's slow on compressed files. """ return True def readall(self): """Read all remaining data""" # avoid RawIOBase default impl return self.read() class PipeReader(RarExtFile): """Read data from pipe, handle tempfile cleanup.""" def __init__(self, rf, inf, cmd, tempfile=None): self._cmd = cmd self._proc = None self._tempfile = tempfile super(PipeReader, self).__init__(rf, inf) def _close_proc(self): if not self._proc: return if self._proc.stdout: self._proc.stdout.close() if self._proc.stdin: self._proc.stdin.close() if self._proc.stderr: self._proc.stderr.close() self._proc.wait() self._returncode = self._proc.returncode self._proc = None def _open(self): super(PipeReader, self)._open() # stop old process self._close_proc() # launch new process self._returncode = 0 self._proc = custom_popen(self._cmd) self._fd = self._proc.stdout # avoid situation where unrar waits on stdin if self._proc.stdin: self._proc.stdin.close() def _read(self, cnt): """Read from pipe.""" # normal read is usually enough data = self._fd.read(cnt) if len(data) == cnt or not data: return data # short read, try looping buf = [data] cnt -= len(data) while cnt > 0: data = self._fd.read(cnt) if not data: break cnt -= len(data) buf.append(data) return EMPTY.join(buf) def close(self): """Close open resources.""" self._close_proc() super(PipeReader, self).close() if self._tempfile: try: os.unlink(self._tempfile) except OSError: pass self._tempfile = None def readinto(self, buf): """Zero-copy read directly into buffer.""" cnt = len(buf) if cnt > self._remain: cnt = self._remain vbuf = memoryview(buf) res = got = 0 while got < cnt: res = self._fd.readinto(vbuf[got:cnt]) if not res: break self._md_context.update(vbuf[got : got + res]) self._remain -= res got += res return got class DirectReader(RarExtFile): """Read uncompressed data directly from archive.""" _cur = None _cur_avail = None _volfile = None def _open(self): super(DirectReader, self)._open() self._volfile = self._inf.volume_file self._fd = XFile(self._volfile, 0) self._fd.seek(self._inf.header_offset, 0) self._cur = self._parser._parse_header(self._fd) self._cur_avail = self._cur.add_size def _skip(self, cnt): """RAR Seek, skipping through rar files to get to correct position""" while cnt > 0: # next vol needed? if self._cur_avail == 0: if not self._open_next(): break # fd is in read pos, do the read if cnt > self._cur_avail: cnt -= self._cur_avail self._remain -= self._cur_avail self._cur_avail = 0 else: self._fd.seek(cnt, 1) self._cur_avail -= cnt self._remain -= cnt cnt = 0 def _read(self, cnt): """Read from potentially multi-volume archive.""" buf = [] while cnt > 0: # next vol needed? if self._cur_avail == 0: if not self._open_next(): break # fd is in read pos, do the read if cnt > self._cur_avail: data = self._fd.read(self._cur_avail) else: data = self._fd.read(cnt) if not data: break # got some data cnt -= len(data) self._cur_avail -= len(data) buf.append(data) if len(buf) == 1: return buf[0] return EMPTY.join(buf) def _open_next(self): """Proceed to next volume.""" # is the file split over archives? if (self._cur.flags & RAR_FILE_SPLIT_AFTER) == 0: return False if self._fd: self._fd.close() self._fd = None # open next part self._volfile = self._parser._next_volname(self._volfile) fd = open(self._volfile, "rb", 0) self._fd = fd sig = fd.read(len(self._parser._expect_sig)) if sig != self._parser._expect_sig: raise BadRarFile("Invalid signature") # loop until first file header while 1: cur = self._parser._parse_header(fd) if not cur: raise BadRarFile("Unexpected EOF") if cur.type in (RAR_BLOCK_MARK, RAR_BLOCK_MAIN): if cur.add_size: fd.seek(cur.add_size, 1) continue if cur.orig_filename != self._inf.orig_filename: raise BadRarFile("Did not found file entry") self._cur = cur self._cur_avail = cur.add_size return True def readinto(self, buf): """Zero-copy read directly into buffer.""" got = 0 vbuf = memoryview(buf) while got < len(buf): # next vol needed? if self._cur_avail == 0: if not self._open_next(): break # length for next read cnt = len(buf) - got if cnt > self._cur_avail: cnt = self._cur_avail # read into temp view res = self._fd.readinto(vbuf[got : got + cnt]) if not res: break self._md_context.update(vbuf[got : got + res]) self._cur_avail -= res self._remain -= res got += res return got class HeaderDecrypt(object): """File-like object that decrypts from another file""" def __init__(self, f, key, iv): self.f = f self.ciph = AES_CBC_Decrypt(key, iv) self.buf = EMPTY def tell(self): """Current file pos - works only on block boundaries.""" return self.f.tell() def read(self, cnt=None): """Read and decrypt.""" if cnt > 8 * 1024: raise BadRarFile("Bad count to header decrypt - wrong password?") # consume old data if cnt <= len(self.buf): res = self.buf[:cnt] self.buf = self.buf[cnt:] return res res = self.buf self.buf = EMPTY cnt -= len(res) # decrypt new data blklen = 16 while cnt > 0: enc = self.f.read(blklen) if len(enc) < blklen: break dec = self.ciph.decrypt(enc) if cnt >= len(dec): res += dec cnt -= len(dec) else: res += dec[:cnt] self.buf = dec[cnt:] cnt = 0 return res # handle (filename|filelike) object class XFile(object): """Input may be filename or file object.""" __slots__ = ("_fd", "_need_close") def __init__(self, xfile, bufsize=1024): if is_filelike(xfile): self._need_close = False self._fd = xfile self._fd.seek(0) else: self._need_close = True self._fd = open(xfile, "rb", bufsize) def read(self, n=None): """Read from file.""" return self._fd.read(n) def tell(self): """Return file pos.""" return self._fd.tell() def seek(self, ofs, whence=0): """Move file pos.""" return self._fd.seek(ofs, whence) def readinto(self, dst): """Read into buffer.""" return self._fd.readinto(dst) def close(self): """Close file object.""" if self._need_close: self._fd.close() def __enter__(self): return self def __exit__(self, typ, val, tb): self.close() class NoHashContext(object): """No-op hash function.""" def __init__(self, data=None): """Initialize""" def update(self, data): """Update data""" def digest(self): """Final hash""" def hexdigest(self): """Hexadecimal digest.""" class CRC32Context(object): """Hash context that uses CRC32.""" __slots__ = ["_crc"] def __init__(self, data=None): self._crc = 0 if data: self.update(data) def update(self, data): """Process data.""" self._crc = rar_crc32(data, self._crc) def digest(self): """Final hash.""" return self._crc def hexdigest(self): """Hexadecimal digest.""" return "%08x" % self.digest() class Blake2SP(object): """Blake2sp hash context.""" __slots__ = ["_thread", "_buf", "_cur", "_digest"] digest_size = 32 block_size = 64 parallelism = 8 def __init__(self, data=None): self._buf = b"" self._cur = 0 self._digest = None self._thread = [] for i in range(self.parallelism): ctx = self._blake2s(i, 0, i == (self.parallelism - 1)) self._thread.append(ctx) if data: self.update(data) def _blake2s(self, ofs, depth, is_last): return blake2s( node_offset=ofs, node_depth=depth, last_node=is_last, depth=2, inner_size=32, fanout=self.parallelism ) def _add_block(self, blk): self._thread[self._cur].update(blk) self._cur = (self._cur + 1) % self.parallelism def update(self, data): """Hash data.""" view = memoryview(data) bs = self.block_size if self._buf: need = bs - len(self._buf) if len(view) < need: self._buf += view.tobytes() return self._add_block(self._buf + view[:need].tobytes()) view = view[need:] while len(view) >= bs: self._add_block(view[:bs]) view = view[bs:] self._buf = view.tobytes() def digest(self): """Return final digest value.""" if self._digest is None: if self._buf: self._add_block(self._buf) self._buf = EMPTY ctx = self._blake2s(0, 1, True) for t in self._thread: ctx.update(t.digest()) self._digest = ctx.digest() return self._digest def hexdigest(self): """Hexadecimal digest.""" return tohex(self.digest()) ## ## Utility functions ## S_LONG = Struct(" len(buf): raise BadRarFile("cannot load byte") return S_BYTE.unpack_from(buf, pos)[0], end def load_le32(buf, pos): """Load little-endian 32-bit integer""" end = pos + 4 if end > len(buf): raise BadRarFile("cannot load le32") return S_LONG.unpack_from(buf, pos)[0], pos + 4 def load_bytes(buf, num, pos): """Load sequence of bytes""" end = pos + num if end > len(buf): raise BadRarFile("cannot load bytes") return buf[pos:end], end def load_vstr(buf, pos): """Load bytes prefixed by vint length""" slen, pos = load_vint(buf, pos) return load_bytes(buf, slen, pos) def load_dostime(buf, pos): """Load LE32 dos timestamp""" stamp, pos = load_le32(buf, pos) tup = parse_dos_time(stamp) return to_datetime(tup), pos def load_unixtime(buf, pos): """Load LE32 unix timestamp""" secs, pos = load_le32(buf, pos) dt = datetime.fromtimestamp(secs, UTC) return dt, pos def load_windowstime(buf, pos): """Load LE64 windows timestamp""" # unix epoch (1970) in seconds from windows epoch (1601) unix_epoch = 11644473600 val1, pos = load_le32(buf, pos) val2, pos = load_le32(buf, pos) secs, n1secs = divmod((val2 << 32) | val1, 10000000) dt = datetime.fromtimestamp(secs - unix_epoch, UTC) dt = dt.replace(microsecond=n1secs // 10) return dt, pos # new-style next volume def _next_newvol(volfile): i = len(volfile) - 1 while i >= 0: if volfile[i] >= "0" and volfile[i] <= "9": return _inc_volname(volfile, i) i -= 1 raise BadRarName("Cannot construct volume name: " + volfile) # old-style next volume def _next_oldvol(volfile): # rar -> r00 if volfile[-4:].lower() == ".rar": return volfile[:-2] + "00" return _inc_volname(volfile, len(volfile) - 1) # increase digits with carry, otherwise just increment char def _inc_volname(volfile, i): fn = list(volfile) while i >= 0: if fn[i] != "9": fn[i] = chr(ord(fn[i]) + 1) break fn[i] = "0" i -= 1 return "".join(fn) # rar3 extended time fields def _parse_ext_time(h, data, pos): # flags and rest of data can be missing flags = 0 if pos + 2 <= len(data): flags = S_SHORT.unpack_from(data, pos)[0] pos += 2 mtime, pos = _parse_xtime(flags >> 3 * 4, data, pos, h.mtime) h.ctime, pos = _parse_xtime(flags >> 2 * 4, data, pos) h.atime, pos = _parse_xtime(flags >> 1 * 4, data, pos) h.arctime, pos = _parse_xtime(flags >> 0 * 4, data, pos) if mtime: h.mtime = mtime h.date_time = mtime.timetuple()[:6] return pos # rar3 one extended time field def _parse_xtime(flag, data, pos, basetime=None): res = None if flag & 8: if not basetime: basetime, pos = load_dostime(data, pos) # load second fractions rem = 0 cnt = flag & 3 for _ in range(cnt): b, pos = load_byte(data, pos) rem = (b << 16) | (rem >> 8) # convert 100ns units to microseconds usec = rem // 10 if usec > 1000000: usec = 999999 # dostime has room for 30 seconds only, correct if needed if flag & 4 and basetime.second < 59: res = basetime.replace(microsecond=usec, second=basetime.second + 1) else: res = basetime.replace(microsecond=usec) return res, pos def is_filelike(obj): """Filename or file object?""" if isinstance(obj, str) or isinstance(obj, str): return False res = True for a in ("read", "tell", "seek"): res = res and hasattr(obj, a) if not res: raise ValueError("Invalid object passed as file") return True def rar3_s2k(psw, salt): """String-to-key hash for RAR3.""" if not isinstance(psw, str): psw = psw.decode("utf8") seed = psw.encode("utf-16le") + salt iv = EMPTY h = sha1() for i in range(16): for j in range(0x4000): cnt = S_LONG.pack(i * 0x4000 + j) h.update(seed + cnt[:3]) if j == 0: iv += h.digest()[19:20] key_be = h.digest()[:16] key_le = pack("LLLL", key_be)) return key_le, iv def rar3_decompress(vers, meth, data, declen=0, flags=0, crc=0, psw=None, salt=None): """Decompress blob of compressed data. Used for data with non-standard header - eg. comments. """ # already uncompressed? if meth == RAR_M0 and (flags & RAR_FILE_PASSWORD) == 0: return data # take only necessary flags flags = flags & (RAR_FILE_PASSWORD | RAR_FILE_SALT | RAR_FILE_DICTMASK) flags |= RAR_LONG_BLOCK # file header fname = b"data" date = 0 mode = 0x20 fhdr = S_FILE_HDR.pack(len(data), declen, RAR_OS_MSDOS, crc, date, vers, meth, len(fname), mode) fhdr += fname if flags & RAR_FILE_SALT: if not salt: return EMPTY fhdr += salt # full header hlen = S_BLK_HDR.size + len(fhdr) hdr = S_BLK_HDR.pack(0, RAR_BLOCK_FILE, flags, hlen) + fhdr hcrc = rar_crc32(hdr[2:]) & 0xFFFF hdr = S_BLK_HDR.pack(hcrc, RAR_BLOCK_FILE, flags, hlen) + fhdr # archive main header mh = S_BLK_HDR.pack(0x90CF, RAR_BLOCK_MAIN, 0, 13) + ZERO * (2 + 4) # decompress via temp rar tmpfd, tmpname = mkstemp(suffix=".rar") tmpf = os.fdopen(tmpfd, "wb") try: tmpf.write(RAR_ID + mh + hdr + data) tmpf.close() cmd = [UNRAR_TOOL] + list(OPEN_ARGS) add_password_arg(cmd, psw, (flags & RAR_FILE_PASSWORD)) cmd.append(tmpname) p = custom_popen(cmd) return p.communicate()[0] finally: tmpf.close() os.unlink(tmpname) def to_datetime(t): """Convert 6-part time tuple into datetime object.""" if t is None: return None # extract values year, mon, day, h, m, s = t # assume the values are valid try: return datetime(year, mon, day, h, m, s) except ValueError: pass # sanitize invalid values mday = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) if mon < 1: mon = 1 if mon > 12: mon = 12 if day < 1: day = 1 if day > mday[mon]: day = mday[mon] if h > 23: h = 23 if m > 59: m = 59 if s > 59: s = 59 if mon == 2 and day == 29: try: return datetime(year, mon, day, h, m, s) except ValueError: day = 28 return datetime(year, mon, day, h, m, s) def parse_dos_time(stamp): """Parse standard 32-bit DOS timestamp.""" sec, stamp = stamp & 0x1F, stamp >> 5 mn, stamp = stamp & 0x3F, stamp >> 6 hr, stamp = stamp & 0x1F, stamp >> 5 day, stamp = stamp & 0x1F, stamp >> 5 mon, stamp = stamp & 0x0F, stamp >> 4 yr = (stamp & 0x7F) + 1980 return (yr, mon, day, hr, mn, sec * 2) def custom_popen(cmd): """Disconnect cmd from parent fds, read only from stdout.""" # needed for py2exe creationflags = 0 if sys.platform == "win32": creationflags = 0x08000000 # CREATE_NO_WINDOW # We need to patch the special UnRar escaping of double quotes on Windows from sabnzbd.misc import list2cmdline_unrar cmd = list2cmdline_unrar(cmd) # run command try: p = Popen(cmd, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, creationflags=creationflags) except OSError as ex: if ex.errno == errno.ENOENT: raise RarCannotExec("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL) raise return p def custom_check(cmd, ignore_retcode=False): """Run command, collect output, raise error if needed.""" p = custom_popen(cmd) out, _ = p.communicate() if p.returncode and not ignore_retcode: raise RarExecError("Check-run failed") return out def add_password_arg(cmd, psw, ___required=False): """Append password switch to commandline.""" if UNRAR_TOOL == ALT_TOOL: return if psw is not None: cmd.append("-p" + psw) else: cmd.append("-p-") def check_returncode(p, out): """Raise exception according to unrar exit code.""" code = p.returncode if code == 0: return # map return code to exception class, codes from rar.txt errmap = [ None, RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError, # 1..4 RarWriteError, RarOpenError, RarUserError, RarMemoryError, # 5..8 RarCreateError, RarNoFilesError, RarWrongPassword, ] # 9..11 if UNRAR_TOOL == ALT_TOOL: errmap = [None] if code > 0 and code < len(errmap): exc = errmap[code] elif code == 255: exc = RarUserBreak elif code < 0: exc = RarSignalExit else: exc = RarUnknownError # format message if out: msg = "%s [%d]: %s" % (exc.__doc__, p.returncode, out) else: msg = "%s [%d]" % (exc.__doc__, p.returncode) raise exc(msg) def hmac_sha256(key, data): """HMAC-SHA256""" return HMAC(key, data, sha256).digest() def membuf_tempfile(memfile): memfile.seek(0, 0) tmpfd, tmpname = mkstemp(suffix=".rar") tmpf = os.fdopen(tmpfd, "wb") try: while True: buf = memfile.read(BSIZE) if not buf: break tmpf.write(buf) tmpf.close() except: tmpf.close() os.unlink(tmpname) raise return tmpname class XTempFile(object): __slots__ = ("_tmpfile", "_filename") def __init__(self, rarfile): if is_filelike(rarfile): self._tmpfile = membuf_tempfile(rarfile) self._filename = self._tmpfile else: self._tmpfile = None self._filename = rarfile def __enter__(self): return self._filename def __exit__(self, exc_type, exc_value, tb): if self._tmpfile: try: os.unlink(self._tmpfile) except OSError: pass self._tmpfile = None ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.450376 SABnzbd-4.3.2/sabnzbd/utils/file_extension.py0000644000000000000000000001415414625637243020400 0ustar00runnerstaff#!/usr/bin/python3 """ function to check and find correct extension of a (deobfuscated) file Note: extension always contains a leading dot """ import puremagic import os import sys from typing import List, Tuple from sabnzbd.filesystem import get_ext, RAR_RE import sabnzbd.cfg as cfg # common extension from https://www.computerhope.com/issues/ch001789.htm POPULAR_EXT = ( "3g2", "3gp", "7z", "aac", "abw", "ai", "aif", "apk", "arc", "arj", "asp", "aspx", "avi", "azw", "bak", "bat", "bin", "bmp", "bz", "bz2", "c", "cab", "cda", "cer", "cfg", "cfm", "cgi", "class", "com", "cpl", "cpp", "cs", "csh", "css", "csv", "cur", "dat", "db", "dbf", "deb", "dll", "dmg", "dmp", "doc", "docx", "drv", "email", "eml", "emlx", "eot", "epub", "exe", "flv", "fnt", "fon", "gadget", "gif", "gz", "h", "h264", "htm", "html", "icns", "ico", "ics", "ini", "iso", "jar", "java", "jpeg", "jpg", "js", "json", "jsonld", "jsp", "key", "lnk", "log", "m4v", "mdb", "mid", "midi", "mjs", "mkv", "mov", "mp3", "mp4", "mpa", "mpeg", "mpg", "mpkg", "msg", "msi", "odp", "ods", "odt", "oft", "oga", "ogg", "ogv", "ogx", "opus", "ost", "otf", "part", "pdf", "php", "pkg", "pl", "png", "pps", "ppt", "pptx", "ps", "psd", "pst", "py", "rar", "rm", "rpm", "rss", "rtf", "sav", "sh", "sql", "svg", "swf", "swift", "sys", "tar", "tex", "tif", "tiff", "tmp", "toast", "ts", "ttf", "txt", "vb", "vcd", "vcf", "vob", "vsd", "wav", "weba", "webm", "webp", "wma", "wmv", "woff", "woff2", "wpd", "wpl", "wsf", "xhtml", "xls", "xlsm", "xlsx", "xml", "xul", "z", "zip", ) DOWNLOAD_EXT = ( "ass", "avi", "azw3", "bat", "bdmv", "bin", "bup", "cbr", "cbz", "clpi", "crx", "db", "diz", "djvu", "docx", "epub", "exe", "flac", "gif", "gz", "htm", "html", "icns", "ico", "idx", "ifo", "img", "inf", "info", "ini", "iso", "jpg", "log", "m2ts", "m3u", "m4a", "m4b", "mkv", "mobi", "mp3", "mp4", "mpls", "nfo", "nib", "nzb", "otf", "par2", "part", "pdf", "pem", "plist", "png", "py", "rar", "releaseinfo", "rev", "sfv", "sh", "srr", "srs", "srt", "ssa", "strings", "sub", "sup", "sys", "tif", "ttf", "txt", "url", "vob", "wmv", "xpi", ) # Combine to one tuple, with unique entries: ALL_EXT = tuple(set(POPULAR_EXT + DOWNLOAD_EXT)) # ... and prepend a dot to each extension, because we work with a leading dot in extensions ALL_EXT = tuple(["." + i for i in ALL_EXT]) def all_extensions() -> Tuple[str, ...]: """returns tuple with ALL (standard + userdef) extensions (including leading dot in extension)""" user_defined_extensions = tuple(["." + i for i in cfg.ext_rename_ignore()]) return ALL_EXT + user_defined_extensions def has_popular_extension(file_path: str) -> bool: """returns boolean if the extension of file_path is a popular, well-known extension""" file_extension = get_ext(file_path) return file_extension in all_extensions() or RAR_RE.match(file_extension) def all_possible_extensions(file_path: str) -> List[str]: """returns a list with all possible extensions (with leading dot) for given file_path as reported by puremagic""" extension_list = [] for i in puremagic.magic_file(file_path): extension_list.append(i.extension) return extension_list def what_is_most_likely_extension(file_path: str) -> str: """Returns most_likely extension, with a leading dot""" # First: Check if text or NZB, as puremagic is not good at that. try: # Only read the start, don't need the whole file with open(file_path, "r") as inp_file: txt = inp_file.read(200).lower() # Yes, a text file ... so let's check if it's even an NZB: if "!doctype nzb public" in txt or "&1" for thisline in getcmdoutput(dfcmd): if thisline.find("/") == 0: # Starts with /, so a real, local device fstype = thisline.split()[1] if debug: print(("File system type:", fstype)) if fstype.lower().find("fat") >= 0 and fstype.lower().find("exfat") < 0: # FAT, but not EXFAT FAT = True if debug: print("FAT found") break elif "win32" in sys.platform: import win32api if "?" in check_dir: # Remove \\?\ or \\?\UNC\ prefix from Windows path check_dir = check_dir.replace("\\\\?\\UNC\\", "\\\\", 1).replace("\\\\?\\", "", 1) try: result = win32api.GetVolumeInformation(os.path.splitdrive(check_dir)[0]) if debug: print(result) if result[4].startswith("FAT"): FAT = True except: pass elif "darwin" in sys.platform: # MacOS formerly known as OSX """ MacOS needs a two-step approach: # First: directory => device server:~ sander$ df /Volumes/CARTUNES/Tuna/ Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on /dev/disk9s1 120815744 108840000 11975744 91% 0 0 100% /Volumes/CARTUNES # Then: device => filesystem type server:~ sander$ mount | grep /dev/disk9s1 /dev/disk9s1 on /Volumes/CARTUNES (msdos, local, nodev, nosuid, noowners) """ dfcmd = "df " + check_dir for thisline in getcmdoutput(dfcmd): if thisline.find("/") == 0: if debug: print(thisline) # Starts with /, so a real, local device device = thisline.split()[0] mountcmd = "mount | grep " + device mountoutput = os.popen(mountcmd).readline().strip() if debug: print(mountoutput) if "msdos" in mountoutput.split("(")[1]: FAT = True break except: pass return FAT if __name__ == "__main__": if debug: print((sys.platform)) try: dir_to_check = sys.argv[1] except: print("Specify dir on the command line") sys.exit(0) if isFAT(dir_to_check): print((dir_to_check, "is on FAT")) else: print((dir_to_check, "is not on FAT")) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.450517 SABnzbd-4.3.2/sabnzbd/utils/getperformance.py0000644000000000000000000000132114625637243020356 0ustar00runnerstaffimport logging import time from .pystone import pystones def getpystone(): # Start calculation maxpystone = 0 start = time.time() # Start with a short run, find the the pystone, and increase runtime until duration took > 0.1 second for pyseed in [1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000]: duration, pystonefloat = pystones(pyseed) maxpystone = max(maxpystone, int(pystonefloat)) # Stop when pystone() has been running for at least 0.1 second if duration > 0.1: break logging.debug("Pystone performance = %d (in %.2f seconds)", maxpystone, time.time() - start) return maxpystone if __name__ == "__main__": print(getpystone()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4506142 SABnzbd-4.3.2/sabnzbd/utils/ssdp.py0000644000000000000000000001245014625637243016333 0ustar00runnerstaff#!/usr/bin/python3 -OO # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.utils.ssdp - Support for SSDP / Simple Service Discovery Protocol plus XML to appear on Windows Method: 1) this service sends a SSDP broadcast with a description.xml URL in it 2) Windows retrieves that description.xml from this service 3) Windows presents the info from the XML in Windows Exporter's Network Based on the following Specs: SSDP: https://tools.ietf.org/html/draft-cai-ssdp-v1-03 XML: UPnP™ Device Architecture 1.1, paragraph 2.3 Device description http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf """ import logging import socket import uuid from threading import Thread, Condition, Lock from typing import Optional class SSDP(Thread): def __init__(self, host, server_name, url, description, manufacturer, manufacturer_url, model, **kwargs): self.__host = host # Note: this is the LAN IP address! self.__server_name = server_name self.__url = url self.__description = description self.__manufacturer = manufacturer self.__manufacturer_url = manufacturer_url self.__model = model self.__ssdp_broadcast_interval = kwargs.get("ssdp_broadcast_interval", 15) # optional, default 15 seconds self.__myhostname = socket.gethostname() # a steady uuid: stays the same as long as hostname and ip address stay the same: self.__uuid = uuid.uuid3(uuid.NAMESPACE_DNS, self.__myhostname + self.__host) # Create the SSDP broadcast message self.__mySSDPbroadcast = f"""NOTIFY * HTTP/1.1 HOST: 239.255.255.250:1900 CACHE-CONTROL: max-age=60 LOCATION: {self.__url}/description.xml SERVER: {self.__server_name} NT: upnp:rootdevice USN: uuid:{self.__uuid}::upnp:rootdevice NTS: ssdp:alive OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01 """ self.__mySSDPbroadcast = self.__mySSDPbroadcast.replace("\n", "\r\n").encode("utf-8") # Create the XML info (description.xml) self.__myxml = f""" 1 0 {self.__url} urn:schemas-upnp-org:device:Basic:1 {self.__server_name} ({self.__myhostname}) {self.__manufacturer} {self.__manufacturer_url} {self.__model} {self.__model} {self.__description} {self.__manufacturer_url} uuid:{self.__uuid} {self.__url} """ self.__stop = False self.__condition = Condition(Lock()) super().__init__() def stop(self): logging.info("Stopping SSDP") self.__stop = True with self.__condition: self.__condition.notify() def run(self): logging.info("Serving SSDP on %s as %s", self.__host, self.__server_name) # the standard multicast settings for SSDP: MCAST_GRP = "239.255.255.250" MCAST_PORT = 1900 MULTICAST_TTL = 2 while not self.__stop: # Do network stuff # Create socket, send the broadcast, and close the socket again try: with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as sock: sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL) sock.sendto(self.__mySSDPbroadcast, (MCAST_GRP, MCAST_PORT)) except: # probably no network pass # Wait until awoken or timeout is up with self.__condition: self.__condition.wait(self.__ssdp_broadcast_interval) def serve_xml(self): """Returns an XML-structure based on the information being served by this service, returns nothing if not running""" if self.__stop: return return self.__myxml # Reserve class variable, to be started later __SSDP: Optional[SSDP] = None # Wrapper functions to be called by program def start_ssdp(*args, **kwargs): global __SSDP __SSDP = SSDP(*args, **kwargs) __SSDP.start() def stop_ssdp(): if __SSDP and __SSDP.is_alive(): __SSDP.stop() __SSDP.join() def server_ssdp_xml(): """Returns the description.xml if the server is alive, empty otherwise""" if __SSDP and __SSDP.is_alive(): return __SSDP.serve_xml() return "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2192485 SABnzbd-4.3.2/po/nsis/sr.po0000644000000000000000000000552114625637207014604 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sr\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" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Прикажи белешке о издању" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Подржите пројекат, дајте добровољан прилог!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Ово ће уклонити САБнзбд са вашег система" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Покрени са системом" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Иконица радне површи" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Придруживање НЗБ датотеке" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Обриши програм" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Обриши подешавања" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Не можете да препишете постојећу инсталацију. \\n\\nПритисните „У реду“ да " "уклоните претходно издање или „Откажи“ да поништите ову надоградњу." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Ваша подешавања и подаци биће сачувани." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2180066 SABnzbd-4.3.2/po/nsis/cs.po0000644000000000000000000000424014625637207014562 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Pavel C , 2022 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Pavel C , 2022\n" "Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Podpořte projekt!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.218549 SABnzbd-4.3.2/po/nsis/fr.po0000644000000000000000000000615514625637207014573 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # Fred L <88com88@gmail.com>, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Fred L <88com88@gmail.com>, 2024\n" "Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Afficher les notes de version" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Soutenez le projet, faites un don !" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" "Le service Windows SABnzbd a changé dans SABnzbd 3.0.0. \\nVous allez devoir" " réinstaller le service SABnzbd. \\n\\nCliquez sur 'OK' pour supprimer les " "services existants ou sur 'Annuler' pour annuler cette mise à niveau." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" "Le programme d'installation ne prend en charge que Windows 64 bits, utilisez" " la version standalone pour l'exécuter sur Windows 32 bits." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" "Le programme d'installation ne prend en charge que Windows 8.1 et supérieur," " utilisez la version autonome legacy pour les versions antérieures de " "Windows." #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "Arrêt de SABnzbd" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Ceci désinstallera SABnzbd de votre système" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Lancer au démarrage" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Icône sur le Bureau" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Association des fichiers NZB" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Supprimer le programme" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Supprimer les paramètres" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Vous ne pouvez pas remplacer une installation existante. \\n\\nCliquez `OK` " "pour supprimer la version précédente ou `Annuler` pour annuler cette mise à " "niveau." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Vos paramètres et données seront conservés." ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.218845 SABnzbd-4.3.2/po/nsis/nl.po0000644000000000000000000000572214625637207014574 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2024\n" "Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Toon opmerkingen bij deze uitgave" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Steun het project, doneer!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" "De SABnzbd Windows Service is aangepast in SABnzbd 3.0.0. Hierdoor zal je de service opnieuw moeten installeren.\\n\\n\n" "Klik `Ok` om de bestaande services te verwijderen of `Annuleren` om te stoppen." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" "Alleen 64-bit wordt ondersteund in de installer, download de standalone " "versie om SABnzbd uit te voeren op 32-bit Windows." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" "Alleen Windows 8.1 en nieuwer worden ondersteund door de installer, download" " de standalone legacy versie om SABnzbd uit te voeren op oudere versies van " "Windows." #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "SABnzbd wordt afgesloten" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Dit verwijdert SABnzbd van je systeem" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Starten met Windows" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Bureaubladpictogram" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB-bestanden openen met SABnzbd" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Programma verwijderen" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Verwijder alle instellingen" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "U kunt geen bestaande installatie overschrijven.\\n\\nKlik op `OK` om de " "vorige versie te verwijderen of op `Annuleren` om te stoppen." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Je instellingen en bestanden blijven behouden." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2194183 SABnzbd-4.3.2/po/nsis/zh_CN.po0000644000000000000000000000453314625637207015163 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "显示版本说明" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "支持该项目,捐助!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "这将从您的系统中卸载 SABnzbd" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "启动时运行" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "桌面图标" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB 文件关联" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "删除程序" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "删除设置" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "不可以覆盖安装。\\n\\n点击“确定”可移除旧版,或点击“取消”取消升级。" #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "您的设置及数据将会保留。" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2183025 SABnzbd-4.3.2/po/nsis/en.po0000644000000000000000000000002414625637207014553 0ustar00runnerstaff# Dummy en.po file ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.219317 SABnzbd-4.3.2/po/nsis/sv.po0000644000000000000000000000574214625637207014615 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # Petter Ramme, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Petter Ramme, 2024\n" "Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Visa releasenoteringar" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Donera och stöd detta projekt!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" "SABnzbd Windows tjänsten ändrades i SABnzbd 3.0.0.\\nSABnzbd tjänsten " "behöver installeras om.\\n\\Välj OK` för att ta bort den befintliga " "tjänsten, eller välj `Cancel`för att avbryta uppdateringen." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" "Installationen stödjer endast 64-bitars Windows, använd den fristående " "versionen för att köra installationen på 32-bitars Windows." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" "Installationen kräver Windows 8.1 eller högre. Använd en fristående äldre " "version av installationen för en äldre version av Windows." #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "Stänger av SABnzbd." #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Detta kommer att avinstallera SABnzbd från systemet" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Kör vid uppstart" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Skrivbordsikon" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB Filassosication" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Radera programmet" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Radera inställningar" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Kan inte skriva över en existerande installation. \\n\\nKlicka 'OK' för att " "avinstallera tidigare version eller 'Avbryt' för att avbryta denna " "uppgradering." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Dina inställningar och ditt data kommer att bevaras." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2190263 SABnzbd-4.3.2/po/nsis/pt_BR.po0000644000000000000000000000506314625637207015167 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_BR\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Mostrar Notas de Lançamento" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Apoie o projeto. Faça uma doação!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Isso irá desinstalar SABnzbd de seu sistema" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Executar na inicialização" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Ícone na Área de Trabalho" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Associação com Arquivos NZB" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Excluir o Programa" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Apagar Configurações" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Você não pode substituir uma instalação existente. \\n\\nClique `OK` para " "remover a versão anterior ou `Cancelar` para cancelar esta atualização." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Suas configurações e os dados serão preservados." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2191057 SABnzbd-4.3.2/po/nsis/ro.po0000644000000000000000000000474114625637207014603 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Arată Notele de Publicare" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Susţine proiectul, Donează!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Acest lucru va dezinstala SABnzbd din sistem" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Executare la pornire" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Icoană Desktop" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Asociere cu Fişierele NZB" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Şterge Program" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Ştergeţi Setări" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Nu puteți suprascrie instalarea existentă. \\n\\nClick `OK` pentru a elimina" " versiunea anterioară sau `Anulare` pentru a anula actualizarea." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Setările şi informaţiile vor fi salvate." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2187002 SABnzbd-4.3.2/po/nsis/it.po0000644000000000000000000000375414625637207014602 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Language-Team: Italian (https://app.transifex.com/sabnzbd/teams/111101/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.218393 SABnzbd-4.3.2/po/nsis/es.po0000644000000000000000000000564314625637207014574 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # Ester Molla Aragones , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Ester Molla Aragones , 2020\n" "Language-Team: Spanish (https://app.transifex.com/sabnzbd/teams/111101/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Mostrar notas de la versión" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "¡Apoye el proyecto, haga una donación!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" "El servicio de Windows para SABnzbd ha cambiado en la versión SABnzbd " "3.0.0.\\nNecesitará volver a instalar el servicio SABnzbd. \\n\\nHaga clic " "en \"OK\" para eliminar los servicios existentes o \"Cancelar\" para " "cancelar la actualización." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" "El instalador solo admite Windows 64-bit, utilice la versión independiente " "para ejecutar Windows 32-bit." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Esto desinstalará SABnzbd de su sistema" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Ejecutar al inicio" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Icono del escritorio" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Asociación de archivos NZB" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Eliminar programa" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Eliminar Ajustes" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "No es posible sobrescribir una instalación existente. \\n\\nPresione `OK' " "para quitar la versión anterior o 'Cancelar' para cancelar la actualización." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Tus ajustes y datos se mantendrán intactos." ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.218764 SABnzbd-4.3.2/po/nsis/nb.po0000644000000000000000000000471214625637207014560 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/sabnzbd/teams/111101/nb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nb\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Vis versjonsmerknader" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Støtt prosjektet, donèr!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Dette vil avinstallere SABnzbd fra ditt system" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Kjør ved oppstart" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Skrivebordsikon" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB-filassosiering" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Fjern program" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Slett innstillinger" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Du kan ikke overskrive en eksisterende installasjon. \\n\\nTrykk 'OK' for å" " fjerne tidligere installasjon, eller 'Avbryt' for å avbryte denne " "oppgraderingen." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Dine innstillinger og data vil bli tatt vare på." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2182314 SABnzbd-4.3.2/po/nsis/de.po0000644000000000000000000000602614625637207014551 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # reloxx13 , 2022 # HandyDandy04, 2024 # Lorenz B, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Lorenz B, 2024\n" "Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Versionshinweise anzeigen" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Bitte unterstützen Sie das Projekt durch eine Spende!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" "Aufgrund von Änderungen am SABnzbd Windows Service ab Version 3.0.0 ist es nötig,\\nden Windows Service neu zu installieren.\\n\\n\r\n" "Drücke `OK` um den existierenden Service zu löschen oder `Abbrechen` um dieses Upgrade abzubrechen." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" "Der Installer unterstützt nur Windows 64-bit. Benutze die Standalone Version" " für Windows 32-bit." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" "Der Installer unterstützt nur Windows 8.1 und höher. Benutze die Standalone-" "Version für ältere Windows Versionen." #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "Beende SABnzbd" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Dies entfernt SABnzbd von Ihrem System" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Beim Systemstart ausführen" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Desktop-Symbol" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Mit NZB-Dateien verknüpfen" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Programm löschen" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Einstellungen löschen" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Eine vorhandene Installation kann nicht überschrieben werden. \\n\\nWählen " "Sie 'OK', um die vorherige Version zu entfernen oder 'Abbrechen' um die " "Aktualisierung abzubrechen." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Ihre Einstellungen und Daten bleiben erhalten." ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.218117 SABnzbd-4.3.2/po/nsis/da.po0000644000000000000000000000466314625637207014552 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Vis udgivelsesbemærkninger" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Støt projektet, donér!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Dette vil afinstallere SABnzbd fra dit system" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Kør ved opstart" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Skrivebordsikon" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB-filtilknytning" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Slet program" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Slet indstillinger" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Du kan ikke overskrive en eksisterende installation. \\n\\nKlik `OK` for at " "fjerne den tidligere version eller `Annuller` for at annullere " "opgraderingen." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Dine indstillinger og data vil blive bevaret." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2178843 SABnzbd-4.3.2/po/nsis/SABnsis.pot0000644000000000000000000000356314625637207015652 0ustar00runnerstaff# # SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.2RC1\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: team@sabnzbd.org\n" "Language-Team: SABnzbd \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "The installer only supports 64-bit Windows, use the standalone version to run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "The installer only supports Windows 8.1 and above, use the standalone legacy version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2186222 SABnzbd-4.3.2/po/nsis/he.po0000644000000000000000000000630614625637207014556 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # ION, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: ION, 2024\n" "Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: he\n" "Plural-Forms: nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "הראה הערות שחרור" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "תמוך במיזם, תרום!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" "שירות Windows של SABnzbd השתנה ב־SABnzbd 3.0.0. \\nתצטרך להתקין מחדש את " "השירות של SABnzbd. \\n\\nלחץ על `אישור` כדי להסיר את השירותים הקיימים או על " "`ביטול` כדי לבטל שדרוג זה." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" "המתקין תומך רק במערכת Windows מסוג 64־סיביות, השתמש בגרסה העצמאית כדי להריץ " "על Windows מסוג 32־סיביות." #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" "המתקין תומך רק במערכת Windows 8.1 ומעלה, השתמש בגרסה העצמאית המיושנת כדי " "להריץ על גרסת Windows ישנה יותר." #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "מכבה את SABnzbd" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "זה יסיר את SABnzbd מהמערכת שלך" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "הרץ בהזנק" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "צור קיצור דרך בשולחן העבודה" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB שייך קבצי" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "מחק תוכנית" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "מחק הגדרות" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "אינך יכול לדרוס התקנה קיימת. \\n\\nלחץ על `אישור` כדי להסיר את הגרסה הקודמת " "או על `ביטול` כדי לבטל שדרוג זה." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "ההגדרות והנתונים שלך ישתמרו." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2189317 SABnzbd-4.3.2/po/nsis/pl.po0000644000000000000000000000506114625637207014572 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Pokaż informacje o wydaniu" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Wspomóż projekt!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "To odinstaluje SABnzbd z systemu" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Uruchom wraz z systemem" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Ikona pulpitu" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "powiązanie pliku NZB" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Usuń program" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Skasuj obecne ustawienia" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Nie można nadpisać istniejącej instalacji. \\n\\n Naciśnij `OK`, aby usunąć " "poprzednia wersję lub `Anuluj` aby anulować aktualizację." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Twoje ustawienia i dane zostaną zachowane." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2191808 SABnzbd-4.3.2/po/nsis/ru.po0000644000000000000000000000576014625637207014613 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Показать заметки о выпуске" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Поддержите проект. Сделайте пожертвование!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Приложение SABnzbd будет удалено из вашей системы" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Запускать вместе с системой" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Значок на рабочем столе" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "Ассоциировать с файлами NZB" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Удалить программу" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Удалить параметры" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Нельзя перезаписать существующее установленное приложение. \\n\\nЧтобы " "удалить предыдущую версию, нажмите кнопку «ОК». Чтобы отменить обновление, " "нажмите кнопку «Отмена»." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Ваши параметры и данные будут сохранены." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2184732 SABnzbd-4.3.2/po/nsis/fi.po0000644000000000000000000000466614625637207014567 0ustar00runnerstaff# SABnzbd Translation Template file NSIS # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: builder/win/NSIS_Installer.nsi msgid "Show Release Notes" msgstr "Näytä julkaisutiedot" #: builder/win/NSIS_Installer.nsi msgid "Support the project, Donate!" msgstr "Tue projektia, lahjoita!" #: builder/win/NSIS_Installer.nsi msgid "" "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to " "reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing " "services or `Cancel` to cancel this upgrade." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports 64-bit Windows, use the standalone version to " "run on 32-bit Windows." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "" "The installer only supports Windows 8.1 and above, use the standalone legacy" " version to run on older Windows version." msgstr "" #: builder/win/NSIS_Installer.nsi msgid "Shutting down SABnzbd" msgstr "" #: builder/win/NSIS_Installer.nsi msgid "This will uninstall SABnzbd from your system" msgstr "Tämä poistaa SABnzbd:n tietokoneestasi" #: builder/win/NSIS_Installer.nsi msgid "Run at startup" msgstr "Suorita käynnistyksen yhteydessä" #: builder/win/NSIS_Installer.nsi msgid "Desktop Icon" msgstr "Työpöydän kuvake" #: builder/win/NSIS_Installer.nsi msgid "NZB File association" msgstr "NZB tiedostosidos" #: builder/win/NSIS_Installer.nsi msgid "Delete Program" msgstr "Poista sovellus" #: builder/win/NSIS_Installer.nsi msgid "Delete Settings" msgstr "Poista asetukset" #: builder/win/NSIS_Installer.nsi msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Et voi asentaa tätä vanhan asennuksen päälle. \\n\\nPaina `OK` poistaaksesi " "edellisen version tai paina `Peruuta` peruuttaaksesi tämän päivityksen." #: builder/win/NSIS_Installer.nsi msgid "Your settings and data will be preserved." msgstr "Asetuksiasi ja tietojasi ei poisteta." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2164483 SABnzbd-4.3.2/po/main/sr.po0000644000000000000000000036135714625637207014570 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sr\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" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Упозорење" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Грeшкa" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Neuspešno pokretanje web interfejsa" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Немогуће наћи веб модел: %s, програм покушава са стандардним моделом" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 program...NIJE pronađen!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "Verzija vašeg UNRAR-a je %s, mi preporučujemo verziju %s ili noviju.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar program...NIJE pronađen!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za program...NIJE pronađen" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Obratite pažnju, hostu 0.0.0.0 će trebati IPv6 adresa za pristup spolja" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP i HTTPS portovi ne mogu biti isti" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS onemogućen zbog nedostajućih CERT i KEY datoteka" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Neuspešno pokretanje web interfejsa: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s покренут" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Гашење SABnzbd је завршено" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s primljen, snimanje i napuštanje..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Fatalna greška pri snimanju trenutnog stanja" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Упешно слање е-поште" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Probno obaveštenje" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Име хоста није унето." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "Везе нису подешене. Подесити макар једну везу." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Лозинка сакривена испод ******, поновите унос" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Погрешни детаљи сервера" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Adresa servera \"%s:%s\" je neispravna" #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Истекло време: Покушајте да упалите SSL или да се привежете на други порт." #: sabnzbd/api.py msgid "Timed out" msgstr "Време је истекло" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Серверу су потребни име и лозинка." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Успешно привезивање!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Аутентификација погрешна, проверити име/лозинку." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "Превише конекција, паузирајте преузимање или поновите касније" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Nemoguće odrediti rezultate konekcije (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Решавање адресе" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ниједно" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Подразумевано" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disk je pun! Tera Pause" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Greška na disku prilikom kreiranja datoteke %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Fatalna greška u Assembler-u" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Premalo prostora na disku, prisiljena PAUZA" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Prekinuto, detektovana enkripcija" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Neželjena ekstenzija je u rar datoteci %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Prekinuto, detektovana neželjena ekstenzija" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Kvota utrošena, pauziram preuzimanja" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Погрешан параметар" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s nije ispravna email adresa" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Потребна је адреса сервера" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Погрешна адреса сервера." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s nije ispravna oktalna vrednost" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Pед није празан, фасцикла се не може променити." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Ne može da se upiše u INI datoteku %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Ne može se kreirati sigurnosna kopija za %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Pogrešno šifrovana lozinka %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "Не могу да пишем у бази дневника, проверите дозволе!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Baza dnevnika je oštećena, kreirana prazna zamena" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Neuspešna SQL komanda, videti izveštaj" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Неуспешно затварање базе, видети извештај" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Погрешне етапе извештаја можете наћи у хронологији за %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Nepoznata greška pri dešifrovanju %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Завршено" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Издвојено %s датотека/фасцикла у %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Неуспешно читање надгледане фасцикле %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Nastavlja se" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Паузирано" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Требате да поставите максимални проток пре него што поставите ограничење" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Neuspešno povezivanje na server %s[%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Ime servera se ne može odrediti" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s će biti ignorisan %s minuta" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Neuspešna inicijalizacija %s@%s iz razloga: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Previše konekcija ka serveru %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Неуспешно пријављивање на сервер %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Povezivanje na %s@%s neuspešno, poruka=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Sumnja u grešku u programu za download" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Гашење" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Неуспешно привезивање на сервер е-поште" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Неуспешна иницијализација TLS везе" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Server nije pravilno odgovorio na helo pozdrav" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Неуспешна аутентификација на серверу е-поште" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Nije pronađen odgovarajući metod autentifikacije" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Nepoznata greška pri autentifikaciji na email server" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Neuspešno slanje e-mail poruke" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Неуспешно затварање везе е-поште" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Nemoguće poslati, nedostaju obavezni podaci" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Немогуће наћи модел е-поруке у %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Нема примаоце, е-порука није послана" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Неуспешно читање %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Нема модела е-поруке" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Za: %s\n" "Od: %s\n" "Datum: %s\n" "Tema: SABnzbd prijavljuje Disk Pun\n" "\n" "Zdravo,\n" "\n" "SABnzbd je stao sa downloadom zato što je disk skoro pun.\n" "Molimo Vas napravite mesta i pokrenite download u SABnzbd ručno.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Немогуће креирати фасциклу %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "Фасцикла %s: %s грешка приступа" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Не може да се промене дозволе од %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Neuspešno kreiranje (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Neuspešno premeštanje %s u %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Грешка у tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Snimanje %s neuspešno" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Učitavanje %s neuspešno" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API кључ недостаје, унети у спољни програм API кључ из Подешавање->Опште:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API кључ је погрешан, унети у спољни програм API кључ из Подешавања->Опште:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py msgid "Daily" msgstr "Дневно" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Понедељак" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Уторак" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Среда" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Четвртак" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Петак" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Субота" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Недеља" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "искљ." #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Server nije definisan!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "ГРЕШКА:" #: sabnzbd/interface.py msgid "Back" msgstr "Назад" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "д" #: sabnzbd/misc.py msgid "h" msgstr "с" #: sabnzbd/misc.py msgid "m" msgstr "м" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Нова верзија доступна!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Грешка креације SSL кључа и сертификата" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Сортирање серије" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Сређивање датумом" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Покретање скрипта" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Previše ugnježdenih nivoa pri raspakivanju [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Спајање" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Непотпуна секвенца датотеке за спајање" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Спој датотеке %s није успело" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Грешка \"%s\" при споја датотеке" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Грешка \"%s\" док сам покренуо 'file_join' на %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Спојено %s датотеке(а)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Neuspešno raspakivanje, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Greška \"%s\" pri raspakivanju RAR datoteka" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Грешка \"%s\" док сам радио 'rar_unpack' на %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Neuspešno brisanje %s!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Proba raspakivanja sa lozinkom \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Распакивање" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Погрешно распакивање, не може да се нађе %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Neuspešno raspakivanje, CRC greška" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Neuspašno raspakivanje, greška u pisanju ili je disk pun?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Neuspešno raspakivanje, putanja je predugačka" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Neuspešno raspakivanje, arhiva zahteva lozinku" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Neupotrebljiva RAR datoteka" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Покушавам 7zip са лозинком \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "видети извештај" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Брза Провера" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Поправи" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Брза Провера ОК" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Покретање пооправљања" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Neuspešna popravka, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Грешка %s при покретања 'par2_repair' на скупу %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Грешка \"%s\" при покретања 'par2_repair' на скупу %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] 'PAR2' је примио погрешне опције, проверите параметри " "Подешавање->Прекидачи" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Проверено за %s, све датотеке су добре" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Проверено за %s, потребна је поправка" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Учитавање %s блокова..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Добављам" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Погрешна поправка, нема довољно блокова за поправку (фали %s)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Поправљање" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Поправљено за %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Диск је пун" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Проверавање" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Провера" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Pokušaj SFV provere" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "остало" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Ovaj server ne dozvoljava SSL na ovom portu" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Вики" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Покретање/Гашење" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Пауза" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Настави" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "НЗБ додат" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Пост-процесирање покренуто" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "посао завршен" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Неуспешан рад" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Ред завршен" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Остале поруке" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Otvori fasciklu završenih" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Недоступно" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Неуспешно слање Prowl поруке" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Neodgovarajući odgovor od strane Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Neuspešno slanje Pushover poruke" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Pogrešan odgovor Pushbullet-a (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Neuspešno slanje Pushbullet poruke" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Nemoguće kreiranje privremene datoteke za %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Грешка додавања %s, уклањање" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Greška pri uklanjanju %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Неуспешан унос %s датотеке са %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Некомпатибилан ред нађен, на могу да наставим" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Грешка учитавање %s, покварена датотека нађена" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB додат у ред" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Игнорисање дуплог NZB-а \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Празан NZB %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Поништено, не може да се заврши" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Грешка увоза %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "ДУПЛИКАТ" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "ШИФРИРАНО" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "ПРЕВЕЛИКО" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "НЕПОТПУНО" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "NEŽELJENI" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "Чекање %s сек" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Преузето за %s на просек од %sБ/с" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Старост" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s артикла нису добро формирани" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s артикла недостају" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s артикла нису дупликате" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Паузирам због дуплог NZB-а \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Упозорења" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Мирoвање" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Ред" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Очисти ред" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Хронологија" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Очисти хронологију" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Ограничење брзине" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "мин." #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Скенирај надгледану фасциклу" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Pročitani svi RSS kanali" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Комплетна фасцикла" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Некомплетна фасцикла" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Реши проблем" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Поново покрени" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Ponovno pokretanje bez prijave" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Излаз" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "У ред прве 10 ставке" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Празно" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Хронологија задњих 10 ставка" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Покрени асистент" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Заустављам..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Проблем са" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd-у је потребан слободан tcp/ip порт за интерни веб сервер.
\n" " Покушан је порт %s на %s, али није доступан.
\n" " Неки други програм користи тај порт или SABnzbd већ ради.
\n" "
\n" " Поново покрените SABnzbd са другим портом." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "Ако опет имате ову грешку, покушајте други број.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd-у је потребна важећа хост адреса за интерни веб сервер.
\n" " Унели сте погрешну адресу.
\n" " Сигурне вредности су localhost и 0.0.0.0
\n" "
\n" " Поново покренути SABnzbd са добром хост адресом." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd је нашао сачуване податке неке друге верзије SABnzbd-а
\n" " али не може да искористи податке са другог програма.

\n" " Морате прво де завршите ред са другом верзијом програма.

\n" " После тога, покренути овај програм са опцијом \"--clean\".
\n" " То ће обрисати актуелни ред и хронилогију!
\n" " SABnzbd чита датотеку \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd не може да нађе датотеке веб интерфејса у %s.
\n" " Молимо да поново инстлирате програм.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd је нашао фаталну грешку:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd је нашао да недостаје датотека 'sqlite3.dll'.

\n" " Неки лоши против-вирусни програми уклањају ту датотеку.
\n" " Проверите против-вирусни програм, поново инсталирајте SABnzbd и пошаљите жалбу својим продавацу против-вируса.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Стиснути Startkey+R и унети линију (пример):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Отворите прозор терминала и унети линију (пример):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Програм није покренут!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Фатална грешка" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Немогуће је покренути претраживач, вероватно није нађен" #: sabnzbd/panic.py msgid "Access denied" msgstr "Приступ одбијен" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Грешка %s: Требате да унесете важеће име/лозинку." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Стари ред је нађен, употребити Статус->Поправи за претварање реда" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Neuspešna kompilacija regularne ekspresije za termin pretrage: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Преузимање је можда погрешно. има %s од потребних %s" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Неуспешно преузимање - није на вашем серверу" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Пост-процесирање" #: sabnzbd/postproc.py msgid "Moving" msgstr "Премештање" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "%s послат у ред" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Грешка преименовања \"%s\" у \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Неуспешно премештање датотека" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Покретање скрипта %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Kod prekida skripte je %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "%s покренуто" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Више" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Грешка пост-процесирања за %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Неуспешно преузимање" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Чишћење %s није успело." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Преузимање завршено" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Немогуће креирање фасцикле %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Нема par2 датотеке" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Неке датотеке нису проверене \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Успешна провера преко СФВ" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Zahteva lozinku" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Brisanje %s neuspešno" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Неуспешна хибернација система" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Неуспено постављање система у стању приправности" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Greška pri gašenju sistema" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Погрешан опис RSS фида \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Немам важећу аутентификацију за фид %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Greška na strani servera (kod greške %s); nemoguće dobiti %s na %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Неуспешно преузимање RSS од %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Server %s koristi nepouzdan HTTPS sertifikat" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS фид %s је празан" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Некомпатибилан Фид" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Nađen prazan RSS unos (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Pokaži interfejs" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Паузирај за" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Паузирај 5 минута" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Паузирај 15 минута" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Паузирај 30 минута" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Паузирај 1 сат" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Паузирај 3 сата" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Паузирај 6 сати" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Угаси" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Преостало" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Додај NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Лоша планификација %s у %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Непозната акција: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Планификација за непостојећи сервер %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Покушај постављања статуса за непостојећи сервер %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Преузми" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Прилепити датотеке" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Распакуј" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Скрипт" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Извор" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Сервери" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Неуспешно" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Чекам" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Popravljanje..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Распакујем..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Премештање..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Покретање скипта..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Преузимање екстра блокова..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Брза провера..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Проверавање..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "Onemogući server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "Omogući server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Ограничење брзине" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Паузирај све" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Паузирај пост-процесирање" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Настави пост-процесирање" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Читај RSS фидове" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Уклони неуспешна посла" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Ukloni završene poslove" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pauziraj poslove sa niskim prioritetom" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pauziraj poslove sa normalnim prioritetom" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pauziraj poslove sa visokim prioritetom" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Настави радови са ниским приоритетом" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Настави радови са нормалним приоритетом" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Настави радови са високим приоритетом" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Омогући управљање квота" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Онемогући управљање квота" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Искључено" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Врло ниско" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Умерено" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Нормалан" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Висок" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Хитно" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Низак" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "сат" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "сата(и)" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "мин." #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "сек." #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "секунди(е)" #: sabnzbd/skintext.py msgid "day" msgstr "дан" #: sabnzbd/skintext.py msgid "days" msgstr "дана" #: sabnzbd/skintext.py msgid "week" msgstr "седмица" #: sabnzbd/skintext.py msgid "Month" msgstr "Месец" #: sabnzbd/skintext.py msgid "Year" msgstr "Година" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Дан у месецу" #: sabnzbd/skintext.py msgid "This week" msgstr "Ове седмице" #: sabnzbd/skintext.py msgid "This month" msgstr "Овог месеца" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Данас" #: sabnzbd/skintext.py msgid "Total" msgstr "Укупно" #: sabnzbd/skintext.py msgid "on" msgstr "укљ." #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametri" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Верзија Python-а" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Почетна страница" #: sabnzbd/skintext.py msgid "or" msgstr "или" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Хост" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Откажи" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Сачувај" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Snimanje..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Да ли сте сигурни?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Кућа" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Подешавање" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Статус" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Помоћ" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Форум" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Подржите пројекат, дајте добровољан прилог!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Опште" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Фасцикле" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Прекидачи" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Планирање" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Обавештења" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Е-пошта" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Категорије" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Сортирање" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Посебно" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Претрага" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Da li ste sigurni da želite ugasiti SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Додај" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Категорија" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Приоритет" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Поправи" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Издвој" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Обриши" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Форсирај" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Заустави" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Унесите УРЛ" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Угаси рачунар" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "У стање приправности" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Хибернација" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Угаси SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Обрађивање" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Име" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Покушај опет" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Скрипте" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Обрисати све ставке са реда?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Очисти NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Очисти NZB и обриши датотеке" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Уклони NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Уклони NZB и обриши датотеке" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Недостају артикли" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Остала квота" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "ручно" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Ресетуј квоту" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Сакриј детаље" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Прикажи детаље" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Прикажи погрешне" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Прикажи све" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Величина" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Очисти NZB са грешком" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Очисти NZB са грешком и обриши датотеке" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Очисти завршене NZB" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Додатне опције NZB-а" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Путања" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Ponovo pokušaj sve neuspešne poslove" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Натерај искључење" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "То ће послати пробну е-поруку Вашем малогу." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Покажи извештај" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Пробна е-порука" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Бележење" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Грешке/Упозорења" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Инфо" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Дебаг" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Везе" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Идентифација артикла" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Збир датотека" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Омогућено" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Veza neuspešna!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokalna IPv4 adresa" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Javna IPv4 adresa" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6 adresa" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nameserver/DNS Pretraga" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Performanse sistema (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Brzina foldera za preuzimanje" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Brzina foldera za kompletirana preuzimanja" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Ponovi test" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "; Датотека подешавања" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "; Кеш" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Ово поново покреће SABnzbd.
Користити ако мислите да програм има " "проблем стабилности.
Преузимање ће бити паузирано и наставиће се после." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Постоје усамљени радови у фасцикли преузимања.
Можете да их обришете " "(укључујући датотеке) или да их поново пошаљете у ред." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "То поново покреће SABnzbd и ради пуну
реконструкцију садржаја реда, " "чувајући већ преузете датотеке.
То мења ред реда." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Промене су изгубљене јер нису сачуване." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Омогући 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "; Верзија" #: sabnzbd/skintext.py msgid "Uptime" msgstr "; Ради" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Резервно" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "За више информација, читајте Вики!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Поновно покретање SABnzbd-а..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "За апликацију промена, поново покренути програм!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd Веб сервер" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd хост" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Хост на којем SABnzbd слуша." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd Порт" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Порт на који SABnzbd чека везе." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Корисничко име SABnzbd-а" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Корисничко име за аутентификацију (опционо)" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Лозинка SABnzbd-а" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Лозинка за аутентификацију (опционо)" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Активирај HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Приступ интерфејсу преко HTTPS адресе." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS порт" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Ако је празно, стандардни порт ће слушати само HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS сертификат" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Датотека или путања до HTTPS сертификата." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS кључ" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Датотека или путања до HTTPS кључа." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS Chain цертификати" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Датотека или путања до HTTPS Chain" #: sabnzbd/skintext.py msgid "Tuning" msgstr "Штеловање" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Интервал RSS провере" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Интервал провере (у минутима, макар 15). Неактивно када користите планер!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Макс брзина линије" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Постатак брзине линије" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "Који постотак брзине линије SABnzbd треба да користи, нпр. 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Лимит кеша артикла" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Кеширати артикле у меморији. То смањује приступ диска.
У бајтовима, " "опционо додати K,M,G. Пример: \"64M\" или \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Списак чишћења" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Листа ектензије за брисање после преузимања.
На пример: nfo или " "nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Сачувај промене" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Ресетуј" #: sabnzbd/skintext.py msgid "Language" msgstr "Језик" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Језик веб интерфејса" #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "API кључ" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Овај кључ допушта пун приступ SABnzbd-а другим програмима." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB кључ" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "Кључ допушта да други програми додају NZB у SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Генериши нов кључ" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "QR Код АПИ кључа" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Екстерни приступ интернету" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Без приступа" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Dodaj NZB datoteke " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (без подешавања)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Цео API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Цео веб интерфејс" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "БЕЛЕШКА: Фасцикле ће бити аутоматски креиране приликом Сачувавања. " "Могуће је коришћење апсолутне путање за сачувавање ван подразумеваних " "фасцикли." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Корисничке фасцикле" #: sabnzbd/skintext.py msgid "Browse" msgstr "Pregledaj" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Привремена фасцикла преузимања" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Смештај непроцесираних преузимања.
Промене су могуће само када је " "ред празан." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Минимални простор за привремену фасциклу" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Паузирај када је простор испод ове вредност.
У бајтовима, опционо " "додати K,М,G,T. НПР: \"800M\" или \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Фасцикла за завршена преузимања" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Смештај завршених, процесираних преузимања.
Може се заобићи у " "дефинисаним категоријама." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Automatski nastavi" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Дозволе за фасциклу завршених преузимања" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Поставља дозволе за завршене датотеке/фасцикле.
У октал. На пример: " "\"755\" или \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Надгледана фасцикла" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Фасцикла за надгледање .nzb датотека." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Интервал скенирања" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Број секунди између 2 провере .nzb датотека" #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Фасцикла модела е-поште" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Фасцикла где се налазе модели е-поште." #: sabnzbd/skintext.py msgid "Password file" msgstr "Лозинка датотеке" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "Датотека са свим лозинкама за шифроване РАР датотеке." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Системске фасцикле" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Фасцикла Администратора" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Локацију за ред и хронологију базе.
Промене су могуће само када је " "ред празан." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Податци неће бити премештени. Потребно поновно покретање " "SABnzbd-а!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Фасцикла извештаја" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Смештај извештаја SABnzbd-а.
Потребно је поновно покретање " "SABnzbd-а!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Фасцикла копије .нзб" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Смештај за сачувавање .нзб датотека." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Подразумевана основна фасцикла" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Преузми све par2 датотеке" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Омогући рекурсивни издвој" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Издвој архиве (rar, zip, 7z) унутра архиве." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignoriši foldere unutar arhiva" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Sve datoteke će biti smeštene u jedan folder" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Само артикли на врху реда" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Упали за мању употребу меморије. Угасити ради спречавања блокирања реда " "спорим радовима." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Пост-процесирај само проверени послови" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Акција када је шифрован РАР преузет" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "Ако је \"Пауза\", требате да поставите лозинку и да наставите рад." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Одбаци" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Radnja kada je otkrivena neželjena ekstenzija" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Neželjene ekstenzije" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Упали SFV провере" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Уради још једну проверу базирану на SFV датотеке." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Korisničke skripte mogu uznačiti posao kao neuspešan" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Kada korisnička skripta vrati kod koji nije nula, posao će biti označen kao " "neuspešan" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Упали преименовање фасцикле" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Користи привремено име при пост-процесирање. Угасити уколико га Ваш систем " "то не прихвата како треба." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Кориснички скрипт пре-реда" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Коришћено пре него што NZB уђе у ред." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Додатни параметри PAR2" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Параметри 'Nice'" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Параметри 'IONice'" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Заустави везу када је ред празан" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Искључи се са сервера када је ред празан или паузиран." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Провери нове верзије" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "И пробне верзије" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Размени размаке у имену фасцикле" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Размени размаке са _ у имену фасцикле." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Размени тачке у имену фасцикле" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Размени тачке са размацима у имену фасцикле." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Napravi Windows kompatibilnim" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "Za servere: osiguraj da su imena kompatibilna sa Windows-om." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Покрени претраживач при покретању" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Покрени Веб претраживач при покретању SABnzbd-а." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Паузирај док се пост-процесира" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "Паузирај преузимања на почетку пост-процесирања и настави после." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Игнориши примере" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Филтрирај примерне датотеке (нпр. видео пример)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Обриши после преузимања" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Сервер" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Накнадна обрада" #: sabnzbd/skintext.py msgid "Naming" msgstr "Именовање" #: sabnzbd/skintext.py msgid "Quota" msgstr "Квота" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Колико може да се преузме овог месеца (К/М/Г)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Дан ресетовања" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Који дан месеца или недеље (1=понедељак) Ваш провајдер ресетује квоту? " "(опционо са hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Да се настави преузимање после ресета квоте?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Период квоте" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Квота је ресетована сваки дан, недеље или месец?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Провери пре преузимања" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Покуша да предвиди успешан завршетак пре стварног преузимања (спорије!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Макс покушаја" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Макс покушаја по серверу" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Поништи рад који не може да се заврши" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Када током преузимања постаје јасно да превише података недостаје, прекинути" " посао" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Додај сервер" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Opis servera" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Порт" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Корисничко име" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Лозинка" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Време истекло" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Време задржавања" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "ССЛ" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Онемогућено" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 je najveći prioritet, 99 je najniži prioritet" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Опционо" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Омогући" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Уклони сервер" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Пробај сервер" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Испразни бројаче" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Пробам детаље сервера..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Проток" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Lične zabeleške" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Dodaj raspored" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Фреквенција" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Акција" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Аргументи" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "trenutni rasporedi" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Кутијица поред имена фида треба да буде одабрана да би фид био омогућен и да" " провери нове ставке.
Када је фид додат, ће узети нове ставке а не оне" " које су већ у RSS фиду осим ако стиснете \"Натерај преузимање\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Читај фид" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Натерај преузимање" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Редослед" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Тип" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Филтер" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Прихвати" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Одбаци" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Захтеви" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "ПотребанCat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Najmanje" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Највише" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Od SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Одговара" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Не одговара" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Преузето" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Сада читај све фидове" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Нотификација е-поштом при завршетку рада" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Никад" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Увек" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Само-Грешке" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Обавештење пуног диска" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Пошаљи е-поруку када је диск пун и SABnzbd паузиран." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Пошаљи RSS нотификације" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Пошаљи е-поруку када RSS фид дода рад у ред." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "СМТП сервер" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Унети сервер излазних е-поруке вашег провајдера." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Е-пошта примаоца" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Адреса на коју се шаље е-порука." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Е-пошта слања" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Е-пошта одакле долази нотификација" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "Корисничко име (ОПЦИОНО)" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Ако је потребна аутентификација за слање е-поште, унети име." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "Лозинка (ОПЦИОНО)" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Ако је потребна аутентификација за слање е-поште, унети лозинку." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Обавештење послато!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Упали „NotifyOSD“" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Центар за обавештења" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Windows notifikacije" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows notifikacije" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Омогући Prowl нотификације" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Потребан Prowl налог" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "API кључ за Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Лични API кључ за Prowl (потребно)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Omogući Pushover notifikacije" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Zahteva Pushover nalog" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Token aplikacije" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Token aplikacije (obavezan)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Korisnički ključ" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Korisnički ključ (obavezan)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Uređaj(i)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Uređaj(i) na koje bi poruke trebale biti poslate" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Omogući Pushbullet notifikacije" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Zahteva Pushbullet nalog" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Lični API ključ" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Vaš lični Pushbullet API ključ (obavezan)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Уређај" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Uređaj na koji bi poruka trebala biti poslata" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Завршавање путање са звездицом * ће спречити креацију фасцикле за рад." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Релативност фасцикле је базирано" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Фасцикла/Путања" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Модел кључа" #: sabnzbd/skintext.py msgid "Clear" msgstr "Очисти" #: sabnzbd/skintext.py msgid "Presets" msgstr "Предподешавања" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Погођене категорије" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Значење" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Модел" #: sabnzbd/skintext.py msgid "Result" msgstr "Резултат" #: sabnzbd/skintext.py msgid "Title" msgstr "Наслов" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Име филма" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Име.Филма" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Име_филма" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Име серије" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Име.серије" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Име_Серије" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Број сезоне" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Број епизоде" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Име епизоде" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Име.Епизоде" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Име_епизоде" #: sabnzbd/skintext.py msgid "Extension" msgstr "Екстензија" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Број дела" #: sabnzbd/skintext.py msgid "Decade" msgstr "Декада" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Оригинално име датотеке" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Мала слова" #: sabnzbd/skintext.py msgid "TEXT" msgstr "ТЕКСТ" #: sabnzbd/skintext.py msgid "text" msgstr "текст" #: sabnzbd/skintext.py msgid "file" msgstr "датотека" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Уреди низ" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "У фасциклама" #: sabnzbd/skintext.py msgid "No folders" msgstr "Нема фасцикле" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "Прилагођено-слово" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Резултат обрађивања" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Све" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Опције ретко коришћене. За њихово значење и објашњење, клинути на дугме " "Помоћ за одлазак на Вики страницу.
Немојте их мењати пре не провере на " "Вики, пошто неке имају озбиљне нежељене ефекате.
Подразумеване вредности " "су између заграда." #: sabnzbd/skintext.py msgid "Values" msgstr "Вредности" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Уреди детаље NZB-а" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Обриши" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Име датотеке" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Слободан простор" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Привремено" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Мулти-операције" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Držite taster shift pritisnut da bi ste odabrali raspon" #: sabnzbd/skintext.py msgid "Check all" msgstr "Proveri sve" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Ponovo pokreni SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Када се ред заврши" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Opcije statusa i interfejsa" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Ili prevucite i pustite datoteke u prozor!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Izgubljena konekcija sa SABnzbd" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "U slučaju ponovnog pokretanja SABnzbd-a ovaj prozor će nestati automatski!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "ПАЖЊА:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Преузми" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Веб интерфејс" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Брзина освежавања" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Koristi globalna podešavanja interfejsa" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Limit stavku u redu" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Limit stavki u istoriji" #: sabnzbd/skintext.py msgid "Date format" msgstr "Формат датума" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "страни" #: sabnzbd/skintext.py msgid "Loading" msgstr "Учитавам" #: sabnzbd/skintext.py msgid "articles" msgstr "artikli" #: sabnzbd/skintext.py msgid "Rename" msgstr "Преименуј" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Поправљење реда" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Prikaži aktivne konekcije" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Деблокирај" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Zapušteni poslovi" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Pošalji nazad u red" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Избриши све" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Ponovo pokušaj sve" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Povuci NZB sa URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Pošalji NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Опционо специфирати име" #: sabnzbd/skintext.py msgid "Submit" msgstr "Пошаљи" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Ukloni sve odabrane fajlove" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Sakrij/prikaži sve završene datoteke" #: sabnzbd/skintext.py msgid "Top" msgstr "Врх" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Дно" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Види извештај скрипта" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Прилагођено" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Брзина" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Потврда брисања реда" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Потврда брисања хронологије" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Koliko dugo ili dokle želite da pauzirate? (na engleskom!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Žao nam je, nismo mogli to da interpretiramo. Pokušajte ponovo." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Паузирај за..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Освежи" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Среди по старост Старије→Новије" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Среди по старост Новије→Старије" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Среди по имену A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Среди по имену Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Среди по величини Мање→Веће" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Среди по величини Веће→Мање" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Асистент брзог-покретања SABnzbd-а" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Верзија SABnzbd-а" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Претходно" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Следеће" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Детаљи сервера" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Овде унети детаље вашег примарног 'usenet' провајдера." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Број веза дозвољене од стране провајдера" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Нпр 8 или 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Одабрати САМО ако Ваш провајдер допушта SSL везе." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Кликнути за пробу унетих детаља." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Нпр." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Подешавање је сада завршено!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd ће сада радити у позадини." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Затварање прозора/језичка претраживаче НЕЋЕ затворити SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Препоручено је да поставите ову локацију као 'маркер' тако да Вам је приступ" " SABnzbd омогућен док он ради у позадини." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Даља помоћ се може наћи на" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Иди на SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Затвори SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Покрени чаробњака" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd долази БЕЗ ИКАКВЕ ГАРАНЦИЈЕ.\n" "Ово је бесплатан програм, и ви сте добродошли да га делите под одређеним условима.\n" "Лиценциран је под GNU GENERAL PUBLIC LICENSE верзија 2 или (по вашем избору) касније верзије.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Неуспешно преименовање сличне датотеке: %s у %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Neautorizovan pristup" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER SE SRUŠIO" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "NZB датотека неупотребљива" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Погрешно учитавање УРЛ-а; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Pokušaj da se učita NZB sa %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2101195 SABnzbd-4.3.2/po/main/cs.po0000644000000000000000000030725714625637207014550 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Pavel C , 2023 # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Výstrahy" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Chyba" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Nezdařilo se spustit webové rozhraní" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Šablona pro web nebyla nalezena: %s, zkouším standardní šablonu" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools vypnut: Nenalezena správná verze! (Nalezena v%s, očekávána v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "Program par2... nenalezeno!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "Nalezen UNRAR verze %s, doporučujeme verzi %s nebo vyšší.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "Program unrar... nenalezen!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "Program 7za... nenalezen!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "Chybí základní moduly, stahování nemůže být spustěno." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Pozor, hostitelská adresa 0.0.0.0 bude vyžadovat IPv6 adresu pro externí " "přístup" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP a HTTPS porty nemohou být stejné" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd spuštěno s kódováním %s, zatímco doporučené je UTF-8. Očekávejte " "problémy se jmény souborů a adresářů při stahování." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "Nezdařilo se nahrát dodatečné certifikáty z balíku certifi." #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS vypnuto z důvodu chybějících CERT a KEY souborů" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "HTTPS vypnuto z důvodu nevalidních CERT a KEY souborů" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Nepodařilo se spustit webové rozhraní:" #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s spustěno" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Vypnutí SABnzbd dokončeno" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Zachycen signál %s, ukládám a ukončuji..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Neopravitelná chyba při ukládání stavového souboru" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "Restartuji protože postprocessor selhal" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "Restartuji protože selhal downloader" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "Restartuji protože selhal assembler" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "Nelze přistoupit k PID souboru %s" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Email funční" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Otestovat notifikace" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "" #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "" #: sabnzbd/api.py msgid "Invalid server details" msgstr "" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Adresa serveru \"%s:%s\" není správná." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Timed out" msgstr "" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "" #: sabnzbd/api.py msgid "Connection Successful!" msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Přihlášené selhalo, zkontrolujte jméno a heslo." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "" #: sabnzbd/api.py msgid "Resolving address" msgstr "Překládám adresu" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Žádný" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Výchozí" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Plný disk! Vynucené pozastavení" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Probém s vytvořením souboru %s na disku" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Neopravitelná chyba v Assembleru" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Příliš málo místa na disku, přenos POZASTAVEN" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "Pozastavený úkol \"%s\" z důvodu zaheslovaného RAR souboru (vyzkoušeli jsme " "všechna zadaná hesla)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "Ukončený úkol \"%s\" z důvodu zaheslovaného RAR souboru (vyzkoušeli jsme " "všechna zadaná hesla)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Ukončeno, detekováno šifrování" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Neočekávaná přípona v rar souboru %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Přerušeno, nalezena neočekávaná připona" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Kvóta přesažena, pozastavuji stahování" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Nesprávný parametr" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s není validní emailová adresa" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Adresa serveru je vyžadována" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "%s neni validní skript" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s není hodnota v osmičkové soustavě" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Fronta nené prázdná, nelze změnit složku." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "Konfigurace uzamčena, nelze uložit nastavení" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Nelze zapisovat do INI souboru %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Nelze vytvořit zálohu souboru %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "Nelze zapisovat do databáze historie, zkontrolujte oprávnění!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Poškozená databáze historie, nahradtě prázdnou databází" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Spustění SQL příkazu selhalo, zkontrolujte log" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Nezdařilo se uzavření databáze, zkontrolujte log" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Chyba dekodéru: nedostatek paměti" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Neznámá chyba při dekódování %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "Přímé rozbalení" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Dokončeno" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Soubory/složky %s rozbaleny do %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "Přímé rozbalení bylo automaticky zapnuto." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "Úkol se začne rozbalovat během stahování pro redukci času post-procesingu. " "Funguje pouze pro úkoly, které nepotřebují opravu." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Nelze číst ze \"Sledované\" složky %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Obnovování" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Pozastaveno" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Musíte nastavit maximální rychlost linky předtím než začnete nastavovat " "limity pro přenos" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Nelze se připojit k serveru %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Nebylo možné přeložit jméno serveru" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s bude ignorován po dobu %s minut" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Příliš mnoho spojení k serveru %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Přihlášení k serveru %s se nezdařilo [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Nejspíše chyba downloaderu" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Vypínání" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "Server %s vyprší za %s dnů" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "Server %s vyčerpal nastavenou kvótu" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Připojení k poštovnímu serveru se nezdařilo" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Nezdařilo se inicializovat TLS spojení" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Server neodpověděl správně na HELO pozdrav" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Nezdařilo se přihlášení k poštovnímu serveru" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Žádná použitelná autentizační metoda nenalezena" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Neznámá chyba přihlášení k poštovnímu serveru" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Nezdařilo se odeslat e-mail" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Nezdařilo se uzavřít spojení pro mail" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Nelze odeslat, chybějí požadovaná data" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Nepodařilo se najít poštovní šablony v %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Nebyli zadáni přijemci, žádný email neodeslán" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Nelze číst %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Nenalezeny poštovní šablony" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Nelze vytvořit adresář %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "Adresář %s: chyba přístupu k %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Nelze změnit oprávnění adresáře %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Chyba vytváření (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Chyba přesunu %s do %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "Zablokován pokus vytvořit adresář %s" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Chyba v tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Ukládání %s selhalo" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Načítání %s selhalo" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "Odmítnuto spojení z:" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "Odmítnuté spojení s hostem \"%s\" z:" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Uživatel přihlášen do webového rozhraní" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Uživatel přihlášen" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Chybějící API klíč , prosím zadejte api klíč z Nastavení->Obecné do svého " "programu třetí strany:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Nesprávný API klíč, použijte api klíč z Nastavení->Obecné ve vašem programu " "třetí strany:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Nezdařený pokus o přihlášení od %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Kanál" #: sabnzbd/interface.py msgid "Daily" msgstr "Denně" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Pondělí" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Úterý" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Středa" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Čtvrtek" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Pátek" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Sobota" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Neděle" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "vypnuto" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Nedefinovaný server!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "CHYBA:" #: sabnzbd/interface.py msgid "Back" msgstr "Zpět" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Dostupná aktualizace!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "Nezdařilo se nahrát soubor: %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Chyba při vytváření SSL klíče a certifikátu" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "Vaš soubor s hesly obsahuje více než 30 záznamů, použití všech těchto hesel " "vude trvat dlouho. Zkuste omezit počet hesel." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "Nezdařilo se přečíst soubor s hesly %s" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "Python skript \"%s\" nemá nastaveno právo spuštění (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Běžící skript" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Nekompletní sekvence spojovaných souborů" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Spojování souboru %s selhalo" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Chyba \"%s\" během spojování souborů" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Chyba \"%s\" v průběhu file_join pro %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Spojeno %s souborů" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Rozbalení selhalo, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Chyba \"%s\" během rozbalování RAR souborů" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Chyba \"%s\" v průběhu rar_unpack pro %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Mazání %s selhalo!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Zkouším unrar s heslem \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Rozbaluji" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Rozbalování selhalo, nezdařilo se najít %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Rozbalování selhalo, CRC chyba" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" "Rozbalování selhalo, soubor je příliš velký pro souborový systém (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Rozbalování selhalo, chyba zápisu nebo plný disk?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Rozbalování selhalo, cesta k souboru je příliš dlouhá." #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Rozbalení selhalo, archiv vyžaduje heslo" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Nepoužitelný RAR soubor" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Porušený RAR soubor" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Zkouším 7zip s heslem \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "více v protokolovacím souboru" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Rychlá kontrola" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Opravit" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Rychlá kontrola OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Spouštím opravu" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Oprava selhala, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Chyba %s při spoustění par2_repair na skupině %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Chyba \"%s\" při spoustění par2_repair na skupině %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] Špatné nastavení PAR2, zkontrolujte volby v Konfigurace->Přepínače" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Zkontrolováno v %s, všechny soubory jsou spravné" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Zkontrolováno v %s, je nutná oprava" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Nesprávné par2 soubory nebo nesprávné parametry PAR2, nelze zkontrolovat ani" " opravit" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Stahuji %s bloků..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Stahuji" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Oprava se nezdařila, nedostatek bloků k opravě (chybí %s)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Opravuji" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] opraveno v %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "Ověřuji opravu" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Plný disk" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Kontroluji další soubory" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Ověřuji" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Kontroluji" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Zkouším SFV ověření" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Tento server nepovoluje SSL na tomto portu" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "Certifikát nesouhlasí se jménem serveru: jméno serveru není obsaženo v " "certifikátu. Toto je chyba serveru." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "Certifikát není validní. Pravděpodobně chyba serveru." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Server %s používá nedůvěryhodný certifikát [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Spuštění/Vypnutí" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pozastavit" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Obnovit stahování" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB přidáno" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Začal post-procesing " #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Úkol dokončen" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Úkol neuspěšný" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Fronta dokončena" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Ostatní zprávy" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Otevřít složku s kompletními soubory" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Nedostupné" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "Nepodařilo se odeslat macOS oznámení" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Nepodařilo se odeslat Prowl zprávu" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Nesprávná odpověd z Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Nezdařilo se odeslat pushover zprávu" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Nesprávná odpověd z Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Nezdařilo se odeslat pushbullet zprávu" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Skript vrátil návratový kód %s a výstup \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Notifikační skript \"%s\" neexistuje" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Nepodařilo se odeslat Windows oznámení" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Nelze vytvořit dočasný soubor pro %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Chyba při přidávání %s, odstraněno" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Chyba při odstraňování %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Nezdařilo se importovat %s souborů z %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Nekompatibilní soubor fronty, nelze pokračovat" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Nelze nahrát %s, detekován porušený soubor" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB přidáno do fronty" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignoruji duplikátní NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "Nezdařilo se duplikovat NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "Duplikátní NZB" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Prázdný NZB soubor %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "Nechtěná přípona v souboru %s (%s)" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Zrušeno, nelze dokončit" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Chyba při importu %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLIKÁT" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "ŠIFROVANÉ" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "PŘÍLIŠ VELKÝ" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "NEKOMPLETNÍ" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "NECHTĚNÝ" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "ČEKÁNÍ %s s" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "PROPAGUJI %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Staženo do %s s průměrnou rychlostí %s B/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Stáří" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Pozastavuji duplikátní NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Výstrahy" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Nečinný" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Fronta" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Vyprázdnit frontu" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historie" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Vyprázdnit historii" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Omezit rychlost" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "minuta" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Zkontrolovat sledovanou složku" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Číst všechny RSS kanály" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Složka dokončených" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Složka nedokončených" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Restart" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Restart bez přihlášení" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Vypnout" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Fronta prvních 10 položek" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Prázdný" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Historie posledních 10 položek" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Zastavuji..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problém s" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd detekovalo závažnou chybu:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Program se nespustil!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Neopravitelná chyba" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Nelze spustit webový prohlížeč, nejspíš nenalezen" #: sabnzbd/panic.py msgid "Access denied" msgstr "Přístup odepřen" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Stará fronta nalezena, použijte Status->Repair pro konverzi fronty" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Nepodařilo se zkompilovat regex pro hledaný výraz: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "" #: sabnzbd/postproc.py msgid "Moving" msgstr "Přesun" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Odesláno %s do fronty" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Nezdařilo se přejmenovat \"%s\" na \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Nezdařilo se přesunout soubory" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Spouštím uživatelský skript %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Navratový kód skriptu je %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Spuštěno %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Více" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Postprocesing selhal pro %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Stahování selhalo" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Čištění %s selhalo." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Stahování dokončeno" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Nelze vytvořit složku dokončených souborů %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Úspěšně ověřeno s využitím SFV souborů" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Zaheslováno" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Odstraňování %s selhalo" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Nezdařilo se hibernovat systém" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Špatný popis RSS kanálu \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Nezdařilo se stáhnout RSS z %s:%s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS kanál %s byl prázdný" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Nekompatibilní kanál" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Prázdný RSS záznam nalezen (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Zobrazit rozhraní" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pozastavit na" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pozastavit na 5 minut" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pozastavit na 15 minut" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pozastavit na 30 minut" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pozastavit na 1 hodinu" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pozastavit na 3 hodiny" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pozastavit na 6 hodin" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Vypnout" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Zbývá" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Přidat NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Neznámá akce: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Zkouším aktualizovat stav neexistujícího serveru %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Stahování" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Spojit soubory" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Rozbalit" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Skript" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Zdroj" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servery" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Selhalo" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Čekání" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Opravuji..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Rozbaluji..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Přesouvám..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Spouštím skript..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Stahuji extra bloky..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Rychlá kontrola..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Kontroluji..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "deaktivovat server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "povolit server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Omezení rychlosti" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pozastavit vše" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Číst RSS kanály" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Odstranit neúspěšné úkoly" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Odstranit dokončené úkoly" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pozastavit úkoly s nízkou prioritou" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pozastavit úkoly s normální prioritou" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pozastavit úkoly s vysokou prioritou" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Obnovit úkoly s vysokou prioritou" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Povolit správu kvót" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Vypnout správu kvót" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "Pozastavit úkoly v kategorii" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "Onovit úkoly v kategorii" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Vypnuto" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Velmi nízká" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normální" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Vysoká" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Nízká" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "hodina" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "hodin" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minut" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sekunda" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "sekund" #: sabnzbd/skintext.py msgid "day" msgstr "den" #: sabnzbd/skintext.py msgid "days" msgstr "dní" #: sabnzbd/skintext.py msgid "week" msgstr "týden" #: sabnzbd/skintext.py msgid "Month" msgstr "měsíc" #: sabnzbd/skintext.py msgid "Year" msgstr "Rok" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Den v měsíci" #: sabnzbd/skintext.py msgid "This week" msgstr "Tento týden" #: sabnzbd/skintext.py msgid "This month" msgstr "Tento měsíc" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Dnes" #: sabnzbd/skintext.py msgid "Total" msgstr "Celkem" #: sabnzbd/skintext.py msgid "on" msgstr "zapnuto" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametry" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Verze pythonu" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Domovská stránka" #: sabnzbd/skintext.py msgid "or" msgstr "nebo" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Zrušit" #: sabnzbd/skintext.py msgid "Log in" msgstr "Přihlásit" #: sabnzbd/skintext.py msgid "Log out" msgstr "Odhlásit" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Zapamatuj si mě" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Uložit" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Ukládám..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Jste si jistí?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Domů" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Nastavení" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Stav" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Nápověda" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Fórum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Problémy" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Podpořte projekt!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Obecné" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Složky" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Přepínače" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Plánování" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Upozornění" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Email" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategorie" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Řazení" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Speciální" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Vyhledávání" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Přidat" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategorie" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Priorita" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Opravit" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Rozbalit" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Smazat" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Vynucené" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Zastaveno" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Zadejte URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Vypnout PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Uspat PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Hibernovat PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Vypnout SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Jméno" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Opakovat" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Skripty" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Smazat všechny položky z fronty?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Vymazat všechny NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Vymazat všechny NZB a smazat soubory" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Odstranit NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Odstranit NZB a smazat soubory" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Chybějící části" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Zbývající kvóta" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "ručně" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Vynulovat kvótu" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Skrýt detaily" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Zobrazit detaily" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Zobrazit neúspěšné" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Zobrazit vše" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Velikost" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Vymazat všechny selhalé NZB" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Vymazat všechny selhalé NZB a smazat soubory" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Vymazat všechny dokončené NZB" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Vymazat NZB na aktuální stránce" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Cesta" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Opakovat všechny nedokončené úkoly" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Vynucené odpojení" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Zobrazit protokol" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Otestovat email" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Protokol" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Chyby/výstrahy" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Ladění" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Spojení" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Zapnuto" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Spojení selhalo!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Místní IPv4 adresa" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Veřejná IPv4 adresa" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6 adresa" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "DNS server / DNS dotazy" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Výkon systému (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Rychlost složky pro download" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Rychlost složko pro dokončené" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "Rychlost internetu" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Opakovat test" #: sabnzbd/skintext.py msgid "Test download" msgstr "Otestovat rychlost stahování" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Využití cache" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "Pokročilé" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "" #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Povolit 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Verze" #: sabnzbd/skintext.py msgid "Uptime" msgstr "" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Záloha" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Restartuji SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Změny vyžadují restart SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd webový server" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd port" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd uživatelské jméno" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd heslo" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "Bezpečnost" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Povolit HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS port" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS certifikát" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "" #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py msgid "Tuning" msgstr "" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Interval konctroly RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maximální rychlost linky" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Procento rychlosti linky" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" #: sabnzbd/skintext.py msgid "History Retention" msgstr "Retence historie" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "Zachovat všechny úkoly" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "Úlohy" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Uložit změny" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Obnovit výchozí" #: sabnzbd/skintext.py msgid "Reset" msgstr "Reset" #: sabnzbd/skintext.py msgid "Language" msgstr "Jazyk" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Vyberte jazyk webového rozhraní." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "Pomozte nám přeložit SABnzbd do vaší řeči!
Doplňte chybějící texty " "nebo vylepšete existující překlad:" #: sabnzbd/skintext.py msgid "API Key" msgstr "API klíč" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "NZB Key" msgstr "" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Generovat nový klíč" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "" #: sabnzbd/skintext.py msgid "External internet access" msgstr "" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Bez přístupu" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Přidat NZB soubory" #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "" #: sabnzbd/skintext.py msgid "Full API" msgstr "" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" #: sabnzbd/skintext.py msgid "User Folders" msgstr "Uživatelská složka" #: sabnzbd/skintext.py msgid "Browse" msgstr "" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "" #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "" #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "Složka se skripty" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "" #: sabnzbd/skintext.py msgid "Password file" msgstr "" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" #: sabnzbd/skintext.py msgid "System Folders" msgstr "" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "" #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "" #: sabnzbd/skintext.py msgid "Post processing" msgstr "" #: sabnzbd/skintext.py msgid "Naming" msgstr "" #: sabnzbd/skintext.py msgid "Quota" msgstr "" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "" #: sabnzbd/skintext.py msgid "Check before download" msgstr "" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Přidat server" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "" #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Pořadí" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Typ" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Odeslat RSS upozornění" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Odeslat email když RSS kanál přidá úkol do fronty." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "" #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "" #: sabnzbd/skintext.py msgid "Email Sender" msgstr "" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "" #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "" #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Zařízení" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Spustit vlastní skript" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "" #: sabnzbd/skintext.py msgid "Clear" msgstr "" #: sabnzbd/skintext.py msgid "Presets" msgstr "" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "" #: sabnzbd/skintext.py msgid "Meaning" msgstr "" #: sabnzbd/skintext.py msgid "Pattern" msgstr "" #: sabnzbd/skintext.py msgid "Result" msgstr "" #: sabnzbd/skintext.py msgid "Title" msgstr "" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "" #: sabnzbd/skintext.py msgid "Show Name" msgstr "" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "" #: sabnzbd/skintext.py msgid "Season Number" msgstr "" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "" #: sabnzbd/skintext.py msgid "Extension" msgstr "" #: sabnzbd/skintext.py msgid "Part Number" msgstr "" #: sabnzbd/skintext.py msgid "Decade" msgstr "" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "" #: sabnzbd/skintext.py msgid "TEXT" msgstr "" #: sabnzbd/skintext.py msgid "text" msgstr "" #: sabnzbd/skintext.py msgid "file" msgstr "" #: sabnzbd/skintext.py msgid "Sort String" msgstr "" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "" #: sabnzbd/skintext.py msgid "No folders" msgstr "" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" #: sabnzbd/skintext.py msgid "Values" msgstr "" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "" #: sabnzbd/skintext.py msgid "Free Space" msgstr "" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "" #: sabnzbd/skintext.py msgid "Check all" msgstr "" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Při dokončení fronty" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "" #: sabnzbd/skintext.py msgid "Fetch" msgstr "" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Webové rozhraní" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "" #: sabnzbd/skintext.py msgid "History item limit" msgstr "" #: sabnzbd/skintext.py msgid "Date format" msgstr "" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "" #: sabnzbd/skintext.py msgid "Loading" msgstr "" #: sabnzbd/skintext.py msgid "articles" msgstr "" #: sabnzbd/skintext.py msgid "Rename" msgstr "Přejmenovat" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Odblokovat" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "" #: sabnzbd/skintext.py msgid "Delete All" msgstr "" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Opakovat vše" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Získat NZB z URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Nahrát NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "" #: sabnzbd/skintext.py msgid "Submit" msgstr "" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "" #: sabnzbd/skintext.py msgid "Top" msgstr "" #: sabnzbd/skintext.py msgid "Bottom" msgstr "" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Vlastní" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Rychlost" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "" #: sabnzbd/skintext.py msgid "Pause for..." msgstr "" #: sabnzbd/skintext.py msgid "Refresh" msgstr "" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd verze" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "" #: sabnzbd/skintext.py msgid "Server Details" msgstr "" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "" #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "" #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "" #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "" #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Neoprávněný přístup" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Zkouším stáhnout NZB z %s" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.212851 SABnzbd-4.3.2/po/main/fr.po0000644000000000000000000040574614625637207014554 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # Fred L <88com88@gmail.com>, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.2RC1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Fred L <88com88@gmail.com>, 2024\n" "Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Avertissement" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Erreur" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Impossible de démarrer l'interface web" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" "Impossible de trouver le template de l'interface web : %s, nouvelle " "tentative avec le template standard" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools désactivé: aucune version correcte n'a été trouvée ! (v%s trouvée," " v%s attendue)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "binaire par2... Introuvable!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "Votre version de UNRAR est %s, nous recommandons la version %s ou plus.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "binaire unrar... Introuvable!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "Binaire 7za ... Introuvable!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" "Des modules essentiels sont manquants, le téléchargement ne peut démarrer." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "S'il vous plaît soyez conscient que l'Hôte 0.0.0.0 aura besoin d'une adresse" " IPv6 pour les accès externes" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "Les ports HTTP et HTTPS ne peuvent pas être identiques" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd a été démarré avec l'encodage %s, celui-ci devrait être UTF-8. " "Attendez-vous à des problèmes avec les noms de fichiers et de répertoires " "Unicode dans les téléchargements." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" "L'umask actuel (%o) pourrait refuser à SABnzbd l'accès aux fichiers et " "dossiers qu'il crée." #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" "Impossible de charger les certificats supplémentaires à partir du package " "certifi" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS désactivé car le certificat et la clé n'ont pas été trouvés" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "HTTPS a été désactivé à cause de fichiers CERT et KEY invalides" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Impossible de démarrer l'interface web : " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s démarré" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Arrêt de SABnzbd terminé" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s intercepté, enregistrement et fermeture en cours..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Erreur fatale lors de l'enregistrement" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "Redémarrage suite au plantage du postprocesseur" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "Redémarrage suite au plantage du téléchargeur" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "Redémarrage suite au plantage de l'assembleur" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "Impossible d'accéder au fichier PID %s" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "L'envoi de l'e-mail a réussi" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Test de Notification" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Le nom d'hôte n'est pas défini." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" "Aucune connexion n'est configurée. Veuillez définir au moins une connexion." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Mot de passe masqué en ******, veuillez le ressaisir." #: sabnzbd/api.py msgid "Invalid server details" msgstr "Paramètres serveur incorrects" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" "Impossible de se connecter à %s sur le port %s. Il semble que %s fonctionne " "comme un serveur web (port 80), peut-être un indexeur, et non comme un " "serveur Usenet. Vous devez spécifier un serveur Usenet." #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "L' adresse du serveur \"%s:%s\" n'est pas valide." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Délai dépassé : essayez d'activer SSL ou de vous connecter sur un port " "différent." #: sabnzbd/api.py msgid "Timed out" msgstr "Délai dépassé" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Protocole SSL inconnu: essayez de désactiver SSL ou de vous connecter sur un" " autre port." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Le serveur requiert un identifiant et un mot de passe." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Connexion réussie!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Echec d'authentification, vérifiez les identifiant/mot de passe." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Trop de connexions, veuillez mettre en pause le téléchargement ou essayer " "plus tard" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Impossible de déterminer le résultat de la connexion (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Résolution de l'adresse" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Aucun" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Par défaut" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disque plein ! Pause forcée" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Erreur de disque lors de la création du fichier %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Erreur fatale dans l'assembleur" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Espace disque faible, PAUSE forcée" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "La tâche \"%s\" a été mise en pause à cause d'un fichier RAR chiffré (tous " "les mots de passe fournis ont été essayés)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "La tâche \"%s\" a été abandonnée à cause d'un fichier RAR chiffré (tous les " "mots de passe fournis ont été essayés)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Interrompu, cryptage détecté" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" "Le fichier RAR \"%s\" contient une extension indésirable. Le fichier " "indésirable est %s " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "L'extension indésirable est dans le fichier rar %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Interrompu, extension indésirable détectée" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" "La tâche \"%s\" est probablement chiffrée en raison d'un RAR ayant le même " "nom à l'intérieur de ce RAR" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" "La tâche \"%s\" est probablement chiffrée : \"password\" dans le nom de " "fichier \"%s\"" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Quota atteint, téléchargement mis en pause" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Paramètre incorrect" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s n'est pas une adresse email valide" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Adresse du serveur requise" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Adresse du serveur erronée" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "%s n'est pas un script valide" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s n'est pas une valeur octale correcte" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" "Le réglage des permissions de %s pourrait refuser à SABnzbd l'accès aux " "fichiers et dossiers qu'il crée." #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "Le chemin réseau \"%s\" ne devrait pas être utilisé ici" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "La file d'attente n'est pas vide, impossible de changer de dossier." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" "Le dossier des téléchargements terminés ne peut pas être le même dossier que" " les téléchargements temporaires, ni être l'un de ses sous-dossiers" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" "N'utilisez pas un dossier à l'intérieur du dossier de l'application pour y " "stocker les scripts, il pourrait être vidé lors des mises à jour." #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "Configuration verrouillée, impossible de sauvegarder les paramètres" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Impossible d'écrire dans le fichier INI %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Impossible de créer le fichier de sauvegarde pour %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "Impossible de restaurer la sauvegarde" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Encodage mot de passe incorrect %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "Impossible d'écrire dans la base de données de l'historique, vérifier les " "droits d'accès !" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Base de données d'historique endommagée, création d'une nouvelle base" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Echec de la commande SQL, voir le journal" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Impossible de fermer la base de données, voir le journal" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Étape de journalisation invalide dans l'historique pour %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Échec du décodeur : mémoire insuffisante" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Erreur inconnue lors du décodage de %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "Désobfuscation ignorée à cause des répertoires DVD/Bluray" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "La désobfuscation a corrigé l'extension de %d fichier(s)" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "La désobfuscation a renommé %d fichier(s)" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "Décompression Directe" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Terminé" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "%s fichiers/dossiers extraits dans %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "La Décompression Directe a été activée automatiquement." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "Les tâches seront décompréssées pendant le téléchargement pour réduire le " "temps de post-traitement. Fonctionne uniquement pour les tâches qui ne " "nécessitent aucune réparation." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Impossible de lire le dossier surveillé %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Reprise en cours" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "En pause" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Vous devez définir une bande passante maximale avant de pouvoir définir une " "limite de bande passante" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Impossible de se connecter au serveur %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Resolution du nom de serveur impossible" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Le serveur %s sera ignoré pendant %s minutes" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "Il n'y a aucun serveur actif !" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Échec d'initialisation de %s@%s pour la raison suivante : %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "Erreur fatale dans le Téléchargeur" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "%s@%s a reçu le code d'état inconnu %s pour l'article %s" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Trop de connexions au serveur %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" "Connexion au serveur %s [%s] à partir de trop d'adresses IP différentes - " "https://sabnzbd.org/multiple-adresses" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Échec de la connexion au serveur %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "La connexion à %s@%s a échoué, message=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Erreur suspecte dans le téléchargeur" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Arrêt en cours..." #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "Le serveur %s expirera dans %s jour(s)" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "Le serveur %s a utilisé le quota spécifié" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Échec de connexion au serveur de messagerie" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Échec de l'initialisation de la connexion TLS" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "" "Le serveur n'a pas répondu correctement au protocole d'identification " "\"hello\"" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Échec de l'authentification au serveur de messagerie" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Aucune méthode d'authentification appropriée n'a été trouvé" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Échec d'authentification inconnu dans le serveur de messagerie" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Échec de l'envoi de l'e-mail" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Échec de la fermeture de la connexion à la messagerie" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Impossible d'envoyer, données requises manquantes" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Impossible de trouver les modèles d'email dans %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Aucun destinataire déterminé, aucun email envoyé" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Impossible de lire %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Aucun modèle email trouvés" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "A : %s\n" "De : %s\n" "Date : %s\n" "Sujet : Alerte SABnzbd : disque plein\n" "\n" "Salut,\n" "\n" "SABnzbd a arrêté le téléchargement car le disque est presque plein.\n" "Merci de faire de la place avant de reprendre manuellement le téléchargement sous SABnzbd.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Impossible de créer le dossier %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s dossier : %s erreur d'accès" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Impossible de changer les permissions pour %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Échec lors de la création de (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Échec lors du déplacement de %s vers %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "Tentative bloquée de création du répertoire %s" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Échec dans tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "L'enregistrement de %s a échoué" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Echec du chargement de %s" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "%s n'est pas du tout inscriptible. Les téléchargements sont bloqués." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" "Impossible d'écrire un nom de fichier long dans %s. Cela peut causer des " "problèmes." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" "Impossible d'écrire un nom de fichier unicode dans %s. Cela peut causer des " "problèmes." #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" "Le fichier %s n'est pas inscriptible à cause des caractères spéciaux dans le" " nom. Cela peut causer des problèmes." #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "Connexion refusée de:" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "Connexion refusée avec le nom d'hôte \"%s\" à partir de :" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Utilisateur connecté à l'interface web" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Utilisateur connecté" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Clé API manquante, entrez la clé API de la configuration générale dans votre" " application tierce :" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Clé API incorrecte, utilisez la clé API de la configuration générale dans " "votre application tierce :" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Echec de la tentative de connexion de %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "Archives de sauvegarde non valides" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Flux RSS" #: sabnzbd/interface.py msgid "Daily" msgstr "Quotidien" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Lundi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Mardi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Mercredi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Jeudi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Vendredi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Samedi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Dimanche" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "non" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Serveur non défini !" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" "Le dossier de catégorie ne peut pas être un sous-dossier du dossier de " "téléchargement temporaire." #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "ERREUR:" #: sabnzbd/interface.py msgid "Back" msgstr "Retour" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" "Pour éviter tous les avertissements utiles, désactivez le paramètre spécial " "'helpful_warnings'." #: sabnzbd/misc.py msgid "d" msgstr "j" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Mise à Jour disponible!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "Échec de l'upload du fichier : %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Erreur lors de la création de la clé et du certificat SSL" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "Votre fichier de mot de passe contient plus de 30 mots de passe. Tester tous" " ces mots de passe prend beaucoup de temps. Essayez de n'y lister que les " "mots de passe utiles." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "Échec de lecture du fichier de mot de passe %s" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "[%s] La commande dans build_command n'est pas définie." #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" "Le script Python \"%s\" n'est pas configuré avec les permissions d’exécution" " (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Tri des séries" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Tri par date" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "Tri des films" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Exécution du script" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Arborescence trop profonde dans le fichier compressé [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Concaténation" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Séquence incomplète des fichiers à fusionner" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "La concaténation du fichiers %s a échoué" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Erreur \"%s\" lors de la concaténation des fichiers" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Erreur \"%s\" lors de l'exécution de file_join sur %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] %s fichiers fusionnés" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Échec de l'extraction, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Erreur \"%s\" lors de l'extraction des fichiers RAR" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Erreur \"%s\" lors de l'exécution de rar_unpack sur %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Impossible de supprimer %s !" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Tentative d'extraction avec le mot de passe \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Extraction" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Échec de l'extraction, %s n'a pas été trouvé" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Échec de l'extraction, erreur CRC" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" "La décompression a échoué, le fichier est trop volumineux pour le système de" " fichiers (FAT ?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "" "Échec de l'extraction, erreur d'écriture ou espace disque insuffisant ?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Extraction échoué, le chemin est trop long" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Échec de l'extraction, l'archive nécessite un mot de passe" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Fichier RAR inutilisable" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Fichier RAR corrompu" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Tentative 7zip avec le mot de passe \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "voir le journal" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Contrôle rapide" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Réparation" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Contrôle rapide OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Réparation en cours" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Échec de la réparation, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Erreur %s lors de l'exécution de par2_repair sur la collection %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Erreur \"%s\" lors de l'exécution de par2_repair sur la collection %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 a reçu des paramètres incorrects, vérifiez dans Configuration-> " "Paramètres Switches" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Vérifié dans %s, tous les fichiers sont corrects" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Vérifié dans %s, réparation nécessaire" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Paramètres ou fichiers PAR2 non valides, impossible de vérifier ou réparer." #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Récupération de %s blocs..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Récupération en cours" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Échec de la réparation, pas assez de blocs de réparation (manque %s)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Réparation en cours" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Réparé(s) dans %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "Vérification de la réparation" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Disque plein" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Vérification des fichiers supplémentaires" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Vérification en cours" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Vérification" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Essai vérification SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "restant" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Ce serveur n'authorise pas de connexion SSL sur ce port" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "Incompatibilité du nom d'hôte du certificat : le nom d'hôte du serveur n'est" " pas répertorié dans le certificat. Il s'agit d'un problème de serveur." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" "Le certificat n'est pas valide. C'est probablement un problème de serveur." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Le serveur %s utilise un certificat peu fiable [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "Échec de la connexion : %s %s@%s:%s (%s)" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Démarrage/Arrêt" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Mettre en pause" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Reprendre" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB ajouté" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Post-traitement démarré" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Tâche terminé" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "La tâche a échoué" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "File d'attente terminée" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Autres messages" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "Ouvrir le dossier" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Ouvrir le dossier des complets" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Non disponible" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "Échec de l'envoi de la notification macOS" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Échec d'envoi du message Prowl" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "Échec d'envoi du message Apprise - aucune URLs définies" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "Une ou plusieurs URL Apprise n'ont pas pu être chargées." #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "Échec de l'envoi d'une ou plusieurs notifications Apprise." #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "Échec d'envoi du message Apprise" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Mauvaise réponse de Pushover (%s) : %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Échec de l'envoi du message Pushover" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Mauvaise réponse de Pusbullet (%s) : %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Échec de l'envoi du message Pushbullet" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Le script a renvoyé le code de sortie %s et le résultat \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Le script de notification \"%s\" est introuvable" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Echec d'envoi de la notification Windows" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Impossible de créer le fichier temporaire pour %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Erreur lors de l'ajout de %s, suppression" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Erreur lors de la suppression de %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Echec de l'importation des fichiers %s depuis %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Fichier de file d'attente incompatible, impossible de continuer" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Erreur lors du chargement de %s, fichier corrompu détecté" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB ajouté à la file d'attente" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Doublon NZB ignoré \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "Échec de duplication du NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "Dupliquer NZB" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "Fichier NZB %s invalide, sera ignoré (erreur : %s)" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Fichier NZB %s vide" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "Le script de pré-file d'attente a marqué la tâche comme échouée" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "Extension non souhaitée dans le fichier %s (%s)" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Interrompu, ne peut être achevé" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Erreur lors de l'importation de %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DOUBLON" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "ALTERNATIVE" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "CHIFFRÉ" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "TROP VOLUMINEUX" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "INCOMPLET" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "INDÉSIRABLE" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "PATIENTER %s sec" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "PROPAGATION %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Téléchargé en %s à %sB/s de moyenne" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Âge" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s articles malformés" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s articles manquants" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s articles avec doublons sans correspondance" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Mise en pause du doublon NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Avertissements" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "A l'arrêt" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "File d'attente" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Vider la file d'attente" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historique" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Vider l'historique" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Limiter la vitesse" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "min" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Analyser le dossier surveillé" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Lire tous les flux RSS" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Dossier complet" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Dossier incomplet" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Résoudre les problèmes" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Redémarrer" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Redémarrer sans se connecter" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Quitter" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Mettre en file d'attente les 10 premiers articles" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Vide" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Historique des 10 derniers articles" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Aller à l'assistant" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Arrêt en cours..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problème avec" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd a besoin d'un port tcp/ip libre pour le serveur Web interne.
\n" " La plage de ports %s à %s a été essayée mais elle n'est pas disponible.
\n" " Un autre logiciel utilise ce port ou SABnzbd est déjà en cours d'exécution.
\n" "
\n" " Veuillez redémarrer SABnzbd avec un port différent." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Si vous obtenez ce message d'erreur à nouveau, veuillez essayer un nombre " "différent.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd a besoin d'une adresse hôte valide pour son serveur Web interne.
\n" " Vous avez spécifié une adresse non valide.
\n" " Les valeurs sûres sont localhost et 0.0.0.0
\n" "
\n" " Veuillez redémarrer SABnzbd avec une adresse hôte correcte." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd a détecté des données sauvegardées avec une autre version de SABnzbd
\n" " mais ne peut réutiliser les données de l'autre programme.

\n" " Vous voudrez peut-être terminer votre première file d'attente avec l'autre programme.

\n" " Après cela, lancez ce programme avec l'option \"--clean\".
\n" " Cette opération effacera la file d'attente actuelle et l'historique !
\n" " SABnzbd a lu le fichier \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd ne peut pas trouver ses fichiers d'interface web dans %s.
\n" " Veuillez réinstaller le programme.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd a détecté une erreur fatale :" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd a détecté que le fichier sqlite3.dll est manquant.

\n" " Certains antivirus mal conçu peuvent supprimer ce fichier.
\n" " S'il vous plaît vérifier votre antivirus, essayez de ré-installer SABnzbd et plaignez vous à l'éditeur de l'antivirus.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Appuyez sur la touche Drapeau+R et tapez la ligne (exemple) :" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Ouvrez une fenêtre de Terminal et tapez la ligne (exemple) :" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Le programme n'a pas démarré !" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Erreur fatale" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" "Impossible de lier le port %s sur %s. Un autre logiciel utilise le port ou " "SABnzbd est déjà en cours d'exécution." #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Impossible de lancer le navigateur web, probablement pas trouvé" #: sabnzbd/panic.py msgid "Access denied" msgstr "Accès refusé" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "" "Erreur %s: vous devez fournir un nom d'utilisateur et un mot de passe " "valide." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" "Ancienne file d'attente détectée, utiliser Statut-> Réparation pour " "convertir la file d'attente" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Echec de la compilation de regex pour la recherche du terme : %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" "Le système de fichiers du dossier des téléchargements terminés %s est au " "format FAT, limitant la taille maximale d'un fichier à 4 Go" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" "Le téléchargement pourrait échouer, seulement %s des %s requis sont " "disponibles" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Le téléchargement a échoué - absent de vos serveur(s)" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Post-traitement" #: sabnzbd/postproc.py msgid "Moving" msgstr "Déplacement" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "%s envoyé dans la file d'attente" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Erreur lors du renommage de \"%s\" en \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Impossible de déplacer les fichiers" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Exécution du script utilisateur %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Le code script de sortie est %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "%s exécuté" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Plus" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Échec du post-traitement pour %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "Le post-traitement a été interrompu" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Échec du téléchargement" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Échec du nettoyage de %s." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Téléchargement terminé" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Impossible de créer le dossier final %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Pas de fichiers par2" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Certains fichiers n'ont pas pu être vérifiés \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Vérifié avec succès en utilisant des fichiers SFV" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "Tentative de vérification RAR" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Protégé par un mot de passe" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] La vérification RAR a échoué: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "Fichiers RAR vérifiés avec succès" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "Echec lors de la vérification des fichiers RAR" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "Essai avec le renommeur RAR" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "Aucun fichier rar antérieur correspondant pour %s" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Échec de la suppression de %s" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Échec de la mise en hibernatation" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Échec de la mise en veille" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Erreur lors de l'arrêt du système" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "Exception DBus reçue %s" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Description du flux RSS incorrecte \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Vous n'avez pas d'authentification valide pour ce flux %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" "Erreur du côté serveur (code serveur %s) ; n'a pas pu obtenir %s sur %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Échec de la récupération RSS de %s : %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Le serveur %s utilise un certificat de sécurité HTTPS non authentifié" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "Le flux RSS %s était vide" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Flux incompatible" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Entrée vide de flux RSS trouvée (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Afficher l’interface" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pause de" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Mettre en pause pendant 5 minutes" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Mettre en pause pendant 15 minutes" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Mettre en pause pendant 30 minutes" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Mettre en pause pendant 1 heure" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Mettre en pause pendant 3 heures" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Mettre en pause pendant 6 heures" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Arrêter" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Restant" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Ajouter NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Mauvaise planification %s à %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Action inconnue : %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Planification pour un serveur non existant %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Test de l'état du serveur inexistant %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Télécharger" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Concaténer" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Décompresser" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "Désobfuscation" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Script" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Source" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Serveurs" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Échoué" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "En attente" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Réparation en cours..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Décompression en cours..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Déplacement en cours..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Exécution de script en cours..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Récupération des blocs supplémentaires ..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Vérification rapide..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Vérification..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "désactiver le serveur" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "activer le serveur" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Limite de vitesse" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Suspendre tout" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Mettre en pause le post-traitement" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Reprendre le post-traitement" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Lire les flux RSS" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Retirer les tâches échouées" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Effacer les tâches terminées" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Mettre en pause les tâches de priorité faible" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Mettre en pause les tâches de priorité normale" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Mettre en pause les tâches de priorité haute" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Reprendre les tâches de priorité faible" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Reprendre les tâches de priorité normale" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Reprendre les tâches de priorité haute" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Activer la gestion de quota" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Désactiver la gestion de quota" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "Mettre en pause les tâches ayant une catégorie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "Reprendre les tâches ayant une catégorie" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Désactivé" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Très bas" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Modéré" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normale" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Haute" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Urgence" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Basse" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "heure" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "heures" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "mins" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sec" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "secondes" #: sabnzbd/skintext.py msgid "day" msgstr "jour" #: sabnzbd/skintext.py msgid "days" msgstr "jours" #: sabnzbd/skintext.py msgid "week" msgstr "semaine" #: sabnzbd/skintext.py msgid "Month" msgstr "Mois" #: sabnzbd/skintext.py msgid "Year" msgstr "Année" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Jour du mois" #: sabnzbd/skintext.py msgid "This week" msgstr "Cette semaine" #: sabnzbd/skintext.py msgid "This month" msgstr "Ce mois" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "Plage de dates sélectionnée" #: sabnzbd/skintext.py msgid "Today" msgstr "Aujourd'hui" #: sabnzbd/skintext.py msgid "Total" msgstr "Total" #: sabnzbd/skintext.py msgid "on" msgstr "oui" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Paramètres" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Version de Python" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Page d'accueil" #: sabnzbd/skintext.py msgid "or" msgstr "ou" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Hôte" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Annuler" #: sabnzbd/skintext.py msgid "Log in" msgstr "Se connecter" #: sabnzbd/skintext.py msgid "Log out" msgstr "Se déconnecter" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Se souvenir de moi" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Enregistrer" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Enregistrement.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Êtes-vous sûr ?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Accueil" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Configuration" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Statut" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Aide" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "Chat en direct" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Incidents" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Soutenez le projet, faites un don !" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Général" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Répertoires" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Switches" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Planification" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Notifications" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Email" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Catégories" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Triage" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Spécial" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Rechercher" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Etes-vous sûr de vouloir arrêter SABnzbd ?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Ajouter" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Catégorie" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Priorité" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Réparer" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Décompresser" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Supprimer" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Forcer" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Arrêter" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Saisir une URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Éteindre le PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Mettre le PC en veille" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Mettre le PC en hibernation" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Arrêter SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Traitement en cours" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Nom" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Réessayer" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Scripts" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Supprimer tous les éléments de la file d'attente ?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "Êtes-vous sûr de vouloir supprimer ces tâches ?" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Vider les NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Purger les NZB & supprimer les fichiers" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Supprimer NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Supprimer le NZB & supprimer les fichiers" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "Supprimer définitivement (ignorer l'archivage)" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Articles manquants" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Quota restant" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manuel" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Réinitialiser le quota maintenant" #: sabnzbd/skintext.py msgid "Archive" msgstr "Archives" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Masquer les détails" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Afficher les détails" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Afficher les échoués" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Afficher Tout" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "Afficher les archives" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Taille" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Purger les NZB échoués" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Purger les NZBs échoués & supprimer les fichiers" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Vider les NZB terminés" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Purger les NZBs de la page en cours" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "NZB supplémentaire optionnel" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Chemin d'accès" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Réessayez toutes les tâches échouées" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Forcer la déconnexion" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" "Déconnecte toutes les connexions actives aux serveurs Usenet. Les connexions" " seront rouvertes après quelques secondes si des éléments sont présents dans" " la file d'attente." #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Ceci enverra un email de test sur votre compte." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Afficher le journal" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Email de test" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Journalisation" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Erreurs/Avertissements" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Debug" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Connections" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Identifiant de l'article" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Collection de fichiers" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Activé" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Echec de connexion !" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Adresse IPv4 locale" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Adresse IPv4 publique" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "Adresse IPv6" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nameserver / DNS Lookup" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "Vitesse de téléchargement limitée par" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "Vitesse du disque" #: sabnzbd/skintext.py msgid "System load" msgstr "Charge du système" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Performance du système ( Pystone )" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Vitesse du dossier \"Download\"" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Vitesse du dossier \"Complete\"" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "Bande passante Internet" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Refaire le test" #: sabnzbd/skintext.py msgid "Test download" msgstr "Tester le téléchargement" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" "Ajoute un fichier test NZB, de la taille spécifiée, rempli de données " "aléatoires. Peut être utilisé pour vérifier votre configuration." #: sabnzbd/skintext.py msgid "Config File" msgstr "Fichier de configuration" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Cache utilisé" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Ceci redémarrera SABnzbd.
\r\n" "Utilisez cette fonction si vous pensez avoir un problème de stabilité.
\r\n" "Les téléchargements en cours seront mis en pause puis repris." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" "
Si l'authentification est activée, vous devrez vous identifier à " "nouveau." #: sabnzbd/skintext.py msgid "Advanced" msgstr "Options avancées" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Il y a des dossiers orphelins dans le répertoire de téléchargement.
Vous pouvez choisir de les supprimer (y compris les fichiers) ou de les " "renvoyer dans la file d'attente." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "Ceci redémarre SABnzbd et fait une complète reconstruction
de la file " "d'attente, tout en conservant les fichiers déjà téléchargés.
Ceci " "modifiera l'ordre de la file d'attente." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Les modifications n'ont pas été enregistrées et seront perdues." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" "La session expirera quand votre adresse IP changera ou quand SABnzbd sera " "redémarré." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Activer 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" "Accélérez les réparations en installant par2cmdline-turbo, il est disponible" " pour de nombreuses plateformes." #: sabnzbd/skintext.py msgid "Version" msgstr "Version" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Temps de fonctionnement" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Secours" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Consultez le Wiki pour plus d'info à ce sujet (en anglais) !" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Redémarrage de SABnzbd en cours..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Les modifications nécessiteront un redémarrage de SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Serveur web SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Hôte SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Hôte sur lequel SABnzbd doit attendre les connexions." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Port que SABnzbd doit surveiller." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "Thème de l'interface web" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "Choisissez un thème." #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Identifiant SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Nom d'utilisateur pour l'authentification (facultatif)." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Mot de passe SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Mot de passe pour l'authentification (facultatif)." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" "Vos paramètres actuels permettent un accès externe complet à l'interface " "SABnzbd si l'hôte ou le port SABnzbd est ouvert vers l'internet." #: sabnzbd/skintext.py msgid "Security" msgstr "Sécurité" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Activer HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Active l'accès à l'interface via une adresse HTTPS." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" "Les navigateurs web modernes et les autres clients n'accepteront pas les " "certificats auto-signés et donneront un avertissement et / ou ne se " "connecteront pas du tout." #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Si vide, le port standard écoutera seulement le HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "Certificat HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Nom du fichier ou chemin du certificat HTTPS." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" "Générer à nouveau les certificat et clé auto-signés. Nécessite le " "redémarrage de SABnzbd !" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "Clé HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Nom du fichier ou chemin de la clé HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "Certificats de chaîne HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Nom du fichier ou chemin d'accès de la chaîne HTTPS." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Réglages" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Invervalle de vérification RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Intervalle de vérification (en minutes, au moins 15). Inactif quand vous " "utilisez le Planificateur !" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Vitesse maximale de la ligne" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Pourcentage de la vitesse de la ligne" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Quel est le pourcentage de la vitesse de la ligne que SABnzbd doive " "utiliser, par exemple 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Limite du cache d'articles" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Mettre les articles en cache pour réduire les accès disque.
En " "Octets, peut être suivi de K,M,G. Par exemple : \"64M\" ou \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "Créer une sauvegarde" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" "Créer une sauvegarde du fichier de configuration et des bases de données " "dans le Dossier de sauvegarde.
Si le Dossier de sauvegarde n'est pas " "défini, la sauvegarde sera créée dans le Dossier des téléchargements " "terminés.
Les sauvegardes récurrentes peuvent être configurées sur la " "page Planification." #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Nettoyer la liste" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Liste des extensions de fichiers qui doivent être supprimés après le " "téléchargement.
nfo
ou nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "Conservation de l'historique" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "Conserver toutes les tâches" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" "Déplacez les tâches vers les archives si l'historique dépasse le nombre de " "tâches spécifié" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" "Supprimer les tâches si l'historique et les archives dépassent le nombre de " "tâches spécifié" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" "Déplacer les tâches vers les archives après le nombre de jours spécifié" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" "Supprimer les tâches de l'historique et des archives après le nombre de " "jours spécifié" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "Déplacer tous les tâches terminées vers les archives" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "Supprimer toutes les tâches terminées" #: sabnzbd/skintext.py msgid "Jobs" msgstr "Tâches" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Enregistrer les modifications" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Rétablir les valeurs par défaut" #: sabnzbd/skintext.py msgid "Reset" msgstr "Réinitialiser" #: sabnzbd/skintext.py msgid "Language" msgstr "Langue" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Choisir la langue de l'interface web." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "Aidez-nous à traduire SABnzbd dans votre langue !
Améliorez les " "traductions existantes ou ajoutez celles qui manquent ici :" #: sabnzbd/skintext.py msgid "API Key" msgstr "Clé API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Cette clé permettra aux programmes tiers d'avoir un accès complet à SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "Clé NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Cette clé permettra aux programmes tiers de pouvoir ajouter des NZB à " "SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Générer une nouvelle clé" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "Clé API code QR" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Accès Internet externe" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" "Vous pouvez définir des droits d'accès pour les systèmes en dehors de votre " "réseau local." #: sabnzbd/skintext.py msgid "No access" msgstr "Aucun accès" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Ajouter des fichiers NZB " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (aucune configuration)" #: sabnzbd/skintext.py msgid "Full API" msgstr "API complète" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Interface Web complète" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Seul l'accès extérieur nécessite un identifiant" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTE: Les dossiers seront créés automatiquement lors de " "l'enregistrement. Il est possible d'utiliser des chemins absolus pour " "sauvegarder en dehors du répertoire par défaut." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Dossiers utilisateur" #: sabnzbd/skintext.py msgid "Browse" msgstr "Parcourir" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Dossier temporaire de téléchargement" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Emplacement de stockage des téléchargements non-traités.
Modifiable " "uniquement si la file d'attente est vide." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Espace disque minimum pour le dossier de téléchargement temporaire" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Mettre en pause lorsque l'espace libre est en-dessous de cette valeur.
En octets, peut être suivi de O,M,G,T. Par exemple : \"800M\" ou " "\"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Dossier des téléchargements terminés" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Emplacement des téléchargements terminés et post-traités.
Peut être " "outrepassé par les catégories définies par l'utilisateur." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" "Utilisez le tri pour organiser et renommer automatiquement vos " "téléchargements terminés." #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "Espace libre minimum pour le dossier des téléchargements terminés" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" "Ne fonctionnera pas si un dossier de catégorie se trouve sur un autre " "disque." #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Reprise auto" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" "Le téléchargement reprendra automatiquement si l'espace libre minimum est à " "nouveau disponible.
S'applique aux dossiers des téléchargements " "temporaires et terminés.
Vérifié toutes les quelques minutes." #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Permissions pour le dossier de téléchargements terminés" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Appliquer ce modèle de permissions aux fichiers/dossiers téléchargés.
En notation octale. Par exemple : \"755\" ou \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Dossier à surveiller" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Dossier d'import automatique des fichiers .nzb." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Intervalle de scan" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "" "Nombre de secondes entre chaque scan du dossier pour vérifier la présence de" " fichiers .nzb." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "Dossier des scripts" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "Dossier contenant les scripts utilisateurs." #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Dossier des modèles d'email" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Dossier contenant les modèles d'email définis par l'utilisateur." #: sabnzbd/skintext.py msgid "Password file" msgstr "Fichier de mot de passe" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Le fichier contenant tous les mots de passe sera testé sur les fichiers RAR " "chiffrés." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Dossiers système" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "Dossiers cachés" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Dossier administrateur" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Emplacement de la file d'attente et de la base de données d'historique.
Ne peut être changé que lorsque la file d'attente est vide." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "Dossier de sauvegarde" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" "Emplacement où sont stockées les sauvegardes du fichier de configuration et " "des bases de données.
Si laissé vide, la sauvegarde sera créée dans le " "Dossier des téléchargements terminés." #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Les données ne seront pas déplacées. Requiert un redémarrage de " "SABnzbd !" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Dossier du fichier journal" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Emplacement des fichiers journaux de SABnzbd.
Redémarrage requis " "!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "Purger les logs" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Dossier de sauvegarde des fichiers .nzb" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Emplacement où les fichier .nzb seront archivés." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Dossier racine par défaut" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Télécharger tous les fichiers par2" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" "Ceci évite les réparations multiples en téléchargeant tous les fichiers par2" " nécessaires." #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Activer l'extraction récursive" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Décompresser les archives (rar, zip, 7z) à l'intérieur des archives." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignorer tous les dossiers à l'intérieur des archives" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Tous les fichiers iront dans un seul dossier." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Télécharger uniquement les articles en tête de file d'attente" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Activer pour moins d'utilisation de la RAM. Désactiver pour éviter que les " "téléchargements lents bloquent la file d'attente." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Ne post-traiter que les tâches vérifiées" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" "Décompresser et lancer les scripts uniquement sur les tâches qui ont passé " "l'étape de vérification. Si désactivé, toutes les tâches seront marquées " "comme Terminées même si elles sont incomplètes." #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Action quand un RAR chiffré est téléchargé" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "En cas de \"Pause\", vous devrez mettre un mot de passe pour reprendre la " "tâche." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "Détection des téléchargements identiques" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" "Détecter les téléchargements identiques basés sur le nom ou le contenu NZB." #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "Détection intelligente des doublons" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "Détecter les doublons basés sur l'analyse du nom de fichier." #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "Autoriser les versions corrigées (proper)" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" "Contourner la détection des doublons si PROPER, REAL ou REPACK est détecté " "dans l'intitulé du téléchargement." #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Rejeter" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "Taguer la tâche" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "Faire échouer la tâche (déplacer vers l'historique)" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "Abandonner le post-traitement" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Action si une extension indésirable est détecté" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "Action lorsqu'une extension indésirable est détectée" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Extensions indésirables" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "Liste noire" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "Liste blanche" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" "Sélectionnez un mode et listez toutes les extensions (non) souhaitées. Par " "exemple: exe ou exe, com" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Activer les contrôles SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Fait une vérification supplémentaire basée sur les fichiers SFV." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Le script utilisateur peut signaler la tâche comme échouée" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Lorsque le script de l'utilisateur renvoie un code de sortie \"non-zéro\", " "la tâche sera signalée comme échouée." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Activer le renommage du dossier" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Utiliser des noms temporaires pendant le post-traitement. Désactiver lorsque" " votre système ne le gère pas correctement." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Script utilisateur de pré-file d'attente" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Utilisé avant qu'un NZB n'entre dans la file d'attente." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "Script de fin de file d'attente" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "Exécuté après la fin du téléchargement de la file d'attente." #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Paramètres PAR2 supplémentaires" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Paramètres 'Nice'" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Paramètres 'IONice'" #: sabnzbd/skintext.py msgid "External process priority" msgstr "Priorité de processus externe" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Se déconnecter lorsque la file d'attente est vide" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Se déconnecter du serveur(s) Usenet lorsque la file d'attente est vide ou en" " pause" #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "Trier automatiquement la file d'attente" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" "Trier automatiquement la file d'attente lorsqu'une nouvelle tâche est " "ajoutée." #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" "La file d'attente sera triée toutes les 30 secondes si le % de " "téléchargement est sélectionné." #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Délai de propagation" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Les publications seront mises en pause jusqu'à ce qu'elles aient au moins " "cet âge. La tâche commence immédiatement si elle est passée en priorité " "Forcée." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Vérifier les mises à jour" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Versions de test également" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Remplacer les espaces dans les noms de dossier" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "" "Remplace les espaces par des underscores ( _ ) dans les noms de dossiers." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "Remplacer les underscores dans le nom du dossier" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "Remplacer les underscores par des points dans les noms de dossiers" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Remplacer les points dans les noms de dossier" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Remplace les points par des espaces dans les noms de dossier" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Rendre Windows compatible" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" "Pour les serveurs : assurez-vous que les noms soient compatibles avec " "Windows." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Lancer le navigateur web au démarrage" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Lance le navigateur web par défaut au démarrage de SABnzbd." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Mettre en pause les téléchargements lors du post-traitement" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Met en pause les téléchargements au début du post-traitement et les reprend " "à la fin." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignorer les échantillons (Samples)" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Exclure les fichiers échantillons (par ex. les samples vidéo)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Supprimer après téléchargement" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "Désobfusquer les noms de fichiers finaux" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" "Si les noms de fichiers (volumineux) dans le dossier final semblent obscurs " "ou dénués de sens, ils seront renommés avec le nom de la tâche." #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" "Tente par ailleurs de trouver l'extension du fichier en se basant sur sa " "signature si l'extension n'est pas présente ou si elle n'a pas de sens." #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "Vérification du certificat HTTPS" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" "Vérifier les certificats lors de la connexion aux indexeurs et sources RSS " "utilisant HTTPS." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "Proxy SOCKS5" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" "Utiliser le proxy SOCKS5 spécifié pour toutes les connexions sortantes." #: sabnzbd/skintext.py msgid "Server" msgstr "Serveur" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Post-traitement" #: sabnzbd/skintext.py msgid "Naming" msgstr "Appellation" #: sabnzbd/skintext.py msgid "Quota" msgstr "Quota" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Combien peut-être télécharger ce mois (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Jour de RAZ" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "A quel jour du mois ou de la semaine (1=lundi) votre fournisseur " "réinitialise le quota ? (Optionnel avec hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "" "Le téléchargement devrait-il reprendre après que le quota soit réinitialisé " "?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Période du quota" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Est-ce que le quota se réinitialise chaque jour, semaine ou mois ?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Vérifiez avant de télécharger" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Tente de prédire la réussite de la tâche avant le téléchargement complet " "(plus lent !)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "Chiffrements SSL" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "Augmenter les performances en forçant un cryptage SSL plus faible." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Nombre de tentatives maximum" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Nombre maximal de tentatives par serveur" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Interrompre les tâches qui ne peuvent être terminées" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "S'il apparait clairement pendant le téléchargement qu'il manque trop de " "données, annuler la tâche" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Ajouter un serveur" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Description du serveur" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Nom d'utilisateur" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Mot de passe" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Délai d'expiration" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "Date d'expiration du compte" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "Avertir 5 jours avant la date d'expiration du compte." #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" "Quota pour ce compte calculé à partir du moment où il est défini. En octets," " éventuellement suivi de K,M,G.
Avertir quand il atteint 0, vérifié " "toutes les quelques minutes." #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Délai de rétention" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "Connexion sécurisée au serveur" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "Vérification du certificat" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" "Minimal: lorsque SSL est activé, vérifier l'identité du serveur à l'aide de " "ses certificats. Strict: vérifier et imposer le nom d'hôte correspondant." #: sabnzbd/skintext.py msgid "Disabled" msgstr "Désactivé" #: sabnzbd/skintext.py msgid "Minimal" msgstr "Minimal" #: sabnzbd/skintext.py msgid "Strict" msgstr "Strict" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 est la priorité la plus élevée, 99 est la priorité la plus faible" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "Obligatoire" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" "En cas d'échecs de connexion, la file d'attente des téléchargements sera " "mise en pause pendant quelques minutes au lieu de passer au serveur suivant." #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Optionnel" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" "Pour les serveurs non fiables, sera ignorée plus longtemps en cas de " "défaillances" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Activer" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Supprimer le serveur" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Tester le serveur" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "RAZ des compteurs" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Test des détails du serveur en cours..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Bande passante" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Notes personnelles" #: sabnzbd/skintext.py msgid "Article availability" msgstr "Disponibilité de l'article" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "%f% disponibles sur %d articles demandés" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Ajouter une planification" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Fréquence" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Action" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Arguments" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Planifications actuelles" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "La case à cocher à coté du nom du flux doit être cochée pour que le flux " "soit activé et qu'il soit pris en compte dans la vérification des nouveaux " "téléchargements.
Quant un flux est ajouté, seuls les nouveaux " "téléchargements seront pris en compte à moins de cliquer sur \"Forcer " "téléchargements\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "Séparez les URL multiples par une virgule" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Lire le flux RSS" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Forcer le téléchargement" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "Appliquer les filtres" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "Modifier" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "Prochain scan à" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Ordre" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Type" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filtre" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Accepter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Rejeter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Obligatoire" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "CatObligatoire" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Au moins" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Au plus" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Depuis SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "À partir de la Série SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Correspond" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Ne correspond pas" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Téléchargé" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Lire tous les flux maintenant" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" "Si seule la catégorie Défaut est sélectionnée, les notifications " "seront activées pour les tâches de toutes les catégories." #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Notification par email lorsque des téléchargements sont terminés" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Jamais" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Toujours" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Erreurs uniquement" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Notifications de disque dur plein" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Envoie un email lorsque le disque dur est plein et que SABnzbd a été mis en " "pause." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Envoyer les notifications RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "Envoie un email quand un flux RSS ajoute un fichier dans la file d'attente." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "Serveur SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Entrez le serveur de courrier sortant de votre FAI." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Email du destinataire" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Adresse email à laquelle seront envoyées les notifications." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Email de l'expéditeur" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Qui doit-on indiquer comme expéditeur de l'email ?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "Identifiant (facultatif)" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Identifiant du compte pour les envois authentifiés." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "Mot de passe du compte (facultatif)" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Mot de passe du compte pour les envois authentifiés." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Notification envoyée !" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Activer NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Centre de notification" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Activer les notifications Windows" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Notifications Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Activer les notifications Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Nécessite un compte Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Clé API pour Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Clé API personnelle pour Prowl (obligatoire)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Activer les notifications Pushover" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Nécessite un compte Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Jeton (token) d'application" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Jeton (token) d'application (obligatoire)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Clé utilisateur" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Clé utilisateur (obligatoire)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Appareil(s)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Appareil(s) auxquels doivent être envoyés les messages" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "Nouvelle tentative d'urgence" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "À quelle fréquence la même notification sera envoyée (en secondes)" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "Expiration d'urgence" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "Réessayer la notification pendant combien de secondes" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Activer les notifications Pushbullet" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Nécessite un compte Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Clé API personnelle" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Votre clé API Pushbullet personnelle (obligatoire)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Appareil" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Appareil sur lequel le message doit être envoyé" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "Activer les notifications Apprise" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" "Envoyer des notifications en utilisant Apprise vers presque n'importe quel " "service de notification" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "URLs par défaut d'Apprise" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "Utilisez une virgule et/ou un espace pour identifier plusieurs URL." #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" "Remplacez les URL par défaut pour les types de notifications spécifiques ci-" "dessous, si vous le souhaitez." #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Script de notification" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Activer le script de notification" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Exécute un script personnalisé" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "Quel script devons-nous utiliser pour les notifications ?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "Les indexeurs peuvent fournir une catégorie à l'intérieur du NZB que SABnzbd" " tentera de faire correspondre aux catégories définies ci-dessous. En outre," " vous pouvez ajouter des termes à \"Catégories de l'indexeur / Groupes\" " "pour faire correspondre plus de catégories. Utilisez des virgules pour " "séparer les termes. Les caractères génériques sont pris en charge.
Plus" " d'informations peuvent être trouvées sur le Wiki." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Terminer le chemin avec une étoile * empêche la création des dossiers de la " "tâche." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Les chemins relatifs des dossiers sont basés sur" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Dossier/Chemin" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "Catégories de l'indexeur / Groupes" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Modèle de clé" #: sabnzbd/skintext.py msgid "Clear" msgstr "Effacer" #: sabnzbd/skintext.py msgid "Presets" msgstr "Modèles prédéfinis" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Catégories affectées" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Signification" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Modèle" #: sabnzbd/skintext.py msgid "Result" msgstr "Résultat" #: sabnzbd/skintext.py msgid "Title" msgstr "Titre" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Nom du film" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Nom.Film" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Nom_Film" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Nom de la série" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Nom.Série" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Nom_Série" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Numéro de la saison" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Numéro de l'épisode" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Nom de l'épisode" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Nom.Épisode" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Nom_Épisode" #: sabnzbd/skintext.py msgid "Extension" msgstr "Extension" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Numéro de bloc" #: sabnzbd/skintext.py msgid "Decade" msgstr "Décennie" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Nom de fichier originel" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "Nom d'origine de la tâche" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Minuscule" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXTE" #: sabnzbd/skintext.py msgid "text" msgstr "texte" #: sabnzbd/skintext.py msgid "file" msgstr "fichier" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Chaîne de caractères de tri" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "Étiquette multi-bloc" #: sabnzbd/skintext.py msgid "Show folder" msgstr "Afficher le dossier" #: sabnzbd/skintext.py msgid "Season folder" msgstr "Dossier de la saison" #: sabnzbd/skintext.py msgid "In folders" msgstr "Dans les dossiers" #: sabnzbd/skintext.py msgid "No folders" msgstr "Pas de dossiers" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "Nom de la tâche en tant que nom de fichier" #: sabnzbd/skintext.py msgid "Series" msgstr "Séries" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "Lettre Capitale" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Résultat traité" #: sabnzbd/skintext.py msgid "Any property" msgstr "N'importe quel attribut" #: sabnzbd/skintext.py msgid "property" msgstr "attribut" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "Attribut GuessIt" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "Attribut.Guessit" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "Attribut_Guessit" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "Taille minimale du fichier" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "Types de tâche concernée" #: sabnzbd/skintext.py msgid "All" msgstr "Tous" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "Séries avec dates de diffusion" #: sabnzbd/skintext.py msgid "Movies" msgstr "Films" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "Autre / Inconnu" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" "

Utilisez les trieurs pour organiser automatiquement vos téléchargements " "terminés. Par exemple, placez tous les épisodes d'une série dans un dossier " "spécifique à la saison. Ou encore, placez les films dans un dossier portant " "le nom du film.

Les trieurs sont essayés par ordre d'apparition et " "peuvent être réorganisés par glisser-déposer.
Le premier trieur actif " "qui correspond à la fois à la catégorie et au type de tâche concernée est " "appliqué.

D'autres options sont disponibles lorsque l'option " "Paramètres avancés est cochée.
Des informations détaillées sont " "disponibles sur le Wiki.

" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "Ajouter un trieur" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "Supprimer le trieur" #: sabnzbd/skintext.py msgid "Test Data" msgstr "Données de test" #: sabnzbd/skintext.py msgid "Quick start" msgstr "Démarrage rapide" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" "Déplacer et renommer tous les épisodes de la catégorie \"tv\" vers un " "dossier de série spécifique" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" "Déplacer et renommer tous les films de la catégorie \"films\" vers un " "dossier de film spécifique" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Options rarement utilisées. Pour leur sens et leur explication, cliquez sur " "le bouton Aide pour accéder à la page Wiki.
Ne pas les modifier sans " "consulter le wiki en premier, car certaines ont de graves effets " "secondaires.
Les valeurs par défaut sont indiquées entre parenthèses." #: sabnzbd/skintext.py msgid "Values" msgstr "Valeurs" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Éditer les détails du NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Supprimer" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Nom de fichier" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Espace libre" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Dossier temporaire" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Multi-Operations" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Maintenez la touche Maj pour sélectionner une plage" #: sabnzbd/skintext.py msgid "Check all" msgstr "Tout sélectionner" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Redémarrer SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "En fin de file d'attente" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Options de statut et d'interface" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Ou glissez-déposez des fichiers sur la fenêtre!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Connexion à SABnzbd perdue..." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "En cas de redémarrage de SABnzbd cet écran disparaîtra automatiquement!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "AVERTISSEMENT :" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Charger" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Interface Web" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Taux de rafraîchissement" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Utiliser les paramètres globaux de l'interface" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Limite des éléments de la file d'attente" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Limite des éléments historisés" #: sabnzbd/skintext.py msgid "Date format" msgstr "Format de la date" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "Colonnes de file d'attente supplémentaires" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "Colonnes d'historique supplémentaires" #: sabnzbd/skintext.py msgid "page" msgstr "page" #: sabnzbd/skintext.py msgid "Loading" msgstr "Chargement" #: sabnzbd/skintext.py msgid "articles" msgstr "articles" #: sabnzbd/skintext.py msgid "Rename" msgstr "Renommer" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Réparer la file d'attente" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Afficher les connexions actives" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Débloquer" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Tâches orphelines" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Renvoyer dans la file d'attente" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Tout supprimer" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Réessayer tous" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Importer le NZB depuis l'URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Uploader le NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Vous pouvez également indiquer un nom de fichier" #: sabnzbd/skintext.py msgid "Submit" msgstr "Soumettre" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Supprimer tous les fichiers sélectionnés" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Afficher/masquer les fichiers terminés" #: sabnzbd/skintext.py msgid "Top" msgstr "Tout en haut" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Tout en bas" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" "Lorsque vous réessayez une tâche, la \"Détection des doublons\" et " "\"Abandonner les travaux qui ne peuvent pas être terminés\" sont désactivés." #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Afficher le journal des scripts" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "Renommer la tâche annulera la Décompression Directe." #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "Le stockage des données locales (cookies) est désactivé dans votre " "navigateur, les réglages de l'interface seront perdus lorsque vous fermerez " "votre navigateur !" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" "Glitter a des (nouvelles) fonctionnalités que vous devriez apprécier !" #: sabnzbd/skintext.py msgid "Custom" msgstr "Personnalisé" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Affichage compact" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "Toujours utiliser la largeur totale de l'écran" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Mise en page par onglets
(file d'attente et historique séparés)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Vitesse" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Confirmer les suppressions de la file d'attente" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Confirmer les suppressions de l'historique" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "Raccourcis clavier" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" "Maj+flèche : parcourir les pages de la file d'attente et de l'historique" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Combien de temps ou jusqu'à quand souhaitez-vous mettre en pause ?" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Désolé, nous n'avons pas pu interpréter ça. Essayez encore." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Mettre en pause pour…" #: sabnzbd/skintext.py msgid "Refresh" msgstr "Rafraîchir" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" "Tous les noms d'utilisateur, mots de passe et clés API sont automatiquement " "supprimés du journal et de la copie de vos réglages." #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "Trier par % téléchargé Most→Least" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Trier par Age Moins récent→Plus récent" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Trier par âge Plus récent→Moins récent" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Trier par nom A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Trier par nom Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Trier par taille Plus petit→Plus grand" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Trier par taille Plus grand→Plus petit" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Upload en cours" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Déconnexion forcée en cours" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Suppression de la tâche" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Suppression des tâches" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Assistant de configuration SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Version de SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Précédent" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Suiv." #: sabnzbd/skintext.py msgid "Server Details" msgstr "Détails du serveur" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Entrez les informations de votre principal fournisseur usenet." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Le nombre de connexions autorisées par votre fournisseur usenet" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Ex. : 8 ou 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "" "Cochez uniquement si votre fournisseur usenet permet les connexions SSL." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Cliquez pour tester les informations entrées." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Par ex. :" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "La configuration est terminée!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd fonctionnera dorénavant en arrière plan." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Fermer la fenêtre/onglet de votre navigateur NE QUITTERA PAS SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Il est recommandé de faire un clic-droit et d'ajouter cette page à vos " "favoris pour accéder à SABnzbd quand il tourne en arrière plan." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Une aide supplémentaire peut être trouvée sur notre" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Aller à SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Quitter SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Lancer l'assistant" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "Restaurer la sauvegarde" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd est fourni sans AUCUNE GARANTIE.\n" "Ce logiciel est gratuit, et vous êtes invité à le redistribuer sous certaines conditions.\n" "Il est distribué sous licence GNU GENERAL PUBLIC LICENSE Version 2 ou toute autre version ultérieure.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "Échec du renommage de %s en %s" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Impossible de renommer le fichier similaire : %s en %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Accès non autorisé" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "Fichier introuvable sur le serveur" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "Le serveur n'a pas pu terminer la requête" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "L'URLGRABBER A PLANTÉ" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Fichier NZB inutilisable" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Échec de récupération de l'URL ; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Essai de récupération du NZB depuis %s" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.213867 SABnzbd-4.3.2/po/main/nl.po0000644000000000000000000037166114625637207014554 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Rik Brouwer, 2022 # Robert Lampe, 2023 # Safihre , 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2024\n" "Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Waarschuwing" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Fout" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Webinterface kan niet gestart worden" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Websjabloon %s niet te vinden; het standaardsjabloon wordt gebruikt." #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools uitgeschakeld, geen bruikbare versie gevonden! (V%s gevonden, V%s " "verwacht)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2-programma niet gevonden." #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "De UNRAR-versie is %s, we adviseren versie %s of hoger te gebruiken.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar-programma niet gevonden." #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za-programma niet gevonden." #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "Essentiële onderdelen ontbreken, er kan niet gedownload worden." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Let op: als je 0.0.0.0 als hostnaam gebruikt, heb je voor externe toegang " "een IPv6-adres nodig" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP- en HTTPS-poort kunnen niet hetzelfde zijn" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd is gestart met de codering %s, dit zou UTF-8 moeten zijn. Je kunt, " "bij het downloaden, problemen krijgen met Unicode namen van bestanden en " "mappen." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" "Huidige umask (%o) zou kunnen beletten dat SABnzbd toegang heeft tot de " "aangemaakte bestanden en mappen." #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "Extra certificaten uit het certifi pakket konden niet geladen worden" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS is uitgeschakeld vanwege ontbrekende CERT- en KEY-bestanden" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "HTTPS uitgeschakeld omdat de CERT en KEY-bestanden niet geldig zijn" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Webinterface kon niet gestart worden: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s is gestart" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd is afgesloten" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signaal %s ontvangen, opslaan en afsluiten..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Onherstelbare fout bij opslaan status" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "SABnzbd wordt herstart omdat de postprocessor is gecrasht" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "SABnzbd wordt herstart omdat de downloader is gecrasht" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "SABnzbd wordt herstart omdat de assembler is gecrasht" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "Kan het PID bestand %s niet benaderen" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "E-mail verzonden" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Test melding" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Geen hostnaam opgegeven." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" "Er zijn geen verbindingen opgegeven. Er is minimaal één verbinding nodig." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Wachtwoord gemaskeerd met ******, voer opnieuw in" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Ongeldige servergegevens" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" "Kon geen verbinding maken met %s op poort %s. Het lijkt erop dat %s " "functioneert als een webserver (poort 80), mogelijk een indexer, geen " "usenetserver. Vul een usenetserver in." #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradres \"%s:%s\" is niet geldig." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Tijdslimiet overschreden. Probeer met SSL aan of gebruik een andere poort." #: sabnzbd/api.py msgid "Timed out" msgstr "Tijdslimiet overschreden" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Onbekend SSL protocol: probeer het zonder SSL of probeer een andere poort." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Server heeft een gebruikersnaam en een wachtwoord nodig." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Succesvol verbonden!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Inloggen mislukt, controleer gebruikersnaam en wachtwoord." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Te veel verbindingen, onderbreek het downloaden of probeer later nog eens." #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Kan verbindingsresultaat niet bepalen (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Adres opzoeken" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Geen" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Standaard" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Schijf is vol; gedwongen pauze" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Schrijffout bij opslaan van bestand %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Onherstelbare fout in de Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Te weinig schijfruimte, pauze geforceerd" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "Download \"%s\" is gepauzeerd vanwege een versleuteld RAR bestand (indien " "aanwezig, zijn alle wachtwoorden geprobeerd)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "Download \"%s\" is afgebroken vanwege een versleuteld RAR bestand (indien " "aanwezig, zijn alle wachtwoorden geprobeerd)." #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Afgebroken, versleuteling ontdekt" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "Ongewenste extensie ontdekt in \"%s\". Het ongewenste bestand is \"%s\" " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "De ongewenste extensie zit in RAR-bestand %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Afgebroken, ongewenste extensie ontdekt" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" "Download \"%s\" is waarschijnlijk versleuteld omdat en een RAR met dezelfde " "naam in de hoofd RAR zit." #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" "Download \"%s\" is waarschijnlijk versleuteld, omdat \"password\" in de naam" " \"%s\" voor komt." #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Quotum verbruikt, download is gestopt" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Incorrecte parameter" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s is geen geldig e-mailadres" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Serveradres verplicht" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Ongeldige servernaam" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "%s is geen geldig script." #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s is geen correct octaal getal" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" "Ingestelde rechten van %s zouden kunnen beletten dat SABnzbd toegang heeft " "tot de aangemaakte bestanden en mappen." #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "We raden af hier de netwerk-locatie \"%s\" te gebruiken" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Wachtrij is niet leeg, andere map kiezen niet mogelijk." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" "De Map voor verwerkte downloads mag niet een map in de Tijdelijke download " "map zijn." #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" "Als de Map voor scripts zich in de SABnzbd installatie-map bevindt kan deze " "automatisch verwijderd worden tijdens updates. We adviseren een andere " "locatie te gebruiken voor je scripts." #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "Configuratie geblokkeerd, kan instellingen niet opslaan" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Schrijven naar het INI-bestand %s lukt niet" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Backupbestand maken voor %s niet mogelijk" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "De backup kon niet hersteld worden" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Foutief gecodeerd wachtwoord %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "Naar de geschiedenis-database schrijven niet mogelijk, controleer de " "toegangsrechten." #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "" "Beschadigde geschiedenis-database, is vervangen door een lege database" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL-commando mislukt, zie logbestand" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Het lukt niet om de database te sluiten, zie log" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Ongeldig loggen van fase in geschiedenis voor %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Decoder fout: onvoldoende geheugen" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Onbekende fout tijdens het decoderen van %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" "Verbetering van bestandsnamen overgeslagen omdat er DVD/Bluray mappen " "gevonden zijn" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "Extensie van %d bestand(en) gecorrigeerd" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "Bestandsnamen van %d bestand(en) aangepast." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "Direct Uitpakken" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Voltooid" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "%s bestanden/mappen uitgepakt in %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "Direct Uitpakken is automatisch ingeschakeld." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "Het uitpakken van downloads wordt al gestart tijdens het downloaden. Dit " "verkort de tijd die nodig is voor het nabewerken. Dit werkt alleen als de " "download niet beschadigd is." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Bewaakte map %s kan niet gelezen worden" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Hervatten" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Gepauzeerd" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Je moet eerst een maximumbandbreedte instellen voordat je een limiet kunt " "instellen" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Verbinding maken met server %s [%s] niet mogelijk" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Servernaam niet te vinden" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s wordt gedurende %s minuten genegeerd" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "Er zijn geen actieve servers!" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Initialisatie van %s@%s mislukt, vanwege: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "Onherstelbare fout in de Downloader" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "%s@%s: Onbekende statuscode %s ontvangen voor artikel %s" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Te veel verbindingen met server %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" "Teveel verschillende IP-adressen probeerde in te loggen op server %s [%s] - " "https://sabnzbd.org/multiple-adresses" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Aanmelden bij server %s mislukt [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Verbinding %s@%s mislukt, bericht=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Vedachte fout in downloader" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Afsluiten" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "Server %s verloopt over %s dag(en)." #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "Het beschikbare quotum voor server %s is verbruikt. " #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Verbinding met e-mailserver mislukt" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "TLS-verbinding mislukt" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "De server reageerde niet op de 'helo'-begroeting" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Aanmelden bij e-mailserver mislukt" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Geen geschikte authenticatiemethode gevonden" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Onbekende authenticatiefout bij de e-mailserver" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Verzenden van e-mail is mislukt" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Beëindigen e-mailverbinding mislukt" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Versturen kan niet, vereiste gegevens ontbreken" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Geen e-mailsjablonen te vinden in %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Geen geadresseerden opgegeven, e-mail niet verstuurd" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "%s kan niet gelezen worden" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Geen e-mailsjablonen gevonden" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd meldt een volle harde schijf\n" "\n" "Hallo,\n" "\n" "SABnzbd is gestopt met downloaden omdat de harde schrijf bijna vol is.\n" "Maak ruimte vrij en laat SABnzbd weer doorgaan.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Niet mogelijk directory %s aan te maken" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s directory: fout %s bij toegang" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Toegangsrechten van %s niet aan te passen" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Aanmaken (%s) mislukt" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Verplaatsen van %s naar %s mislukt" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "Poging om map %s aan te maken geblokkeerd" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Probleem met tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Opslaan van %s lukt niet" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Inlezen van %s mislukt" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" "Het is niet mogelijk bestanden te schrijven in %s. Hierdoor kan er niet " "gedownload worden." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" "Bestanden met lange bestandsnamen kunnen niet worden opgeslagen in %s. Dit " "kan voor problemen zorgen tijdens het downloaden." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" "Bestanden met speciale karakters in de bestandsnaam kunnen niet worden " "opgeslagen in %s. Dit kan voor problemen zorgen tijdens het downloaden." #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" "Het is niet mogelijk bestanden met speciale tekens op te slaan in %s. Dit " "geeft mogelijk problemen bij het verwerken van downloads." #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "Verbinding geweigerd van: " #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "Verbinding met hostnaam \"%s\" geweigerd van:" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Gebruiker heeft ingelogd" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Gebruiker ingelogd" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API-sleutel ontbreekt; vul de API-sleutel van 'Configuratie' => 'Algemeen' " "in bij het externe programma:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-sleutel incorrect; vul de API-sleutel van 'Configuratie' => 'Algemeen' " "in bij het externe programma:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Mislukte login poging van %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "Ongeldig backup bestand" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py msgid "Daily" msgstr "Dagelijks" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Maandag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Dinsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Woensdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Donderdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Vrijdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Zaterdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Zondag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "uit" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Onbekende server." #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" "Een Categorie specifieke map mag niet een map in de Tijdelijke download map " "zijn." #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "FOUT:" #: sabnzbd/interface.py msgid "Back" msgstr "Terug" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" "Om alle waarschuwingen met mogelijke problemen te blokkeren kan de Speciale " "optie 'helpful_warnings' uitgezet worden." #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Update beschikbaar!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "Kon het volgende bestand niet uploaden: %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Fout bij aanmaken SSL-sleutel en -certificaat" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "Je wachtwoordenbestand bevat meer dan 30 wachtwoorden, het testen van al " "deze wachtwoorden kost heel veel tijd. Zorg ervoor dat je alleen maar " "nuttige wachtwoorden in dit bestand zet." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "Kan het wachtwoord bestand niet uitlezen %s" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "[%s] Het commando in build_command is ongedefinieerd" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "Python-script '%s' heeft geen uitvoerpermissie (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Serie sorteren" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Datum sorteren" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "Film sorteren" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Script uitvoeren" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Teveel niveaus om uit te pakken [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Samenvoegen" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Onvolledige reeks van samenvoegbare bestanden" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Samenvoegen van bestanden %s is mislukt" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fout \"%s\" bij samenvoegen van bestanden" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Fout %s bij 'file_join' op %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] %s bestanden samengevoegd" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Uitpakken mislukt, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fout \"%s\" bij het uitpakken van RAR-bestanden" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fout \"%s\" bij uitvoeren van 'rar_unpack' op %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Verwijderen van %s mislukt." #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Unrar proberen met wachtwoord \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Uitpakken" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Uitpakken mislukt, kan %s niet vinden" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Uitpakken mislukt, CRC-fout" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "Uitplakken mislukt, bestand te groot voor het bestandssysteem (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Uitpakken mislukt, schrijffout of schijf vol?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Uitpakken mislukt, bestandspad is te lang" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Uitpakken mislukt, archief vereist wachtwoord" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Onbruikbaar RAR-bestand" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Beschadigd RAR-bestand" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Uitpakpoging met 7zip en wachtwoord '%s'" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "zie logbestand" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Snelle controle" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparatie" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Snelle Controle OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Reparatie starten" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparatie mislukt, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Fout %s bij uitvoeren van par2-reparatie op set %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fout '%s' bij reparatie van set %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2-opties incorrect, controleer Configuratie=>Instellingen " "schakelaars" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] %s geverifieerd, alle bestanden zijn goed" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Geverifieerd in %s, reparatie is nodig" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Ongeldige par2 bestanden of ongeldige Par2 parameters, kan niet verifiëren " "en repareren." #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "%s herstelblokken downloaden..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Ophalen" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparatie mislukt, te weinig herstelblokken (%s tekort)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Repareren" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Gerepareerd in %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "Reparatie controleren" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Schijf is vol" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Controleren van extra bestanden" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Verifiëren" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Controleren" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Probeer SFV-verificatie" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "over" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "De server staat geen SSL toe op deze poort" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "Servernaam komt niet overeen met de servernamen in het certificaat. Dit is " "een server-probleem." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" "Certificaat niet geldig. Dit is hoogstwaarschijnlijk een server-probleem." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Server %s gebruikt een niet betrouwbaar certificaat [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "Kon geen verbinding maken: %s %s@%s:%s (%s)" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Opstarten/Afsluiten" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pauze" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Doorgaan" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "Download toegevoegd" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Nabewerken gestart" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Download voltooid" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Download mislukt" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Wachtrij voltooid" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Andere berichten" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "Open map" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Open map met voltooide downloads" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Niet beschikbaar" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "Kon macOS notificatie niet verzenden" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Verzenden van Prowl-bericht mislukt" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "Eén of meerdere Apprise-URL's konden niet worden geladen." #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "Kon één of meerdere Apprise-meldingen niet verzenden" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "Verzenden van Apprise-bericht mislukt" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Slecht antwoord van Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Pushover-bericht sturen mislukt" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Slecht antwoord van Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Pushbullet-bericht sturen mislukt" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Script gaf code %s en resultaat '%s'" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Meldingsscript '%s' bestaat niet" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Versturen Windows-melding mislukt" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Kan geen tijdelijk bestand maken voor %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Fout bij toevoegen van %s, wordt weer verwijderd" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Fout bij verwijderen van %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Importeren van %s bestanden van %s mislukt" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Onbruikbaar wachtrij bestand gevonden, kan niet verder" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Fout bij inladen van %s, corrupt bestand gevonden" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "Download aan wachtrij toegevoegd" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Dubbele download \"%s\" overgeslagen" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "Download '%s' geweigerd omdat het een dubbele is" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "Dubbele download" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "Corrupte NZB %s wordt overgeslagen (foutmelding: %s)" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "NZB-bestand %s is leeg" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "Wachtrij filter script heeft de download afgekeurd" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "Ongewenste extensie gevonden in %s (%s) " #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Afgebroken, kan niet voltooid worden" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Fout bij importeren van %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUBBEL" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "ALTERNATIEF" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "VERSLEUTELD" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "TE GROOT" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "ONVOLLEDIG" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "ONGEWENST" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "WACHT %s sec" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "VERSPREIDINGSWACHTTIJD %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Gedownload in %s met een gemiddelde snelheid van %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Leeftijd" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artikelen zijn misvormd" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artikelen ontbreken" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artikelen hadden afwijkende duplicaten" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Dubbele download \"%s\" gepauzeerd" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Meldingen" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Rust" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Wachtrij" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Wis wachtrij" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Geschiedenis" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Wis de volledige geschiedenis" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Beperk snelheid" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "min" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Bewaakte map uitlezen" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Lees alle RSS-feeds uit" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Map voltooid" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Tijdelijke download map" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Probleemoplosser" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Herstart" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Herstarten zonder login" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Afsluiten" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Wachtrij Eerste 10 Items" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Leeg" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Geschiedenis Laaste 10 Items" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Ga naar Wizard" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Afsluiten..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Probleem met" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd heeft een vrije TCP/IP poort nodig voor de interne webserver.
\n" "Poort %s op %s is geprobeerd, maar is niet beschikbaar.
\n" "Een ander programma gebruikt de poort al of SABnzbd is al actief.
\n" "
\n" "Start SABnzbd met een ander poort nummer." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "Als je dit bericht weer krijgt, probeer dan een ander nummer.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd heeft een geldig host adres voor de interne webserver.
\n" "Je hebt een onbruikbaar adres opgegeven.
\n" "Veilige waarden zijn localhost en 0.0.0.0
\n" "
\n" "Start SABnzbd met een geldig host adres." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd heeft opgeslagen data van een andere SABnzbd versie gevonden
\n" " maar kan de data van deze andere versie niet opnieuw gebruiken.

\n" " Rond zo nodig eerst je werk met de andere versie af.

\n" " Herstart daarna deze versie met de optie \"--clean\".
\n" " Dit zal de huidige downloads en geschiedenis wissen!
\n" " SABnzbd las het bestand \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd kan de web-interface bestanden niet vinden in %s.
\n" "Installeer het programma opnieuw.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd heeft een fatale fout ontdekt:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd heeft ontdekt dat het bestand sqlite3.dll ontbreekt.

\n" "Sommige slecht ontworpen virusscanners verwijderen dit bestand.
\n" "Controleer je virus scaner, probeer SABnzbd opnieuw te installeren en klaag bij je leverancier.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Gebruik Windowstoets-R en type deze regel in (voorbeeld):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Open een \"Terminal\" venster en type deze regel in (voorbeeld):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Programma is niet opgestart!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Fatale fout" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" "Kan niet binden aan poort %s van %s. Andere software gebruikt deze poort of " "SABnzbd is al actief." #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Kan de web-browser niet starten, geen gevonden" #: sabnzbd/panic.py msgid "Access denied" msgstr "Toegang geweigerd" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Fout %s: Je moet een geldige gebruikersnaam en wachtwoord invullen." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Oude wachtrij gevonden, gebruik Status->Reparatie om te converteren" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Het compileren van 'regex' voor de zoekterm lukt niet: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" "De map voor voltooide downloads %s staat op een FAT systeem, de maximale " "file omvang is dan maar 4G" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" "Download mislukt waarschijnlijk, slechts %s van de benodigde %s beschikbaar" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Download mislukt - Niet meer op je server(s)" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Nabewerking" #: sabnzbd/postproc.py msgid "Moving" msgstr "Verplaatsen" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "%s naar de wachtrij gestuurd" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Fout bij hernoemen van \"%s\" tot \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Verplaatsen van bestanden mislukt" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Gebruiker script %s loopt" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Exit code van het script is %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "%s is klaar" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Meer" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Nabewerking van %s mislukt (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "Nabewerking is afgebroken" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Download mislukt" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Opschonen van %s mislukt" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Download voltooid" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Kan bestemmingsmap %s niet maken" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Geen par2 groepen" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Sommige bestanden konden niet geverifieerd worden met \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Verificatie m.b.v. SFV-bestanden is gelukt" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "Probeer RAR-verificatie" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Versleuteld" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] RAR verificatie niet gelukt: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "RAR bestanden zijn succesvol geverifieerd" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "RAR bestanden zijn niet verifieerbaar" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "RAR-hernoeming wordt geprobeerd" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "Geen voorgaand rar-bestand gevonden bij %s" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Verwijderen van %s mislukt" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Kan systeem niet in slaapstand krijgen" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Kan het systeem niet in standby krijgen" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Fout bij het afsluiten van het systeem" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "DBus foutmelding %s " #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Foutieve RSS-feed definitie \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Geen geldige inlog gegevens beschikbaar voor RSS-feed %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Server fout (code is %s); kon geen %s van %s krijgen" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Kan RSS-feed \"%s\" niet lezen vanwege: \"%s\"" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Server %s gebruikt een onbetrouwbaar HTTPS-certificaat" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS-feed %s is leeg" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Ongeschikte RSS-feed" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Lege RSS-feed gevonden (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Toon webinterface" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pauzeer" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pauzeer 5 minuten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pauzeer 15 minuten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pauzeer 30 minuten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pauzeer 1 uur" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pauzeer 3 uur" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pauzeer 6 uur" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Afsluiten" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Nog te doen" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "NZB toevoegen" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Foutieve taak %s om %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Onbekende actie: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Taak voor niet bestaande server %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Poging de status van niet-bestaande server %s in te stellen" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Download" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Samenvoegen" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Uitpakken" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "Bestandsnaam verbeteren" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Script" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Bron" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servers" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Mislukt" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Wacht" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Repareren..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Uitpakken..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Verplaatsen..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Script uitvoeren..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Extra herstelblokken downloaden..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Snelle Controle..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Verificatie..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "Server uit:" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "Server aan:" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Maximum snelheid" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Alles pauzeren" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pauzeer nabewerken" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Hervat nabewerken" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Uitlezen RSS-feeds" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Verwijder mislukte downloads" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Verwijder voltooide downloads" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pauzeer downloads met prioriteit \"Laag\"" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pauzeer downloads met prioriteit \"Normaal\"" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pauzeer downloads met prioriteit \"Hoog\"" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Hervat downloads met prioriteit \"Laag\"" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Hervat downloads met prioriteit \"Normaal\"" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Hervat downloads met prioriteit \"Hoog\"" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Schakel quotum beheer in" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Schakel quotum beheer uit" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "Pauzeer downloads met categorie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "Hervat downloads met categorie" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Uit" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Zeer Laag" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Gematigd" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normaal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Hoog" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Noodgeval" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Laag" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "uur" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "uren" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "min" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sec" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "seconden" #: sabnzbd/skintext.py msgid "day" msgstr "dag" #: sabnzbd/skintext.py msgid "days" msgstr "dagen" #: sabnzbd/skintext.py msgid "week" msgstr "week" #: sabnzbd/skintext.py msgid "Month" msgstr "maand" #: sabnzbd/skintext.py msgid "Year" msgstr "jaar" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Dag van de maand" #: sabnzbd/skintext.py msgid "This week" msgstr "Deze Week" #: sabnzbd/skintext.py msgid "This month" msgstr "Deze Maand" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "Datumbereik" #: sabnzbd/skintext.py msgid "Today" msgstr "Vandaag" #: sabnzbd/skintext.py msgid "Total" msgstr "Totaal" #: sabnzbd/skintext.py msgid "on" msgstr "aan" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parameters" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python versie" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Startpagina" #: sabnzbd/skintext.py msgid "or" msgstr "of" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Server" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Annuleren" #: sabnzbd/skintext.py msgid "Log in" msgstr "Aanmelden" #: sabnzbd/skintext.py msgid "Log out" msgstr "Afmelden" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Mij onthouden" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Opslaan" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Opslaan.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Weet je het zeker?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Startpagina" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Instellingen" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Status" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Hulp" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "Live Chat" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Problemen" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Steun het project, doneer!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Algemeen" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Mappen" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Opties" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Taakplanner" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Meldingen" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "E-mail" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Categorieën" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sorteren" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Speciaal" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Zoeken" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Weet je zeker dat je SABnzbd wilt afsluiten?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Toevoegen" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Categorie" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioriteit" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Repareren" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Uitpakken" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Opschonen" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Forceren" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Stop" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "PC afsluiten" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "PC standby" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "PC slapen" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "SABnzbd afsluiten" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Nabewerking" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Naam" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Opnieuw" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Scripts" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Verwijder alle downloads uit de wachtrij?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "Weet je zeker dat je deze downloads wilt verwijderen?" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Verwijder alle downloads" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Verwijderen incl. bestanden" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Verwijder download" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Verwijder download incl. bestanden" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "Permanent verwijderen (archief overslaan)" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Ontbrekende artikelen" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Quotum over" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "handmatig" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Quotum nu resetten" #: sabnzbd/skintext.py msgid "Archive" msgstr "Archief" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Verberg details" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Toon details" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Toon mislukte" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Toon Alles" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "Toon archief" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Omvang" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Verwijder mislukte downloads" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Verwijder mislukte downloads incl. bestanden" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Verwijder voltooide downloads" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Verwijder downloads op deze pagina" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Eventuele extra NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Pad" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Probeer alle mislukte downloads opnieuw" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Verbreek verbindingen" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" "Verbreek alle actieve verbindingen naar usenet servers. Verbindingen worden " "na een paar seconden weer geopend als er nog downloads in de wachtrij staan." #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Hiermee stuur je een test e-mail." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Download log" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "E-mail testen" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Loggen" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Fouten/Waarschuwingen" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+Debug" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Verbindingen" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Artikelnummer" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Bestandsverzameling" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Actief" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Verbinding mislukt!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokaal IPv4-adres" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Openbaar IPv4-adres" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6-adres" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nameserver / DNS opzoeken" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "Downloadsnelheid beperkt door" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "Hardeschijf" #: sabnzbd/skintext.py msgid "System load" msgstr "Systeembelasting" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Systeemprestaties (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Snelheid van download map" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Snelheid van verwerkte downloads map" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "Internet Bandbreedte" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Herhaal test" #: sabnzbd/skintext.py msgid "Test download" msgstr "Test download" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" "Voeg een test NZB (gevuld met willekeurige data) toe aan de wachtrij. " "Hiermee kan je controleren of alles goed werkt." #: sabnzbd/skintext.py msgid "Config File" msgstr "Instellingen bestand" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Gebruikte buffer" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Deze knop zal SABnzbd herstarten.
Dit kan nuttig zijn wanneer je " "vermoedt dat het programma niet stabiel is.
Het downloaden zal vóór de " "herstart gestopt worden en daarna weer doorgaan." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" "
Als authenticatie ingeschakeld is, zal je opnieuw moeten inloggen." #: sabnzbd/skintext.py msgid "Advanced" msgstr "Geavanceerd" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Er staan verweesde downloads in de download map.
Je kunt ze verwijderen " "(inclusief bestanden) of ze terug naar de wachtrij sturen." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "De \"Repareren\" knop herstart SABnzbd met een complete
\r\n" "reconstructie van de wachtrij, met behoud van al gedownloade bestanden.
\r\n" "Dit beïnvloedt wel de volgorde." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Wijzigingen niet opgeslagen en zullen verloren gaan." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" "Als je IP adres veranderd of SABnzbd opnieuw wordt opgestart, zal de sessie " "verlopen." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "7Zip toestaan" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" "Versnel reparaties door par2cmdline-turbo te installeren. Beschikbaar voor " "veel besturingssystemen." #: sabnzbd/skintext.py msgid "Version" msgstr "Versie" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Tijd in de lucht" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Reserve" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Lees de Wiki pagina over dit onderwerp" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "SABnzbd herstart nu..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Wijzigingen worden pas actief na herstart!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Webserver" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Host" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Host adres waar op SABnzbd luistert." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Poort" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Poort waar op SABnzbd luistert." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "Webinterface Stijl" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "Kies een stijl voor de webinterface." #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Gebruikersnaam" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Gebruikersnaam voor web login." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Wachtwoord" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Wachtwoord voor web login." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" "Als de Host of Poort open is gesteld naar het internet zorgen de huidige " "instellingen ervoor dat de webinterface volledig beschikbaar is voor " "externen." #: sabnzbd/skintext.py msgid "Security" msgstr "Beveiliging" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Activeer HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Webinterface beschikbaar via HTTPS" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" "Self-signed (onofficiële) certificaten worden door moderne webbrowsers en " "andere programma's meestal niet geaccepteerd waardoor deze een foutmelding " "geven of helemaal niet kunnen verbinden." #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS Poort" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Indien leeg, werkt de standaard poort uitsluitend met HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS-certificaat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Naam of pad naar het HTTPS-Certificaatbestand." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" "Maak een nieuw zelf-ondertekend certificaat en sleutel. SABnzbd moet dan " "opnieuw gestart worden." #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS-sleutelbestand" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Naam of pad van het HTTPS-sleutelbestand." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS chain-bestand" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Bestandsnaam of padnaam van HTTPS chain-bestand" #: sabnzbd/skintext.py msgid "Tuning" msgstr "Afstelling" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS-feed uitlees interval" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Minuten tussen het uitlezen (minimaal 15). Niet actief bij gebruik van de " "Taakplanner!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maximale snelheid internetverbinding" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Percentage van snelheid internetverbinding" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Welk percentage van de maximale internet snelheid mag SABnzbd gebruiken? " "B.v. 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Artikelbuffer grootte" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Bewaar de artikelen in het werkgeheugen (verminderd schijf gebruik).
In bytes, in K,M,G notatie. Bijvoorbeeld: \"64M\" of \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "Maak backup" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" "Maak een backup van de configuratie en de database in de Backup Map.
Als " "er geen Backup Map is ingesteld wordt de backup aangemaakt in de Map voor " "verwerkte downloads.
Automatische backups kunnen worden ingesteld via de " "Taakplanner." #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Opschoon lijst" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Lijst van extensies die na downloaden verwijderd moeten worden.
Voorbeeld: nfo of nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "Geschiedenis bewaren" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "Behoud alle downloads" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" "Verplaats voltooide downloads naar het archief als de geschiedenis het " "opgegeven aantal voltooide downloads overschrijdt." #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" "Verplaats voltooide downloads naar het archief na het opgegeven aantal dagen" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "Verplaats alle voltooide downloadsnaar het archief" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "Verwijder alle voltooide downloads" #: sabnzbd/skintext.py msgid "Jobs" msgstr "Downloads" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Opslaan" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Beginwaarden terugzetten" #: sabnzbd/skintext.py msgid "Reset" msgstr "Herstel" #: sabnzbd/skintext.py msgid "Language" msgstr "Taal" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Kies een taal." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "Help ons om SABnzbd in jouw taal te vertalen!
Met nieuwe vertalingen of" " verbeteringen kun je hier terecht:" #: sabnzbd/skintext.py msgid "API Key" msgstr "API-sleutel" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Met deze sleutel heeft een extern programma volledige toegang tot SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB-sleutel" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Met deze sleutel kan een extern programma NZB-bestanden naar SABnzbd sturen." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Maak een nieuwe sleutel" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "QR-code van de API-sleutel" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Externe toegang" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" "Je kunt toegangsrechten instellen voor systemen buiten je lokale netwerk. " #: sabnzbd/skintext.py msgid "No access" msgstr "Geen toegang" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Voeg NZB-bestanden toe " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (geen Configuratie)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Volledige API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Volledig webinterface" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Alleen voor externe toegang is aanmelden nodig" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "Let op: mappen worden vanzelf aangemaakt bij \"Opslaan\"." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Gebruikersmappen" #: sabnzbd/skintext.py msgid "Browse" msgstr "Bladeren" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Tijdelijke download map" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Map om onbewerkte downloads op te slaan
Kan alleen gewijzigd worden " "als de wachtrij leeg is." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimale vrije ruimte voor tijdelijke download map" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "Download wordt gepauzeerd als er te weinig ruimte vrij is" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Map voor verwerkte downloads" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "(kan aangepast worden door de categorieën)." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" "Gebruik Sorteren om automatisch je voltooide downloads te organiseren en " "hernoemen." #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "Minimale vrije ruimte voor verwerkte downloads map" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "Werkt niet als een categorie-pad naar een andere schijf verwijst." #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Automatisch doorgaan" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" "Het downloaden zal automatisch hervat worden als de minimale vrije ruimte " "weer beschikbaar is.
Is van toepassing op zowel de tijdelijke als " "verwerkte download map.
Wordt elke paar minuten gecontroleerd." #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Toegangsrechten voor verwerkte downloads" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Zet toegangsrechten voor verwerkte bestanden/mappen, alleen octale notatie!" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Bewaakte map" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "" ".nzb bestanden in deze map worden automatisch toegevoegd aan de wachtrij." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Bewaakte map verversingsinterval" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Aantal seconden tussen het lezen van de bewaakte map." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "Map voor scripts" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "Map met scripts van de gebruiker" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Map met e-mailsjablonen" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Map met e-mailsjablonen." #: sabnzbd/skintext.py msgid "Password file" msgstr "Wachtwoordenbestand" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Bestand met alle wachtwoorden die uitgeprobeerd moeten worden op " "versleutelde RAR-bestanden." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Systeemmappen" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "Verborgen mappen" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Administratieve map" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Map waar de wachtrij en geschiedenisdatabase worden opgeslagen.
Kan " "alleen gewijzigd worden als de wachtrij leeg is." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "Backup map" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" "Map waar de backups van de configuratie en databases worden opgeslagen.
Als deze map niet is ingesteld worden de backups aangemaakt in de Map voor" " verwerkte downloads." #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "De bestanden worden niet verplaatst. SABnzbd moet herstart " "worden!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Map voor logging" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Map waarin de log bestanden worden opgeslagen
Vereist een " "herstart." #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "Logs wissen" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Map voor het bewaren van NZB-bestanden" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Map waar reserve kopieën opgeslagen worden." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Basis map" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Download alle PAR2-bestanden" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" "Dit voorkomt extra reparatie pogingen, doordat alle beschikbare par2 files " "direct worden gedownload." #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Recursief uitpakken toestaan" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Uitpakken van archieven (rar, zip, 7z) binnen archieven toestaan" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Negeer mappen binnen archieven" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Alle bestanden gaan in één map" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Download alleen artikelen van het begin van de wachtrij" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Aanzetten zal leiden tot minder geheugen gebruik.
Uitzetten om te " "voorkomen dat langzame downloads de wachtrij blokkeren." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Verwerk alleen correct geverifieerde downloads" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" "Uitpakken en scripts worden alleen uitgevoerd op opdrachten die succesvol " "geverifieerd zijn. Als deze optie uitgeschakeld is zullen alle opdrachten " "gemarkeerd worden als succesvol, zelfs als dat niet zo is." #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Actie wanneer versleuteld RAR-bestand wordt gedownload" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Als je \"Pause\" kiest, dan dien je een wachtwoord in te stellen en de " "download vrij te geven" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "Identieke downloaddetectie" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" "Detecteer identieke downloads op basis van de naam of de inhoud van de NZB." #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "Slimme detectie van dubbele downloads" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" "Detecteer dubbele downloads op basis van de analyse van de bestandsnaam." #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "Sta verbeterde downloads toe" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" "Sla slimme detectie van dubbele downloads over als de naam van de download " "PROPER, REAL of REPACK bevat." #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Verwerpen" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "Label download" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "Keur download af" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "Nabewerking afbreken" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Actie bij ontdekken van ongewenste extensie" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "Actie bij ontdekken van een ongewenste extensie" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Ongewenste extensies" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "Blacklist" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "Whitelist" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" "Kies een stand en voer een lijst van alle (on)gewenste extensies in. " "Voorbeeld: exe or exe, com" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Voer SFV-gebaseerde controles uit" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Doe een extra verificatie m.b.v. SFV-bestanden" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Een gebruikersscript kan een download afkeuren" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Wanneer het script een exit code anders dan 0 geeft, zal de download worden " "afgekeurd." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Gebruik tijdelijke mapnamen" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Gebruik tijdelijke mapnamen tijdens de nabewerking. Zet dit uit wanneer je " "systeem daar problemen mee heeft." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Wachtrij-filter script" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Word uitgevoerd vóór een download aan de wachtrij word toegevoegd" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "Script voor na het afronden van de wachtrij" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "Script wordt uitgevoerd nadat de wachtrij is gedownload." #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Extra PAR2 parameters" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "\"Nice\" parameters" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "\"IONice\" parameters" #: sabnzbd/skintext.py msgid "External process priority" msgstr "Externe process prioriteit" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Verbreek verbindingen wanneer er niets te doen is" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Verbreek verbindingen wanneer de wachtrij leeg is of er gepauzeerd wordt." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "Wachtrij automatisch sorteren" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" "De wachtrij wordt automatisch gesorteerd wanneer er een nieuwe opdracht " "wordt toegevoegd" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" "De wachtrij wordt elke 30 seconden opnieuw gesorteerd als de optie % " "gedownload is gekozen." #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Verspreidingswachttijd" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Downloads zullen gepauzeerd worden tot ze minimaal deze leeftijd hebben. " "Instellen van prioriteit Forceren zal de download meteen starten." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Periodieke controle voor nieuwe versies" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Ook test versies" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Vervang spaties in mapnamen" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Vervang spaties door onderliggende streepjes in namen van mappen." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "Vervang onderstrepingstekens in mapnamen" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "Vervang onderstrepingstekens door punten in mapnamen." #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Vervang punten in mapnamen" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Vervang punten door spaties in namen van mappen." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Maak compatibel met Windows" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "Voor opslag op servers: gebruik namen die werken op Windows" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Start webbrowser bij opstarten" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Start de web browser wanneer SABnzbd opstart." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Onderbreek downloaden tijdens nabewerken" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "Onderbreek downloaden tijdens nabewerken." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Negeer samples" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Wat te doen met \"sample\"-bestanden?" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Verwijderen na download" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "Verbeter bestandsnamen van voltooide downloads" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" "Als bestandsnamen van (grote) bestanden na een voltooide download onlogisch " "of verhaspelt lijken (obfuscated), worden ze vervangen door de naam van de " "download." #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" "Als de bestandsextensie van een bestand ontbreekt of verhaspelt is, zal er " "geprobeerd worden de correcte extensie te vinden op basis van de inhoud van " "het bestand." #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "HTTPS certificaatverificatie" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" "Controleer certificaten bij beveiligde verbindingen met indexers en RSS-" "feeds." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "SOCKS5 Proxy" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "Gebruik een SOCKS5 proxy server voor alle uitgaande verbindingen." #: sabnzbd/skintext.py msgid "Server" msgstr "Server" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Nabewerking" #: sabnzbd/skintext.py msgid "Naming" msgstr "Naamgeving" #: sabnzbd/skintext.py msgid "Quota" msgstr "Quotum" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Hoeval mag deze maand worden gedownload (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Reset dag" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Op welke dag van de maand of week (1=maandag) wordt het quotum gereset? " "(Eventueel met hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "" "Moet het downloaden automatisch doorgaan bij het ingaan van het nieuwe " "quotum?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Quotum periode" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Wordt het quotum elke dag, week of maand gereset?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Controle vóór downloaden" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Probeer de succes kans van een download van te voren in te schatten " "(langzamer!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "SSL-sleutels" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" "Verhoog de prestaties door een eenvoudigere SSL versleuteling toe te passen." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Maximum aantal pogingen" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Maximaal aantal pogingen per server" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Download afbreken als deze zeker niet kan worden voltooid" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Als tijdens het downloaden duidelijk wordt dat te veel data ontbreekt, breek" " dan de download af" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Voeg server toe" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Servernaam" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Poort" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Gebruikersnaam" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Wachtwoord" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Tijdslimiet" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "Verloopdatum" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "Ontvang 5 dagen voor de verloopdatum een waarschuwing." #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" "Quotum voor dit account, wordt geteld vanaf het moment dat het voor het " "eerst ingesteld wordt. In bytes, in K,M,G notatie.
Er wordt een " "waarschuwing gegeven als het quotum bereikt is, dit wordt elke paar minuten " "gecontroleerd." #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Bewaartijd" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "Beveiligde verbinding met de server" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "Certificaatverificatie" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" "Minimaal: wanneer SSL geactiveerd is, controleer de identiteit van de server" " m.b.v. de certificaten. Strikt: controleer en vereis dat het geldige " "certificaat bij deze servernaam hoort." #: sabnzbd/skintext.py msgid "Disabled" msgstr "Uit" #: sabnzbd/skintext.py msgid "Minimal" msgstr "Minimaal" #: sabnzbd/skintext.py msgid "Strict" msgstr "Strikt" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 is de hoogste en 99 de laagste prioriteit" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "Vereist" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" "Het downloaden zal een aantal minuten gepauzeerd worden wanneer deze server " "niet beschikbaar is." #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Optioneel" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" "Voor onbetrouwbare servers, deze zullen langer worden genegeerd wanneer ze " "fouten veroorzaken." #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Inschakelen" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Verwijder" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Test Server" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Tellers op nul" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Server instellingen aan het testen..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Bandbreedte" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Persoonlijke aantekeningen" #: sabnzbd/skintext.py msgid "Article availability" msgstr "Beschikbaarheid van artikelen" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "%f% van %d opgevraagde artikelen" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Taak toevoegen" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Frequentie" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Actie" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Parameters" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Huidige taken" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Om de RSS-feed automatisch te verwerken, vink het selectievlakje bij de " "definitie naam aan.
Wanneer een nieuwe feed wordt gedefinieerd, zullen " "alleen nieuwe items gevonden worden en geen bestaande, behalve wanneer je de" " op \"Forceer download\" klikt." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "Zet komma's tussen de URLs" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Uitlezen" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Forceer download" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "Filters toepassen" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "Wijzigen" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "Wordt uitgevoerd om" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Volgorde" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Filter" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Accepteren" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Titel Bevat Niet" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Titel Bevat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "Categorie Is" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Minimaal" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Maximaal" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Vanaf SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "Vanaf Serie SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Geselecteerd" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Verworpen" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Gedownload" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Alle feeds nu uitlezen" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" "Notificaties zullen worden verstuurd voor alle downloads als de " "Standaard categorie geselecteerd is." #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Stuur een e-mail na het voltooien van elke download" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Nooit" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Altijd" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Alleen bij fouten" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Stuur een e-mail wanneer de harde schijf vol is" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Stuur een e-mail wanneer SABnzbd gestopt is vanwege een volle harde schijf." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Verstuur een e-mail voor RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "Verstuur een e-mail wanneer een RSS-feed downloads
aan de wachtrij " "heeft toevoegd." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP-server" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Het adres van de e-mailserver van je internet provider." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Ontvanger" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Adres waarnaar de e-mail verstuurd wordt." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Afzender" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Wie zou de email gestuurd moeten hebben?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "OPTIONEEL: Account gebruikersnaam" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Wanneer authenticatie nodig is, de gebruikersnaam." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "OPTIONEEL: Account wachtwoord" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Wanneer authenticatie nodig is, het wachtwoord." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Melding verzonden" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "NotifyOSD activeren" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Berichtencentrum" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Windows meldingen activeren" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows Meldingen" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Prowl meldingen activeren" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Een Prowl account is noodzakelijk" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "API-sleutel voor Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Persoonlijke API-sleutel voor Prowl (noodzakelijk)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Pushover meldingen activeren" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Hiervoor is een Pushover account nodig" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Applicatie token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Applicatie token (verplicht)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Gebrukers sleutel" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Gebrukers sleutel (verplicht)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Apparaten" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Apparaat of apparaten die het bericht moeten ontvangen" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "Noodgeval herhaling" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "Hoevaak moet de notification herhaald worden (in seconden)" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "Einde van noodgeval" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "Hoeveel seconden moet de notificatie herhaald worden" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Pushbullet meldingen activeren" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Hiervoor is een Pushbullet account nodig" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Persoonlijke API-sleutel" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Persoonlijke Pushbullet API-sleutel (verplicht)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Apparaat" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Apparaat dat de berichten moet ontvangen" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "Apprise-meldingen activeren" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" "Stuur meldingen met behulp van Apprise naar bijna elke bestaande service." #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "Standaard Apprise-URL's" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "Gebruik een komma en/of spatie om meer dan één URL op te geven." #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" "Overschrijf hieronder, indien gewenst, de standaard-URL's voor specifieke " "meldingstypen." #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Notificatie Script" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Notificatie script activeren" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Voer een zelfgemaakt script uit" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "Welk script moet uitgevoerd worden voor de notificatie?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "Indexers kunnen een categorie in de NZB plaatsen en SABnzbd zal die proberen" " toe te passen op onderstaande categorieën. Daarnaast kun je patronen " "invullen in de kolom \"Indexer Categorieën/Groepen\". Gebruik komma's om " "patronen te scheiden. Joker tekens (? en *) zijn toegestaan.
Meer " "informatie op de Wiki." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Als het pad eindigt met een ster *, dan worden geen aparte download mappen " "gemaakt." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Maplocaties gebaseerd op" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Map/Pad" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "Indexer Categorieën / Groepen" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Uitleg" #: sabnzbd/skintext.py msgid "Clear" msgstr "Wissen" #: sabnzbd/skintext.py msgid "Presets" msgstr "Standaardinstellingen" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Beïnvloede categorieën" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Betekenis" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Patroon" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultaat" #: sabnzbd/skintext.py msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Film Naam" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Film.Naam" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Film_Naam" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Serie Naam" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Serie.Naam" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Serie_Naam" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Seizoen Nummer" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Aflevering Nummer" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Aflevering Naam" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Aflevering.Naam" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Aflevering_Naam" #: sabnzbd/skintext.py msgid "Extension" msgstr "Extensie" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Volgnummer" #: sabnzbd/skintext.py msgid "Decade" msgstr "Decennium" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Originele bestandsnaam" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "Originele Downloadnaam" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Kleine letters" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py msgid "text" msgstr "tekst" #: sabnzbd/skintext.py msgid "file" msgstr "bestand" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Sorteertekst" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "Meervoudig label" #: sabnzbd/skintext.py msgid "Show folder" msgstr "Map per serie" #: sabnzbd/skintext.py msgid "Season folder" msgstr "Map per seizoen" #: sabnzbd/skintext.py msgid "In folders" msgstr "In mappen" #: sabnzbd/skintext.py msgid "No folders" msgstr "Geen mappen" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "Downloadnaam als Bestandsnaam" #: sabnzbd/skintext.py msgid "Series" msgstr "Series" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "Aanpassen van hoofd- en kleine letters" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Bewerkt resultaat" #: sabnzbd/skintext.py msgid "Any property" msgstr "Alle eigenschappen" #: sabnzbd/skintext.py msgid "property" msgstr "eigenschap" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "GuessIt Eigenschap" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "GuessIt.Eigenschap" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "GuessIt_Eigenschap" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "Minimale bestandsgrootte" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "Type downloads" #: sabnzbd/skintext.py msgid "All" msgstr "alles" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "Series met datums" #: sabnzbd/skintext.py msgid "Movies" msgstr "Films" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "Anders / Onbekend" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" "

Gebruik Sorteren om automatisch je voltooide downloads te organiseren. Bijvoorbeeld het automatisch verplaatsen van alle afleveringen van een serie in een seizoensspecifieke map. Of plaats films in een map met de naam van de film.

\n" "\n" "

Sorteringen worden in de getoonde volgorde geprobeerd en kunnen worden herschikt door ze te slepen.
De eerste actieve Sortering die overeenkomt met zowel de betreffende categorie als het type taak wordt toegepast.

\n" "\n" "

Meer opties zijn beschikbaar wanneer Geavanceerde instellingen zijn aangevinkt.
Gedetailleerde informatie is te vinden op de Wiki.

" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "Sortering toevoegen" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "Sortering verwijderen" #: sabnzbd/skintext.py msgid "Test Data" msgstr "Testgegevens" #: sabnzbd/skintext.py msgid "Quick start" msgstr "Snel beginnen" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" "Verplaats en hernoem alle afleveringen in de \"tv\" categorie naar een " "specifieke map voor de serie." #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" "Verplaats en hernoem alle films in de categorie \"films\" naar een " "specifieke map voor de film." #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Zelden gebruikte opties. Voor betekenis en uitleg, klik op de Help knop om " "naar de Wiki te gaan.
Wijzig hier niet zonder eerst de uitleg op de Wiki " "te lezen. Er kunnen nadelige bijwerkingen optreden.
De standaard " "instellingen staan tussen haakjes." #: sabnzbd/skintext.py msgid "Values" msgstr "Waarden" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Bewerk download details" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Verwijder" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Bestandsnaam" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Vrije ruimte" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Tijdelijke map" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Meervoudige bewerking" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Houdt Shift toets ingedrukt om meer te selecteren" #: sabnzbd/skintext.py msgid "Check all" msgstr "Selecteer alles" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Start SABnzbd opnieuw" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Na afronden wachtrij" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Status en webinterface opties" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Of sleep bestanden in dit venster!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Verbinding met SABnzbd verbroken" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "Wanneer SABnzbd opnieuw is gestart, gaat dit venster vanzelf weg!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "WAARSCHUWING:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Ophalen" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Webinterface" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Ververssnelheid" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Instellen voor alle sessies" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Items in wachtrij" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Items in geschiedenis" #: sabnzbd/skintext.py msgid "Date format" msgstr "Datumnotatie" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "Extra kolommen aan wachtrij toevoegen" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "Extra kolommen aan geschiedenis toevoegen" #: sabnzbd/skintext.py msgid "page" msgstr "Pagina" #: sabnzbd/skintext.py msgid "Loading" msgstr "Laden" #: sabnzbd/skintext.py msgid "articles" msgstr "artikelen" #: sabnzbd/skintext.py msgid "Rename" msgstr "Naam" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Wachtrij reparatie" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Toon actieve verbindingen" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Deblokkeren" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Verweesde downloads" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Stuur terug naar de wachtrij" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Alles wissen" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Alles opnieuw proberen" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Haal NZB op via URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "NZB uploaden" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Geef eventueel een andere naam" #: sabnzbd/skintext.py msgid "Submit" msgstr "Verstuur" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Verwijder alle geselecteerde bestanden" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Toon/verberg voltooide bestanden" #: sabnzbd/skintext.py msgid "Top" msgstr "Boven" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Onder" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" "Wanneer een download Opnieuw geprobeerd wordt, staan 'Identieke/Slimme " "downloaddetectie' en 'Download afbreken als deze zeker niet kan worden " "voltooid' uit." #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Toon Script resultaat" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "Als je de naam wijzigt zal het Direct Uitpakken gestopt worden." #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "\"Local Storage\" (cookies) is uitgeschakeld in je web browser, niet alle " "instellingen zullen worden onthouden." #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "Glitter heeft enkele (nieuwe) functies die je mogelijk aanspreken!" #: sabnzbd/skintext.py msgid "Custom" msgstr "Aangepast" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Compacte weergave" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "Gebruik de volledige schermbreedte" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Weergave in tabs
(wachtrij en geschiedenis apart weergeven)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Snelheid" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Bevestig verwijderen uit wachtrij" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Bevestig verwijderen uit geschiedenis" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "Sneltoetsen" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "Shift+Pijltoets: Blader door de wachtrij- en geschiedenispagina's" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Voor hoe lang of tot wanneer wilt u pauzeren? (in het Engels!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Sorry, het opgegeven kunnen wij niet verwerken. Probeer nogmaals." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pauzeer..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Ververs" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" "Alle gebruikersnamen, wachtwoorden en API-sleutels worden automatisch " "verwijderd uit het logbestand en de bijgevoegde kopie van je instellingen." #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "Sorteer Op % Gedownload Meest→Minst" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sorteer op Leeftijd Oud→Nieuw" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sorteer op Leeftijd Nieuw→Oud" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sorteer op Naam A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sorteer op Naam Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sorteer op Omvang Klein→Groot" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sorteer op Omvang Groot→Klein" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Uploaden" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Verbinding verbreken" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Item aan het verwijderen" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Items aan het verwijderen" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Snelstart Hulp" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd versie" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Vorige" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Volgende" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Server instellingen" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Vul hier de gegevens van je primaire Usenet server in." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Het aantal verbindingen dat je provider toestaat." #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Bv. 8 of 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Vink dit alleen aan als je provider SSL-verbindingen toestaat." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Klik om de verbinding te testen." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Voorbeeld" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Alles ingesteld!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd is actief op de achtergrond." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Afsluiten van het browservenster zal SABnzbd niet stoppen." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Tip: maak een \"Bladwijzer\" of \"Favoriet\" voor deze locatie, zodat je " "SABnzbd gemakkelijk terug kunt vinden." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Voor meer informatie bekijk de" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Ga naar SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Stop SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Wizard starten" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "Backup herstellen" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd wordt aangeboden ZONDER ENIGE VORM VAN GARANTIE.\n" "Het is vrije software en je mag het, onder bepaalde voorwaarden, verder verspreiden.\n" "De licentie is de GNU GENERAL PUBLIC LICENSE Versie 2 of (naar eigen keuze) een latere versie.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "Hernoemen van %s naar %s mislukt" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Hernoemen van gelijkaardig bestand %s naar %s mislukt" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Geen toegangsrechten" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "Bestand bestaat niet op de server" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "De server kon de opdracht niet uitvoeren" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER FATALE FOUT" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Onbruikbaar NZB-bestand" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "URL ophalen mislukt; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Probeer NZB op te halen van %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2177422 SABnzbd-4.3.2/po/main/zh_CN.po0000644000000000000000000033514714625637207015143 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # Kangwei Li , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Kangwei Li , 2023\n" "Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "警告" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "错误" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "web 界面启动失败" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "无法找到 web 模板: %s,正在尝试标准模板" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "SABCTools 已禁用:未找到正确的版本!(找到 v%s,要求 v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 可执行程序... *未* 找到!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "您的 UNRAR 程序版本为 %s,我们建议使用 %s 或更高版本。
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar 可执行程序... *未* 找到" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za 可执行程序... *未*找到!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "请注意 0.0.0.0 主机名需要 IPv6 地址才能从外部访问" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP 与 HTTPS 端口不能相同" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "SABnzbd 以 %s 编码启动了,正常应该是 UTF-8。会导致下载文件夹中统一标准编码的文件和文件夹名称出现问题。" #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "由于缺少 CERT 及 KEY 文件,已禁用 HTTPS" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "无法启动 web 界面: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s 已启动" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd 关闭完成" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "捕捉到 %s 信号,正在保存并退出..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "保存状态时遇到致命错误" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "成功发送电子邮件" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "测试通知" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "主机名未设置。" #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "未设置连接。请设置至少一个连接。" #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "密码会以 ****** 显示,请重新输入" #: sabnzbd/api.py msgid "Invalid server details" msgstr "服务器信息无效" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "服务器地址 \"%s:%s\" 无效。" #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "超时: 请尝试启用 SSL 或连接其他端口。" #: sabnzbd/api.py msgid "Timed out" msgstr "超时" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "未知的 SSL 协议:尝试禁用 SSL 或者连接不同的端口。" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "服务器需要用户名与密码。" #: sabnzbd/api.py msgid "Connection Successful!" msgstr "连接成功!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "身份认证失败,请检查用户名/密码。" #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "连接数过多,请先暂停下载或稍后再试" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "无法判断连接结果 (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "正在解析地址" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "无" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "默认" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "磁盘已满! 强制暂停" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "创建文件 %s 时磁盘出错" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Assembler 出现致命错误" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "磁盘空间过低,强制 *暂停*" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "\"%s\" 任务已暂停,因其包含加密 RAR 文件 (已尝试所有的密码,如果提供了的话)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "\"%s\" 任务已终止,因其包含加密 RAR 文件 (已尝试所有的密码,如果提供了的话)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "已中止,发现加密文件" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "RAR 文件“%s”中出现不需要的扩展名。不需要的文件名为 %s " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "rar 文件中出现不需要的扩展名 %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "已中止,侦测到不需要的扩展名" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "任务 \"%s\" 可能受加密保护,RAR 文件中存在相同名称的 RAR 文件。" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "任务 \"%s\" 可能受加密保护:文件名 \"%s\" 中有 \"password\" 字符" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "配额已耗尽,暂停下载" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "参数不正确" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s 不是有效的电子邮箱地址" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "服务器地址必填" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "服务器地址无效。" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s 不是有效的八进制值" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "队列非空,无法变更文件夹。" #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "无法写入 INI 文件 %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "无法为 %s 创建备份文件" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "密码编码错误 %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "无法写入“历史记录”数据库,请检查访问权限!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "“历史记录”数据库已损坏,已创建空数据库代替" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL 命令执行失败,参见日志" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "无法关闭数据库,参见日志" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "%s 历史信息中 stage 日志无效" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "解码器失败:内存不足" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "解码 %s 时发生未知错误" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "完成" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "已解压 %s 个文件/文件夹,耗时 %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "无法读取监视文件夹 %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "恢复中" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "已暂停" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "设置带宽限制前,您必须设置最大带宽值" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "无法连接到服务器 %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "服务器名无法解析" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "服务器 %s 将被忽略 %s 分钟" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "无法初始化 %s@%s,原因为: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "服务器 %s 连接数过多 [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "无法登录服务器 %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "连接 %s@%s 失败,消息=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "下载器疑似错误" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "正在关闭" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "无法连接到邮件服务器" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "无法发起 TLS 连接" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "服务器未正确回复 helo 问候" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "无法在邮件服务器上验证身份" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "未找到合适的身份验证方法" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "邮件服务器出现未知身份验证错误" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "无法发送 e-mail" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "无法关闭邮件连接" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "无法发送,缺少必要的数据" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "无法找到 email 模板:%s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "未给定收件人,电子邮件未发出" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "无法读取 %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "未找到 email 模板" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd 报告磁盘已满\n" "\n" "Hi,\n" "\n" "由于磁盘几乎已满,SABnzbd 已停止下载。\n" "请腾出空间再手动让 SABnzbd 续传。\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "无法创建目录 %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s 目录: %s 访问出错" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "无法更改 %s 的权限" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "创建失败 (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "将 %s 移动到 %s 失败" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "tempfile.mkstemp 出错" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "保存 %s 失败" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "加载 %s 失败" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "用户已在 web 界面登录" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "用户已登录" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "缺 API Key,请将“配置”->“常规”中的 api key 输入到第三方程序中:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "API Key 不正确,请在第三方程序中使用“配置”->“常规”中的 api key:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "%s 中有失败的登陆请求" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py msgid "Daily" msgstr "每天" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "周一" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "周二" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "周三" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "周四" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "周五" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "周六" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "周日" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "关" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "未定义服务器!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "错误:" #: sabnzbd/interface.py msgid "Back" msgstr "返回" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "天" #: sabnzbd/misc.py msgid "h" msgstr "小时" #: sabnzbd/misc.py msgid "m" msgstr "分钟" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "有更新可用!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "创建 SSL key 及证书出错" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "Python 脚本 \"%s\" 不具有执行 (+x) 权限" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "TV 排序" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "日期排序" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "电影排序" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "正在执行脚本" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "解压嵌套层级过深 [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "正在合并" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "可合并的文件队列不完整" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "%s 文件合并失败" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] \"%s\" 合并文件时出错" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "\"%s\" 对 %s 运行 file_join 时出错" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] 已合并 %s 个文件" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "解压失败,%s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] \"%s\" 解压 RAR 文件时出错" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "出现错误 \"%s\",正对 %s 执行 rar_unpack 操作" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "删除 %s 失败!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "正在尝试 unrar,使用密码 \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "正在解压" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "解压失败,找不到 %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "解压失败,CRC 错误" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "解压失败,文件太大文件系统不支持 (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "解压失败,写入出错或磁盘已满?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "解压失败,路径过长" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "解压失败,压缩文件需要密码" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "无法使用的 RAR 文件" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "损坏的 RAR 文件" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "正在尝试 7zip,密码 \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "查看日志文件" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "快速检查" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "修复" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] 快速检查 OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "正在开始修复" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "修复失败,%s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "%s 对集合 %s 执行 par2_repair 时出错" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "\"%s\" 对集合 %s 执行 par2_repair 时出错" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "[%s] PAR2 收到的选项不正确,请检查您的“配置”->“参数”设置" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] 验证耗时 %s,所有文件均完好无损" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] 验证耗时 %s,需要修复" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "正在装取 %s 块..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "正在装取" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "修复失败,修复块不足 (缺 %s 块)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "正在修复" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] 已修复,耗时 %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "磁盘空间已满" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "正在验证" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "正在检查" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "正在尝试 SFV 验证" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "剩余" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "该服务器不允许在该端口使用 SSL" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "%s 服务器使用了不受信任的证书 [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "启动/关闭" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "暂停" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "续传" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "已添加 NZB" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "后期处理已开始" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "任务已完成" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "任务失败" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "队列已完成" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "其他信息" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "打开完成文件夹" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "不可用" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "无法发送 Prowl 消息" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Pushover 响应异常 (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "无法发送 pushover 信息" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Pushbullet 响应异常 (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "无法发送 pushbullet 信息" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "脚本返回退出代码 %s 及输出内容 \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "通知脚本 \"%s\" 不存在" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "无法发送 Windows 通知" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "无法为 %s 创建临时文件" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "加载 %s 出错,正在移除" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "移除 %s 时出错" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "导入 %s 文件失败,来自 %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "发现不兼容的队列文件,无法继续处理" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "无法加载 %s,侦测到损坏文件" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB 已添加到队列" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "正在忽略重复 NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "失败于重复的 NZB 文件 \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "重复的 NZB 文件" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "空 NZB 文件 %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "预队列脚本将任务标记为失败的" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "已中止,无法完成" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "导入 %s 出错" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "*重复*" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "*加密*" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "*太大*" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "*不完整*" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "不需要" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "*等待* %s 秒" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "传播延迟生效,等待 %s 分钟" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "已下载,耗时 %s,平均速度 %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "发布时间" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s 篇文章损坏" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s 篇文章缺失" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s 篇文章存在未匹配的重复" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "正在暂停重复 NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "警告信息" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "空闲" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "队列" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "清空队列" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "历史" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "清空历史" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "限速" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "分钟" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "扫描监视文件夹" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "读取所有 RSS feed" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "完成文件夹" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "未完成文件夹" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "疑难解决" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "重启" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "清除登录身份凭据设置并重新启动" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "退出" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "将前十项加入队列" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "清空" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "最近十条历史记录" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "转到向导" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "正在停止..." #: sabnzbd/panic.py msgid "Problem with" msgstr "问题" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd 的内部 web 服务器需要一个空闲的 tcp/ip 端口。
\n" " 已尝试端口 %s(位于 %s),但不可用。
\n" " 有其他软件占用了该端口,或者 SABnzbd 已经在运行,
\n" "
\n" " 请使用其他端口号重启 SABnzbd。" #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "如果您再次收到本错误信息,请尝试其他数字。
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd 的内部 web 服务器需要有效的主机地址。
\n" " 您指定的地址无效。
\n" " 安全的值有 localhost 与 0.0.0.0
\n" "
\n" " 请使用适当的主机地址重启 SABnzbd。" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd 侦测到其他 SABnzbd 版本已保存的数据
\n" " 但无法重新使用其他程序的数据。

\n" " 您可能需要先完成其他程序的队列。

\n" " 之后再使用 \"--clean\" 选项启动本程序。
\n" " 该选项将清除当前队列及历史!
\n" " SABnzbd 读取到的文件是 \"%s\"。" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd 无法找到位于 %s 的 web 界面文件。
\n" " 请重新安装本程序。
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd 侦测到致命错误:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd 侦测发现缺少 sqlite3.dll 文件。

\n" " 一些很差劲的病毒扫描程序会移除此文件。
\n" " 请检查您的病毒扫描程序,尝试重新安装 SABnzbd 并向病毒扫描程序厂商反映。
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "请按 开始菜单键+R 并输入下面一行命令 (例):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "请打开“终端”窗口并输入下面一行命令 (例):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "程序未启动!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "致命错误" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "绑定端口 %s 在 %s 上失败。其它的程序正在使用此端口或者说 SABnzbd 正在运行。" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "无法启动浏览器,可能未找到" #: sabnzbd/panic.py msgid "Access denied" msgstr "访问被拒绝" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "错误 %s: 您需要提供有效的用户名与密码。" #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "侦测到旧版队列,请使用“状态”→“修复”转换队列" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "为搜索关键词编译正则表达式失败: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "已完成文件夹 %s 位于 FAT 文件系统上,这样会有最大文件为 4GB 的限制。" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "下载可能会失败,只有 %s 块 (需要 %s) 可用" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "下载失败 - 不在该服务器上" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "后期处理" #: sabnzbd/postproc.py msgid "Moving" msgstr "正在移动" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "已将 %s 发送到队列" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "将 \"%s\" 重命名为 \"%s\" 出错" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "移动文件失败" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "正在执行用户脚本 %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "脚本退出代码为 %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "执行 %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "更多" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "后期处理失败:%s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "下载失败" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "%s 清理失败。" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "下载完成" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "无法创建最终文件夹 %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] 无 par2 集合" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "部分文件的验证结果与 \"%s\" 不符" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "成功使用 SFV 文件验证" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "正在尝试基于 RAR 的验证" #: sabnzbd/postproc.py msgid "Passworded" msgstr "有密码" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] 基于 RAR 的验证失败: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "RAR 文件验证成功" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "RAR 文件验证失败" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "移除 %s 失败" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "系统休眠失败" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "系统待机失败" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "关闭系统时出错" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "RSS feed 描述不正确 \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "feed %s 无有效的身份认证凭据" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "服务器端错误 (服务器代码 %s);无法获取 %s (服务器 %s)" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "无法检索 %s 的 RSS: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "服务器 %s 使用的 HTTPS 证书不受信任" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS Feed %s 为空" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "feed 不兼容" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "发现空的 RSS 条目 (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "显示界面" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "暂停" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "暂停 5 分钟" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "暂停 15 分钟" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "暂停 30 分钟" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "暂停 1 小时" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "暂停 3 小时" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "暂停 6 小时" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "关闭" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "剩余" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "添加 NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "定时任务 %s 存在问题,时间为 %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "未知操作: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "定时任务的服务器不存在 %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "正在尝试设置不存在的服务器 %s 的状态" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "下载" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "合并文件" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "解压" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "脚本" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "来源" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "服务器" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "失败" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "等待" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "正在修复..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "正在提取..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "正在移动..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "正在执行脚本..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "正在装取额外块..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "快速检查..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "正在验证..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "禁用服务器" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "启用服务器" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "限速" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "全部暂停" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "暂停后期处理" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "继续后期处理" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "读取 RSS feed" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "移除失败任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "移除已完成任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "暂停低优先级任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "暂停常规优先级任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "暂停高优先级任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "继续低优先级任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "继续常规优先级任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "继续高优先级任务" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "启用配额管理" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "禁用配额管理" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "关" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "非常低" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "适中" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "常规" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "高" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "紧急" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "低" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "小时" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "小时" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "分钟" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "秒" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "秒" #: sabnzbd/skintext.py msgid "day" msgstr "天" #: sabnzbd/skintext.py msgid "days" msgstr "天" #: sabnzbd/skintext.py msgid "week" msgstr "周" #: sabnzbd/skintext.py msgid "Month" msgstr "月" #: sabnzbd/skintext.py msgid "Year" msgstr "年" #: sabnzbd/skintext.py msgid "Day of month" msgstr "每月特定一天" #: sabnzbd/skintext.py msgid "This week" msgstr "本周" #: sabnzbd/skintext.py msgid "This month" msgstr "本月" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "今天" #: sabnzbd/skintext.py msgid "Total" msgstr "总计" #: sabnzbd/skintext.py msgid "on" msgstr "开" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "参数" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python 版本" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "主页" #: sabnzbd/skintext.py msgid "or" msgstr "或" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "主机" #: sabnzbd/skintext.py msgid "Cancel" msgstr "取消" #: sabnzbd/skintext.py msgid "Log in" msgstr "登录" #: sabnzbd/skintext.py msgid "Log out" msgstr "注销" #: sabnzbd/skintext.py msgid "Remember me" msgstr "记住我" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "保存" #: sabnzbd/skintext.py msgid "Saving.." msgstr "正在保存.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "是否确定?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "主页" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "配置" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "状态" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "帮助" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "论坛" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "问题" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "支持该项目,捐助!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "常规" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "文件夹" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "参数" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "定时任务" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "通知" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Email" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "分类" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "排序" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "特殊" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "搜索" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "是否确定要关闭 SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "添加" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "分类" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "优先级" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+修复" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+解压" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+删除" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "强制" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "停止" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "输入 URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "电脑关闭" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "电脑待机" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "电脑休眠" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "关闭 SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "处理" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "名称" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "重试" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "脚本" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "删除队列中全部项?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "清空 NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "清空 NZB 并删除文件" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "移除 NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "移除 NZB 并删除文件" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "缺失文章" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "剩余配额" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "手动" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "立即重置配额" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "隐藏详情" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "显示详情" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "只显示失败项" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "显示全部项" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "尺寸" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "清除失败 NZB" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "清除失败 NZB 并删除文件" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "清除已完成 NZB" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "清理本页的 NZB 文件" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "可选补充 NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "路径" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "重新尝试下载所有已失败任务" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "强制断开连接" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "这将发送一封测试邮件到您的账号当中。" #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "显示日志" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "测试邮件" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "日志" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "错误/警告" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ 信息" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ 调试" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "连接" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "文章 id" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "文件集" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "启用" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "连接失败!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "本地 IPv4 地址" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "公网 IPv4 地址" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6 地址" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "域名服务器 / DNS 查询" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "系统性能 (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "下载文件夹读写速度" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "完成文件夹写入速度" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "重复测试" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "配置文件" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "已用缓存" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "这将重新启动 SABnzbd。
如果您认为程序存在稳定性问题,请使用该项。
重启前将暂停下载,之后将继续下载。" #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "
若启用身份认证,您将需要重新登录。" #: sabnzbd/skintext.py msgid "Advanced" msgstr "高级" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "下载目录中存在孤立任务。
您可以选择删除任务 (及其文件) 或将它们发回队列。" #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "“修复”按钮可重启 SABnzbd 并执行完整的
队列内容重建操作,同时将保留已下载的文件。
队列的顺序会有所改变。" #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "更改未保存,改动将丢失。" #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "每当您的 IP 地址发生变化,或当 SABnzbd 重启,登录会话将自动过期。" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "启用 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "版本" #: sabnzbd/skintext.py msgid "Uptime" msgstr "启动时间" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "备份" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "关于该项请参阅 Wiki 帮助!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "正在重新启动 SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "变更需要重启 SABnzbd 才会生效!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd Web 服务器" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd 主机" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "SABnzbd 应监听的主机。" #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd 端口" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "SABnzbd 应监听的端口。" #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd 用户名" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "可选身份验证用户名。" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd 密码" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "可选身份验证密码。" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "安全" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "启用 HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "启用 HTTPS 地址访问界面。" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS 端口" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "若留空,则将监听 HTTPS 标准端口。" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS 证书" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "HTTPS 证书文件名或路径。" #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "生成新的自签名证书和密钥。需要重启 SABnzbd!" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS Key" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "HTTPS Key 文件名或路径。" #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS 链证书" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "HTTPS 链文件名或路径。" #: sabnzbd/skintext.py msgid "Tuning" msgstr "调节" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS 检查间隔" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "检查间隔 (分钟,最小值为 15)。若使用“定时任务”则不会有效!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "最大线路速度" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "线路速度的百分比" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "SABnzbd 应占用的线路速度的百分比,如 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "文章缓存限制" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "在内存中缓存文章,以减轻硬盘访问压力。
单位为字节,可以选择加上 K、M、G 后缀。例如: \"64M\" 或 \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "清理列表" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "下载后应删除的文件扩展名列表。
例如: nfo 或 nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "保存更改" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "恢复默认值" #: sabnzbd/skintext.py msgid "Reset" msgstr "重置" #: sabnzbd/skintext.py msgid "Language" msgstr "语言" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "选择 web 界面的语言。" #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "帮助我们来本地化 SABnzbd !
您可以在这里来添加未被翻译的文字或者改进现有的翻译:" #: sabnzbd/skintext.py msgid "API Key" msgstr "API Key" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "该 key 将授予第三方程序 SABnzbd 的完整权限。" #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB Key" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "该 key 将允许第三方程序将 NZB 添加到 SABnzbd 中。" #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "生成新的 Key" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API Key QR 码" #: sabnzbd/skintext.py msgid "External internet access" msgstr "外部互联网访问" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "无权访问" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "添加 NZB 文件 " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (不允许配置)" #: sabnzbd/skintext.py msgid "Full API" msgstr "完整 API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "完整 Web 界面" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "只对外部访问要求登录" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "注: 保存时将自动创建文件夹。您可以使用绝对路径以保存到默认文件夹以外的地方。" #: sabnzbd/skintext.py msgid "User Folders" msgstr "用户文件夹" #: sabnzbd/skintext.py msgid "Browse" msgstr "浏览" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "临时下载文件夹" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "存储未处理下载数据的位置。
仅当队列为空时可以更改。" #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "临时下载文件夹的最小剩余空间" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "当剩余空间低于该值时自动暂停。
单位为字节,可选添加 K、M、G、T 后缀。例如: \"800M\" 或 \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "完成下载文件夹" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "存储完成且已完全处理的下载数据的位置。
可以通过用户定义分类额外调整。" #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "完成下载文件夹的最小剩余空间" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "当某分类的路径位于另一磁盘上时不生效。" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "自动续传" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "完成下载权限" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "设置完成文件/文件夹的权限值。
八进制记法。例如: \"755\" 或 \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "监视文件夹" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "要监视 .nzb 文件的文件夹。" #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "监视文件夹扫描速度" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "扫描 .nzb 文件的间隔时间。" #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "脚本文件夹" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "包含用户脚本的文件夹。" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "邮件模板文件夹" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "包含用户定义的电子邮件模板的文件夹。" #: sabnzbd/skintext.py msgid "Password file" msgstr "密码文件" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "包含要对加密 RAR 文件进行尝试的所有密码的文件。" #: sabnzbd/skintext.py msgid "System Folders" msgstr "系统文件夹" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "管理文件夹" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "队列管理及历史数据库的存放位置。
仅当队列为空时可以修改。" #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "备份文件夹" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "备份配置文件和数据库的位置。
如果留空,备份将存放于完成下载文件夹中。" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "数据不会自动移动。需要重启 SABnzbd 才能生效!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "日志文件夹" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "SABnzbd 日志文件的位置。
需要重启 SABnzbd 才能生效!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "清除日志" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr ".nzb 备份文件夹" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "存储 .nzb 文件的位置。" #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "默认基本文件夹" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "下载所有 par2 文件" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "当需要时下载所有的 par2 文件以避免多次运行修复。" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "启用递归解压" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "解压压缩包内的压缩包 (rar, zip, 7z)。" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "忽略压缩包中的文件夹结构" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "所有文件保存到单个目录。" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "只获取队列最顶端的文章" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "启用可减少内存占用。禁用可避免慢速任务拖慢队列进度。" #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "仅对经验证的任务进行后期处理" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "下载到加密的 RAR 文件时采取的操作" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "若选择“暂停”,您将需要设置密码并手动续传对应任务。" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "舍弃" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "失败的任务 (移动到历史)" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "侦测到不需要的扩展名时的操作" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "不需要的扩展名" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "启用基于 SFV 的检查" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "根据 SFV 文件进行额外验证。" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "用户脚本可将任务标记为失败" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "用户脚本返回非零的退出代码时,对应的任务将被标记为失败。" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "启用文件夹重命名" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "后期处理过程中使用临时名称。若您的系统无法正常处理请禁用。" #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "加入队列前执行的用户脚本" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "用于在 NZB 进入队列前执行。" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "额外的 PAR2 参数" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Nice 参数" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "IONice 参数" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "清空队列时断开" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "队列为空或暂停时从 Usenet 服务器断开连接。" #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "传播延迟" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "在文章发布时长尚不足该值时暂停下载文章。将任务优先级设为“强制”可跳过此延迟。" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "检查新版本" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "同时检索测试版本信息" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "替换文件夹名称中的空格" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "将文件夹名称中的空格替换成下划线。" #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "替换文件夹名称中的点号" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "将文件夹名称中的小数点替换成空格。" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "确保与 Windows 兼容" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "供服务器使用: 确保名称与 Windows 系统兼容。" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "启动时启动浏览器" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "启动 SABnzbd 时启动默认 web 浏览器。" #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "后期处理过程中暂停下载" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "开始后期处理时暂停下载,完成后续传。" #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "忽略样本文件" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "过滤样本文件 (如视频样本)。" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "下载后删除" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "HTTPS 证书验证" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "当用 HTTPS 方式连接索引和RSS源时验证证书。" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "服务器" #: sabnzbd/skintext.py msgid "Post processing" msgstr "后期处理" #: sabnzbd/skintext.py msgid "Naming" msgstr "命名" #: sabnzbd/skintext.py msgid "Quota" msgstr "配额" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "本月能下载多少数据量 (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "重置时间" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "您的 ISP 会在每月或每周的哪天 (1=星期一) 重置配额? (可选加上 hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "配额重置后是否自动续传下载?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "配额周期" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "配额会每天、每周或每月重置吗?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "下载前检查" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "在实际下载之前尝试预测可以成功下载的完整程度 (会减慢下载进度!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "SSL 加密算法" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "降低 SSL 的加密难度以便获得更高的性能。" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "最多重试次数" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "各服务器重试的最多次数" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "中止无法完成的任务" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "下载时若发现缺失数据过多,则中止对应任务" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "添加服务器" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "服务器描述" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "端口" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "用户名" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "密码" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "超时" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "账户到期时间" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "保存期限" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "到服务器的安全连接" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "证书验证" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "最小:启动 SSL 时,使用服务器自己的证书来验证身份。严格:验证并强制 hostname 一致。" #: sabnzbd/skintext.py msgid "Disabled" msgstr "禁用" #: sabnzbd/skintext.py msgid "Minimal" msgstr "最小" #: sabnzbd/skintext.py msgid "Strict" msgstr "严格" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 为最高优先级,100 为最低优先级" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "可选" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "对于不稳定的服务器,在失败后将会被忽略更长的时间" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "启用" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "移除服务器" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "测试服务器" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "清除统计" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "正在测试服务器详细情况..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "带宽" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "注释" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "添加定时任务" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "频率" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "动作" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "参数" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "当前定时任务" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "需要勾选 feed 名称旁边的复选框才能启用并自动检查新项。
添加 feed 后,它将只选取新项目,而不选取已经处于 RSS feed " "当中的项,除非您按“强制下载”。" #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "以逗号来分开多个链接" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "读取 Feed" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "强制下载" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "应用过滤器" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "编辑" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "序号" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "类型" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "过滤器" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "接受" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "否决" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "需要" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "需要分类" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "至少" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "至多" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "来自 SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "来自剧目 SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "已匹配" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "未匹配" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "已下载" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "立即读取全部 Feed" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "任务完成 Email 通知" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "从不" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "总是" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "仅当发生错误时" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "磁盘已满通知" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "磁盘已满、SABnzbd 暂停时发送 email。" #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "发送 RSS 通知" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "RSS feed 添加任务到队列时发送 email。" #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP 服务器" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "设为您 ISP 的 email 出站服务器。" #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Email 收件者" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "发送 email 的目标电子邮箱地址。" #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Email 发送者" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "我们应该说是谁发送了这封 email?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "*可选* 账号用户名" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "email 身份认证所用的账号名称。" #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "*可选* 账号密码" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "email 身份认证所用的密码。" #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "通知已发送!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "启用NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "通知中心" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "启用 Windows 通知" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "屏显通知" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "启用 Prowl 通知" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "需要 Prowl 账号" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Prowl 的 API 密钥" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Prowl 的个人 API 密钥 (必填)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "启用 Pushover 通知" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "需要 Pushover 账号" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "应用程序 token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "应用程序令牌 (必填)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "用户 key" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "用户密钥 (必填)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "设备" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "信息发送的目标设备" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "启用 Pushbullet 通知" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "需要 Pushbullet 账号" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "个人 API key" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "您自己的 Pushbullet API key (必填)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "设备" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "信息发送的目标设备" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "通知脚本" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "启用通知脚本" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "执行自定义脚本" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "应该执行哪个脚本来发出通知?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "索引可以在 NZB 文件中提供分类信息,SABnzbd 会尝试在以下分类中匹配。另外,您可以在 \"索引 Categories / Groups\" " "中添加关键词来匹配更多的分类。使用逗号来分开关键词,关键词中可使用通配符。
你可以在维基中查看更多的相关信息。" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "路径末尾加上星号 * 可避免创建任务文件夹。" #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "基于相对文件夹" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "文件夹/路径" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "索引 Categories / Groups" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "匹配符释义" #: sabnzbd/skintext.py msgid "Clear" msgstr "清除" #: sabnzbd/skintext.py msgid "Presets" msgstr "预设" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "影响分类" #: sabnzbd/skintext.py msgid "Meaning" msgstr "释义" #: sabnzbd/skintext.py msgid "Pattern" msgstr "匹配" #: sabnzbd/skintext.py msgid "Result" msgstr "结果" #: sabnzbd/skintext.py msgid "Title" msgstr "标题" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "影片 名称" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "影片.名称" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "影片_名称" #: sabnzbd/skintext.py msgid "Show Name" msgstr "节目 名称" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "节目.名称" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "节目_名称" #: sabnzbd/skintext.py msgid "Season Number" msgstr "季数" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "集数" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "集 名" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "集.名" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "集_名" #: sabnzbd/skintext.py msgid "Extension" msgstr "扩展名" #: sabnzbd/skintext.py msgid "Part Number" msgstr "分段号" #: sabnzbd/skintext.py msgid "Decade" msgstr "年代" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "原始文件名" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "大小写" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py msgid "text" msgstr "text" #: sabnzbd/skintext.py msgid "file" msgstr "文件" #: sabnzbd/skintext.py msgid "Sort String" msgstr "排序字串" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "分文件夹" #: sabnzbd/skintext.py msgid "No folders" msgstr "不分文件夹" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "大小写已调整" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "处理结果" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "全部" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "极少用到的选项。要获取其含义及解释,请点击“帮助”按钮访问 Wiki 页面。
在查看 Wiki " "之前请不要更改这些选项,它们会有很严重的副作用。
括号中为默认值。" #: sabnzbd/skintext.py msgid "Values" msgstr "值" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "编辑 NZB 详情" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "删除" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "文件名" #: sabnzbd/skintext.py msgid "Free Space" msgstr "剩余空间" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "临时文件夹" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "多选操作" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "按 shift 键可选择范围" #: sabnzbd/skintext.py msgid "Check all" msgstr "全选" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "重新启动 SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "队列完成时" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "状态与界面选项" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "或将文件拖拽到本窗口!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "失去与 SABnzbd 的连接.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "SABnzbd 重启后本画面将自动消失!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "警告:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "装取" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Web 界面" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "刷新频率" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "使用全局界面设置" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "队列数目限制" #: sabnzbd/skintext.py msgid "History item limit" msgstr "历史数目限制" #: sabnzbd/skintext.py msgid "Date format" msgstr "日期格式" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "页" #: sabnzbd/skintext.py msgid "Loading" msgstr "正在加载" #: sabnzbd/skintext.py msgid "articles" msgstr "篇文章" #: sabnzbd/skintext.py msgid "Rename" msgstr "重命名" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "队列修复" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "显示活动连接" #: sabnzbd/skintext.py msgid "Unblock" msgstr "解封" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "孤立任务" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "发回队列" #: sabnzbd/skintext.py msgid "Delete All" msgstr "全部删除" #: sabnzbd/skintext.py msgid "Retry all" msgstr "全部重试" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "从 URL 装取 NZB" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "上传 NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "可以选择指定文件名" #: sabnzbd/skintext.py msgid "Submit" msgstr "提交" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "移除已选文件" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "隐藏/显示已完成文件" #: sabnzbd/skintext.py msgid "Top" msgstr "置顶" #: sabnzbd/skintext.py msgid "Bottom" msgstr "置底" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "查看脚本日志" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "您的浏览器已禁用 LocalStorage (cookies)。界面设置将在您关闭浏览器后丢失!" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "你可能会喜欢一些 Glitter 的(新)功能!" #: sabnzbd/skintext.py msgid "Custom" msgstr "自定义" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "精简外观" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "标签化外观
(分别显示队列与历史记录)" #: sabnzbd/skintext.py msgid "Speed" msgstr "速度" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "确认队列删除" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "确认历史删除" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "您希望在多久之后/什么时候暂停? (用英语作答!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "抱歉,无法理解您的输入。请重试。" #: sabnzbd/skintext.py msgid "Pause for..." msgstr "暂停..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "刷新" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "按发布时间排序 最早→最新" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "按发布时间排序 最新→最早" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "按名称排序 A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "按名称排序 Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "按尺寸排序 最小→最大" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "按尺寸排序 最大→最小" #: sabnzbd/skintext.py msgid "Uploading" msgstr "正在上传" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "正在强制断开连接" #: sabnzbd/skintext.py msgid "Removing job" msgstr "正在移除任务" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "正在移除任务" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd 快速上手向导" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd 版本" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "上一步" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "后" #: sabnzbd/skintext.py msgid "Server Details" msgstr "服务器详情" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "请输入您的主 usenet 提供商的详细信息。" #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "提供商所允许的连接数" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "如 8 或 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "仅当您的服务商允许 SSL 连接时选择。" #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "点击可测试所输入的信息。" #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "如" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "设置完成!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd 将在后台运行。" #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "关闭浏览器窗口/标签页 *不会* 导致 SABnzbd 关闭。" #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "建议您右击鼠标并将该链接加入书签以便在 SABnzbd 在后台运行时访问它。" #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "更详尽的帮助可以在我们的网站上找到" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "转到 SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "退出 SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "启动向导" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd *不负任何担保责任*。\n" "这是一款自由软件,欢迎您在约定的条件下传播。\n" "本软件依 GNU GENERAL PUBLIC LICENSE 第 2 版或 (若您愿意) 任意较新版本授权。\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "重命名相似文件失败: %s 为 %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "未授权访问" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "服务器上无此文件" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "服务器无法完成请求" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "*URLGRABBER 已崩溃*" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "不可用的 NZB 文件" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "URL 装取失败; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "正在尝试从 %s 装取 NZB" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2115798 SABnzbd-4.3.2/po/main/en.po0000644000000000000000000001012514625637207014526 0ustar00runnerstaff# English corrections for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-07-04 10:12+0000\n" "PO-Revision-Date: 2015-07-04 12:26+0000\n" "Last-Translator: shypike \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Pause low prioirty jobs" msgstr "Pause low priority jobs" msgid "Pause normal prioirty jobs" msgstr "Pause normal priority jobs" msgid "Pause high prioirty jobs" msgstr "Pause high priority jobs" msgid "Resume low prioirty jobs" msgstr "Resume low priority jobs" msgid "Resume normal prioirty jobs" msgstr "Resume normal priority jobs" msgid "Resume high prioirty jobs" msgstr "Resume high priority jobs" msgid "" " 
SABnzbd shutdown finished.
Wait for about 5 second and then " "click the button below.

Refresh
" msgstr "" " 
SABnzbd shutdown finished.
Wait for about 5 seconds and then " "click the button below.

Refresh
" msgid "Retry all failed" msgstr "Retry All Failed" msgid "disable server" msgstr "Disable server:" msgid "enable server" msgstr "Enable server:" msgid "The server didn't reply properly to the helo greeting" msgstr "The server didn't reply properly to the hello greeting" msgid "API Key missing, please enter the api key from Config->General into your 3rd party program:" msgstr "API key missing, please enter the API key from Config->General into your 3rd party program:" msgid "API Key incorrect, Use the api key from Config->General in your 3rd party program:" msgstr "API key incorrect, Use the API key from Config->General in your 3rd party program:" msgid "HTTPS Chain Certifcates" msgstr "HTTPS Chain Certificates" msgid "Replace Spaces in Foldername" msgstr "Replace spaces in folder name" msgid "Replace dots in Foldername" msgstr "Replace dots in folder name" msgid "How long or untill when do you want to pause? (in English!)" msgstr "How long or until when do you want to pause? (in English!)" msgid "Timeleft" msgstr "Time left" msgid "Optionally specify a filename" msgstr "Optionally specify a name" msgid "Confirm Queue Deletions" msgstr "Confirm queue deletions" msgid "Confirm History Deletions" msgstr "Confirm history deletions" msgid "System Performance (Pystone)" msgstr "System performance (Pystone)" msgid "Web Interface" msgstr "Web interface" msgid "Script returned exit code %s and output \"%s\"" msgstr "Notification script returned exit code %s and output \"%s\"" msgid "If empty, the standard port will only listen to HTTPS." msgstr "If empty, the SABnzbd Port set above will listen to HTTPS." msgid "Posts will be paused untill they are at least this age. Setting job priority to Force will skip the delay." msgstr "Posts will be paused until they are at least this age. Setting job priority to Force will skip the delay." msgid "Support the project, Donate!" msgstr "Support the project, donate!" msgid "User script can flag job as failed" msgstr "Post-processing script can flag job as failed" msgid "When the user script returns a non-zero exit code, the job will be flagged as failed." msgstr "When the post-processing script returns a non-zero exit code, the job will be flagged as failed." msgid "unrar binary... NOT found" msgstr "unrar binary... NOT found!" msgid "Downloads will not unpacked." msgstr "Downloads will not be unpacked." msgid "Seperate multiple URLs by a comma" msgstr "Separate multiple URLs with a comma" msgid "Advanced" msgstr "Advanced Settings" msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 is highest priority, 99 is the lowest priority" msgid "Filter out sample files (e.g. video samples)." msgstr "Filter out sample files (e.g. video samples/proofs)." msgid "Pre-queue user script" msgstr "Pre-queue script"././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2165842 SABnzbd-4.3.2/po/main/sv.po0000644000000000000000000033326014625637207014564 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Varning" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Fel" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Det gick inte att starta webbgränssnittet" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Hittar inte webbmall: %s, försöker med standardmall" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 binär... EJ funnen!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "Din UNRAR version är %s, vi rekommenderar version %s eller högre.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar binär... EJ funnen!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za binär... EJ funnen!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Tänk på att värdnamnet 0.0.0.0 behöver en IPv6-adress för extern åtkomst" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP och HTTPS portar kan inte vara likadana" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Avaktiverade HTTPS då CERT och KEY -filer saknas" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Misslyckades att starta webbgränsnitt: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s startad" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd nedstängning utförd." #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s mottagen, sparar och stänger..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Kritiskt fel vid sparande av läge" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "E-mail sändning lyckades" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Testa notifikation" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Adressen är inte angiven." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" "Inga anslutningar är aktiverade. Var vänlig aktivera minst en anslutning." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Lösenordet är dolt med ******, försök igen" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Ogiltiga serverdetaljer" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradressen \"%s:%s\" är ej giltig." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Timeout: Försök aktivera SSL eller anslut via en annan port." #: sabnzbd/api.py msgid "Timed out" msgstr "Timeout" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Servern kräver användarnamn och lösenord." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Anslutning lyckades!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Autentisering misslyckades, kontrollera användarnamn och lösenord." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "För många anslutningar, pausa en nedladdning eller försök igen senare" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Det gick inte att ansluta (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Lösa adress" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ingen" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Standard" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disken är full! Pausar..." #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Diskfel vid skapande av fil %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Kritiskt fel i Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "För lite diskutrymme pausar systemet" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Avbruten, kryptering detekterad." #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Oönskad filändelse i RAR-fil %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Avbruten, oönskad filändelse detekterad" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Din kvot är uppnådd, pausar nerladdning" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Fel parameter" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s är inte en godkänd e-mail adress" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Kräver serveradress" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Ogiltig serveradress" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s är inte rätt siffervärde" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Kön är inte tom, kan inte byta mapp." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Kan inte skriva till INI filen %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Kan inte skapa backup-fil för %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Felaktigt kodat lösenord %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "Kan inte skriva till historikdatabasen, kontrollera åtkomsträttigheter!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Skadad hitsotrikdatabas, skapade en tom ersättare" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL Kommando misslyckades, se logg" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Det gick inte att stänga databasen, se logg" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Felaktig loggning i historiken av %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Okänt fel under avkodning av %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Färdig" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Uppackad %s filer/mappar i %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Kan ej läsa övervakad mapp %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Fortsätter" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Pausad" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "Du måste ange maximal bandbredd innan du kan ange bandbreddsgräns" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Kan ej ansluta till server %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Servernamn kunde inte läsas" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s kommer att ignoreras i %s minuter" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Misslyckades att initiera %s@%s med orsak %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "För många anslutningar till servern %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Det gick inte att logga in på server %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Anslutning %s@%s misslyckades, meddelande=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Misstänker fel i nedladdare" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Påbörjar nedstängning av SABnzbd.." #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Det gick inte att ansluta till mailserver" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Det gick inte att initialisera TLS anslutning" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Servern svarade inte ordentligt till hälsningen" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Autentisering till mailserver misslyckades" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Ingen passande autentikationsmetod hittades" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Okänd autentikationmisslyckande i mailservern" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Det gick inte att skicka e-mail" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Det gick inte att stänga e-mail anslutning" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Kunde inte skicka, saknar nödvändig data" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Kan ej finna e-mail mallar i %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Ingen mottagare angiven, ingen e-post har skickats" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Kan ej läsa %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Inga e-postmallar funna" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Till: %s\n" "Från: %s\n" "Datum: %s\n" "Ämne: SABnzbd rapporterar att disk är full\n" "\n" "Hej,\n" "\n" "SABnzbd har stoppat nerladdningen på grund av att din disk inte har tillräckligt med utrymme kvar.\n" "Frigör utrymme och återuppta nerladdningen manuellt.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Kan ej skapa mapp %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s mapp: %s åtkomst misslyckad" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Det gick inte att ändra rättigheter på %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Skapande av (%s) misslyckades" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Det gick inte att flyta %s till %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Fel i tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Sparar %s misslyckades" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Laddning av %s misslyckades" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API-nyckel saknas, skriv in api-nyckeln från Konfiguration-> Allmänt i ditt " "tredjepartsprogram:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-nyckel felaktig, använd api-nyckeln från Konfiguration-> Allmänt i ditt " "tredjepartsprogram:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Flöde" #: sabnzbd/interface.py msgid "Daily" msgstr "Dagligen" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Måndag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Tisdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Onsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Torsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Fredag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Lördag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Söndag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "av" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Odefinerad server!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "FEL:" #: sabnzbd/interface.py msgid "Back" msgstr "Bakåt" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Uppdatering tillgänglig" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Det gick inte att skapa SSL-nyckel eller certifikat." #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Seriesortering" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Datum sortering" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Kör skript" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Nästling för djup [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Slår ihop" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Ej komplett sekvens av filer för ihopläggning" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Filsammanslagning av %s misslyckades" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fel \"%s\" under filsammanslagning" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Fel \"%s\" när du kör file_join på %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Slår ihop %s filer" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Uppackning misslyckades, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fel \"%s\" under uppackning av RAR fil(er)" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fel \"%s\" när du kör rar_unpack på %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Borttagning av %s misslyckades!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Försöker att packa upp med lösenord %s" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Packar upp" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Uppackning misslyckades, gick inte att hitta %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Uppackning misslyckades, CRC-fel" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Uppackning misslyckades, skrivfel eller disken full?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Uppackning misslyckades, sökvägen är för lång" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Uppackning misslyckades, arkivet kräver lösenord" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Oanvändbar RAR-fil" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Provar 7zip med lösenord \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "se loggfil" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Snabbkontrollerar" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparera" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Snabbkontroll OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Startar reparation" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparation misslyckades, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Fel %s när du kör par2_repair på %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fel \"%s\" medans par2_repair kördes på %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 har fått felaktiga alternativ, ändra dessa via Config->Switches " "inställningarna" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verifierad i %s, alla filer är ok" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verifiering i %s, kräver reparation" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Hämtar %s block..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Hämtar" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Misslyckad reparation, finns ej tillräckligt med reparationsblock (%s " "saknas)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Reparerar" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Reparerad i %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Disken är full" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Verifierar" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Kontrollerar" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Försöker verifiera SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "kvar" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Den här servern tillåter in SSL på denna port" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Starta/Stäng" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pausa" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Återuppta" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB tillagd" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Efterbehandling påbörjad" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Arbetet utförd" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Jobb misslyckades" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Kön färdig" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Andra meddelanden" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Öppna färdig mapp" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Ej tillgänglig" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Misslyckades att skicka Prowlmeddelande" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Dålig respons från Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Misslyckades att skicka pushovermeddelande" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Dålig respons från Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Misslyckades att skicka pushbulletmeddelande" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Kan inte skapa temp -fil för %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Det gick inte att lägga till %s, tar bort" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Fel vid borttagning av %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Det gick inte att importera %s filer från %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Felaktig köfil funnen, kan ej fortsätta" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Laddningsfel %s, felaktig fil detekterad" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB tillagd i kön" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorerar dubblett för NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "NZB filen %s är tom" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Avbrutet, kan inte slutföras" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Det gick inte att importera %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUBLETT" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "KRYPTERAT" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "FÖR STOR" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "INKOMPLETT" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "OÖNSKAD" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "VÄNTA %s SEKUNDER" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Hämtade i %s vid ett genomsnitt på %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Ålder" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artiklar var felaktiga" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artiklar saknades" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artiklar hade icke-matchande dubletter" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Pausar dubblett för NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Varningar" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Inaktiv" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Kö" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Rensa kö" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historik" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Töm historik" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Hastighetsbegränsning" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "min" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Scanna bevakad mapp" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Läs alla RSS-flöden" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Färdig mapp" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Ofullständig mapp" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Felsök" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Starta om" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Starta om utan login" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Avsluta" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Kö (10 första sakerna)" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Tom" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Historik (10 senaste sakerna)" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Gå till guiden" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Stänger..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problem med" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd behöver en ledig tcp/ip -port för sin interna webbserver.
\n" " Port %s på %s testades , men den är inte tillgänglig.
\n" " Någon annan applikation använder porten eller så körs redan SABnzbd.
\n" "
\n" " Vänligen starta om SABnzbd med ett annat portnummer." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Om du får detta felmeddelande igen, var vänlig försök med en annan " "siffra.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd behöver en giltig värdadress för dess interna webbserver.
\n" " Du har specifierat en ogiltig adress.
\n" " Säkra värdadresser är localhost och 0.0.0.0
\n" "
\n" " Var vänlig starta om SABnzbd med en giltig värdadress." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd har upptäckt sparad data från en annan version av SABnzbd
\n" " men kan inte återanvända datan från det andra programmet.

\n" " Färdigställ dina nedladdningar med det andra programmet först.

\n" " Därefter kan du starta det här programmet med alternativet \"--clean\".
\n" " Detta kommando kommer att ta bort din nuvarande kö och historik!
\n" " SABnzbd read the file \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd kan inte hitta webbgränssnittets filer i %s.
\n" " Var vänlig installera om programmet.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd upptäckte ett allvarligt fel:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd upptäckte att filen sqlite3.dll saknas.

\n" " Det händer att bristfälligt designade virusprogram tar bort denna fil.
\n" " Var vänlig kontrollera ditt virusprogram, försök installera om SABnzbd och klaga till din återförsäljare.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Tryck på Startknappen+R och skriv raden (exempel):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Öppna ett Terminal-fönster och skriv raden (exempel):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Programmet startade inte!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Allvarligt fel" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Kan inte starta webbläsaren, hittades troligtvis inte" #: sabnzbd/panic.py msgid "Access denied" msgstr "Åtkomst nekades" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Error %s: Du måste ange ett giltigt användarnamn och lösenord." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Gammal kö hittad, använd Status -> Reparera för att konvertera kön" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Det gick inte att kompilera regex för sök-sträng: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Nerladdningen kan misslyckas, bara %s av krävda %s finns tillgängligt" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Nerladdning misslyckades - Inte på din server eller servrar" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Efterbehandling" #: sabnzbd/postproc.py msgid "Moving" msgstr "Flyttar" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Skickat %s till kö" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Det gick inte att döpa om \"%s\" till \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Misslyckades med att flytta filer" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Kör användarskript %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Skriptets utgångskod är %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Körde %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Mer" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Efterbehandling misslyckades för %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Hämtning misslyckades" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Rensning av %s misslyckades." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Hämtningen slutfördes" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Kan inte skapa slutgiltig mapp %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Ingen par2 sats" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Some files failed to verify against \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Verifieringen lyckades med SFV-filer" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Lösenordskyddad" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Borttagning av %s misslyckades" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Kunde inte sätta systemet i vänteläge" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Det gick inte att sätta systemet i viloläge" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Fel uppstod då systemet skulle stängas" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Felaktigt RSS-flödesbeskrivning \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Har inte giltig autentisering för flöde %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Server fel (serverkod %s); kunde inte få %s på %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Det gick inte att hämta RSS flödet från %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Server %s använder ett otillförlitlig HTTPS-certifikat" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS-flödet %s var tomt" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Inkompatibel feed" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Tom RSS post hittades (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Visa gränssnitt" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pausa för" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pausa 5 minuter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pause 15 minuter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pausa 30 minuter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pausa 1 timme" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pausa 3 timmar" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pausa 6 timmar" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Stäng Av" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Återstår" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Lägg till NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Fel schema %s vid %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Okänd åtgärd: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Schema för icke existerande server %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Försöker att sätta status på icke existerande server %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Nedladdning" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Slår ihop filer" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Packa upp" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Skript" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Källa" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servrar" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Misslyckades" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Väntar" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Reparerar..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Extraherar..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Flyttar..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Kör skript..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Hämtar extra block..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Snabbkontroll..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Verifierar..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "avaktivera server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "aktivera server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Hastighetsgräns" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pausa Allt" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pausa efterbehandla" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Återuppta efterbehandla" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Läs RSS-flöden" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Ta bort misslyckade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Ta bort färdiga jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pausa lågprioriterade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pausa normalprioriterade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pausa högprioriterade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Återuppta lågprioriterade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Återuppta normalprioriterade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Återuppta högprioriterade jobb" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Aktivera kvothantering" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Avaktivera kvothantering" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Av" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Mycket låg" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Medel" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Hög" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Nödfall" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Låg" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "timme" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "timmar" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minuter" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sek" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "sekunder" #: sabnzbd/skintext.py msgid "day" msgstr "dag" #: sabnzbd/skintext.py msgid "days" msgstr "dagar" #: sabnzbd/skintext.py msgid "week" msgstr "vecka" #: sabnzbd/skintext.py msgid "Month" msgstr "Månad" #: sabnzbd/skintext.py msgid "Year" msgstr "År" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Månadsdag" #: sabnzbd/skintext.py msgid "This week" msgstr "Denna vecka" #: sabnzbd/skintext.py msgid "This month" msgstr "Denna månad" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "I dag" #: sabnzbd/skintext.py msgid "Total" msgstr "Totalt" #: sabnzbd/skintext.py msgid "on" msgstr "den" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametrar" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python-version" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Webbplats" #: sabnzbd/skintext.py msgid "or" msgstr "eller" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Adress" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Avbryt" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Spara" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Sparar.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Är du säker?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Hem" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Konfiguration" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Status" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Hjälp" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Donera och stöd detta projekt!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Allmänt" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Mappar" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Switchar" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Schemaläggare" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Meddelanden" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "E-post" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategorier" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sortering" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Speciell" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Sök" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Är du säker på att du vill stänga av SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Lägg till" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategori" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioritet" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparera" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Packar upp" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Ta bort" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Tvinga" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Stopp" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Ange URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Stäng av PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Sparläge PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Viloläge PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Stäng av SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Bearbetar" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Namn" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Försök igen" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Skript" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Ta bort alla saker från kön?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Rensa NZB:er" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Rensa NZB:er och ta bort filer" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Ta bort NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Ta bort NZB och filer" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Saknade artiklar" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Kvot kvar" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manuell" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Återställ Kvot nu" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Göm detaljer" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Visa detaljer" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Visa Misslyckade" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Visa alla" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Storlek" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Rensa Misslyckade NZB:er." #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Rensa Misslyckade NZB:er och ta bort filer" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Rensa färdiga NZB:er" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Valfri Kompletterande NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Sökväg" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Starta om alla misslyckade jobb" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Tvinga frånkoppling" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Detta kommer att skicka ett test e-mail till ditt konto." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Visa logg" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Testa E-post" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Loggning" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Fel/Varning" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Debug" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Anslutningar" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Artikel-ID" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Filuppsättning" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Aktiverad" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Anslutning misslyckades!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokal IPv4 adress" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Publik IPV4 adress" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6-adress" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Namnserver /DNS Lookup" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Systemprestanda (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Nerladdningsmapphastighet" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Komplett mapphastighet" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Gör om test" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Konfig fil" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Använt cache" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Detta kommer att starta om SABnzbd.
Använd det när du tror att " "programmet har stabilitetsproblem.
Nerladdningar kommer att pusas innan" " omstarten och återupptas efteråt." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Det finns övergivna jobb i nedladdningsmappen.
Du kan välja mellan att " "radera dem (inklusive filer) eller skicka tillbaka dem i kön." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Ändringarna har inte sparats och kommer att försvinna." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Aktivera 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Version" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Upptid" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Säkerhetskopiera" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Läs Wiki Help för detta!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Startar om SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Ändringar kräver omstart av SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd Webbserver" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd Adress" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Adress som SABnzbd ska lyssna på." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd-port" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Port som SABnzbd ska lyssna på." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd Användarnamn" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Väljbart autentiserings användarnamn." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd Lösenord" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Väljbart autentiserings lösenord." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "HTTPS Aktivera" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Aktivera åtkomst till webbkontrollen med HTTPS adress." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS-port" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Om tom kommer standardporten endast lyssna till HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS Certifikat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Filnamn eller sökväg till HTTPS Certifikat." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS Nyckel" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Filnamn eller sökväg till HTTPS Nyckel." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS-kedjecertifikat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Filnamn eller sökväg till HTTPS-kedja" #: sabnzbd/skintext.py msgid "Tuning" msgstr "Optimering" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS Uppdateringsintervall" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Kontrollintervall (i minuter, minst 15). Ej aktiv om du använder " "Schemaläggaren!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maximal linjehastighet" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Procent av linjehastighet" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "Vilken procent av linjehastigheten ska SABnzbd använda, te.x 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Cachestorlek för artiklar" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Sparar artiklar i minnet för att reducera diskåtkomst.
I bytes, " "följt av K,M,G. Till exempel: \"64M\" eller \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Rensa lista" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Lista av filändelser som skall bli borttagna efter nerladdning.
Till " "exempel: nfo or nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Spara ändringar" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Återställ" #: sabnzbd/skintext.py msgid "Language" msgstr "Språk" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Välj språk till webbkontrollen." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "API-nyckel" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Denna nyckel ger tredjepartsprogram full tillgång till SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB-nyckel" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Denna nyckel ger tredjepartsprogram möjlighet att lägga till NZB:er i " "SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Generera Ny Nyckel" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API- eller QR-kod" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Extern internetåtkomst" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Ingen åtkomst" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Lägg till NZB-filer " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (ingen Konfigurering)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Full API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Fullt Webgränsnitt" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "OBS: Mappar kommer att skapas automatiskt när du Sparar. Du måste " "ange exakta sökvägar till dina mappar för att spara utanför " "standardmapparna." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Användarmappar" #: sabnzbd/skintext.py msgid "Browse" msgstr "Bläddra" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Temporär nedladdningsmapp" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Plats för att lagra ej bearbetade nedladdningar.
Kan endast ändras " "när kön är tom." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimal fri plats för temporär nedladdningsmapp" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pausa när fri plats är nära sin gräns.
I bytes, följt av " "K,M,G,T. Till exempel: \"800M\" or \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Färdig nedladdningsmapp" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Plats för att lagra bearbetade och färdiga nedladdningar.
Kan " "åsidosättas av användar-definierade kategorier." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Autoåterupptagning" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Rättigheter för färdiga nedladdningar" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Sätt rättigheter för färdiga filer och mappar.
Använd siffror. Till " "exempel: \"755\" or \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Övervakad Mapp" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Mapp som igenomsöks automatiskt efter .nzb filer." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Skanningsintervall för Övervakade mappar" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Sekunder mellan skanningar för .nzb filer." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Mapp för E-mail mallar" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Mapp som innehåller användar-definierade e-mail mallar." #: sabnzbd/skintext.py msgid "Password file" msgstr "Lösenordsfil" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fil som innehåller alla lösenord som ska prövas på krypterade RAR-filer." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Systemmappar" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Administrativ mapp" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Plats för köadministration och historiedatabas.
Kan bara ändras när " "kön är tom." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "Data kommer inte tas bort. Kräver omstart av SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Loggmapp" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Plats för sparade loggfiler från SABnzbd.
Kräver omstart av " "SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr ".nzb Reservmapp" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Plats där .nzb filer sparas." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Standard basmapp" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Ladda ner alla par2 filer" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Aktivera rekursiv uppackning" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Packa upp arkiv (rar,zip,7z) inuti arkiven." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignorera alla mappar i arkiven" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Alla filer kommer hamna i en mapp." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Bara artiklarna för början av kön" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Aktivera för lägre minnesanvändning. Avaktivera för att förhindra långsamma " "jobb att blockera kön." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Efterbehandla endast verifierade jobb" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Händelse när krypterade RAR är nerladdad" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "Om \"Pausad\", så behöver du ange ett lösenord för att återuppta jobbet." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Kasta" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Händelse när oönskad filändelse hittad" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Oönskade filändelser" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Använd SFV-baserade kontroller" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Gör en extra kontroll med SFV filer" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Användarskript kan flagga jobb som misslyckat" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "När ett användarskript returnerar ett icke-nollutgångsvärde, så kommer " "jobbet att flaggas som misslyckat" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Döp om mappar" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Använd temporära namn under efterbehandling. Avslaget när ditt system inte " "stöder det." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Kö-specifika användarskript" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Används innan en NZB tas in i kön." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Extra PAR2 parametrar" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Bra parametrar" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "IONice parametrar" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Koppla ifrån när kön är tom" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Koppla ifrån usenet servrarna när kön är tom eller pausad." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Kolla efter ny utgåva" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Även testutgåvor" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Ersätt mellanslag i mappnamn" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Ersätt mellanslag med understreck i mappnamn." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Ersätt punkter i mappnamn" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Ersätt punkter med mellanslag i mappnamn" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Gör Windows-kompatibel" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "För servrar: Gör att namn är kompatibla med Windows." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Starta webbläsare vid uppstart" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Startar standard webbläsaren när SABnzbd startar." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Pausa nedladdning under efterbehandling" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Pausas nedladdning när efterbehandling börjar och återupptar nedladdning när" " efterbehandling är klar." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignorera Sample-filer" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Filtrera ut sample-filer (ex. video samplingar)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Ta bort efter nedladdning" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Server" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Efterbehandling" #: sabnzbd/skintext.py msgid "Naming" msgstr "Döpning" #: sabnzbd/skintext.py msgid "Quota" msgstr "Kvot" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Hur mycket kan laddas ner denna månad (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Nollställ dag" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "På vilken dag i månaden eller veckan (1=Måndag) nollställer din ISP din " "kvot? (Alternativt med hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Skall nerladdning återupptas efter att kvot är nollställd?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Kvotperiod" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Nollställs kvoten varje dag, vecka eller månad?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Kontrollera innan nerladdning" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Försök att förutspå lyckad överföring innan nerladdningen påbörjas " "(saktare!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Max antal omförsök" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Max antal omförsök per server" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Avbryt jobb som inte kan kompletteras" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Under nerladdning och det märks att för mycket data saknas, avbryt jobbet" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Lägg till server" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Serverbeskrivning" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Användarnamn" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Lösenord" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Tidsgräns" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Retensionstid" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Avaktiverad" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 är högst prioritet, 99 är lägst prioritet" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Valfri" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Aktivera" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Ta bort server" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Testserver" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Nollställ räknare" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Testar serverdetaljer..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Bandbredd" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Personliga noteringar" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Lägg till schema" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Förekomst" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Åtgärd" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argument" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Aktuella scheman" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Kryssrutan bredvid flödesnamnet ska aktiveras för att flödet automatiskt ska" " kontrolleras för nya objekt.
När ett flöde läggs till kommer det bara " "att välja nya objekt och inte allt som redan finns i RSS-flöded så länge du " "inte klickar på \"Tvinga nedladdning\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Läs flöde" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Tvinga nedladdning" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Ordning" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Typ" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Acceptera" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Avvisa" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Kräver" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "KräverKat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Minst" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Högst" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Från SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Matchade" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Inte Matchade" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Nedladdad" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Läsa Alla Flöden Nu" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "E-post notifiering när jobb är slutfört" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Aldrig" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Alltid" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Bara vid fel" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Full hårddisk notifiering" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Skicka e-mail när hårddisken är full och SABnzbd har pausat." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Skicka RSS-notiser" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Skicka E-post när ett RSS-flöde lägger till jobb till kön." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP-server" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Ställ in din ISP's server för utgående e-mail." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "E-post mottagare" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "E-postadress att skicka e-post till." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "E-post avsändare" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Vem ska vi skicka e-posten från?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "VALFRITT Kontoanvändarnamn" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Användarnamn för e-post som kräver autentisering." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "VALFRITT Användarlösenord" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Lösenord för e-post som kräver autentisering." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Notis skickad!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Aktivera NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Meddelandecenter" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Aktivera Windows-notiser" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows-notiser" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Aktivera Prowl-notiser" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Kräver ett Prowl-konto" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "API-nyckel för Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Personlig API-nyckel för Prowl (krävs)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Aktivera Pushover-notiser" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Kräver ett Pushover-konto" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Applikations Token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Applikations token (krav)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Användarnyckel" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Användarnyckel (krävs)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Enhet(er)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Enhet(er) där medellandet skall skickas" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Aktivera Pushbullet-notiser" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Kräver ett Pushbullet-konto" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Personlig API-nyckel" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Din personliga API-nyckel (krävs)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Enhet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Enheter där meddelande skall skickas" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Avsluta sökvägen med en asterisk * kommer förhindra jobb att skapa mappar" #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Relativa mappar är baserade på" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Mapp/Sökväg" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Hjälp till Sorteringssträng" #: sabnzbd/skintext.py msgid "Clear" msgstr "Rensa" #: sabnzbd/skintext.py msgid "Presets" msgstr "Förinställningar" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Påverkade kategorier" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Betyder" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Mönster" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Film Namn" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Film.Namn" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Film_Namn" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Show Namn" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Show.Namn" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Show_Namn" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Säsongsnummer" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Episodnummer" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Episodnamn" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Episod.Namn" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Episod_Namn" #: sabnzbd/skintext.py msgid "Extension" msgstr "Filändelse" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Delnummer" #: sabnzbd/skintext.py msgid "Decade" msgstr "Årtionde" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Originalfilnamn" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Små bokstäver" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py msgid "text" msgstr "text" #: sabnzbd/skintext.py msgid "file" msgstr "fil" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Sorteringssträng" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "In mapp" #: sabnzbd/skintext.py msgid "No folders" msgstr "Ingen mapp" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "versal-justerade" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Hanterade resultat" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Alla" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Sällan använda inställningar. För deras mening och förklaring, klicka på " "Hjälpknappen för att komma till Wiki-sidan.
Ändra inte dessa utan att " "kolla med Wiki först, då vissa kan ha seriösa " "sidoeffekter.
Standardvärdet är mellan paranteser." #: sabnzbd/skintext.py msgid "Values" msgstr "Värden" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Ändra NZB detaljer" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Ta bort" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Filnamn" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Ledigt diskutrymme" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Temporär Mapp" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Multi-operationer" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Håll in shiftknappen för att välja omfång" #: sabnzbd/skintext.py msgid "Check all" msgstr "Markera alla" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Starta om SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "När kön är färdig" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Status och gränsnittsinställningar" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Eller dra och släpp filer i fönstret!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Förlorade förbindelse till SABnzbd.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "Om SABnzbd startar om kommer denna skärm att försvinna automatiskt!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "VARNING:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Hämta" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Webbkontrollsutseende" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Uppdateringsfrekvens" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Använda globala gränsnittsinställningar" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Kö artikelgräns" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Historik artikelgräns" #: sabnzbd/skintext.py msgid "Date format" msgstr "Datumformat" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "sida" #: sabnzbd/skintext.py msgid "Loading" msgstr "Laddar" #: sabnzbd/skintext.py msgid "articles" msgstr "artiklar" #: sabnzbd/skintext.py msgid "Rename" msgstr "" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Köreparation" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Visa aktiva anslutningar" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Ta bort blockering" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Övergivna jobb" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Skicka tillbaka i kön" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Ta bort alla" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Starta om alla" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Hämta NZB från URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Ladda upp NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Alternativt ange ett filnamn" #: sabnzbd/skintext.py msgid "Submit" msgstr "Skicka" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Ta bort alla markerade filer" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Visa/göm färdiga filer" #: sabnzbd/skintext.py msgid "Top" msgstr "Topp" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Botten" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Visa skriptlogg" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Anpassa" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Hastighet" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Bekräfta Kö-borttagningar" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Bekräfta Historik-borttagningar" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Hur lång tid eller tills då vill du pausa? (på engelska!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Tyvärr, vi kunde inte tolka det. Försök igen." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pausa i..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Uppdatera" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sortera efter ålder Äldst→Nyast" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sortera efter ålder Nyast→Äldst" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sortera efter namn A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sortera efter namn Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sortera efter storlek Minst→Störst" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sortera efter storlek Störst→Minst" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Snabbstart Guide" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd Version" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Föregående" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Nästa" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Serveruppgifter" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Fyll i uppgifter om din primära usenet leverantör." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Antalet anslutningar som tillåts av din leverantör" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Te.x 8 eller 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Välj bara om din leverantör tillåter SSL-anslutningar." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Klicka här för att testa dina angivna serveruppgifter." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "T.ex." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Installationen är nu utförd!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd kommer nu att köras i bakgrunden." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "SABnzbd kommer inte att stängas av om du stänger ett fönster eller en tab i " "webbläsaren." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Det är rekommenderat att du sparar denna plats som ett bokmärke för att " "komma åt SABnzbd när det körs i bakgrunden." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Övrig hjälp kan du hitta på våran" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Gå till SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Avsluta SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Starta guide" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd har ABSOLUT INGEN GARANTI\n" "Detta är gratis mjukvara, du är välkommen att sprida det under vissa omständigheter.\n" "Det är licensierat under GNU GENERAL PUBLIC LICENSE Version 2 eller (ditt val) en senare version.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Det gick inte att döpa om liknande fil: %s till %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Otillåten åtkomst" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER KRASHADE" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Oanvändbar NZB fil" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "URL hämtning misslyckades; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Försöker att hämta NZB från %s" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.215696 SABnzbd-4.3.2/po/main/pt_BR.po0000644000000000000000000034055314625637207015145 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Henrique Moreno, 2023 # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_BR\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Alerta" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Erro" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Falha ao iniciar a interface web" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" "Não foi possível encontrar o template web: %s. Tentando o template padrão" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "aplicativo par2... NÃO encontrado!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "Sua versão UNRAR é %s, nós recomendamos a versão %s ou superior.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "aplicativo unrar... NÃO encontrado!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "aplicativo 7za... NÃO encontrado!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "Módulos essenciais estão faltando, não é possível baixar." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Esteja ciente de que o nome de host 0.0.0.0 vai precisar de um endereço IPv6" " para acesso externo" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "Portas HTTP e HTTPS não podem ser iguais" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd iniciou com codificado %s, deveria ser UFT-8. Esperado problemas com" " arquivos e nomes de diretórios Unicode nos downloades." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" "Mascara atual (%o) pode negar ao SABnzbd acesso aos arquivos e diretórios " "criados." #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "Não foi possível carregar certificado do pacote certifi." #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS desabilitado pela falta de arquivos CERT e KEY" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "HTTPs desabilitado por caus de arquivo CERT e KEY invalidos" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Falha ao iniciar a interface web " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s iniciado" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Encerramento do SABnzbd concluído" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Sinal %s encontrado. Salvando e saindo..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Erro fatal ao salvar estado" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "Reiniciado por falha de pós processamento." #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "Reiniciado por falha de download" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "Reiniciado por falha de assembler" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "Não é possível acessar arquivo PID %s" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "E-mail enviado com sucesso" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Notificação de teste" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "O nome do host não foi definido." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "Não há conexões definidas. Por favor, defina pelo menos uma conexão." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Senha mascarada em ******, digite novamente" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Detalhes inválidos do servidor" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Endereço de servidor \"%s:%s\" não é válido." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Tempo esgotado: Tente habilitar o SSL ou conectar em uma porta diferente." #: sabnzbd/api.py msgid "Timed out" msgstr "Tempo esgotado" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Servidor requer usuário e senha." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Conexão com Sucesso!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Falha de autenticação, verifique usuário / senha." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Excesso de conexões, por favor pause o download ou tente novamente mais " "tarde" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Não foi possível determinar o resultado da conexão (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Resolvendo endereço" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Nenhum" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Padrão" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disco cheio! Forçando Pausa" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Erro de disco na criação do arquivo %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Erro fatal no Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Muito pouco espaço em disco. Forçando PAUSE" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "Tarefa \"%s\" pausado por causa de arquivo RAR encripitado (se fornecido, " "todos as senhas foram tentadas)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "Tarefa \"%s\" abortado por causa de arquivo RAR encripitado (se fornecido, " "todos as senhas foram tentadas)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Cancelado, criptografia detectada" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" "Em \"%s\" extensão não necessária em arquivo RAR. Arquivo não necessário é " "%s " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "A extensão indesejada está no arquivo rar %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Cancelado, extensão indesejada detectada" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Quota esgotada, pausando o download" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Parâmetro incorreto" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s não é um endereço de e-mail válido" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Endereço do servidor necessário" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Endereço do servidor inválido." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s não é um valor octal correto" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "A fila não está vazia. Não será possível mudar de pasta." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Não é possível gravar no arquivo INI %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Não é possível criar um arquivo de backup para %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Senha %s codificada incorretamente" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "Não é possível gravar os dados de histórico, verifique as permissões de " "acesso!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Dados de histórico danificados, criado um substituto vazio" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "O comando SQL falhou. Consulte o log" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Falha ao fechar o banco de dados. Consulte o log" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Registro inválido de etapa no histórico para %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Erro desconhecido ao decodificar %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Concluído" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Descompactados %s arquivos/pastas em %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Não é possível ler a Pasta de Assistidos %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Continuar" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Pausado" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Você deve definir a largura de banda máxima antes de definir um limite de " "banda" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Não é possível conectar ao servidor %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Nome de servidor não encontrado" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "O servidor %s será ignorado por %s minutos" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Falha ao iniciar %s@%s devido as seguintes razões: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Excesso de conexões ao servidor %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Falha de logon ao servidor %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "A conexão a %s@%s falhou. Mensagem=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Erro suspeito no downloader" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Encerrando" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Falha ao conectar ao servidor de e-mail" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Falha ao iniciar a conexão TLS" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "O servidor não respondeu propriamente a chamada de reconhecimento" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Falha ao autenticar com o servidor de e-mail" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Nenhum método de autenticação apropriado foi encontrado" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Falha de autenticação desconhecida no servidor de e-mail" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Falha ao enviar o e-mail" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Falha ao fechar a conexão de e-mail" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Não foi possível enviar, faltam dados obrigatórios" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Não é possível encontrar modelos de e-mail em %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Nenhum destinário fornecido, e-mail não enviado" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Não é possível ler %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Nenhum modelo de e-mail encontrado" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Para: %s\n" "De: %s\n" "Data: %s\n" "Assunto: SABnzbd informa Disco Cheio\n" "\n" "Olá,\n" "\n" "SABnzbd parou de baixar porque o disco está quase cheio.\n" "Por favor, arrume espaço e continue SABnzbd manualmente.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Não é possível criar a pasta %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "pasta %s: %s erro de acesso" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Não é possível alterar permissões de %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Falha ao criar (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Falha ao mover %s para %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Falha em tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Falha ao salvar %s" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Falha ao carregar %s" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Chave de API faltando. Por favor insira a chave de API de " "Configuração->Geral em seu programa de terceiros:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Chave de API incorreta. Use a chave de API de Configuração->Geral em seu " "programa de terceiros:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py msgid "Daily" msgstr "Diariamente" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "segunda-feira" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "terça-feira" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "quarta-feira" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "quinta-feira" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "sexta-feira" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "sábado" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "domingo" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "desligado" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Servidor não definido!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "ERRO:" #: sabnzbd/interface.py msgid "Back" msgstr "Voltar" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Atualização Disponível!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Erro ao criar chave SSL e certificado" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Ordenação de Séries" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Ordenação por data" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Executando script" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Aninhamento de descompactação com muitos níveis [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Unindo" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Sequência de arquivos multiparte incompleta" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "A união de arquivos de %s falhou" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Erro \"%s\" na união de arquivos" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Erro \"%s\" ao executar file_join em %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Unidos %s arquivos" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "A descompactação falhou. %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Erro \"%s\" ao descompactar os arquivos RAR" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Erro \"%s\" ao executar rar_unpack em %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "A exclusão de %s falhou!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Tentando descompactar com a senha \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Descompactando" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "A descompactação falhou. Não foi possível encontrar %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "A descompactação falhou. Erro de CRC" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "A descompactação falhou. Erro de escrita ou disco cheio?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Descompactação falhou, o caminho é muito extenso" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "A descompactação falhou. O arquivo exige uma senha" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Arquivo RAR inutilizável" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Testando 7zip com a senha \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "veja o arquivo de log" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Verificação Rápida" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparar" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Verificação Rápida OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Iniciando reparação" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparação falhou, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Erro %s ao executar par2_repair no conjunto %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Erro \"%s\" ao executar par2_repair no conjunto %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 recebeu opções incorretas. Verifique em Configuração->Opções" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificado em %s. Todos os arquivos corretos" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificado em %s. É necessário reparar" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Obtendo %s blocos..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Obtendo" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparação falhou. Blocos de reparação insuficientes (faltam %s)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Reparando" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Reparado em %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Disco cheio" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Verificando" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Verificando" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Tentando verificação SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "restantes" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Este servidor não permite SSL nesta porta" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Inicialização/Encerramento" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pausar" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Continuar" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB Adicionado" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Pós-processamento iniciado" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Tarefa concluída" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Tarefa com falha" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Fila concluída" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Outras Mensagens" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Abrir pasta de finalizados" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Não disponível" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Falha ao enviar mensagem Prowl" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Resposta incorreta do Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Falha ao enviar mensagem pushover" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Resposta incorreta do Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Falha ao enviar mensagem pushbullet" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Não é possível criar um arquivo temporário para %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Erro ao adicionar %s. Removendo" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Erro ao remover %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Falha ao importar %s arquivos de %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Encontrado arquivo de fila incompatível. Não é possível continuar" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Erro ao carregar %s. Arquivo corrompido detectado" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB adicionado à fila" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorando NZB duplicado \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Arquivo NZB %s vazio" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Cancelado, não é possível concluir" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Erro ao importar %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLICADO" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "CRIPTOGRAFADO" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "MUITO GRANDE" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "INCOMPLETO" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "INDESEJADO" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "Espere %s segundo(s)" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Baixado em %s a uma média de %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Idade" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artigos estavam malformados" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artigos estavam faltando" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artigos tinham duplicatas não-correspondentes" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Pausando NZB duplicado \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Alertas" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Inativo" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Fila" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Limpar Fila" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Histórico" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Limpar Histórico" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Limitar Velocidade" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "min" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Varrer pasta de assistidos" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Ler todos os feeds RSS" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Pasta de Finalizados" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Pasta de Não-Finalizados" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Resolução de problemas" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Reiniciar" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Reinicie sem login" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Sair" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Fila dos primeiros 10 items" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Esvaziar" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Histórico dos últimos 10 items" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Ir para o assistente" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Parando..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problema com" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd precisa de uma porta tcp/ip livre para seu servidor web interno.
\n" " A porta %s em %s foi tentada, mas não está disponível.
\n" " Algum outro software usa a porta ou o SABnzbd já está rodando.
\n" "
\n" " Por favor reinicie o SABnzbd com um número de porta diferente." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Se você receber esta mensagem de erro outra vez, tente um número " "diferente.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd precisa de um endereço de host válido para seu servidor web interno.
\n" " Você especificou um endereço inválido.
\n" " Valores seguros são localhost e 0.0.0.0
\n" "
\n" " Por favor reinicie o SABnzbd com um endereço de host correto." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd detectou dados salvos de outra versão do SABnzbd
\n" " mas não pode reutilizar os dados do outro programa.

\n" " Você pode querer terminar sua fila antes com o outro programa.

\n" " Após isso inicie este programa com a opção \"--clean\".
\n" " Isto irá apagar a fila atual e histórico!
\n" " SABnzbd leu o arquivo \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd não pode encontrar seus arquivos da interface web em %s.
\n" " Por favor instale o programa novamente.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd detectou um erro fatal:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd detectou que o arquivo sqlite3.dll está faltando.

\n" " Alguns anti-vírus mal projetados removem este arquivo.
\n" " Por favor, verifique o seu anti-vírus, tente reinstalar o SABnzbd e reclame com o seu fornecedor de anti-vírus.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Aperte a tecla Windows+R e digite a linha (exemplo):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Abra uma janela de terminal e digite a linha (exemplo):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "O programa não iniciou!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Erro fatal" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Não é possível iniciar o navegador. Provavelmente não foi encontrado" #: sabnzbd/panic.py msgid "Access denied" msgstr "Acesso negado" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Erro %s: Você precisa fornecer um nome de usuário e senha válidos." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" "Fila antiga detectada, use \"Situação -> Reparação da fila\" para converter " "a fila" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Falha ao compilar a expressão para o termo pesquisado: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" "O download pode falhar. Somente %s de %s necessários estão disponíveis" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "O download falhou - Não está em seu(s) servidor(s)" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Pós-processamento" #: sabnzbd/postproc.py msgid "Moving" msgstr "Movendo" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Enviados %s para a fila" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Erro ao renomear \"%s\" para \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Falha ao mover arquivos" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Executando script de usuário %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Código de saída do script é %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "%s executado" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Mais" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "O pós-processamento falhou para %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "O download falhou" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "A limpeza de %s falhou." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Download concluído" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Não é possível criar a pasta final %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Nenhum conjunto par2" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Alguns arquivos falharam na verificação de \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Verificado com sucesso. Usando arquivos SFV." #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "com senha" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "A remoção de %s falhou" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Falha ao hibernar o sistema" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Falha ao colocar o sistema em espera" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Erro ao desligar o sistema" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Descrição de feed RSS incorreta \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Não há autenticação válida para o feed %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" "Erro do servidor (código do servidor %s); não foi possível obter %s de %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Falha ao obter RSS de %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Servidor %s usa um certificado HTTPS não confiável" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "O feed RSS %s estava vazio" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Feed incompatível" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Entrada RSS vazia encontrada (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Exibir interface" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pausa de" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pausar por 5 minutos" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pausar por 15 minutos" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pausar por 30 minutos" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pausar por 1 hora" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pausar por 3 horas" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pausar por 6 horas" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Encerrar" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Restante" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Adicionar NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Agendamento %s incorreto em %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Ação desconhecida: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Agendamento para um servidor inexistente %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Tentando definir o status do servidor inexistente %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Download" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Unir arquivos" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Descompactar" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Script" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Código fonte" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servidores" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Falhou" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Aguardando" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Reparando..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Extraindo..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Movendo..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Executando script..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Obtendo blocos extras..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Verificação Rápida..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Verificando..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "desativar o servidor" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "ativar o servidor" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Limite de velocidade" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pausar Todos" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pausar o pós-processamento" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Continuar o pós-processamento" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Ler feeds RSS" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Remover tarefas com falha" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Remover trabalhos encerrados" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pausa tarefas de baixa prioridade" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pausa tarefas de prioridade normal" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pausa tarefas de alta prioridade" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Continua tarefas de baixa prioridade" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Continua tarefas de prioridade normal" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Continua tarefas de alta prioridade" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Ativar gerenciamento de cota" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Desativar gerenciamento de cota" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Desligado" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Muito Baixa" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Moderada" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Alta" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Emergencial" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Baixa" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "hora" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "horas" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "min" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "seg" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "segundos" #: sabnzbd/skintext.py msgid "day" msgstr "dia" #: sabnzbd/skintext.py msgid "days" msgstr "dias" #: sabnzbd/skintext.py msgid "week" msgstr "semana" #: sabnzbd/skintext.py msgid "Month" msgstr "Mês" #: sabnzbd/skintext.py msgid "Year" msgstr "Ano" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Dia do mês" #: sabnzbd/skintext.py msgid "This week" msgstr "Esta semana" #: sabnzbd/skintext.py msgid "This month" msgstr "Este mês" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Hoje" #: sabnzbd/skintext.py msgid "Total" msgstr "Total" #: sabnzbd/skintext.py msgid "on" msgstr "ligado" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parâmetros:" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Versão do Python" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Página inicial" #: sabnzbd/skintext.py msgid "or" msgstr "ou" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Host" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Cancelar" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Gravar" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Salvando..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Você tem certeza?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Início" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Configuração" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Situação" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Ajuda" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Fórum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Apoie o projeto. Faça uma doação!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Gerais" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Pastas" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Opções" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Agendamento" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Notificações" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "E-mail" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Categorias" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Ordenação" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Especial" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Busca" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Tem certeza de que quer encerrar o SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Adicionar" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Categoria" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioridade" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparar" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Descompactar" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Excluir" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Forçar" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Parar" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Digite a URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Desligar o PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "PC em espera" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Hibernar o PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Encerrar o SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Processamento" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Nome" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Repetir" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Scripts" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Eliminar todos os itens da fila?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Limpar NZBs" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Limpar NZBs & Excluir Arquivos" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Remover NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Remover NZB & Excluir Arquivos" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Artigos faltando" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Quota restante" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manual" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Redefinir Quota agora" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Ocultar detalhes" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Mostrar detalhes" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Mostrar Falhados" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Mostrar Todos" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Tamanho" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Limpar NZBs Falhados" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Limpar NZBs Falhados & Excluir Arquivos" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Limpar NZBs Terminados" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "NZB Suplementar Opcional" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Caminho" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Atualizar todos os trabalhos com falha" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Forçar Desconexão" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Isto irá enviar um e-mail de teste para sua conta." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Mostrar Logs" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Testar E-mail" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Logs" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Erros/Avisos" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Debug" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Conexões" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Identificador de artigo" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Conjunto de arquivos" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Ativo" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Conexão falhou!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Enderaço IPv4 local" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Endereço IPv4 público" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "Endereço IPv6" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nome do servidor / DNS Lookup" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Performance do Sistema (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Velocidade de download da pasta" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Completar velocidade da pasta" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Repetir teste" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Arquivo de Configuração" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Cache utilizado" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Isto irá reiniciar o SABnzbd.
Use-o quando você achar que o programa " "tem um problema de estabilidade.
Os downloads serão pausados antes de " "reiniciar e retomados depois." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Existem tarefas órfãs na pasta de downloads.
Você pode optar por " "excluí-las (incluindo arquivos) ou enviá-las de volta para a fila." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "O botão \"Reparar\" irá reiniciar o SABnzbd e fazer uma reconstrução
completa do conteúdo da fila, preservando arquivos já baixados.
Isto " "modificará a ordem da fila." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "As alterações não foram salvas e serão perdidas." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Ativar 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Versão" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Tempo ativo" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Backup" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Leia a sessão ajuda no Wiki sobre isso!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Reiniciando SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Mudanças exigirão um reinício do SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Servidor Web do SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Host do SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Computador onde o SABnzbd ficará ativo." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Porta do SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Porta onde o SABnzbd será ativado." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Usuário do SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Usuário de autenticação opcional." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Senha do SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Senha de autenticação opcional." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Habilitar HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Ativar acesso à interface por um endereço HTTPS." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "Porta HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Se estiver vazio, a porta padrão só irá funcionar com HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "Certificado HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Nome do arquivo ou caminho para o certificado HTTPS." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "Chave HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Nome do arquivo ou caminho para a chave HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "Cadeia de Certificados HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Nome de arquivo ou caminho da Cadeia HTTPS." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Ajustes finos" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Intervalo de verificação de RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Intervalo de verificação (em minutos, ao menos 15). Inativo quando você usar" " o Agendador!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Velocidade máxima da linha" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Percentual de velocidade da linha" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Qual percentual de velocidade da linha o SABnzbd deve utilizar, por exemplo," " 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Limite de Cache de Artigos" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Manter artigos em memória para reduzir o acesso a disco.
Em bytes, " "opcionalmente seguido de K,M,G. Por exemplo: \"64M\" ou \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Lista de Limpeza" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Lista de extensões de arquivo que devem ser excluídos após o download.
Por exemplo: nfo ou nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Salvar Alterações" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Reiniciar" #: sabnzbd/skintext.py msgid "Language" msgstr "Idioma" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Selecione um idioma para a interface web." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "Chave API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Esta chave dará a programas de terceiros pleno acesso ao SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "Chave NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Esta chave permitirá que programas de terceiros adicionem NZBs ao SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Gerar Nova Chave" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API Key QR Code" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Acesso externo da Internet" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Sem acesso" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Adicionar arquivos NZB " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (sem Configuração)" #: sabnzbd/skintext.py msgid "Full API" msgstr "API completa" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Interface Web completa" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTA: Pastas serão criadas automaticamente ao salvar. Você pode " "usar caminhos absolutos para salvar fora das pastas padrão." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Usar Pastas" #: sabnzbd/skintext.py msgid "Browse" msgstr "Navegar" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Pasta Temporária de Downloads" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Local para armazenar downloads não processados.
Só pode ser alterado" " quando a fila estiver vazia." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Espaço livre mínimo para a pasta temporária de downloads" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Pausar automaticamente quando o espaço livre estiver abaixo deste valor.
Em bytes, opcionalmente seguido de K,M,G,T. Por exemplo: \"800M\" ou " "\"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Pasta de Downloads Concluídos" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Local para armazenar downloads concluídos, totalmente processados​​.
Pode ser anulado por categorias definidas pelo usuário." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Retomar automaticamente" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Permissões para downloads concluídos" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Definir padrão de permissões para arquivos/pastas concluídos.
Em " "notação octal. Por exemplo: \"755\" ou \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Pasta de Assistidos" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Pasta para monitorar por arquivos .nzb." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Velocidade de Varredura na Pasta de Assistidos" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Quantidade de segundos entre as varreduras de arquivos .nzb." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Pasta de Modelos de E-mail" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Pasta contendo modelos de e-mail definidos pelo usuário" #: sabnzbd/skintext.py msgid "Password file" msgstr "Arquivo de senhas" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Arquivo contendo todas as senhas que serão testadas em arquivos RAR " "criptografados." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Pastas de Sistema" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Pasta Administrativa" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Localização do banco de dados de histórico e administrador de fila.
Só pode ser alterado quando a fila estiver vazia." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Dados não serão movidos. Será necessário reiniciar o SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Pasta de Log" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Local dos arquivos de log do SABnzbd.
Será necessário reiniciar o " "SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Pasta de Backup de .nzb" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Local onde os arquivos .nzb serão armazenados." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Pasta Inicial Padrão" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Baixar todos os arquivos PAR2" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Ativa descompactação recursiva" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Descompacta os arquivos (rar, zip, 7z) dentro de arquivos." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignorar qualquer pasta arquivada" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Todos os arquivos irão em uma única pasta." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Apenas Obter Artigos para o Topo da Fila" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Ative para menor uso de memória. Desative para impedir que trabalhos lentos " "bloqueiem a fila." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Pós-processar apenas os trabalhos verificados" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Ação quando RAR criptografado é baixado" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "Em caso de \"Pausa\", você precisa definir uma senha e retomar a tarefa." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Descartar" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Ação quando extensão indesejada for detectada" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Extensões indesejadas" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Habilitar verificações baseadas em SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Fazer uma verificação extra baseada em arquivos SFV." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "O script do usuário pode marcar um trabalho como falho" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Quando um script do usuário retornar um código de saída diferente de zero, o" " trabalho será marcado como falho" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Habilitar renomeação de pasta" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Usar nomes temporários durante o pós-processamento. Desative quando seu " "sistema não lidar com isso corretamente." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Script de usuário de pré-fila" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Utilizado antes de um NZB entrar na fila." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Parâmetros Extras PAR2" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Parâmetros Nice" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Parâmetros IONice" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Desconecte quando fila vazia" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Desconecte do(s) servidor(es) Usenet quando a fila estiver vazia ou " "pausada." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Procurar por nova versão" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Também versões de testes" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Substituir espaços no nome da pasta" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Substituir espaços por sublinhado no nome das pastas." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Substituir pontos no nome da pasta" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Substituir pontos por espaços no nome da pasta." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Tornar Windows compatível" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" "Para servidores: tenha certeza que os nomes são compatíveis com o Windows." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Abrir navegador ao iniciar" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Abrir o navegador padrão ao iniciar o SABnzbd." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Pausar o download durante o pós-processamento." #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Pausar o download no início do pós-processamento e retomar quando concluído." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignorar amostras" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Exclui arquivos de amostra. Exemplo: amostras de vídeo." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Excluir após download" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Servidor" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Pós-processamento" #: sabnzbd/skintext.py msgid "Naming" msgstr "Nomeando" #: sabnzbd/skintext.py msgid "Quota" msgstr "Quota" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Quanto pode ser baixado neste mês (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Primeiro dia do ciclo" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Em que dia do mês ou da semana (1 = segunda-feira) seu provedor de Internet " "redefine sua quota? (Opcionalmente com hh: mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "O download deve retomar quando a quota for restabelecida?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Período da quota" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "A quota é restabelecida a cada dia, semana ou mês?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Verifique antes de baixar" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Tentar prever a conclusão bem sucedida de um futuro download? (lento!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Máximo de tentativas" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Número máximo de tentativas por servidor." #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Cancela tarefas que não podem ser concluídas" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Quando durante o download ficar claro que muitos dados estão faltando, " "cancela a tarefa" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Adicionar Servidor" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Descrição do servidor" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Porta" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Usuário" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Senha" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Tempo limite" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Tempo de retenção" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Desativado" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 é a prioridade mais alta, 99 é a prioridade mais baixa" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Opcional" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Habilitar" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Remover servidor" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Testar Servidor" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Limpar Contadores" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Testando detalhes do servidor..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Largura de banda" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Notas pessoais" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Adicionar Agendamento" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Frequência" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Ação" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Parâmetros" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Agendamentos Atuais" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "A caixa de seleção ao lado do nome do feed deve ser assinalada para que o " "feed seja ativado e automaticamente verificado por novos itens.
Quando " "um feed é adicionado, ele só vai pegar novos itens e não algo que já esteja " "no feed RSS a menos que você pressione \"Forçar Download\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Ler Feed" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Forçar Download" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Ordem" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Tipo" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filtro" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Aceitar" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Recusar" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Requer" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "RequiresCat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "No mínimo" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "No máximo" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "De SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Correspondido" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Não Encontrado" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Baixados" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Ler Todos os Feeds Agora" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Notificar por e-mail na conclusão da tarefa" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Nunca" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Sempre" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Somente para erros" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Notificações de Disco Cheio" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Enviar e-mail quando o disco estiver cheio e SABnzbd estiver pausado." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Enviar notificações RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Enviar e-mail quando um feed RSS adicionar tarefas à fila." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "Servidor SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Define o servidor para envio de e-mails." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Destinatário do E-mail" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Endereço de e-mail para receber os e-mails." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "E-mail do Remetente" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Quem devemos dizer que enviou o e-mail?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "Nome de usuário OPCIONAL da conta" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Nome da conta, para e-mails com autenticação." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "Senha OPCIONAL da conta" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Senha, para e-mails com autenticação." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Notificação Enviada!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Habilitar NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Centro de Notificações" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Habilitar notificações Windows" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Notificações Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Ativar notificações Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Requer uma conta Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Chave API para Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Chave API pessoal para Prowl (obrigatório)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Habilitar notificações Pushover" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Necessário uma conta Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Token da aplicação" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Token da aplicação (obrigatório)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Chave do usuário" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Chave do usuário (obrigatório)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Dispositivo(s)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Dispositivo(s) para qual a mensagem deve ser enviada" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Habilitar notificações Pushbullet" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Necessária uma conta Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Chave API pessoal" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Chave Pushbullet API pessoal (necessária)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Dispositivo" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Dispositivo para qual a mensagem deve ser enviada" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Para evitar a criação de pastas de trabalho, adicione um asterisco (*) " "depois do caminho." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Caminho base das pastas relativas" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Pasta/Caminho" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Modelo do padrão" #: sabnzbd/skintext.py msgid "Clear" msgstr "Limpar" #: sabnzbd/skintext.py msgid "Presets" msgstr "Predefinições" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Categorias Afetadas" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Significado" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Modelo" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultado" #: sabnzbd/skintext.py msgid "Title" msgstr "Tí­tulo" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Nome Filme" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Nome.Filme" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Nome_Filme" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Nome do Show" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Nome.do.Show" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Nome_do_Show" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Número da Temporada" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Número do Episódio" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Nome do Episódio" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Nome.Episódio" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Nome_Episódio" #: sabnzbd/skintext.py msgid "Extension" msgstr "Extensão" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Número do Episódio" #: sabnzbd/skintext.py msgid "Decade" msgstr "Década" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Nome do arquivo original" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Minúsculas" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXTO" #: sabnzbd/skintext.py msgid "text" msgstr "texto" #: sabnzbd/skintext.py msgid "file" msgstr "arquivo" #: sabnzbd/skintext.py msgid "Sort String" msgstr "String de ordenação" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "Em pastas" #: sabnzbd/skintext.py msgid "No folders" msgstr "Sem pastas" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "ajuste de maiúsculas" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Resultado Processado" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Todos" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Opções raramente utilizadas. Para seu significado e explicação, clique no " "botão Ajuda para ir para a página Wiki.
Não altere estas sem checar o " "Wiki em primeiro lugar, já que algumas têm sérios efeitos colaterais.
Os " "valores padrão estão entre parênteses." #: sabnzbd/skintext.py msgid "Values" msgstr "Valores" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Editar Detalhes do NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Eliminar" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Nome do arquivo" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Espaço Disponível" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Pasta temporária" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Multi-Operações" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Segure a tecla shift para selecionar um intervalo" #: sabnzbd/skintext.py msgid "Check all" msgstr "Selecionar todos" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Reiniciar SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Ao terminar a fila" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Estado e opções de interface" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Ou arraste e solte arquivos na janela!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Conexão perdida com SABnzbd.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "No caso de reinício do SABnzbd, esta janela irá desaparecer automaticamente!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "AVISO:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Obter" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Interface Web" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Taxa de atualização" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Usar configurações globais de interface" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Limite de itens na fila" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Limite de itens no histórico" #: sabnzbd/skintext.py msgid "Date format" msgstr "Formato da data" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "página" #: sabnzbd/skintext.py msgid "Loading" msgstr "Carregando" #: sabnzbd/skintext.py msgid "articles" msgstr "artigos" #: sabnzbd/skintext.py msgid "Rename" msgstr "Renomear" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Reparação da fila" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Exibir conexões ativas" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Desbloquear" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Trabalhos órfãos" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Enviar de volta para a fila" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Excluir Todos" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Repetir todos" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Buscar NZB de uma URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Enviar NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Opcionalmente, especifique um nome de arquivo" #: sabnzbd/skintext.py msgid "Submit" msgstr "Enviar" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Remover todos os arquivos selecionados" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Esconder/Exibir arquivos completos" #: sabnzbd/skintext.py msgid "Top" msgstr "Topo" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Base" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Exibir Log do Script" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Personalizado" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Velocidade" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Confirmar Exclusões da Fila" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Confirmar Exclusões do Histórico" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Por quanto tempo ou até quando você quer pausar? (em Inglês!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Perdão, não conseguimos interpretar isso. Tente novamente." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pausar por..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Atualizar" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Ordenar por Idade Mais antigo→Mais novo" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Ordenar por Idade Mais novo→Mais antigo" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Ordenar por Nome A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Ordenar por Nome Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Ordenar por Tamanho Menor→Maior" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Ordenar por Tamanho Maior→Menor" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Assistente de Início Rápido do SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Versão do SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Anterior" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Próx" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Detalhes do Servidor" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Por favor insira os detalhes de seu provedor de usenet primário." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "O número de conexões permitidas por seu provedor" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Ex: 8 ou 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Selecione somente se seu provedor permitir conexões SSL." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Clique para testar os detalhes informados." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Ex." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "A configuração está completa!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd agora será executado em segundo plano." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Fechar qualquer janela/aba do navegador NÃO vai fechar o SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Recomenda-se que você adicione este local como favorito para acessar o " "SABnzbd quando ele estiver sendo executado em segundo plano." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Mais ajuda pode ser encontrada em nosso" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Ir para o SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Sair do SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Iniciar o Assistente" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd não possui QUALQUER GARANTIA.\n" "É software livre, e você está convidado a redistribuí-lo sob certas condições.\n" "Está licenciado sob a LICENÇA PÚBLICA GERAL GNU Versão 2 ou (a seu critério) qualquer versão posterior.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Falha ao renomear arquivo similar: %s para %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Acesso não autorizado" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER PAROU DE FUNCIONAR" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Arquivo NZB inutilizável" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "A busca da URL falhou; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Tentando obter NZB de %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2160015 SABnzbd-4.3.2/po/main/ro.po0000644000000000000000000034661314625637207014562 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Eduard Baniceru , 2021 # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Avertisment" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Eroare" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Pornirea interfeţei-web nereuşită" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Nu se poate găsi şablon web:%s, se încearcă şablon standard" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools dezactivat: nu s-a găsit o versiune corectă! (Găsită v%s, se " "așteaptă v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "binar par2 ... Negăsit!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "Versiunea ta de UNRAR este %s, noi recomandăm versiunea %s sau mai mare." #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "binar unrar... Negăsit!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "Fişier executabil 7za ... Indisponibil!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "Lipsesc module esențiale, descărcarea nu poate începe." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Vă rugăm să fiţi conştienţi că numele gazdei 0.0.0.0 va avea nevoie de o " "adresa IPv6 pentru acces extern" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "Porturile HTTP și HTTPS nu pot fi aceleași" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd a fost pornit cu encodarea %s, aceasta trebuie să fie UTF-8. Pot " "apărea probleme cu denumiri de fișiere și directoare Unicode în descărcări." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "Nu pot încărca certificate adiționale din pachetul certifi" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Dezactivează HTTPS din cauza lipsei fişierelor CERT şi KEY" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "HTTPS dezactivat din cauza fișierelor invalide CERT și KEY" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Nu am putu porni interfața web: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s pornit" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Închidere SABnzbd terminată" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Semnal %s prins, salvez şi ies..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Eroare fatală la salvare" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "Nu pot accesa fișierul PID %s" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Email reuşit" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Notificări Test" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Numele gazdei nu este setat." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" "Nu sunt conexiuni stabilite. Vă rugăm să stabiliţi cel puţin o conexiune." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Parolă ascunsă în ******, Vă rugăm să re-introduceţi" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Detalii server invalide" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Adresa server \"%s:%s\" nu este validă" #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "A depăşit timpul alocat : Încercaţi să activaţi SSL sau conectarea pe un " "port diferit." #: sabnzbd/api.py msgid "Timed out" msgstr "A depăşit timpul alocat" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Serverul necesită nume utilizator şi parolă" #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Conexiune Reuşită!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Autentificare nereuşită, verifică nume utilizator/parolă." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Prea multe conexiuni, vă rugăm să întrerupeţi descărcarea sau să încercaţi " "din nou mai târziu" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Nu pot determina reultatul conexiunii (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Reolvare adresă" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Niciunul" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Implicit" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disc plin! Pauză Forţată" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Eroare disc la crearea fişierului %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Eroare fatală în Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Prea puţin spaţiu disc forţez PAUZĂ" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "Sarcina „%s” a fost întreruptă din cauza fișierului RAR criptat (toate " "parolele oferite au fost încercate)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "Sarcina „%s” a fost anulată din cauza fișierului RAR criptat (toate parolele" " oferite au fost încercate)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Terminat, encriptare detectată" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "Extensie nedorită în fișierul RAR al „%s”. Fișierul nedorit este %s" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Extensii fișier nedorite în fișierul rar %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Oprit, extensii nedorite detectate" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" "Sarcina „%s” este probabil criptată din cauza unui RAR cu același nume în " "acest RAR" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "Sarcina „%s” este probabil criptată: „parolă” în fișierul „%s”" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Cotă epuizată, întrerupem descărcarea" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Parametru Incorect" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s nu este o adresă email validă" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Adresă server necesară" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Adresă server invalidă" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s nu este o valoare octală corectă" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Coada nu este goală, nu pot schimba dosar." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" "Directorul de descărcări finalizate nu poate fi același, sau un subdirector " "al directorului de descărcări temporare" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "Configurație blocată, nu pot salva setările" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Nu pot scrie în fişierul INI %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Nu pot crea copie de rezervă pentru %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Parolă %s codificată greşit" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "Nu pot scrie în baza de date ISTORIC, verificaţi permisiunile de acces." #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Bază de date Istoric coruptă, creat un nou fişier gol" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Comandă SQL Nereuşită, vedeţi jurnal" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Închidere bază de date nereuşită, vedeţi jurnal" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Jurnal istoric stagii invalid pentru %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Eroare decodare: lipsă memorie" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Eroare Necunoscută în timpul decodării %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "Dezarhivare directă" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Finalizat" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Dezarhivat %s fişierele/dosarele în %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "Dezarhivarea directă a fost activată automat." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "Sarcinile vor începe dezarhivarea pe parcursul descărcării pentru a reduce " "timpul de postprocesare, Funcționează doar pentru sarcinile care nu necesită" " reparare." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Nu pot citi Dosar Urnărire %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Reluare" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Întrerupt" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Trebuie să seta-ţi lățimea de bandă maximă înainte de a seta o limită de " "viteză." #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Nu mă pot conecta la serverul %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Numele de server nu se rezolvă la DNS" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Serverul %s va fi ignorat pentru %s minute" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Nu am putu inițializa %s@%s din cauza următorului motiv: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Prea multe conexiuni la serverul %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Autentificare nereuşită la serverul %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Conectare %s@%s eșuată, mesaj=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Eroare suspectă în sistemul de descprcare" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Închidere" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Conectare server mail nereuşită" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Iniţializare conexiune TLS nereuşită" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Serverul nu a răspuns în mod corect la cererea de inițiere" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Autentificare server mail nereuşită" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Nu am găsit nici o metodă potrivită de autentificare" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Eroare necusnoscută la autentificarea la serverul de mail" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Trimitere email nereuşiă" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Închidere conexiune mail nereuşită" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Nu pot trimite, informații necesare lipsă" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Nu pot gasi şabloane email în %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Destinatar necunoscut, niciun email trimis" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Nu pot citi %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Şabloane email negăsite" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "From: %s\n" "To: %s\n" "Date: %s\n" "Subject: SABnzbd raporteaza Disc Plin\n" "\n" "Salut,\n" "\n" "SABnzbd sa oprit din descarcare, deoarece discul este aproape plin.\n" "Va rugam sa faceti loc si reluati SABnzbd manual.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Nu pot crea dosarul %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "dosarul %s: eroare accesare %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Nu pot schimba permisiunile lui %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Facere nereuşită (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Mutare %s în %s nereuşită" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Eroare în tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Salvarea %s nereuşită" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Încărcarea %s nereuşită" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "Conectare refuzată cu gazda „%s” de la:" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Utilizatorul s-a autentificat în interfața web" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Utilizator logat" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Cheie API lipsă, vă rugăm să introduceţi cheia api de la " "Configurare->General în programul dumneavoastră terţ" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Cheie API incorectă, Folosiţi cheia api din Configurare->General în " "programul dumneavoastră terţ:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Încercare de conectare nereușită de la %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Flux" #: sabnzbd/interface.py msgid "Daily" msgstr "Zilnic" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Luni" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Marţi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Miercuri" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Joi" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Vineri" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Sâmbătă" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Duminică" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "dezactivat" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Server nedefinit!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" "Directorul de categorii nu poate fi un subdirector al directorului de " "descărcări temporare." #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "EROARE:" #: sabnzbd/interface.py msgid "Back" msgstr "Înapoi" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Actualizare Disponibilă!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "Eșuare la încărcarea fișierului: %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Eroare la crearea cheiei şi certificatlui SSL" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "Fișierul tău cu parole conține peste 30 de parole, verificarea tuturor " "necesită mult timp. Listează doar parolele utile." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "Eșuare la citirea fișierului cu parole %s" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "[%s] Comanda din build_command este nedefinită." #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "Scriptul Python „%s” nu are permisiuni de executare (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Sortare Seriale" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Sortare Dată" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Rulare script" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Numărul de arhive încorporate este prea mare [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Unim" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Secvenţă incompletă de unire fişiere" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Unirea fişierului %s nereuşită" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Eroare \"%s\" în timpul unirii fişierelor" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Eroare \"%s\" în timpul file_join a %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Unit %s fişierele" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Dezarhivare nereuşită, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Eroare \"%s\" în timpul dezarhivării fişierelor RAR" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Eroare \"%s\" în timpul rar_unpack a %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Ştergere %s nereuşită!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Încerc unrar cu parola \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Dezarhivare" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Dezarhivare nereuşită, nu pot găsi %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Dezarhivare nereuşită, eroare CRC" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" "Dezarhivare eșuată, fișier prea mare pentru sistemul de fișiere (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Dezarhivare nereuşită, eroare scriere sau disc plin?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Dezarhivare eșuată, calea este prea lungă" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Dezarhivare nereuşită, arhiva necesită o parolă" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Fișier RAR ce poate fi folosit" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Fișier RAR corupt" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Încerc 7zip cu parola \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "vezi fişier jurnal" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Verificare Rapidă" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Repară" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Verficare Rapidă OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Pornire Reparare" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparare nereuşită, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Eroare %s în timpul rulării par2_repair pe setul %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Eroare \"%s\" în timpul rulării par2_repair pe setul %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 a primit opţiuni incorecte, verifică setările " "Configurare->Comutatoare" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificat în %s, toate fişierele sunt corecte" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificat în %s, reparare necesară" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Fișiere par2 invalide sau parametri PAR2 invalizi, nu pot verifica sau " "repara" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Descărcare %s blocuri..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Descărcare" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparare nereuşită, blocuri reparare insuficiente (%s mai puţin)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Se repară" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Reparat în %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "Se verifică repararea" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Disc plin" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Se verifică fișierele extra" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Se verifică" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Se verifică" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Încerc verificare SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "rămas" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Acest server nu permite SSL pe acest port" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "Neportivire certificat: denumirea serverului nu este listată în certificat. " "Aceasta este o problemă de server." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "Certificat invalid. Este cel mai probabil o problemă de server." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Serverul %s utilizează un certificat nesigur [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Pornire/Închidere" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pauză" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Reia" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB-uri Adăugate" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Post-procesare pornită" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Sarcină terminată" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Sarcină eșuată" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Coadă finalizată" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Alte Mesaje" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Deschide dosar descărcări complete" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Indisponibil" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "Eșuare la trimiterea notificării macOS" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Nu am putu trimite mesajul Prowl" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Răspuns greșit de la Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Nu am putut trimite mesajul de pushover" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Răspuns greșit de la Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Nu am putu trimite mesajul pushbullet" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Scriptul a returnat codul de ieșire %s și rezultatele următoare \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Scriptul de notificare \"%s\" nu există" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Nu am putut trimite notificări în Fereastră" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Nu pot crea fişier temporar pentru %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Eroare adăugare %s, ştergem" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Eroare ştergere %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Importare %s a fişierelor de la %s nereuşită" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Fişier coadă găsit incompatibil, nu pot înainta" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Eroare încărcare %s, fişier corupt detectat" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB adăugat în coadă" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorăm duplicat NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "Eșuare duplicat NZB „%s”" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "NZB duplicat" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Fişier NZB gol %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "Scriptul pre-coadă a marcat sarcina ca nereușită" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "Extensie nedorită în fișierul %s (%s)" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Anulat nu poate fi finalizat" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Eroare importare %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLICAT" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "ENCRIPTAT" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "PREA MARE" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "INCOMPLET" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "NEDORIT" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "AŞTEAPTĂ %s sec" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "SE PROPAGHEAZĂ %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Descărcat în %s cu o medie de %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Vârsta" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s articolele au fost incorecte" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s articolele au fost lipsă" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s articolele au avut duplicate diferite" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Întrerupem duplicat NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Atenționări" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Inactiv" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Coadă" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Goleşte Coadă" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Istoric" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Şterge Istoricul" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Limitare de Viteză" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "min" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Scanează dosar urmărire" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Citește toate feed-urile RSS" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Dosar Complet" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Dosar Incomplet" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Depanare" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Repornește" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Reporneşte fără autorizare" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Ieșire" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Pune la Coadă Primele 10 Obiecte" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Gol" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Istoric Ultimele 10 Obiecte" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Dute la vrăjitor" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Se oprește..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problemă cu" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd are nevoie de un tcp/ip port liber pentru serverul său intern.
\n" " Portul %s de pe %s a fost încercat , dar nu este disponibil.
\n" " Alt program foloseşte portul sau SABnzbd este deja pornit.
\n" "
\n" " Vă rugăm să reporniţi SABnzbd cu un număr de port diferit." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Dacă primiţi acest mesaj de eroare din nou, vă rugăm să încercaţi un alt " "număr.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd are nevoie de o adresă gazdă validă pentru serverul său intern.
\n" " Dvs. a-ţi specificat o adresă invalidă.
\n" " Valori sigure sunt localhost şi 0.0.0.0
\n" "
\n" " Vă rugăm să reporniţi SABnzbd cu o adresă gazdă bună." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd a detectat informaţii salvate de la o altă versiune SABnzbd
\n" " dar nu poate să refolosească informaţiile de la cealaltă versiune de program.

\n" " Ar fi bine să terminaţi coada mai întâi cu cealaltă versiune de program.

\n" " După aceia , porniţi programul cu opţiunea \"--clean\".
\n" " Aceasta va şterge coada curentă şi istoricul!
\n" " SABnzbd citeşte fişierul \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd nu poate găsi fişierele de la interfaţa-web %s.
\n" " Vă rugăm să reinstalaţi programul din nou.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd a detectat o eroare fatală:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd a detectat că fişierul sqlite3.dll lipseşte.

\n" " Unele antivirusuri şterg acest fişier.
\n" " Vă rugăm să verificaţi antivirusul , încercaţi să reinstalaţi SABnzbd şi plângeţivă autorului antivirusului.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Apasă Start+R şi scrie linia (exemplu):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Deschide fereastra Terminal şi scrie linia (exemplu):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Aplicaţia nu a pornit!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Eroare fatală" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" "Nu pot rezerva portul %s pe %s. Alt software utilizează portul sau SABnzbs " "rulează deja." #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Nu pot porni navigatorul web, probabil nu a fost găsit" #: sabnzbd/panic.py msgid "Access denied" msgstr "Acces interzis" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Eroare %s: Trebuie să furnizaţi un nume utilizator şi parolă valid" #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" "Coadă de descărcare veche detectată, utilizează Stare->Reparare pentru a " "converti coada" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Compilarea unei căutări regex nereuşită: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" "Directorul de descărcări finalizate %s se află pe sistem de fișiere FAT, " "limitând dimensiunea maximă a fișierului la 4GB" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Descărcarea ar putea eşua, doar %s din %s disponibil" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Descărcare euată, - Nu este pe serverul(ele) dumneavoastră" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Post-procesare" #: sabnzbd/postproc.py msgid "Moving" msgstr "Mutare" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Trimis %s în coadă" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Eroare redenumire \"%s\" în \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Nu am putu muta fişier" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Rulare script utilizator %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Codul de ieșire a scriptului este %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Durată %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Mai mult" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Post Procesare Nereuşită pentru %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "Post-procesarea a fost întreruptă" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Descărcarea a eșuat" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Ştergerea lui %s nereuşită." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Descărcare terminată" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Nu pot crea dosar final %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Niciun set par2" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Unele fişiere nu au fost verificate corect cu \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Verificare reuşită cu fişierele SFV" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "Încerc verificare RAR" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Parolat" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] verificarea RAR a eșuat: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "Fișierele RAR verificate cu succes" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "Verificarea fișierelor RAR a eșuat" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Ştergerea %s nereuşită" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Punere sistem în hibernare nereuşită" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Punere sistem în aşteptare nereuşită" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Eroare la oprirea sistemului" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Descriere flux RSS incorectă \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Autentificare invalida pentru flux %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Eroare la server (codul server %s); nu am putu lua %s în data de %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Descărcare %s: %s din RSS nereuşită" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Serverul %s utilizează un certificat HTTPS nesigur" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "Fluxul RSS %s a fost gol" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Fulx RSS incompatibil" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Valoare RSS gasită a fost goală (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Arată interfața" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pauză timp de" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pauză timp de 5 minute" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pauză timp de 15 minute" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pauză timp de 30 minute" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pauză timp de o oră" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pauză timp de 3 ore" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pauză timp de 6 ore" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Închidere" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Rămas" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Adaugă NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Programator Greşit %s la %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Acţiune necunoscută: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Planificare pentru un server inexistent %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Încerc să setez starea unui server nexistent %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Descarcă" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Uneşte fişierele" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Dezarhivează" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Script" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Sursă" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servere" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Nereuşit" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Se așteaptă" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Reparare..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Dezarhivare..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Mutare..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Rulare script..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Descărcare blocuri extra..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Verificare Rapidă..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Verificare..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "dezactivează server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "activează server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Limitare de Viteză" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pauză Toate" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pauză post-procesare" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Reia post-procesare" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Citeşte fluxuri RSS" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Elimină sarcini nereuşite" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Elimină sarcinile finalizate" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Întrerupte sarcinile cu prioritate redusă" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Întrerupe sarcinile cu prioritate normală" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Întrerupe sarcinile cu prioritate ridicată" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Reia sarcinile cu prioritate redusă" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Reia sarcinile cu prioritate normală" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Reia sarcinile cu prioritate ridicată" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Activează gestionarea cotelor" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Dezactivează gestionarea cotelor" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Oprit" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Foarte scăzută" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Moderat" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Ridicată" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Urgență" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Scăzută" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "oră" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "ore" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minute" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sec" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "secunde" #: sabnzbd/skintext.py msgid "day" msgstr "zi" #: sabnzbd/skintext.py msgid "days" msgstr "zile" #: sabnzbd/skintext.py msgid "week" msgstr "săptămână" #: sabnzbd/skintext.py msgid "Month" msgstr "Lună" #: sabnzbd/skintext.py msgid "Year" msgstr "An" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Zi din lună" #: sabnzbd/skintext.py msgid "This week" msgstr "Săptămâna aceasta" #: sabnzbd/skintext.py msgid "This month" msgstr "Luna aceasta" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Azi" #: sabnzbd/skintext.py msgid "Total" msgstr "Total" #: sabnzbd/skintext.py msgid "on" msgstr "activat" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametrii" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Versiune Python" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Pagină de pornire" #: sabnzbd/skintext.py msgid "or" msgstr "sau" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Gazdă" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Anulează" #: sabnzbd/skintext.py msgid "Log in" msgstr "Autentificare" #: sabnzbd/skintext.py msgid "Log out" msgstr "Deconectare" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Ține-mă minte" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Salvează" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Salvăm.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Sunteţi sigur?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Pagina de pornire" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Configurare" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Stare" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Ajutor" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Probleme" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Susţine proiectul, Donează!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "General" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Directoare" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Comutatoare" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Planificare" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Notificări" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Email" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Categorii" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sortare" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Special" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Caută" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Sunteţi sigur că doriţi să inchideţi SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Adaugă" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Categorie" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioritate" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparare" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Dezarhivare" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Ştergere" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Forțează" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Stop" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Introdu URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Închide PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Repaus PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Hibernare PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Închide SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "În curs de procesare" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Nume" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Reîncearcă" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Script-uri" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Ştergeţi toate obiectele din coadă?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Şterge NZB-uri" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Şterge NZB-uri & Fişiere Şterse" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Şterge NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Şterge NZB & Fişiere Şterse" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Articole lipsă" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Cotă rămasă" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manual" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Resetează Cota acum" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Ascunde detaliile" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Arată detalii" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Arată Nereuşite" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Arată toate" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Mărime" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Şterge NZB-uri nereuşite" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Şterge NZB-uri Nereuşite & Fişiere Şterse" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Şterge NZB-uri Complete" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "NZB Suplimentar Opţional" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Cale" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Reîncearcă toate sarcinile eșuate" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Forţează Deconectarea" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Acesta va trimite un email test către contul dvs." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Arată Jurnalizarea" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Email Test" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Jurnalizare" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Erori/Avertismente" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Depanare" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Conexiuni" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Identificator Articol" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Set fişiere" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Activat" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Conectare eșuată!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Adresa IPv4 locală" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Adresa IPv4 publică" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "Adresa IPv6" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Server de nume/Căutare DNS" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Perfromanță Sistem (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Viteză de descărcare director" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Vitează completă director" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Repetă test" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Fişier Configurare" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Cache Folosit" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Acest lucru va reporni SABnzbd.
Folosiţi-l atunci când credeţi că " "programul are o problemă de stabilitate.
Descărcarea va fi oprită " "înainte de repornire şi reluată ulterior." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" "
Dacă este activată autentificarea v-a trebuie să vă logați din nou." #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Sunt sarcini orfane în dosarul de descărcare.
Puteţi alege în a le " "şterge (inclusiv fişierele) sau a le trimite înapoi în coadă." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "Butonul \"Reparare\" va reporni SABnzbd şi face o reconstrucţie completă a conţinutului coadei de descărcare , menţinând fişierele deja " "descărcate.
Acest lucru va modifica ordinea în coada de descărcare." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Modificările nu au fost salvate, şi vor fi pierdute." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" "Atunci când modificați adresa IP sau dacă SABnzbd este repornit sesiunea " "dumneavoastră va expira." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Activează 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Versiune" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Durata Funcţionării" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Server Secundar" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Citeşte Ajutorul Wiki despre asta !" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Repornim SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Modificările vor necesita repornirea SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Server Web SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Gazdă SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Nume Gazdă unde SABnzbd va asculta." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Portul pe care SABnzbd îl va asculta." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Nume Utilizator SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Nume Utilizator autentificare opţional" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Parolă SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Parolă autentificare opţională" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Activează HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Permite acesarea interfeţei de la o adresă HTTPS." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Dacă e gol, portul standard va asculta doar în HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "Certificat HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Nume fişier sau cale Certificat HTTPS." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "Cheie HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Nume fişier sau cale Cheie HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "Certificate Cheie HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Nume fişier sau cale cheie HTTPS." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Optimizări" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Interval Verficare RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Interval verificare (în minute, cel puţin 15). Inactiv când se foloseşte " "Planificatorul!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Viteză maximă a conexiunii" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Procent din viteza conexiunii" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "Ce procent din viteza conexiuni poate fi utilizat de SABnzbd, ex. 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Limită Cache Articole" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Stochează articolele în memorie pentru a reduce acesul disc.
În " "octeţi, opţional urmaţi de K,M,G. De exemplu : \"64M\" sau\"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Listă Curăţenie" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Listă de extensii fișiere ce trebuie să fie șterse după descărcare.
De " "exemplu: nfo or nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Salvează Modificările" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Resetează" #: sabnzbd/skintext.py msgid "Language" msgstr "Limbă" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Alegeţi o limbă interfaţă web." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "Cheie API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Această cheie va oferi programelor terţe acces deplin la SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "Cheie NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Această cheie va permite programelor terţe să adauge NZB-uri în SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Generează o Cheie Nouă" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "Cheie API sau Cod QR" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Acces extern la internet" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Fără acces" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Adaugă fișiere NZB " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (fără Configurare)" #: sabnzbd/skintext.py msgid "Full API" msgstr "API Complet" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Interfață Web completă" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Doar accesul extern necesităr autentificare" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTĂ:Dosarele vor fi create automat când se Salvează. Puteţi " "utiliza căi absolute pentru a salva în afara dosarelor implicite." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Dosare Utilizator" #: sabnzbd/skintext.py msgid "Browse" msgstr "Răsfoire" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Dosar Descărcare Temporar" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Locaţie de stocare a descărcărilor neprelucrate.
Poate fi schimbată " "doar atunci când coada este goală." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minim de Spaţiu Liber pentru Dosar Descărcare Temporar" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pauză când spaţiul liber este sub această valoare.
În octeţi, " "urmaţi opţional de K, M, G, T. De exemplu: \"800M\" sau \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Dosar Descărcări Finalizate" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Locație pentru stocare , a descărcărilor procesate complet.
Poate fi" " suprascris de categoriile definite de utilizator." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Auto repornire" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Permisiuni pentru descărcări finalizate" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Setează permisiunile pentru fişierele/directoarele finalizate.
În " "valori octale. De exemplu: \"755\" sau \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Dosar Monitorizat" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Dosar pentru supraveghere fişiere .nzb." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Viteză Scanare Dosar Monitorizat" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Numărul de secunde între scanarea de fişiere .nzb." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Dosar Şabloane Email" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Dosar ce conţine şabloane email utilizator." #: sabnzbd/skintext.py msgid "Password file" msgstr "Fișier parole" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "Fişier ce conţine parole pentru fişiere RAR encriptate." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Dosare Sistem" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Dosar Administrativ" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Locaţia coadei admin şi istoricul bazei de date.
Poate fi folosit " "doar când coada e goală." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Informaţiile vor nu vor fi mutate. Necesită repornire SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Dosar Jurnal" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Locaţie a fişierelor jurnal ale SABnzbd.
Necesită repornire " "SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Dosar Copie de Siguranţă .nzb" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Locaţie unde fişierele .nzb vor fi stocate." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Dosar de Bază Implicit" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Descarcă toate fișierele par2" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Activează dezarhivarea recursivă" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Dezarhivează arhivele (rar, zip, 7z) conținute în alte arhive." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignoră orice director din interiorul arhivelor" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Toate fișierele merg într-un singur director" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Ia Articole doar din Vârful Coadei" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Activează pentru folosire de memorie mai puţină. Dezactivaţi pentru a " "preveni ca sarcinile lente să blocheze coada." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Post-Procesează Doar Sarcinile Verificate" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Acțiuni când se descarcă un RAR encriptat" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "În cazul \"Întrerupere\", dumneavoastră trebuie să introduceți parola și să " "reluați sarcina." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Ignoră" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Acțiune când se detectează o extensie nedorită" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Extensii nedorite" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Activează verficări SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Fă o verificare extra bazată pe fişiere SFV" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Sarcina cu script a utilizatorului a eșuat" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Când un script de utilizator returnează o ieșire diferit de codul de ieșire," " sarcina v fi marcată ca fiind nereușită." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Activează redenumire dosar" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Foloseşte nume temporare în timpul post procesării. Dezactivaţi când " "sistemul dvs. nu gestionează aceasta corect." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Script utilizator Pre-Coadă" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Folosit înainte ca un NZB să intre în coadă." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Parametri Extra PAR2" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Parametri Nice" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Parametri IONice" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Deconectează când Coada e Goală" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Deconectează de la serverul(ele) Usenet când coada e goală sau în pauză." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Întârziere de propagare" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Articolele vor fi întrerupte până ce vor avea cel puțin vechimea aceasta. " "Dacă setați prioritatea descărcării ca Forțat evitați această întârziere." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Verifică Versiuni Noi" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Testeaza şi versiuni de încercare" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Înlocuieşte Spaţiile din Numele Dosarelor" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Înlocuieşte spaţiile cu _ în numele dosarelor." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Înlocuieşte punctele din Numele Dosarelor" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Înlocuieşte puntele cu spaţii în numele dosarelor." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Fă Windows compatibil" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "Pentru servere: asigurați-vă că numele sun comparibile cu Windows" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Porneşte Navigator Web la Pornire" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Porneşte navigatorul web implicit când se porneşte SABnzbd." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Întrerupe Descărcarea în Timpul Post-Procesare" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Întrerupe descărcare la începerea post procesării şi reporneşte când e " "terminată." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignoră Monstre" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Ignoră fişiere monstră (de ex. monstre video)" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Şterge după descărcare" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Server" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Post procesare" #: sabnzbd/skintext.py msgid "Naming" msgstr "Redenumire" #: sabnzbd/skintext.py msgid "Quota" msgstr "Cotă" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Cât de mult poate fi descărcat în acestă lună (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Zi resetare" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "În ce zi a lunii sau săptămână (1=Luni) ISP dumneavoastră resetează cota? " "(Opțional cu hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Se reia descărcarea după resetarea cotei?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Perioadă Cotă" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Cota se resetează în fiecare zi, săptămână sau lună ?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Verifică înainte de descărcare" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Încearcă să prezici decărcarea cu succes înaintea descărcării reale (mai " "lent!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Număr Maxim reîncercări" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Număr Maxim reîncercări pe server" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Anulează sarcini care nu pot fi terminate" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Atunci când e clar că o sarcină va eșua din cauza lipsei de date pe " "server(e), anulează sarcina" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Adaugă Server" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Descriere server" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Nume de Utilizator" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Parolă" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Timp Expirare" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Timp Retenţie" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Dezactivat" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "" "0 este prioritatea cea mai ridicată, 99 este prioritatea cea mai scăzută" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Opţional" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Activează" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Şterge Server" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Test Server" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Resetează Statistici" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Testez detalii server..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Descărcat" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Note personale" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Adaugă Planificare" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Frecvenţă" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Acțiune" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argumente" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Planificări Curente" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Caseta de lângă numele fluxului trebuie să fie selectată pentru ca fluxul să" " fie verificat de obiecte noi automat.
Când un flux este adăugat , el " "va lua doar obiectele noi şi nu cele deja existente, cu excepţia când " "apăsaţi \"Descărcare Forţată\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Citeşte Flux" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Descărcare Forţată" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Ordine" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Tip" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filtru" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Acceptă" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Respinge" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Necesită" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "NecesităCategoria" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Cel puțin" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Cel mult" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "De la SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Potrivite" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Nepotrivit" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Descărcate" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Citeşte Toate Fluxurile Acum" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Notificări Email Sarcină Terminată" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Niciodată" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Întotdeauna" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Doar-erori" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Notificări Disc Plin" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Trimite email când discul este plin şi SABnzbd este întrerupt." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Trimite notificări RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Trimite email când un flux RSS adaugă sarcini în coadă." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "Server SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Setează serverul dvs. ISP pentru trimitere email." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Destinatar Email" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Adresă de email către care se trimite email." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Expeditor Email" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Cine ar trebui să spunem că a trimis email?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "Nume Cont OPŢIONAL" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Pentru email autentificat, nume cont." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "Parolă Cont OPŢIONAL" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Pentru email autentificat, parola." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Notificare Trimisă!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Activează NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Centru Notificări" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Activează notificări Windows" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Notificări Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotificăOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Activează notificări Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Necesită cont Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Cheie API pentru Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Cheie API personală pentru Prowl (necesară)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Activează notificări Pushover" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Necesită cont Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Token de Aplicație" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Token de Aplicație (necesar)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Cheie Utilizator" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Cheie Utilizator (necesară)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Dispozitiv(e)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Dispozitiv(e) la care să se trimită mesajul" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Activează notificare Pushbullet" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Necesită un cont Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Cheie API personală" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Cheie personală API Pushbullet (necesară)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Dispozitiv" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Dispozitiv la care să se trimită mesajul" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Scipt de Notificare" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Activează scriptul de notificare" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Execută script personalizat" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "Ce script să fie executat pentru notificări?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Finalizarea unei căi cu un asterix * va preveni crearea de dosare sarcini." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Dosarele relative se bazează pe" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Dosar/Cale" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Model Cheie" #: sabnzbd/skintext.py msgid "Clear" msgstr "Şterge" #: sabnzbd/skintext.py msgid "Presets" msgstr "Presetări" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Categorii Afectate" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Semnificaţie" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Șablon" #: sabnzbd/skintext.py msgid "Result" msgstr "Rezultat" #: sabnzbd/skintext.py msgid "Title" msgstr "Titlu" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Nume Film" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Nume.Film" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Nume_Film" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Nume Serial" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Nume.Serial" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Nume_Serial" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Număr Sezon" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Număr Episod" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Nume Episod" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Nume.Episod" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Nume_Episod" #: sabnzbd/skintext.py msgid "Extension" msgstr "Extensie" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Număr Parte" #: sabnzbd/skintext.py msgid "Decade" msgstr "Deceniu" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Nume de Fişier Original" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Litere Mici" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py msgid "text" msgstr "text" #: sabnzbd/skintext.py msgid "file" msgstr "fișier" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Şir Caractere Sortare" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "În dosare" #: sabnzbd/skintext.py msgid "No folders" msgstr "Fără dosare" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "ajustare nume fişier" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Rezultat Procesat" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Toate" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Opţiuni folosite rar. Pentru explicaţiile şi semnificaţia lor, click pe " "meniul Ajutor şi vizitează pagina Wiki.
Nu modificaţi aceste setări fără" " a verifica mai întâi pagina Wiki , pentru că unele pot cauza probleme " "serioase .
Valorile originale sunt în paranteze ." #: sabnzbd/skintext.py msgid "Values" msgstr "Valori" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Editează Detalii NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Şterge" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Nume de fișier" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Spațiu liber" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Dosar Temporar" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Operaţii-Multiple" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Ține-ți tasta shift pentru a selecta un interval" #: sabnzbd/skintext.py msgid "Check all" msgstr "Selectează tot" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Repornește SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "La terminarea coadei de descărcare" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Opțiuni stare și interfață" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Sau trage fișierele în fereastră!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Am pierdut conexiunea cu SABnzbd.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "În cazul repornirii SABnzbd acest ecran va dispărea în mod automat!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "ATENŢIE:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Descarcă" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Interfață Web" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Rată actualizare" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Folosește setările globale de interfață" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Limită maximă la coadă" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Limită maximă la Istoric" #: sabnzbd/skintext.py msgid "Date format" msgstr "Format dată" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "pagină" #: sabnzbd/skintext.py msgid "Loading" msgstr "Se încarcă" #: sabnzbd/skintext.py msgid "articles" msgstr "articole" #: sabnzbd/skintext.py msgid "Rename" msgstr "Redenumește" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Coadă reparare" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Arată conexiuni active" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Deblochează" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Sarcini orfane" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Trimite înapoi la coadă" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Șterge tot" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Reîncearcă toate" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Descarcă NZB din URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Încarcă NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Opţional specifică un nume de fişier" #: sabnzbd/skintext.py msgid "Submit" msgstr "Trimite" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Elimină toate fișierele selectate" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Ascunde/arată fișierele finalizate" #: sabnzbd/skintext.py msgid "Top" msgstr "Vârf" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Coadă" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Vezi Jurnal Script" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "Stocarea locală (module cookie) sunt dezactivate în browserul dumneavoastră," " setările de interfață vor fi pierdute la încridegea browserului!" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Personalizat" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Aspect compact" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Interfață tabelară
(coadă și istoric separate)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Viteză" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Confirmă Ştergere Coadă" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Confirmă Ştergere Istoric" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Cât timp sau până când doriți să întrerupeți? (în Engleză!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Ne pare rău, nu am putut interpreta informațiile. Încearcă din nou." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pauză timp de..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Reîmprospătează" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sortează după Vârstă Cel mai Vechi→Cel mai Nou" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sortează după Vârstă Cel mai Nou→Cel mai Vechi" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sortează după Nume A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sortează după Nume Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sortează după Mărime Cel mai Mic→Cel mai Mare" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sortează după Mărime Cel mai Mare→Cel mai Mic" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Încărcare" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Forțează deconectarea" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Elimin sarcina" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Elimin sarcinile" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Vrăjitor Pornire-Rapidă SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Versiune SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Precedent" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Următorul" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Detalii Server" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "" "Vă rugăm să introduceţi detaliile furnizorului dvs principal de usenet." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Numărul de conexiuni permis de furnizor" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "De ex. 8 sau 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Selectează doar dacă furnizorul dvs. permite conexiuni SSL." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Clic pentru a testa detaliile introduse." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "De ex." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Instalarea este acum completă!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd va rula acum în fundal." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Închidere a oricărei ferestrele browser/file NU va închide SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Este recomandat să faceţi clic dreapta şi să faceţi o scurtatură , pe care " "să o folosiţi pentru a accesa SABnzbd când rulează în fundal." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Ajutor suplimentar poate fi găsit pe pagina noastră" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Du-te la SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Închide SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Porneşte Vrăjitor" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd vine cu ABSOLUT NICI O GARANŢIE.\n" "Acesta este software gratis, şi sunteţi binevenit să-l redistribuiţi în anumite condiţii.\n" "Este licenţiat sub GNU General Public License versiunea 2 sau (la opţiunea dumneavoastră) orice versiune ulterioară.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Redenumire fişiere similare : %s în %s nereuşită" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Acces neautorizat" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "Fișierul nu este pe server" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER S-A BLOCAT" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Fişier NZB Inutilizabil" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Descărcare URL nereuşită; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Încerc să descarc NZB de la %s" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.213331 SABnzbd-4.3.2/po/main/it.po0000644000000000000000000025710014625637207014546 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Language-Team: Italian (https://app.transifex.com/sabnzbd/teams/111101/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "" #: SABnzbd.py msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "" #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "" #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "" #: sabnzbd/api.py msgid "Invalid server details" msgstr "" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "" #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Timed out" msgstr "" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "" #: sabnzbd/api.py msgid "Connection Successful!" msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "" #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "" #: sabnzbd/api.py msgid "Resolving address" msgstr "" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "" #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "" #: sabnzbd/downloader.py msgid "Resuming" msgstr "" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "" #: sabnzbd/interface.py msgid "Daily" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "" #: sabnzbd/interface.py msgid "Back" msgstr "" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "" #: sabnzbd/misc.py msgid "h" msgstr "" #: sabnzbd/misc.py msgid "m" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "" #: sabnzbd/panic.py msgid "Problem with" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "" #: sabnzbd/panic.py msgid "Fatal error" msgstr "" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "" #: sabnzbd/panic.py msgid "Access denied" msgstr "" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "" #: sabnzbd/postproc.py msgid "Moving" msgstr "" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "" #: sabnzbd/skintext.py msgid "day" msgstr "" #: sabnzbd/skintext.py msgid "days" msgstr "" #: sabnzbd/skintext.py msgid "week" msgstr "" #: sabnzbd/skintext.py msgid "Month" msgstr "" #: sabnzbd/skintext.py msgid "Year" msgstr "" #: sabnzbd/skintext.py msgid "Day of month" msgstr "" #: sabnzbd/skintext.py msgid "This week" msgstr "" #: sabnzbd/skintext.py msgid "This month" msgstr "" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "" #: sabnzbd/skintext.py msgid "Total" msgstr "" #: sabnzbd/skintext.py msgid "on" msgstr "" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "" #: sabnzbd/skintext.py msgid "Python Version" msgstr "" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "" #: sabnzbd/skintext.py msgid "or" msgstr "" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "" #: sabnzbd/skintext.py msgid "Cancel" msgstr "" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "" #: sabnzbd/skintext.py msgid "Saving.." msgstr "" #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "" #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "" #: sabnzbd/skintext.py msgid "Uptime" msgstr "" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "" #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "" #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py msgid "Tuning" msgstr "" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "" #: sabnzbd/skintext.py msgid "Language" msgstr "" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "" #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "NZB Key" msgstr "" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "" #: sabnzbd/skintext.py msgid "External internet access" msgstr "" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "" #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "" #: sabnzbd/skintext.py msgid "Full API" msgstr "" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" #: sabnzbd/skintext.py msgid "User Folders" msgstr "" #: sabnzbd/skintext.py msgid "Browse" msgstr "" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "" #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "" #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "" #: sabnzbd/skintext.py msgid "Password file" msgstr "" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" #: sabnzbd/skintext.py msgid "System Folders" msgstr "" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "" #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "" #: sabnzbd/skintext.py msgid "Post processing" msgstr "" #: sabnzbd/skintext.py msgid "Naming" msgstr "" #: sabnzbd/skintext.py msgid "Quota" msgstr "" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "" #: sabnzbd/skintext.py msgid "Check before download" msgstr "" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "" #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "" #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "" #: sabnzbd/skintext.py msgid "Email Sender" msgstr "" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "" #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "" #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "" #: sabnzbd/skintext.py msgid "Clear" msgstr "" #: sabnzbd/skintext.py msgid "Presets" msgstr "" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "" #: sabnzbd/skintext.py msgid "Meaning" msgstr "" #: sabnzbd/skintext.py msgid "Pattern" msgstr "" #: sabnzbd/skintext.py msgid "Result" msgstr "" #: sabnzbd/skintext.py msgid "Title" msgstr "" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "" #: sabnzbd/skintext.py msgid "Show Name" msgstr "" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "" #: sabnzbd/skintext.py msgid "Season Number" msgstr "" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "" #: sabnzbd/skintext.py msgid "Extension" msgstr "" #: sabnzbd/skintext.py msgid "Part Number" msgstr "" #: sabnzbd/skintext.py msgid "Decade" msgstr "" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "" #: sabnzbd/skintext.py msgid "TEXT" msgstr "" #: sabnzbd/skintext.py msgid "text" msgstr "" #: sabnzbd/skintext.py msgid "file" msgstr "" #: sabnzbd/skintext.py msgid "Sort String" msgstr "" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "" #: sabnzbd/skintext.py msgid "No folders" msgstr "" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" #: sabnzbd/skintext.py msgid "Values" msgstr "" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "" #: sabnzbd/skintext.py msgid "Free Space" msgstr "" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "" #: sabnzbd/skintext.py msgid "Check all" msgstr "" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "" #: sabnzbd/skintext.py msgid "Fetch" msgstr "" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "" #: sabnzbd/skintext.py msgid "History item limit" msgstr "" #: sabnzbd/skintext.py msgid "Date format" msgstr "" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "" #: sabnzbd/skintext.py msgid "Loading" msgstr "" #: sabnzbd/skintext.py msgid "articles" msgstr "" #: sabnzbd/skintext.py msgid "Rename" msgstr "" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "" #: sabnzbd/skintext.py msgid "Unblock" msgstr "" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "" #: sabnzbd/skintext.py msgid "Delete All" msgstr "" #: sabnzbd/skintext.py msgid "Retry all" msgstr "" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "" #: sabnzbd/skintext.py msgid "Submit" msgstr "" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "" #: sabnzbd/skintext.py msgid "Top" msgstr "" #: sabnzbd/skintext.py msgid "Bottom" msgstr "" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "" #: sabnzbd/skintext.py msgid "Pause for..." msgstr "" #: sabnzbd/skintext.py msgid "Refresh" msgstr "" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "" #: sabnzbd/skintext.py msgid "Server Details" msgstr "" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "" #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "" #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "" #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "" #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2118478 SABnzbd-4.3.2/po/main/es.po0000644000000000000000000036052614625637207014550 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Ester Molla Aragones , 2020 # 1024mb , 2023 # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Spanish (https://app.transifex.com/sabnzbd/teams/111101/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Advertencia" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Se ha producido un error" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Error al iniciar la interfaz web" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" "No se puede encontrar la plantilla web: %s, intentando con la plantilla " "estandar" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools deshabilitado: ¡no se ha encontrado la versión correcta! (Se ha " "encontrado la v%s, se esperaba la v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 binario... NO encontrado!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "Su versión UnRAR es %s, recomendamos la versión %s o superior.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar binario... NO encontrado" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "No se encontró el binario de 7za" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "Faltan módulos imprescindibles, no se puede iniciar la descarga." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Tenga en cuenta que el nombre de equipo 0.0.0.0 necesitará una dirección " "IPv6 para el acceso externo" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "Los puertos de HTTP y de HTTPS no pueden ser iguales" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "Se ha iniciado SABnzbd con codificación %s, la codificación debería ser " "UTF-8. Habrá problemas con el archivo en Unicode y con los nombres de " "directorio en las descargas." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" "La umask actual (%o) podría denegarle acceso a SABnzbd a los archivos y " "carpetas que este crea." #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" "No se han podido cargar los certificados adicionales del paquete certifi" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS deshabilitado debido a la falta de archivos CERT y KEY" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" "HTTPS deshabilitado debido a que los archivos CERT y KEY no son válidos" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Error al iniciar la interfaz web: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s comenzó" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Cierre de SABnzbd terminado" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Señal %s capturado, guardando y saliendo..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Error grave al guardar estado" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "Reiniciando a causa de un posprocesador colgado" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "Reiniciando debido al cuelgue del descargador" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "Reiniciando debido al cuelgue del ensamblador" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "No se puede acceder al archivo PID %s" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Email exitoso" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Notificación de prueba" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "El hostname no está definido." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "No se han configurado conexiones. Configure al menos una conexión." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Contraseña protejido por ******, favor reingresar" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Detalles de servidor invalidos" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "La dirección del servidor «%s:%s» no es válida." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Tiempo agotado: Trate conectar en puerto diferente o encender SSL." #: sabnzbd/api.py msgid "Timed out" msgstr "Tiempo agotado" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Protocolo SSL desconocido: intente desabilitar el SSL o conectarse a un " "puerto diferente." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "El servidor necesita usuario y contraseña." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "¡Conexión exitosa!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Autenticación fallida, compruebe el usuario o la contraseña." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Demasiadas conexiones; pause las descargas o inténtelo de nuevo más tarde" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "No se pudo determinar el resultado de la conexión (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Resolviendo sitio" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ninguno" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Predeterminado" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disco lleno! Pausando la cola" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Error de disco al crear el archivo %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Error grave en el ensamblador" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Muy poco espacio en disco forzando PAUSA" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "Se ha pausado la tarea \"%s\" debido al archivo codificado RAR (se han " "probado todas las contraseñas, si se han suministrado)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "Se ha cancelado la tarea \"%s\" debido al archivo codificado RAR (se han " "probado todas las contraseñas, si se han suministrado)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Abortado, detectamos cifrados" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" "Se ha encontrado una extensión no deseada en el fichero RAR \"%s\". El " "fichero no deseado es %s " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Se ha encontrado una extensión desconocida en el fichero rar %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Se interrumpió la acción porque se detectó una extensión no deseada" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" "La tarea \"%s\" está codificada probablemente debido al RAR con el mismo " "nombre dentro de este RAR" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" "La tarea \"%s\" está probablemente codificada: \"contraseña\" en el nombre " "de archivo \"%s\"" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Quota gastado, pausando cola" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Parámetro incorrecto" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s no es una dirección de correo electrónico válida." #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Se necesita la dirección del servidor" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Dirección del servidor no válida." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s no es un valor octal correcto" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Cola no esta vacía, no se puede cambiar el directorio" #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "Configuración bloqueada, no se puede guardar la configuración" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "No se puede escribir al archivo INI %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "No se puede crear copia de seguridad del archivo %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Contraseña incorrectamente codificado %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "No se puede escribir en la base de datos de historia, compruebe los derechos" " de acceso !" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "" "La base de datos del Historial está dañada, se ha reemplazado vaciándola" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Comando SQL ha fallado, vea el registro" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "No se pudo cerrar el base de datos, vea el registro" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Registro de etapa invalido para transferencia terminada %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Fallo del decodificador: no hay memoria" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Error inespecifico mientras descodificando %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "Descomprimir directamente" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Completado" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Descompresos %s archivos/directorios en %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "Descomprimir directamente se ha habilitado automáticamente." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "Las tareas comenzarán a descomprimirse durante la descarga para reducir el " "tiempo de procesamiento posterior. Solamente para las tareas que no " "necesitan reparación." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Directorio Watched %s no se puede leer" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Reanudando" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "En pausa" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Debe establecer un ancho de banda máximo antes de poder establecer un límite" " de ancho de banda" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Error en inicio de conexion a servidor %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "No se puede resolver el nombre de servidor" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "El servidor %s se ignorará por %s minutos" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Error al inicializar %s@%s con la razón: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Demasiadas conexiones con el servidor %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Registraccion fallo para servidor %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Ha fallado la conexión a %s@%s, el mensaje=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Error sospechoso en downloader" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Apagando" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "No se pudo conectar al servidor de correo" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "No se pudo inicializar la conexión TLS" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "El servidor no respondió adecuadamente al saludo helo" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "No se pudo autenticar con el servidor de correo" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "No se ha encontrado ningún método de autenticación adecuado" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "" "Se produjo un fallo de autenticación desconocido en el servidor de correo" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "No se pudo enviar correo electrónico" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "No se pudo cerrar la conexión de correo" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "No se ha podido enviar, faltan datos" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "No se pudo encontrar plantillas de email en %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Sin destinatarios no se pudo enviar el email" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "No se puede leer %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "No se encontraron plantillas de correo electrónico" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Para: %s\n" "De: %s\n" "Fecha: %s\n" "Asunto: SABnzbd informa de un disco lleno\n" "\n" "Hola:\n" "\n" "SABnzbd ha detenido las descargas porque casi se ha llenado el disco.\n" "Haga algo de espacio y reanude SABnzbd manualmente.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "No se pudo crear el directorio %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "Directorio %s: Error al acceder a %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "No se puede cambiar los permisos de %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Error al crear (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Error al mover %s a %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Fallo en tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Guardar de %s no se pudo completar." #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Cargar de %s no se pudo completar." #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "Se deniega la conexión con el nombre de equipo \"%s\" desde:" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Usuario conectado a la interfaz web" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Usuario conectado" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Falta clave de API, favor ingresar la clave desde Config->General en tu " "aplicacion externa:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Clave de API erróneo, favor ingresar la clave correcta desde Config->General" " en tu aplicacion externa:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Intento fallido de inicio de sesión desde %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Canal" #: sabnzbd/interface.py msgid "Daily" msgstr "Diariamente" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Lunes" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Martes" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Miércoles" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Jueves" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Viernes" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Sábado" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Domingo" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "desactivado" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "¡Servidor no definido!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" "El directorio Categoría no puede ser un subdirectorio del directorio de " "descargas temporal." #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "ERROR:" #: sabnzbd/interface.py msgid "Back" msgstr "Atrás" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "¡Actualización Disponible!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "Error al subir archivo: %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Error al crear la llave SSL y el certificado" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "Su archivo de contraseña contiene más de 30 contraseñas, probar todas estas " "contraseñas conlleva mucho tiempo. Intente registrar solamente contraseñas " "útiles." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "Error al leer el archivo de contraseña %s" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "[%s] El comando en build_command no está definido." #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" "La secuencia de comandos Python \"%s\" no tiene configurado el permiso de " "ejecutar (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Ordenación de Series" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Ordenar por fecha" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "Clasificación de películas" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Ejecutando script" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "" "El anidamiento de descompresiones ha resultado demasiado profundo [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Uniendo" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Secuencia incompleta de archivos a unir" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Error al unir el fichero %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Error \"%s\" al unir archivos" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Error \"%s\" al ejecutar file_join en %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] %s ficheros unidos." #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Error al descomprimir, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Error \"%s\" al descomprimir ficheros RAR" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Error \"%s\" al ejecutar rar_unpack sobre %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "¡Error al eliminar %s!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Intentado descomprimir rar con contraseña \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Descomprimiendo" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Error al descomprimir; Imposible encontrar %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Error de CRC al descomprimir" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" "La descompresión ha fallado, el archivo es demasiado grande para el sistema " "de archivos (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "" "Error al descomprimir; ¿Error de escritura, o tal vez el disco está lleno?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Aperture de archivo fallo, la via es muy larga" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Error al descomprimir; El archivo está protegido por contraseña" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Archivo RAR inutilizable" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Fichero RAR corrupto" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Tratando 7zip con la contraseña \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "ver fichero de log" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Chequeo Rápido" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparar" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Chequeo Rápido OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Iniciando reparación" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "La reparación ha fallado, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Error %s al ejecutar par2_repair en el conjunto %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Error %s al ejecutar par2_repair en el conjunto %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 ha recibido opciones incorrectas, chequea tus ajustes en " "Preferencias->Switches" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificado en %s, todos los archivos correctos" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificado en %s, se necesita reparar" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Archivos par2 no válidos o parámetros PAR2 no válidos, no se puede verificar" " ni reparar" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Recuperando %s bloques..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Recuperando" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Ha fallado la reparación, no existen bloques de reparación suficientes (%s " "short)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Reparando" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Reparado en %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "Reparación de verificación" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Disco lleno" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Comprobando archivos extra" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Verificando" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Verificando" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Intentando verificación por SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "Restante" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Este servidor no permite SSL en este puerto" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "Desajuste del certificado de nombre de equipo: el nombre de equipo del " "servido no está en la lista del certificado. Se trata de un problema con el " "servidor." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" "El certificado no es válido. Probablemente se trate de un problema con el " "servidor." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "El servidor %s utiliza un certificado que no es de confianza [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Inicio/Apagado" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pausar" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Reanudar" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB añadido" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Procesamiento posterior empezado" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Tarea finalizada" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Trabajo fallido" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Cola terminada" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Otros mensajes" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Abrir todo el folder" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "No disponible" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "Fallo al enviar la notificación macOS" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "No se pudo enviar el mensaje de Prowl" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Mala respuesta de Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "No se pudo enviar el mensaje de Pushover" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Mala respuesta de Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "No se updo enviar el mensaje de Pushbullet" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" "La secuencia de comandos ha devuelto el código de salida %s y ha emitido " "\"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "El script de notificación \"%s\" no existe" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Fallo al mandar la notificación de Windows" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "No se puede crear el archivo temporal para %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Error al añadir %s, eliminando" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Error al quitar %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Error al importar %s ficheros desde %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "" "Se ha encontrado un fichero de cola incompatible, no se puede continuar" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Error al cargar %s, archivo corrupto" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB añadido a la cola" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorando NZB Duplicado \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "Fallo al duplicar NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "Duplicar NZB" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "Fichero NBZ inválido: %s, omitiendo (razón=%s)" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Fichero NZB vacío: %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" "La secuencia de comandos de la cola preestablecida ha marcado la tarea como " "fallida" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "Extensión no deseada en el archivo %s (%s)" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Abortado, No puede ser completado" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Error importando %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLICADO" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "ENCRIPTADO" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "DEMASIADO GRANDE" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "INCOMPLETO" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "NO DESEADO" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "ESPERAR %s seg" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "PROPAGANDO %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Descargado en %s a una media de %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Edad" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artículos estaban mal formados." #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artículos no encontrados" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artículos contenían duplicados inconexos" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Pausando NZB duplicados \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Advertencias" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Inactivo" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Cola" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Limpiar Cola" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historial" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Purgar historial" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Limitar Velocidad" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "mín" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Escanear directorio bajo observación" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Leer todos los canales RSS" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Carpeta Completa" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Carpeta Incompleta" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Resolver un problema" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Reiniciar" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Reiniciar sin sesión iniciada" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Salir" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Encolar los primeros 10 elementos" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Vacía" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Histórico últimos 10 elementos" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Ir al Asistente" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Deteniendo..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problema con" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd necesita un puerto tcp/ip libre para su servidor web interno.
\n" " Se ha intentado en el puerto %s en %s, pero no está disponible.
\n" " Puede que otro software ya esté utilizando este puerto, o que SABnzbd ya esté en ejecución.
\n" "
\n" " Por favor reinicia SABnzbd indicando un número de puerto diferente." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Si obtiene este mensaje de error consecutivamente, por favor inténtelo de " "nuevo con otro número.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd necesita una dirección IP para su servidor web interno.
\n" " Has especificado una dirección inválida.
\n" " Valores seguros son localhost y 0.0.0.0
\n" "
\n" " Por favor reinicia SABnzbd con una dirección o nombre de host correctos." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd ha detectado información guardada de otra versión de SABnzbd
\n" " pero no puede ser reutilizada por la otra versión.

\n" " Tal vez quieras finalizar primero tu cola actual con la otra versión.

\n" " Tras ello, ejecuta este programa con la opción \"--clean\".
\n" " Esto eliminará la cola e historial actuales!.
\n" " SABnzbd leer el archivo \"%s\"" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd no puede encontrar sus ficheros de la interfaz web en %s.
\n" " Por favor instala el programa de nuevo.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd ha detectado un error grave:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd ha detectado que el fichero sqlite3.dll no existe.

\n" " Algunos virus de de pésima calidad eliminan este fichero.
\n" " Por favor revisa la configuración de tu antivirus y quéjate a tu proveedor del AntiVirus. Tras ello reinstala SABnzbd.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Presiona la Tecla de Windows+R y teclea la línea (ejemplo)" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Apre una ventana de Consola y teclea la línea (ejemplo)" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "El programa no ha arrancado!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Error grave" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" "No es posible vincular al puerto %s en %s. Otro software está utilizando el " "puerto o SABnzbd ya se está ejecutando." #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "" "Imposible iniciar el navegador, probablemente no se le haya encontrado" #: sabnzbd/panic.py msgid "Access denied" msgstr "Acceso denegado" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Error %s: Necesitas introducir un usuario y contraseña válidos." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" "Se ha encontrado una cola antigua, utilice Estado->Reparar para convertir la" " cola" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Compilación de regex para término fallo: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" "Directorio de descargas completo %s está en el sistema de archivos FAT, y " "limita el tamaño de archivo máximo a 4GB" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "La descarga fallo, solo %s de los %s requeridos estan disponibles" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Descarga fallida - No está en tu(s) servidor(es)" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Post-Procesado" #: sabnzbd/postproc.py msgid "Moving" msgstr "Moviendo" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Enviado(s) %s a la cola" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Error al renombrar \"%s\" a \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Error al mover ficheros" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Ejecutando script de usuario %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "El código de retorno del Script es %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Se ejecutó %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Más" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Error al post-procesar %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "La descarga falló" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Ha fallado la limpieza de %s" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Descarga Completada" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Imposible crear directorio final %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] No hay conjuntos par2" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Han fallado algunos ficheros al verificarse \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Se ha verificado correctamente utilizando ficheros SFV" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "Intentando la verificación basada en RAR" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Con contraseña" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] La verificación basada en RAR ha fallado: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "Los archivos RAR se han verificado con éxito" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "No se han podido verificar los archivos RAR" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "No hay un archivo rar anterior correspondiente para %s" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Error al eliminar %s" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Error al hibernar el sistema" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Error al suspender el sistema" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Error al apagarel sistema" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "Se ha recibido una excepción DBus %s" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "iaDescripción de canal RSS incorrecta \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "No se encontró autenticación válida para el feed %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" "Error del lado servidor (código enviado por el servidor: %s); no se ha " "podido conseguir %s en %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Error al recuperar RSS desde %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "El servidor %s utiliza un certificado HTTPS no fiable" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "El canal RSS %s estaba vacío" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Canal Incorrecto" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Entrada RSS vacía (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Mostrar interfaz" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pausar durante" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pausar 5 minutos" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pausar 15 minutos" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pausar 30 minutos" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pausar 1 hora" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pausar 3 horas" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pausar 6 horas" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Apagar" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Restante" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Añadir NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Planificación incorrecta %s a las %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Acción desconocida: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Planificación para servidor %s inexistente" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Intentando cambiar el estado de servidor inexistente %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Descargar" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Unir ficheros" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Descomprimir" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Script" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Fuente" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servidores" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Fallido" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "En espera" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Reparando..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Extrayendo..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Moviendo..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Ejecutando script..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Recuperando bloques extra..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Chequeo Rápido..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Verificando..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "deshabilitar servidor" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "habilitar servidor" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Límite de Velocidad" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pausar todo" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pausar post-procesamiento" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Reanudar post-procesamiento" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Leer entradas RSS" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Eliminar trabajos fallidos" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Eliminar trabajos completados" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pausar trabajos de prioridad baja" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pausar trabajos de prioridad normal" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pausar trabajos de prioridad alta" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Reanudar trabajos de prioridad baja" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Reanudar trabajos de prioridad normal" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Reanudar trabajos de prioridad alta" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Habilitar la administración de cuota" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Gestión de cuotas Desactivar" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "Pausar tareas con la categoría" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "Reanudar tareas con la categoría" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Apagado" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Muy baja" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Moderada" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Alta" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Emergencia" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Baja" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "hora" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "horas" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "mins" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "seg" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "segundos" #: sabnzbd/skintext.py msgid "day" msgstr "día" #: sabnzbd/skintext.py msgid "days" msgstr "días" #: sabnzbd/skintext.py msgid "week" msgstr "semana" #: sabnzbd/skintext.py msgid "Month" msgstr "Mes" #: sabnzbd/skintext.py msgid "Year" msgstr "Año" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Día del mes" #: sabnzbd/skintext.py msgid "This week" msgstr "Esta semana" #: sabnzbd/skintext.py msgid "This month" msgstr "Este mes" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Hoy" #: sabnzbd/skintext.py msgid "Total" msgstr "Total" #: sabnzbd/skintext.py msgid "on" msgstr "activado" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametros" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Version de Python" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Pagina principal" #: sabnzbd/skintext.py msgid "or" msgstr "o" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Equipo" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Cancelar" #: sabnzbd/skintext.py msgid "Log in" msgstr "Iniciar sesión" #: sabnzbd/skintext.py msgid "Log out" msgstr "Cerrar sesión" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Mantenerme conectado" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Guardar" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Guardando..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "¿Estás seguro?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Inicio" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Config." #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Estado" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Ayuda" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Foro" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Problemas" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "¡Apoye el proyecto, haga una donación!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "General" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Directorios" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Switches" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Planificación" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Notificaciones" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Correo" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Categorías" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Ordenación" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Especial" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Buscar" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "¿Seguro que deseas detener SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Añadir" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Categoría" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioridad" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparar" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Descomprimir" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Eliminar" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Forzar" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Parar" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Introduzca la URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Apagar PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Suspender PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Hibernar PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Apagar SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "En proceso" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Nombre" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Reintentar" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Scripts" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "¿Eliminar todos los elementos de la cola?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Purgar NZBs" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Purgar NZBs y Eliminar Ficheros" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Eliminar NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Eliminar NZB y Eliminar Ficheros" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Artículos no encontrados" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Quota disponible" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manual" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Reinicializar Quota ahora" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Ocultar detalles" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Mostrar detalles" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Mostrar los Fallidos" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Mostrar Todo" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Tamaño" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Purgar los NZBs fallidos" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Purgar NZBs fallidos y sus ficheros" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Purgar NZBs completados" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Purgar los NZB en la página actual" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "NZB Suplementario Opcional" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Ruta" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Vuelva a intentar todos los trabajos con errores" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Forzar desconexión" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" "Desconectar todas las conexiones activas a los servidores usenet. La " "conexiones volverán a abrirse tras unos segundos si hay elementos en la " "cola." #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Se enviará un email de prueba a tu cuenta" #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Ver Logging" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Email de prueba" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Registros de sucesos" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Errores/Advertencias" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+Depuración" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Conexiones" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Identificador de artículo" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Conjunto de ficheros" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Habilitado" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "¡Ha fallado la conexión!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Dirección IPv4 local" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Dirección IPv4 pública" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "Dirección IPv6" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nombre del servidor / Búsqueda de DNS" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Rendimiento del sistema ( Pystone )" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "La velocidad de descarga carpeta" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Velocidad completa carpeta" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "Ancho de banda de internet" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Repita la prueba" #: sabnzbd/skintext.py msgid "Test download" msgstr "Descarga de prueba" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" "Añade una prueba verificada NZB del tamaño especificado con datos " "aleatorios. Puede utilizarse para verificar su configuración." #: sabnzbd/skintext.py msgid "Config File" msgstr "Fichero de Config" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Caché utilizada" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Esto reiniciará SABnzbd.
Usalo cuando creas que el programa está " "colgado.
Las descargas se pausarán antes de reiniciar, y se reanudarán " "a continuación." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "Si la autenticación esta activada, tendrás que conectarte de nuevo." #: sabnzbd/skintext.py msgid "Advanced" msgstr "Avanzado" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Existen trabajos huérfanos en la carpeta de descarga.
Puedes escoger " "por eliminarlos (incluyendo los ficheros) o enviarlos de nuevo a la cola." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "El botón \"Reparar\" reiniciará SABnzbd y hará una reconstrucción
completa del contenido de la cola, preservando las descargas ya " "terminadas.
Esto modificará el orden de la cola." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "No se han guardado los cambios, y se perderán." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "Cuando tu dirección IP cambie o reinicies SABnzbd, la sesión caduca." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Habilitar 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Versión" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Tiempo en Activo" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Copia de seguridad" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Lee la ayuda en la Wiki (inglés) acerca de esto!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Reiniciando SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Los cambios requieren reiniciar SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Servidor web de SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Host de SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Dónde debería escuchar el Host de SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Puerto de SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Puerto en que SABnzbd debería escuchar" #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Usuario SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Nombre de usuario opcional" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Contraseña de SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Contraseña opcional" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" "Si el host de SABnzbd o el puerto está expuesto al internet, su " "configuración actual le permitirá acceso externo total a la interfaz de " "SABnzbd." #: sabnzbd/skintext.py msgid "Security" msgstr "Seguridad" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Habilitar HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Habilia el acceso a la interfaz con una dirección HTTPS" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "Puerto HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Si se deja vacío, el puerto estándar escuchará por HTTPS" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "Certificado HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Nombre de archivo o ruta al Certificado SSL" #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" "Genere un certificado autofirmado nuevo y una llave. ¡Requiere reiniciar " "SABnzbd!" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "Clave privada SSL" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Nombre de archivo o ruta a la clave privada SSL" #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "Cadena de Certificados HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Nombre de archivo o ruta de acceso a la cadena de HTTPS." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Ajustes" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Intervalo de chequeo RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Intervalo de Chequeo (en minutos, mínimo 15). No toma efecto si utilizas el " "Planificador!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Velocidad máxima de línea" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Porcentaje de velocidad de línea" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Porcentaje de la velocidad de la línea que SABnzbd debería utilizar, por " "ejemplo 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Límite de cacheo de artículos" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Cachear artículos en memoria para reducir el acceso a disco.
En " "bytes, opcionalmente seguido de K,M,G. Por ejemplo: \"64M\" o \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Lista de elementos a limpiar" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Lista de extensiones de archivo que se deben eliminar después de la descarga" "
Por ejemplo : . nfo o nfo, sfv < /b>" #: sabnzbd/skintext.py msgid "History Retention" msgstr "Historial de retención" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "Mantener todas las tareas" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "Tareas" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Guardar cambios" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Restaurar valores por defecto" #: sabnzbd/skintext.py msgid "Reset" msgstr "Reiniciar" #: sabnzbd/skintext.py msgid "Language" msgstr "Idioma" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Selecciona un idioma para la interfaz web." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "¡Ayúdanos a traducir SABnzbd en tu idioma!
Traduce textos que aun no " "tienen ninguna traducción o mejora los que ya lo están traducidos aquí:" #: sabnzbd/skintext.py msgid "API Key" msgstr "Clave API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Esta clave le permitirá a programas de terceros acceso completo a SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "Clave NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Esta clave permitirá acceso a programas de terceros para añadir NZBs a " "SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Generar nueva clave" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "Código QR de la clave API" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Acceso a internet externa" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Acceso denegado" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Añadir archivos NZB " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (sin Config)" #: sabnzbd/skintext.py msgid "Full API" msgstr "API completa" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Interfaz web completa" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Solo acceso externo requieren conexión de usuario" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTA: Los directorios se crean automáticamente al guardar. Puedes " "usar una ruta absoluta, exterior a los directorios predefinidos." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Directorios del usuario" #: sabnzbd/skintext.py msgid "Browse" msgstr "Examinar" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Directorio de descarga temporal" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Localización donde guardar descargas incompletas.
Sólo se puede " "cambiar si la cola est&aa; vací" #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Espacio libre mínimo para el directorio de descargas temporales" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Parar automáticamente cuando el espacio libre esté por debajo de este " "valor.
En bytes, opcionalmente seguido de K,M,G,T. Por ejemplo: " "\"800M\" ó \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Directorio de descargas completadas" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Ubicación donde guardar descargas finalizadas, totalmente procesaddas.
Puede ser obviado debido a categorías definidas por el usuario." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Auto reanudar" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Permisos para descargas completadas" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Ajustar patrón de permisos para ficheros/directorios completados.
En" " notación ocal. Por ejemplo:\"755\" ó \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Directorio a vigilar" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Directorio a monitorizar en busca de ficheros .nzb." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Velocidad de escaneo de la carpeta vigilada" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Número de segundos entre pasadas en busca de ficheros .nzb." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "Directorio de Scripts" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "Directorio que contiene secuencias de comandos del usuario." #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Directorio de plantillas de Email" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Directorio que contiene plantillas de email definidas por el usuario." #: sabnzbd/skintext.py msgid "Password file" msgstr "Archivo de contraseñas" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fichero que contiene todas las contraseñas a usar en ficheros RAR " "protegidos." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Directorios del sistema" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Directorio de administración" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Ubicación de la base de datos de historial y administración.
Sólo se" " puede cambiar si la cola está vacía." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Los datos no se moverán. Requiere queu SABnzbd sea reiniciado!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Directorio de Historial" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Ubicación de los ficheros de log para SABnzbd.
Requiere reiniciar " "SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Directorio de Backups de .nzbs" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Ubicación donde se guardarán los ficheros .nzb." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Directorio base por defecto" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Descargar todos los archivos PAR2" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" "Esto evita que se ejecuten varias reparaciones mediante la descarga de todos" " los archivos par2 cuando sea necesario." #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Activar descompresión recursiva" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Descomprimir archivos (rar,zip,7z) dentro de otros archivos." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignorar cualquier carpeta dentro de archivos" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Todos los archivos irán en una sola carpeta ." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Sólo obtener artículos para el primer elemento de la Cola" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Habilitar para usar menos memoria. Deshabilitar para prevenir que trabajos " "que se ralentizen bloqueen la cola." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Post-procesar sólo trabajos verificados" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Accion cuando un archivo RAR cifrado es bajado" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "In caso de PAUSA, necesitara escribir una contrasena para continuar el " "trabajo." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "Permitir comunicados adecuados" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Descartar" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "Etiquetar tarea" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "Tarea fallida (mover a historial)" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Acción al detectar extensiones no deseadas" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "extensiones no deseadas" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Habilitar verificacion basada en SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Realiza una verificación extra basada en ficheros SFV." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Script de usuario puede marcar un trabajo como fallado" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Cuando la secuencia de comandos de usuario devuelve un código de salida " "distinto de cero, el trabajo se marca como fallido ." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Habilitar renombrado de directorios" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Usa nombres temporales durante el procesado. Deshabilitalo si tu sistema se " "vuelve inestable con ello habilitado." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Script de usuario Pre-cola" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Se usa precediendo a la entrada de un NZB en la cola del sistema." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Parámetros PAR2 extra" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Parámetros Nice" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Parámetros IONice" #: sabnzbd/skintext.py msgid "External process priority" msgstr "Prioridad del proceso externo" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Desconectar si la cola está vacía" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Desconecta del servidor de Usenet cuando la cola está vacía, o pausada." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "Cola de clasificación automática" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" "Clasifique tareas de forma automática en la cola cuando se añade una tarea " "nueva." #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Demora de la propagación" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Los mensajes serán pausados hasta que alcancen al menos esta edad. Esta " "espera puede evitarse si se le da el valor Forzar a la prioridad de la " "tarea." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Buscar Nva Versión" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "También libera de prueba" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Reemplazar espacios en el nombre de directorio" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "" "Reemplaza los espacios con guiones bajos en los nombres de directorio." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Reemplazar puntos en los directorios" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Reemplaza los puntos con espacios en los nombres de directorio." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Hacer compatible con Windows" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" "Para los servidores : asegúrese de que los nombres son compatibles con " "Windows ." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Lanzar navegador al Arrancar" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Ejecuta el navegador por defecto del sistema al arrancar SABnzbd." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Pausar Descargas Durante el Post-Procesado" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Pausa las descargas al principio del post-procesado, y reanuda al terminar." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignorar Samples" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Filtra la descarga de ficheros de ejemplo (e.g. un sample de vídeo)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Eliminar tras descargar" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "Deobfuscar nombres de archivos finales" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" "Si los nombres de archivo de archivos (grandes) en el directorio final están" " demasiado encriptadas o no tienen sentido, se volverán a renombrar con el " "nombre de la tarea." #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "Validación del certificado HTTPS" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" "Verificar certificados al conectarse a indexadores y fuentes RSS usando " "HTTPS." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Servidor" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Post procesado" #: sabnzbd/skintext.py msgid "Naming" msgstr "Nombrado" #: sabnzbd/skintext.py msgid "Quota" msgstr "Cuota" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Cantidad de descarga permitida este mes (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Día de reinicio del conteo" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "En qué día del mes o semana (1=Lunes) resetea tu proveedor la cuota mensual?" " (Opcional con hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "¿Deberían las descargas resumirse tras reiniciarse la cuota?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Periodo de la cuota" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "¿Cada cuánto se resetea la cuota?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Chequear antes de descargar" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Intenta predecir si la descarga actual se completará con éxito (ojo, esto " "tarda!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "Cifrado SSL" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" "Mejora el rendimiento forzando un cifrado SSL con una intensidad inferior." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Reintentos máximos" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Máximo número de reintentos por servidor" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Trabajos abortados no pueden ser completados" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Cuando este bajando, si es claro que mucha data esta faltando, aborte el " "trabajo." #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Añadir servidor" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Descripción del servidor" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Puerto" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Nombre de usuario" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Contraseña" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Expiración del plazo (Timeout)" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Periodo de retención" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "Conexión segura al servidor" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "Verificación del certificado" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" "Mínimo: cuando se habilita el SSL, verifica la identidad del servidor " "utilizando sus certificados. Estricto: verifica y obliga a que el nombre de " "equipo sea equivalente." #: sabnzbd/skintext.py msgid "Disabled" msgstr "Deshabilitado" #: sabnzbd/skintext.py msgid "Minimal" msgstr "Mínimo" #: sabnzbd/skintext.py msgid "Strict" msgstr "Estricto" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 El prioridad más alta, 99 es la prioridad más baja" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Opcional" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" "Para los servidores poco fiables, se ignorará durante más tiempo en caso de " "fallos" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Habilitar" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Eliminar servidor" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Probar Servidor" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Resetear contadores" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Testeando información del servidor" #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Ancho de Banda" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Notas personales" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Añadir planificación" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Frecuencia" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Acción" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argumentos" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Tareas Programadas Actuales" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "La casilla junto al nombre de la fuente debería marcarse para habilitar la " "fuente y que se marquen automáticamente los nuevos elementos.
Cuando " "una fuente se añade, sólo se cogerán los elementos nuevos y nada de lo que " "ya exista, salvo que presiones \"Forzar Descarga\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "Separar varias URL con una coma" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Leer Fuente" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Forzar Descarga" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "Aplicar filtros" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Orden" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Tipo" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filtrar" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Aceptar" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Rechazar" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Necesita" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "RequiereCat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Al menos" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Como máximo" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "De SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "Desde mostrar SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Encontrado(s)" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "No encontrado" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Descargado" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Leer todas las fuentes ahora" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Notificación por email al terminar" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Nunca" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Siempre" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Sólo Errores" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Notificaciones de Disco Lleno" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Envía un email cuando el disco se ha llenado y SABnzbd se ha tenido que " "parar." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Enviar notificaciones RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Enviar email cuando una fuente RSS añade un trabajo a la cola." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "Servidor SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Indica los ajustes de tu correo electrónico saliente." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Destinatario" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Dirección de correo electrónico a la que enviar el mensaje." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Remitente" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "¿Quién quieres que aparezca como remitente?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "Nombre de usuario OPCIONAL" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "" "Para correos electrónicos con autentificación, poner el nombre de usuario." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "Contraseña de usuario OPCIONAL" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Para correos electrónicos con autentificación, poner la contraseña." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "¡Notificación enviada!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Habilitar NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Centro de Notificación" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Activar notificaciones Windows" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Notificaciones Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Activar notificaciones Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Necesitas una cuenta Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Clave API de Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Clave privada de la API de Prowl" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Activar notificaciones Pushover" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Necesitas una cuenta Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Token de aplicación" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Token de aplicación (obligatorio)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Clave de usuario" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Clave de usuario (obligatoria)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Dispositivo(s)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Dispositivo(s) a los que enviar el mensaje" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "Reintento de emergencia" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "Con cuánta frecuencia (en segundos) se enviará la misma notificación" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "Expiración de emergencia" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "Cuántos segundos continuará reintentándose su notificación" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Activar notificaciones Pushbullet" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Necesitas una cuenta en Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Clave API personal" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Tu clave API personal de Pushbullet (obligatoria)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Dispositivo" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Dispositivo al que enviar el mensaje" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Script de notificación" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Activar script de notificación" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Ejecutar un script personalizado" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "¿Que script deberíamos ejecutar para notificaciones?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "Los Indexer pueden suministrar una categoría dentro de NZB, que SABnzbd " "intentará emparejar con las categorías que se definen a continuación. " "Además, puede añadir términos a \"Categorías Indexer / Grupos\" para " "emparejar más categorías. Utilice comas para separar los términos. Se " "permite el uso de comodines en los términos.
Puede encontrar más " "información en la Wiki." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Terminar la ruta con un * previene que se creen directorios de trabajo." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Los directorios relativos, lo son a" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Directorio/Ruta" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "Categorías Indexer / Grupos" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Patrón" #: sabnzbd/skintext.py msgid "Clear" msgstr "Limpiar" #: sabnzbd/skintext.py msgid "Presets" msgstr "Preajustes" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Categorías Afectadas" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Significado" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Patrón" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultado" #: sabnzbd/skintext.py msgid "Title" msgstr "Título" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Nombre de Película" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Nombre.de.pelicula" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Nombre_de_pelicula" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Nombre de la Serie" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Nombre.serie" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Nombre_serie" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Número de la temporada" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Número del capítulo" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Nombre del capítulo" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Nombre.capítulo" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Nombre_capítulo" #: sabnzbd/skintext.py msgid "Extension" msgstr "Extensión" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Numero de Parte" #: sabnzbd/skintext.py msgid "Decade" msgstr "Década" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Nombre fichero original" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "Nombre de la tarea original" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Minúsculas" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXTO" #: sabnzbd/skintext.py msgid "text" msgstr "texto" #: sabnzbd/skintext.py msgid "file" msgstr "archivo" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Ordenar cadena" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "En directorios" #: sabnzbd/skintext.py msgid "No folders" msgstr "Sin Directorios" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "Nombre de la tarea para el nombre de archivo" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "ajustado a mayus-minus" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Resultado del procesado" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Todos" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Opciones usadas raramente. Para su significado y explicación, haga clic en " "el botón de Ayuda para ir al Wiki.
No cambie esto sin chequear primero en" " la wiki,ya que algunos ajustes tienen severas consecuencias.
Los valores" " por defecto se muestran entre paréntesis." #: sabnzbd/skintext.py msgid "Values" msgstr "Valores" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Editar Detalles de NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Eliminar" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Nombre de archivo" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Espacio libre" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Carpeta temporal" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Op.Múltiples" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Mantén presionada la tecla shift para seleccionar un rango" #: sabnzbd/skintext.py msgid "Check all" msgstr "Marcar todo" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Reiniciar SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Al finalizar cola" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Opciones de estado e interfaz" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "¡ó arrastra y suelta ficheros en la propia ventana!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Se ha perdido la conexión con SABnzbd.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "Esta ventana desaparecerá automáticamente una vez SABnzbd se haya " "reiniciado." #: sabnzbd/skintext.py msgid "WARNING:" msgstr "AVISO:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Obtener" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Interfaz web" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Frecuencia de actualización" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Usar ajustes de la interfaz global" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Límite de elementos encolables" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Límite del historial" #: sabnzbd/skintext.py msgid "Date format" msgstr "Formato de fecha" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "página" #: sabnzbd/skintext.py msgid "Loading" msgstr "Cargando" #: sabnzbd/skintext.py msgid "articles" msgstr "artículos" #: sabnzbd/skintext.py msgid "Rename" msgstr "Renombrar" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Reparar cola" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Mostrar conexiones activas" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Desbloquear" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Trabajos descolgados" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Enviar de nuevo a la cola" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Eliminar todo" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Re-intentar todo" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Descargar NZB desde URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Subir NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Opcionalmente especificar un nombre de fichero" #: sabnzbd/skintext.py msgid "Submit" msgstr "Enviar" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Eliminar todos los ficheros seleccionados" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Ocultar/Mostrar ficheros completados" #: sabnzbd/skintext.py msgid "Top" msgstr "Superior" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Último" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Ver bitacora de Scripts" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "Tu buscador de internet tiene las cookies desactivadas, la configuración de " "la interfaz se perderá si cierras el explorador." #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "¡Glitter tiene alguna nueva funcionalidad que puede gustarte!" #: sabnzbd/skintext.py msgid "Custom" msgstr "Personalizar" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Diseño compacto" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Diseño de pestañas
(separa la cola de espera y la historia)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Velocidad" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Confirmar eliminación de la cola" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Confirmar eliminación del historial" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "¿Durante cuánto tiempo quieres dejarlo pausado?" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "" "Lo siento, no hemos podido interpretar eso. Vuelve a intentarlo de nuevo." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pausar durante..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Actualizar" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" "Todos los nombres de usuarios, contraseñas y llaves-API se eliminan " "automáticamente del registro y se incluye una copia de su configuración." #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Ordenar por Fecha Más viejo→Más nuevo" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Ordenar por Fecha Más nuevo→Más viejo" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Ordenar por nombre A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Ordenar por nombre Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Ordenar por Tamaño Más pequeño→Más grande" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Ordenar por Tamaño Más grande→Más pequeño" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Subiendo" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Forzar la desconexión" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Eliminar tarea" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Eliminar tareas" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Asistente de Configuración de SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Versión de SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Anterior" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Siguiente" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Detalles del servidor" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Por favor introduce los datos de tu proveedor principal de Usenet." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Número de conexiones permitidas a tu proveedor" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "P.ej. 8 ó 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Selecciona sólo si tu proveedor permite conexiones SSL." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Haz clic para probar los detalles introducidos." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Por ej." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "¡La configuración ha terminado!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd ahora quedará ejecutando en segundo plano." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Si cierras las pestañas o el navegador, SABnzbd NO se cerrará." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Se recomienda que guardes esta ubicación como favorito y la añadas a tu " "navegador para acceder a SABnzbd cuando quieras." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Puedes encontrar más ayuda en nuestro" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Ir a SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Salir SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Iniciar Asistente" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd se entrega SIN NINGUNA GARANTÍA.\n" "Este es un software libre, y eres bienvenido a redistribuirlo bajo determinadas condiciones.\n" "Está licenciado bajo la versión 2 ó posterior de GNU GENERAL PUBLIC LICENSE.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Error al renombrar ficheros similares: %s a %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Acceso no autorizado" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "El fichero no se encuentra en el servidor" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "El servidor no ha podido completar la solicitud" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "EL URLGRABBER HA FALLADO" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Archivo NZB inusable" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Error al recuperar la URL; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Tratando de buscar NZB de %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2134995 SABnzbd-4.3.2/po/main/nb.po0000644000000000000000000033256714625637207014544 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/sabnzbd/teams/111101/nb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nb\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Advarsel" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Feil" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Kunne ikke starte webgrensesnittet" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Kan ikke finne webmal: %s, prøver standardmal" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools deaktivert: Fant ikke korrekt versjon! (Fant v%s, forventet v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2-binærfil... IKKE funnet!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "Din Unrar-versjon er %s, vi anbefaler versjon %s eller høyere.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar-binærfil... IKKE funnet!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za-binærfil... IKKE funnet!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Husk at vertsnavnet 0.0.0.0 krever en IPv6-adresse for ekstern tilgang" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP og HTTPS-portene kan ikke være det samme" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd ble startet med koding %s, dette burde være UTF-8. Forvent problemer" " med Unicode filer- og katalognavn i nedlastinger." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Deaktiverte HTTPS på grunn av manglende CERT- og KEY-filer." #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Kunne ikke starte webgrensesnittet: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s startet" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd er nå avsluttet" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s mottatt, lagrer og avslutter..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Kritisk feil ved lagring av tilstand" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "E-post sendning lykkes" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Test varslingen" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Du har ikke stilt inn vertsnavn." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "Ingen tilkoblinger er aktivert. Du må aktivere minst en tilkobling." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Passordet er skjult med ******, prøv igjen" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Ugyldige server-innstillinger" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradressen \"%s:%s\" er ikke gyldig." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Tidsavbrudd: Prøv å aktivere SSL eller bruk en annen port." #: sabnzbd/api.py msgid "Timed out" msgstr "Tidsavbrudd" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Ukjent SSL-protokoll: Prøv å deaktivere SSL eller koble til på en annen " "port." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Server krever brukernavn og passord." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Tilkobling lyktes!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Godkjenning mislyktes, kontroller brukernavn og passord." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "For mange tilkoblinger, sett nedlasting på pause eller prøv igjen senere" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Kunne ikke koble til (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Løs adresse" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ingen" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Standard" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disken er full! Pauser..." #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Diskfeil under opprettelse av fil %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Kritisk feil i Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "For lite diskplass, nedlasting satt på pause" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Avbrutt, kryptering funnet" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Uønsket forlenging finnes i rar fil %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Avbryt, uønsket forlenging oppdaget" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Kvote oppbrukt, setter nedlasting på pause" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Feil parameter" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s er ikke en godkjent e-post-adresse" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Krever server-adresse" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Ugyldig server-adresse." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s er ikke en korrekt oktal verdi" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Køen er ikke tom, kan ikke bytte mappe." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Kan ikke skrive til INI-fil %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Kan ikke sikkerhetskopiere fil %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Feil kodet passord %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "Kan ikke skrive til historikkdatabase, sjekk filrettigheter" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Skadet historikkdatabase, opprettet ny database" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL-kommando mislyktes, se logg" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Kunne ikke stenge databasen, se logg" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Ugyldig scenen logging i historien for %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Ukjent feil oppstod under dekoding av %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Ferdig" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Utpakket %s filer/mapper på %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Kan ikke lese den overvåkede mappen %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Gjenopptar" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Pauset" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "Du må sette maks båndbredde før du kan sette en båndbreddebegrensning" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Kan ikke koble til server %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Kunne ikke finne servernavn" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s vil bli ignorert i løpet av %s minutter" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Feilet å starte %s@%s grunnet: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "For mange tilkoblinger til server %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Kunne ikke logge inn på server %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Kontaker %s@%s feilet, feilmelding=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Mistenker feil i nedlaster" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Starter avslutning av SABnzbd.." #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Kunne ikke koble til mailserver" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Kunne ikke starte TLS-tilkobling" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Serveren svarte ikke ordentlig til helo hilsen" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Autentisering mot mailserveren mislyktes" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Ingen passende autentiseringsmetode ble funnet" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Ukjent godkjenningsfeil i e-postserveren" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Kunne ikke sende e-post" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Kunne ikke stenge e-post-tilkobling" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Kan ikke sendes, mangler nødvendig data" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Kan ikke finne e-post-maler i %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Ingen mottaker oppgitt, e-post ikke sendt" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Kan ikke lese %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Ingen e-post-mal funnet" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd rapporterer at disken er full\n" "\n" "Hei,\n" "\n" "SABnzbd har stoppet all nedlasting da lagringsdisken nesten er full.\n" "Frigjør mer diskplass og gjenoppta nedlasting manuelt.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Kan ikke opprette mappe %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s mappe: %s tilgang mislyktes" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Kunne ikke endre rettigheter på %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Opprettelse av (%s) mislyktes" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Kunne ikke flytte %s til %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Feil i tempfil.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Lagring av %s mislyktes" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Lasting av %s mislyktes" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Bruker logget inn i webgrensesnitt" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Bruker pålogget" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API-nøkkel mangler, skriv inn API-nøkkelen fra Konfigurasjon->Generelt i " "ditt tredjepartsprogram:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-nøkkel er feil, bruk API-nøkkel fra Konfigurasjon->Generelt i ditt " "tredjepartsprogram:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Mislykket påloggingsforsøk fra %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "RSS-kilde" #: sabnzbd/interface.py msgid "Daily" msgstr "Daglig" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Mandag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Tirsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Onsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Torsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Fredag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Lørdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Søndag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "av" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Udefinert server!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "FEIL:" #: sabnzbd/interface.py msgid "Back" msgstr "Tilbake" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Oppdatering tilgjengelig" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Kunne ikke lage SSL-nøkkel eller sertifikat." #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Seriesortering" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Dato sortering" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Kjører skript" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Utpakking nestet for dypt [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Slår sammen filer" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Ufullstendig sekvens av oppdelte filer" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Filsammenslåing av %s mislyktes" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Feil \"%s\" under filsammenslåing" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Feil \"%s\" under kjøring av file_join på %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Slår sammen %s filer" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Utpakking mislyktes, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Feil \"%s\" under utpakking av RAR fil(er)" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Feil \"%s\" under kjøring av rar_unpack på %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Fjerning av %s mislyktes!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Prøver unrar med passord \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Utpakker" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Utpakking mislyktes, kunne ikke finne %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Utpakking mislyktes, CRC-feil" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "Utpakking feilet, filen er for stor for filsystemet (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Utpakking mislyktes, skrivefeil eller er disken full?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Utpakking feilet, stien er for lang" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Utpakking mislyktes, arkivet krever passord" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Ubrukelig RAR-fil" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Prøver 7zip med password \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "se loggfil" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Hurtigkontrollerer" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparerer" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Hurtigkontroll OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Starter reparasjon" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparasjon mislyktes, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Feil %s under kjøring av par2_repair på %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Feil \"%s\" under kjøring av par2_repair på %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 mottok feil kommandoer, undersøk brytere i Konfigurasjon->Brytere" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verifiseing tok %s, alle filer er ok" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verifisering tok %s, krever reparasjon" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Henter %s blokker..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Henter" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Mislykket reparasjon, finner ikke nødvendige reparasjonsblokker (%s mangler)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Reparerer" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Reparert på %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Harddisken er full" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Verifiserer" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Undersøker" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Prøver SFV-verifisering" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "gjenstår" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Denne serveren tillater ikke SSL på denne porten" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Oppstart/avsluttning" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Stans midlertidig" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Gjenoppta" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "La til NZB-fil" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Etterbehandling startet" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Jobb fullført" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Jobb mislyktes" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Køen er ferdig" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Andre meldinger" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Åpne fullført mappe" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Ikke tilgjengelig" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Klarte ikke å sende Prowl melding" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Ukorrekt svar fra Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Klarte ikke å sende pushover-melding" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Ukorrekt svar fra Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Klarte ikke å sende pushbullet-melding" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Klarte ikke å sende Windows melding" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Kan ikke lage midlertidig fil for %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Kunne ikke legge til %s, tar bort" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Feil ved fjerning av %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Kunne ikke importere %s filer fra %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Feilaktig kø-fil funnet, kan ikke fortsette" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Lastingsfeil %s, feilaktig fil oppdaget" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB er lagt til i køen" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorerer duplikatfil \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Tom NZB-fil %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Avbrutt, kan ikke fullføres" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Kunne ikke importere %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLIKAT" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "KRYPTERT" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "FOR STOR" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "UFULLSTENDIG" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "UØNSKET" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "VENT %s sek" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Hentet filer på %s med gjenomsnitts hastighet på %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Tid" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artikler var korrupte" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artikler manglet" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artikler hadde ulike duplikater" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Stanser duplikatfil \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Advarsler" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Ledig" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Kø" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Slett kø" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historikk" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Slett historikk" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Hastighetsbegrensning" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "minutt" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Sjekk overvåkingsmappe" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Les alle RSS-kanaler" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Ferdig mappe" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Ufullstendig mappe" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Feilsøking" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Starte på nytt" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Restart uten å logge inn" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Avslutte" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Kø (10 første)" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Tom" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Historikk (10 siste)" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Gå til guiden" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Avslutter..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problem med" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd trenger en ledig TCP/IP-port for sin interne webserver.
\n" " Port %s på %s ble forsøkt brukt, men er utilgjengelig.
\n" " Enten er porten allerede i bruk av et annet program, eller så kjører SABnzbd fra før av.
\n" "
\n" " Start SABnzbd på nytt med et annet portnummer." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "Prøv et annet nummer hvis du får denne feilmeldingen på nytt.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd krever en gyldig adresse for sin interne webserver.
\n" " Du har spesifisert en ugyldig adresse.
\n" " Korrekte verdier er localhost og 0.0.0.0
\n" "
\n" " Vennligst start SABnzbd på ny med en gyldig adresse." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd oppdaget instillinger fra en annen SABnzbd-versjon
\n" " men kan ikke bruke disse.

\n" " Kanskje vil du fullføre nedlastingskøen i det gamle programmet først?

\n" " Etter det kan du starte dette programmet med \"--clean\"-parameteren.
\n" " Dette vil slette nedlastingskø og historie!
\n" " SABnzbd leste filen \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd kan ikke finne filene for webgrensesnittet i %s.
\n" " Vennligst installer programmet på nytt.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd oppdaget en kritisk feil:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd oppdaget at filen sqlite3.dll is mangler.

\n" " Enkelte antivirus-programmer fjerner denne filen.
\n" " Vennligst sjekk ditt antivirusprogram og forsøk å installer SABnzbd på nytt.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Trykk Start+R og skriv inn linjen (eksempel):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Åpne et terminalvindu og skriv inn linjen (eksempel):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Programmet startet ikke!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Kritisk feil" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Kan ikke starte webserveren, ble sannsynlig vis ikke funnet" #: sabnzbd/panic.py msgid "Access denied" msgstr "Ingen tilgang" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Feil %s: Du må oppgi et gyldig brukernavn og passord." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Gammel kø oppdaget. Bruk Status -> Reparer for å konvertere køen" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Kunne ikke lage regex for søkestreng: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Nedlasting kan feile, kun %s av kravet på %s tilgjengelig" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Nedlastning feilet - Finnes ikke på din(e) server(e)" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Etterbehandling" #: sabnzbd/postproc.py msgid "Moving" msgstr "Flytter" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Sendte %s til køen" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Kunne ikke endre navn fra \"%s\" til \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Klarte ikke å flytte filer" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Kjør brukerskript %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Skript-avsluttingskode er %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Kjørte i %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Mer" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Etterbehandling mislyktes for %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Nedlasting mislyktes" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Rensning av %s mislyktes" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Nedlasting ferdig" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Kan ikke opprette mappe %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Ingen par2 deler" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Some files failed to verify against \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Verifisering med SFV-filer var vellykket" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Passord" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Fjerning av %s mislyktes" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Dvalemodus feilet" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Kunne ikke sette systemet i ventemodus" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Feil under avslutting av systemet" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Feilaktig RSS-kilde beskrivelse \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Ugyldig autentisering for nyhetsstrøm %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Serverside-feil (serverkode %s); kunne ikke hente %s på %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Kunne ikke hente RSS-kilde fra %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Server %s bruker et usikkert HTTP sertifikat" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS-kilde %s var tom" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Ukompatibel nyhetsstrøm" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Tom RSS post funnet (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Vis grensesnitt" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pause for" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pause 5 minutter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pause 15 minutter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pause 30 minutter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pause 1 time" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pause 3 timer" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pause 6 timer" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Avslutt" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Gjenstår" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Legg til NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Feil skjema %s ved %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Ukjent handling: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Skjema for ikke eksisterende server %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Forsøker å sette status på ikke-eksisterende server %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Nedlastning" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Slå sammen filer" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Utpakking" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Skript" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Kilde" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Servere" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Mislyktes" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Venter" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Reparerer..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Trekker ut..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Flytter..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Kjører skript..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Henter ektra blokk..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Hurtigkontroll..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Verifserer..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "Deaktiver server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "Aktiver server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Hastighetsgrense" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pause Allt" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pause etterbehandling" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Gjenoppta etterbehandling" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Les RSS-kilde" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Fjerne mislykkede jobber" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Fjern ferdige jobber" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pause jobber med lav prioritet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pause jobber med normal prioritet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pause jobber med høy prioritet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Gjenoppta jobber med lav prioritet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Gjenoppta jobber med normal prioritet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Gjenoppta jobber med høy prioritet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Aktiver kvotebegrensninger" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Deaktiver kvotebegrensninger" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Av" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Veldig lav" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Moderer" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Høy" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Nødssituasjon" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Lav" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "time" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "timer" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minutter" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sekund" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "sekunder" #: sabnzbd/skintext.py msgid "day" msgstr "dag" #: sabnzbd/skintext.py msgid "days" msgstr "døgn" #: sabnzbd/skintext.py msgid "week" msgstr "uke" #: sabnzbd/skintext.py msgid "Month" msgstr "Måned" #: sabnzbd/skintext.py msgid "Year" msgstr "År" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Dag i måneden" #: sabnzbd/skintext.py msgid "This week" msgstr "Denne uken" #: sabnzbd/skintext.py msgid "This month" msgstr "Denne måneden" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "I dag" #: sabnzbd/skintext.py msgid "Total" msgstr "Totalt" #: sabnzbd/skintext.py msgid "on" msgstr "på" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametere" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python-versjon" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Startside" #: sabnzbd/skintext.py msgid "or" msgstr "eller" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Adresse" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Avbryt" #: sabnzbd/skintext.py msgid "Log in" msgstr "Logg på" #: sabnzbd/skintext.py msgid "Log out" msgstr "Logg av" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Husk meg" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Lagre" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Lagrer.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Er du sikker?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Hjem" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Konfigurasjon" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Status" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Hjelp" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Støtt prosjektet, donèr!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Generelt" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Mapper" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Svitsjer" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Nedlastingsplan" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Varsler" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "E-Post" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategorier" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sortering" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Spesiell" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Søk" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Er sikker på at du vil slå av SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Legg-til" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategori" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioritet" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparere" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Pakker opp" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Fjern" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Tving" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Stopp" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Slå av PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Ventemodus PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Dvalemodus PC" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Avslutning av SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Bearbeidinger" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Navn" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Prøv igjen" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Skripts" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Slett alt fra køen?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Slett NZB-filer" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Slett NZB & tilhørende filer" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Fjern NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Fjern NZB & slett filer" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Manglende artikler" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Gjenværende kvote" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manuelt" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Nullstill kvote nå" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Skjul detaljer" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Vis detaljer" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Vis Mislykkede" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Vis alle" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Størrelse" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Fjern Mislykkede NZBer" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Fjern Mislykkede NZBer & Slett Filer" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Fjern Ferdige NZBer" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Alternativ tilleggs NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Snarvei" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Prøv alle mislykkede jobber på nytt" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Tving frakobling" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Dette vil sende en test e-post til din konto." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Logg" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Test E-post" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Logging" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Feil/Advarsel" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Feilsøking" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Tilkoblinger" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Artikkel-id" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Filsett" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Aktivert" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Tilkobling mislykket!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokal IPv4-adresse" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Offentlig IPv4 adresse" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6-adresse" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Navnserver / DNS oppslag" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Systemytelse (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Nedlastingsmappe-hastighet" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Ferdig mappe-hastighet" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Gjenta test" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Konfig fil" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Brukt hurtigbuffer" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Dette vil starte om SABnzbd.
Brukes når du tror programmet er " "ustabilt.
Nedlastning vil bli satt på pause før omstarten og gjenoppta " "etterpå." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Det finnes foreldreløse jobber i nedlastningsmappen.
Du kan velge å " "slette disse (filene vil også bli slettet) eller sende dem tilbake i " "nedlastningskøen." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Endringer som ikke er lagret vil gå tapt." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Aktiver 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Versjon" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Oppetid" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Sikkerhetskopi" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Les Wiki Help fer dette!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Starter SABnzbd på nytt..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Endringer krever omstart av SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd Webbserver" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd Adresse" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Adressen som SABnzbd skal bruke." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd-port" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Porten som SABnzbd skal bruke." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd Brukernavn" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Kan velge autentiserings brukernavn." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd Passord" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Kan velge autentiserings passord." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "HTTPS Aktivere" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Aktiverer tilgangen til webgrensesnittet med HTTPS adresse." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS-port" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Om tom, så vil standardporten bare lytte til HTTPS" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS Sertifikat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Filnavn eller søkesti til HTTPS Sertifikat." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS Nyckel" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Filnavn eller søkesti til HTTPS Nøkkel." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS-lenke sertificater" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Filnavn eller sti til HTTPS-lenke" #: sabnzbd/skintext.py msgid "Tuning" msgstr "Justeringer" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS Oppdateringsintervall" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Sjekk intervall (i minutter, minst 15). Ikke aktiv når du bruker " "nedlastingsplan!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maks linje-hastighet" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Prosent av linjehastighet" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "Hvor mange prosent av linjehastigheten skal SABnzbd bruke, feks. 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Cachestørrelse for artikkler" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Lagrer artikler i minnet for å redusere diskaktivitet.
I bytes, " "fulgt av K,M,G. For eksempel: \"64M\" eller \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Rens liste" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Liste over filtyper som skal slettes etter nedlasting.
For eksempel: " "nfo eller nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Lagre endringer" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Nullstill" #: sabnzbd/skintext.py msgid "Language" msgstr "Språk" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Velg språket til Webgrensesnittet." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "API-nøkkel" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Denne nøkkelen vil gi tredjepartsprogrammer full tilgang til SABnzbd" #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB-nøkkel" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Denne nøkkelen vil gi tredjepartsprogrammer lov til å legge til NZBer til " "SABnzbd" #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Generer Ny Nøkkel" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API-nøkkel QR-kode" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Ekstern internettilgang" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Ingen tilgang" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Legg til NZB filer " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (Ingen konfigurasjon)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Full API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Fullt webgrensesnitt" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "OBS: Mapper kommer til å bli opprettet automatiskt når du Lagrer. " "Du må angi korrekte søkestier til din mapper for å kunne lagre utenfor " "standardmappene." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Brukermapper" #: sabnzbd/skintext.py msgid "Browse" msgstr "Bla gjennom" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Midlertidig nedlastingsmappe" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Plass for å lagre ikke bearbeidede nedlastinger.
Kan kun endres når " "køen er tom." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimal fri plass for midlertidig nedlastingsmappe" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pause når fri plass er nærme grensen.
I bytes, fulgt av " "K,M,G,T. For eksempel: \"800M\" eller \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Ferdig nedlastingsmappe" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Plass for å lagre bearbeidede og ferdige nedlastinger.
Kan " "overstyres av brukerdefinerte kategorier." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Gjenoppta automatisk" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Rettigheter for ferdige nedlastinger" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Sett rettigheter for ferdige filer og mapper.
Bruk tall. For " "eksempel: \"755\" or \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Overvåket Mappe" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Mappe som automatiskt søkes igjennom etter .nzb filer." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Skanningsintervall for Overvåkede mappar" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Sekunder mellom skanninger for .nzb filer." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Mappe for E-post maler" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Mappe som inneholder brukerdefinerte e-post maler." #: sabnzbd/skintext.py msgid "Password file" msgstr "Passordfil" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fil som inneholder alle passordene som skal forsøkes på krypterte RAR filer." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Systemmapper" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Administrativ Mappe" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Lokasjon for køadmin og historikkdatabase.
Kan bare endres når køen " "er tom." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "Data vil ikke bli flyttet. Krever SABnzbd restart!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Loggmappe" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Plass for lagrede loggfiler fran SABnzbd.
Krever omstart av " "SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr ".nzb Reservemappe" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Plass der .nzb filer lagres." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Standard base filsti" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Last ned alle par2 filer" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Aktiver rekursiv utpakking" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Pakk ut arkiver (rar, zip, 7z) inne i arkiver" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignorer alle mapper inne i arkiver" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Alle filer vil bli lagt til samme mappe" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Bara artiklene fra begynnelsen av køen" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Aktiveres for mindre minneforbruk. Deaktiver for å forhindre langsom jobb da" " køen blokkeres." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Etterbehandle kun verifiserte nedlastinger" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Reaksjon når kryptert RAR fil lastes ned" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "I tilfelle \"Pause\", så trenger du å sette et passord og gjenoppta jobben." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Forkast" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Handling når uønsket filtype oppdaget" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Uønsket filtyper" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Aktiver SFV-baserte sjekker" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Utfør ekstra verifisering basert på SFV filer" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Brukerskript kan flagge jobb som mislykket" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Når brukerskriptet returnerer en ikke-null exit kode, vil jobben bli flagget" " som mislykket." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Aktiver omdøping av mappe" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Bruk midlertidige navn under postprosessering. Deaktiver når systemet ditt " "ikke håndtere dette skikkelig." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Før-kø bruker skript" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Brukes før en NZB blir lagt til kø" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Ekstra PAR2 parametere" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Nice parametere" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "IONice parametere" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Koble fra når køen er tom" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Kople fra usenet serverne når køen er tom eller pauset." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Se etter ny utgave" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Også nye utgivelser" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Erstatt mellomrom i mappenavn" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Erstatt mellomrom med understrek i mappenavn." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Erstatt punktum i mappenavn" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Erstatt punktum med mellomrom i mappenavn" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Gjør Windows-kompatibel" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "For servere: sørg for at navn er kompatibel med Windows." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Starter webleseren ved oppstart" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Starter standard webleser når SABnzbd starter." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Pause nedlasting under etterbehandling" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Pauser nedlasting når etterbehandling begynner og gjenopptar nedlasting når " "etterbehandling er ferdig." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignorer Sample-filer" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Filtrere ut sample-filer (ex. video samplinger)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Fjern etter nedlasting" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Server" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Postprosessering" #: sabnzbd/skintext.py msgid "Naming" msgstr "Filnavn" #: sabnzbd/skintext.py msgid "Quota" msgstr "Kvote" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Hvor mye can lastes ned denne måneden (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Nullstillingsdag" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "På hvilken dag i måneden eller uken (1=mandag) resetter til nettilbyder " "kvoten? (Valgfritt med tt:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Skal nedlasting starte på nytt etter at kvoten er resatt?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Kvoteperiode" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Blirkvoten resatt hver dag, uke, eller måned?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Sjekk før nedlasting" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Prøve å beregne om ferdigstillelse er mulig før selve nedlastingen " "(tregere!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Maksimum antall forsøk" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Maksimum antall forsøk per server" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Avbryt jobber som ikke kan fullføres" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Avbryt jobben om det blir klart under nedlasting at for mye data mangler" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Legg til server" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Serverbeskrivelse" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Brukernavn" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Passord" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Tidsavbrudd" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Tidsrom for liggefrist" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Deaktivert" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 er høyeste prioritet, 99 er laveste prioritet" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Valgfritt" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Aktivere" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Ta bort server" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Testserver" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Nullstill Tellere" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Tester serverinstillinger..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Båndbredde" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Persolige notater" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Legg til nedlastingsplan" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Hyppighet" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Handling" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argument" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Aktuelle nedlastingsplaner" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Avkrysningsboksen ved kildenavnet må aktiveres for at kilden automatiskt " "skal kontrolleres for nye objekt.
Når en kilde legges til, legges det " "kun til nye objekt(ikke objekt som allerede finnes). Alle objekter i kilden " "vises når du klikker på \"Tving nedlastning\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Les kilde" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Tving nedlasting" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Sortering" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Type" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Akseptere" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Avvise" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Krever" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "KreverKat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Minst" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Høyst" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Fra SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Like" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Ingen treff" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Nedlastet" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Les alle kilder nå" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "E-Post varsling når nedlasting er ferdig" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Aldri" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Alltid" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Bara ved feil" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Full harddisk varsling" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Send e-post når harddisken er full og SABnzbd har pauset." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Send RSS varsler" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Send e-post nå en RSS feed legger til en nedlasting til køen." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP-tjener" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Still inn din ISP's server for utgående e-post." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "E-post mottaker" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "E-post adresse til mottaker." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "E-post avsender" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Hvem skal vi sende e-posten fra?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "VALGFRITT Brukernavn" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Brukernavn for e-post som krever autentisering." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "VALGFRITT Passord" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Passord for e-post som krever autentisering." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Varsel sendt!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Aktiver NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Varselsenter" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Windows-varslinger" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Aktiver Windows-varslinger" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Aktiver Prowl-varslinger" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Krever en Prowl-konto" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "API-nøkkel for Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Personlig API-nøkkel for Prowl (påkrevd)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Aktiver Pushover-varslinger" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Krever en Pushover-konto" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Program-token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Program-token (påkrevd)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Brukernøkkel" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Brukernøkkel (påkrevd)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Enhet(er)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Enhet(er) som meldingen skal sendes til" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Aktiver Pushbullet-varslinger" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Krever en Pushbullet-konto" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Personlig API-nøkkel" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Din personlige Pushbullet API-nøkkel (påkrevd)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Enhet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Enheten meldingen skal sendes til" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Ved å avslutte filstien med en asterisk * vil arbeidsmapper ikke bli " "opprettet" #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Relative mapper er basert på" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Mappe/Søkesti" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Hjelp til Sorteringsstreng" #: sabnzbd/skintext.py msgid "Clear" msgstr "Rens" #: sabnzbd/skintext.py msgid "Presets" msgstr "For innstillinger" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Påvirkede kategorier" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Betyr" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Mønster" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py msgid "Title" msgstr "Tittel" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Film Navn" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Film.Navn" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Film_Navn" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Show Navn" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Show.Navn" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Show_Navn" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Sesongnummer" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Episodenummer" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Episodenavn" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Episode.Navn" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Episode_Navn" #: sabnzbd/skintext.py msgid "Extension" msgstr "endelse" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Delnummer" #: sabnzbd/skintext.py msgid "Decade" msgstr "Titall" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Originalfilnavn" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Små bokstaver" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py msgid "text" msgstr "tekst" #: sabnzbd/skintext.py msgid "file" msgstr "fil" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Sorteringsstreng" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "I mappe" #: sabnzbd/skintext.py msgid "No folders" msgstr "Ingen mappe" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "justert for store og små bokstaver" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Prosesser resultat" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Alle" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Sjeldent brukte valg. for å finne forklaring og betydning, klikk på " "hjelpknappen for å gå til Wiki siden.
Ikke endre på disse uten å sjekke " "Wiki først, siden noen av dem har alvorlige bieffekter.
Standardverdiene " "står i parantes." #: sabnzbd/skintext.py msgid "Values" msgstr "Verdier" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Endre NZB detaljer" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Fjern" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Filnavn" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Ledig plass" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Midlertidig Mappe" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Multioperasjoner" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Hold shift-tasten for å velge et område" #: sabnzbd/skintext.py msgid "Check all" msgstr "Merk alle" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Start SABnzbd på nytt" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Når køen er ferdig" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Status og grensesnittalternativer" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Eller dra og slipp filer i vinduet!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Mistet tilkobling til SABnzbd.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "Hvis SABnzbd skulle starte på nytt vil denne skjermen forsvinne automatisk!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "ADVARSEL:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Hent" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Webgrensesnitt" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Oppdateringsfrekvens" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Bruk globale grensesnittinnstillinger" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Kø-grense" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Historikk-grense" #: sabnzbd/skintext.py msgid "Date format" msgstr "Datoformat" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "side" #: sabnzbd/skintext.py msgid "Loading" msgstr "Laster" #: sabnzbd/skintext.py msgid "articles" msgstr "artikler" #: sabnzbd/skintext.py msgid "Rename" msgstr "Endre navn" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Reparer Kø" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Vis aktive tilkoblinger" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Fjern blokkering" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Etterlatte jobber" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Send tilbake til kø" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Ta bort alle" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Prøv alle på nytt" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Hent NZB fra URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Last opp NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Valgfritt spesifiser filnavn" #: sabnzbd/skintext.py msgid "Submit" msgstr "Send" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Fjern alle valgte filer" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Skjul/vis fullførte filer" #: sabnzbd/skintext.py msgid "Top" msgstr "Topp" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Bunn" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Se skriptlogg" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Tilpasse" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Hastighet" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Bekreft Sletting av Kø" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Bekreft Sletting av Historie" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Hvor lenge ønsker du å pause? (skriv på engelsk!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Beklager, vi kunne ikke finne ut av det. Prøv igjen." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pause i..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Oppdatere" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sorter etter alder Eldst→Ny" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sorter etter alder Ny→Eldst" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sorter etter navn A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sorter etter navn Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sorter etter størrelse Minst→Størst" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sorter etter størrelse Størst→Minst" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Hurtigstart Guide" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd Versjon" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Forrige" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Neste" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Serverinstillinger" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Skriv inn opplysningene om din primære usenet leverandør." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Antallet tilkoblinger som er tillatt av din leverandør" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "F.eks 8 eller 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Velges kun om din leverandør tillater SSL-tilkoblinger." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Klikk her for å teste serverinstillingene." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Eks." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Installasjonen er nå ferdig!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd kommer nå å kjøres i bakgrunnen." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "SABnzbd kommer ikke til å avsluttes om du lukker vinduet eller fanen i " "webleseren." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Det er anbefalt at du lagrer denne siden som et bokmerke for å treffe " "SABnzbd når det kjøres i bakgrunnen." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Øvrig hjelp kan du finne på vår" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Gå til SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Avslutt SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Start Veiviser" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd kommer HELT UTEN GARANTI.\n" "Dette er fri programvare, og du kan redistribuere det under visse vilkår.\n" "Det er lisensier under GNU GENERAL PUBLIC LICENSE Versjon 2 eller senere versjoner.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Kunne ikke endre navn på lik fil: %s til %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Uautorisert tilgang" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER KRASJET" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Feil, Ubrukelig akrivfil" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "URL henting mislyktes; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Forsøker å hente NZB fra %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2114284 SABnzbd-4.3.2/po/main/de.po0000644000000000000000000040000614625637207014515 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # C E , 2020 # Nikolai Bohl , 2020 # Ben Hecht , 2021 # Manuel C. Senn, 2021 # Andreas Kames, 2021 # Simon W., 2021 # Nils Briggen, 2022 # reloxx13 , 2022 # kameb, 2023 # HandyDandy04, 2024 # Safihre , 2024 # Gjelbrim Haskaj, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Gjelbrim Haskaj, 2024\n" "Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Achtung" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Fehler" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Fehler beim Starten der Weboberfläche." #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" "Konnte Web-Vorlage nicht finden: %s Versuche die Standard-Vorlage zu " "verwenden." #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools deaktiviert: Keine korrekte Version gefunden! (Gefunden v%s, " "Erwartet v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2-Programmdatei nicht gefunden!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "Deine UNRAR-Version ist %s, wir empfehlen Version %s oder höher.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar-Programmdatei nicht gefunden!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za-Programmdatei nicht gefunden" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "Wichtige Module fehlen, herunterladen kann nicht gestartet werden." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Bitte beachten Sie, dass der 0.0.0.0-Hostname eine IPv6-Adresse benötigen " "wird für den externen Zugriff." #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP und HTTPS Ports dürfen nicht identisch sein!" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd wurde mit Encoder/Zeichensatz %s gestartet, Dieser sollte UTF-8 " "sein. Es werden Probleme mit Unicode codierten Dateien und " "Ordnerbezeichnungen in Downloads erwartet." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" "Die aktuellen Zugriffseinstellungen (%o) könnte SABnzbd den Zugriff auf die " "erstellten Dateien und Ordner von SABnzbd verweigern." #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "Konnte weitere Zertifikate vom Paket certifi nicht laden." #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS wegen fehlenden Zertifikats- und Schlüsseldateien deaktiviert." #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" "HTTPS wurde wegen ungültigen Zertifikats- und Schlüsseldateien deaktiviert" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Fehler beim Starten der Web-Oberfläche: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s gestartet" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd wurde beendet" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s erkannt. Wird gespeichert und beendet …" #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Schwerer Fehler beim Speichern des Zustands" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "Neustart aufgrund eines abgestürzten Nachbearbeitungsprozesses" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "Neustart aufgrund eines abgestürzten Downloaders" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "Neustart aufgrund eines abgestürzten Assemblers" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "Zugriff auf PID Datei %s nicht möglich" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "E-Mail erfolgreich versendet" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Benachrichtigungen testen" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Der Hostname wurde nicht angegeben" #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" "Keine Verbindungen angegeben. Bitte geben Sie mindestens eine Verbindung " "ein." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Passwort ist als ****** maskiert. Bitte erneut eingeben." #: sabnzbd/api.py msgid "Invalid server details" msgstr "Ungültige Server-Angaben" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" "Verbindung zu %s auf Port %s konnte nicht hergestellt werden. Es scheint, " "als sei %s ein Webserver (Port 80), vielleicht ein Indexer, aber kein " "Usenet-Server. Trage einen Usenet-Server ein." #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Server-Adresse \"%s:%s\" ist ungültig." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Zeitüberschreitung: Versuche es mit eingeschalteten SSL oder einen anderen " "Port." #: sabnzbd/api.py msgid "Timed out" msgstr "Zeitüberschreitung" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Unbekanntes SSL-Protokoll: SSL deaktivieren oder alternativen Port " "versuchen." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Server benötigt ein Benutzername und ein Passwort." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Verbindung erfolgreich hergestellt!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "" "Authentifizierung fehlgeschlagen. Überprüfen Sie Benutzername und Passwort." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Zu viele Verbindungen. Bitte halten Sie die Downloads an oder versuchen Sie " "es später erneut." #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Die Verbindung konnte nicht überprüft werden. (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Adresse wird aufgelöst …" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Nichts" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Standard" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Festplatte voll! Downloads werden angehalten." #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Festplattenfehler beim Anlegen der Datei %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Schwerer Fehler im Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Angehalten wegen zu wenig freiem Speicherplatz" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "\"%s\" wurde angehalten, da es ein verschlüsseltes RAR Archiv enthält (falls" " unterstützt, wurden alle Passwörter ausprobiert)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" " \"%s\" wurde abgebrochen, da es ein verschlüsseltes RAR Archiv enthält " "(falls unterstützt, wurden alle Passwörter ausprobiert)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Abgebrochen, Verschlüsselung vorhanden" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "Unerwünschter Typ \"%s\" in RAR Datei. Unerwünschte Datei ist %s " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Unerwünschter Dateityp im RAR-Archiv %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Abgebrochen, unerwünschte Dateieindung gefunden" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" "Aufgabe \"%s\" ist wahrscheinlich verschlüsselt, RAR hat den gleichen Namen " "wie das gepackte RAR-Archiv" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "Aufgabe \"%s\" ist wahrscheinlich verschlüsselt: \"Passwort\" im Dateiname \"%s\"" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Kontingent aufgebraucht, Downloads werden angehalten" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Fehlerhafter Parameter" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s ist keine gültige E-Mail-Adresse" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Server-Adresse wird benötigt" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Ungültige Server-Adresse." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "%s ist kein gültiges Script" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s ist kein gültiger Oktal-Wert" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" "Die aktuellen Zugriffseinstellungen (%s) könnte SABnzbd den Zugriff auf die " "erstellten Dateien und Ordner von SABnzbd verweigern." #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "Netzwerkpfad \"%s\" ist hier nicht erlaubt" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "" "Ordner kann nicht geändert werden, da die Warteschlange nicht leer ist." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" "Der \"Abgeschlossene Downloads\"-Ordner darf kein Unterordner des " "\"Temporäre Downloads\"-Ordners sein." #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" "Verwenden Sie keinen Ordner im Anwendungsordner als Ihren Skriptordner, er " "könnte während Updates geleert werden." #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" "Konfiguration ist gesperrt, Einstellungen können nicht gespeichert werden" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Kann INI-Datei %s nicht schreiben" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Kann keine Sicherungsdatei erstellen für %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "Backup konnte nicht wiederhergestellt werden" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Ungültig kodiertes Passwort %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" "Kann nicht in die Verlaufsdatenbank schreiben, überprüfe die Zugriffsrechte!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Verlaufsdatenbank geschädigt, eine leere neue wurde erstellt" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL-Befehl fehlgeschlagen. Beachten Sie das Nachrichtenprotokoll." #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "" "Fehler beim Schliessen der Datenbank. Beachten Sie das Nachrichtenprotokoll." #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Ungültiges Stufen-Protokoll im Verlauf für %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Decoder Fehler: Nicht genügend Speicher" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Unbekannter Fehler %s beim Dekodieren" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" "Entschleiern wird aufgrund von DVD/Blu-ray-Verzeichnissen übersprungen" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "Entschleiern korrigierte die Erweiterung von %d Datei(en)" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "Entschleiern hat %dDatei(en) umbenannt" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "Direkt entpacken" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Fertiggestellt" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "%s Datei(en)/Ordner entpackt in %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "Direkt entpacken wurde automatisch aktiviert" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "Aufträge werden bereits während des Download-Vorgangs entpackt, um die " "Nachbearbeitungszeit zu verkürzen. Nur für Aufträge, die nicht repariert " "werden müssen." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Überwachter Ordner %s kann nicht gelesen werden" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Fortgesetzt" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Angehalten" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Bevor ein Bandbreitenlimit gesetzt werden kann, muss die maximale Bandbreite" " festgelegt werden" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Verbindung zum Server %s kann nicht hergestellt werden. %s" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Konnte Servernamen nicht auflösen" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s wird für %s Minuten ignoriert" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "Es gibt keine aktiven Server!" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Fehler %s@%s zu initialisieren, aus folgendem Grund: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "Schwerer Fehler im Downloader" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Zu viele Verbindungen zu Server %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" "Von zu vielen unteschiedlichen IP Adressen beim Server eingeloggt %s[%s] " "https://sabnzbd.org/multiple-adresses" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Anmelden beim Server fehlgeschlagen. %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Fehler beim Verbinden mit %s@%s, Meldung = %s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Vermute Fehler im Downloader" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Wird beendet …" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "Server %s läuft in %s Tag(en) ab" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "Server %s hat das angegebene Kontingent verbraucht" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Verbindung zum Mail-Server konnte nicht hergestellt werden" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Aufbau der TLS-Verbindung fehlgeschlagen" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Keine korrekte Server-Antwort auf den HELO/EHLO-Check" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Authentifizierung beim Mail-Server fehlgeschlagen" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Keine passende Authentifizierungsmethode gefunden" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Unbekannter Authentifizierungsfehler des E-Mail-Servers" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Senden des E-Mails fehlgeschlagen" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Schliessen der Mail-Verbindung fehlgeschlagen" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Absenden nicht möglich, benötigte Daten fehlen" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "In %s konnten keine E-Mail-Vorlagen gefunden werden" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Keine E-Mail gesendet da keine Empfänger angegeben" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "%s kann nicht gelesen werden" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Keine E-Mail-Vorlagen gefunden" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd meldet eine volle Festplatte\n" "\n" "Hallo,\n" "\n" "SABnzbd hat mit dem Herunterladen aufgehört, da die Festplatte fast voll \"\n" "ist.\n" "Bitte geben Sie manuell Speicherplatz frei und setzen Sie die Downloads \"\n" "danach fort.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Verzeichnis %s konnte nicht angelegt werden" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "Zugriff auf das Verzeichnis %s fehlgeschlagen: %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Rechte von %s konnten nicht geändert werden" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Erstellen von %s fehlgeschlagen" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Verschieben von %s nach %s fehlgeschlagen" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "Versuch das Verzeichnis %s zu erstellen wurde blockiert" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Fehler in tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Fehler beim Speichern von %s" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Fehler beim Laden von %s" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "%s ist nicht beschreibbar. Downloads sind dadurch blockiert." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" "Kann keinen langen Dateinamen in %s schreiben. Dies kann Probleme " "verursachen." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" "Kann keinen Dateinamen in Unicode in %s schreiben. Dies kann Probleme " "verursachen." #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" "Dateinamen mit Umlaute können nicht in %s gespeichert werden. Dies kann zu " "Problemen führen." #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "Abgelehnte Verbindung von:" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "Verbindung vom Host \"%s\" abgelehnt von:" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Benutzer im Web-Interface angemeldet" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Benutzer angemeldet" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API-Schlüssel fehlt. Bitte API-Schlüssel aus Einstellungen->Allgemein in die" " externe Anwendung eingeben:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-Schlüssel ungültig. Bitte API-Schlüssel aus Einstellungen->Allgemein in " "die externe Anwendung eingeben:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Fehlerhafter Login Versuch von %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "Invalides Backup Archiv" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py msgid "Daily" msgstr "Täglich" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Montag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Dienstag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Mittwoch" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Donnerstag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Freitag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Samstag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Sonntag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "Aus" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Undefinierter Server!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" "Der Category-Ordner darf kein Unterordner des Temporärer Download-Ordners " "sein." #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "FEHLER:" #: sabnzbd/interface.py msgid "Back" msgstr "Zurück" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" "Um alle hilfreichen Warnungen zu verbergen, deaktiviere die extra " "Einstellung 'helpful_warnings'." #: sabnzbd/misc.py msgid "d" msgstr "t" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Neue Version verfügbar!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "Hochladen fehlgeschlagen: %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Fehler beim Anlegen des SSL-Schlüssels und -Zertifikats." #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "Ihre Passwort-Datei enthält mehr als 30 Passwörter, das Testen aller " "Passwörter dauert sehr lange. Versuchen Sie, nur nützliche Passwörter " "aufzulisten." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "Die Passwortdatei %s konnte nicht gelesen werden" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "[%s] Der Befehl in build_command ist nicht definiert." #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "Dem Pythonskript \"%s\" fehlen die Ausführungsrechte (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Sortieren von TV-Serien" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Sortieren nach Datum" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "Film Sortierung" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Ausführen des Skripts" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Entpacken zu tief verschachtelt [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Zusammenfügen" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Unvollständiger Ablauf beim zusammenführen von Dateien" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Fehler beim Zusammenfügen von %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fehler \"%s\" beim Zusammenfügen der Dateien" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Fehler \"%s\" beim Ausführen von file_join auf %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] %s Dateien zusammengefügt" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Entpacken fehlgeschlagen. %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fehler \"%s\" beim Entpacken der RAR-Dateien" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fehler \"%s\" beim Ausführen von rar_unpack auf %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Löschen von %s fehlgeschlagen!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Versuche entpacken mit Passwort \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Entpacken" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Entpacken fehlgeschlagen. Konnte %s nicht finden." #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Entpacken fehlgeschlagen. CRC-Fehler" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" "Entpacken fehlgeschlagen - Datei zu groß für Dateisystem (Formatierung FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "" "Entpacken fehlgeschlagen. Fehler beim Schreiben oder volle Festplatte?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Entpacken fehlgeschlagen, Pfad ist zu lang" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Entpacken fehlgeschlagen. Archiv benötigt ein Passwort." #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "RAR-Datei beschädigt" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Defekte RAR Datei" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Versuche 7zip mit Passwort \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "Beachten Sie die Protokolldatei" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Schnelle Überprüfung" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparieren" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Schnelle Überprüfung erfolgreich" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Beginn der Reparatur" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparatur fehlgeschlagen. %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Fehler \"%s\" beim Ausführen von par2_repair auf %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fehler \"%s\" beim Ausführen von par2_repair auf dem Satz %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] Ungültige PAR2-Optionen. Überprüfen Sie die Angaben in Einstellungen ->" " Schalter." #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Überprüft in %s. Alle Dateien fehlerfrei." #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Überprüft in %s. Reparatur wird benötigt." #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Ungültige par2-Dateien oder ungültige PAR2-Parameter, Auftrag konnte nicht " "überprüft oder repariert werden" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "%s Blöcke werden abgerufen …" #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Abrufen" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Reparatur fehlgeschlagen. Nicht genug Reparatur-Blöcke vorhanden (%s zu " "wenig)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Reparieren" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Repariert in %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "Überprüfe Reparatur" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Festplatte voll" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Überprüfe zusätzliche Dateien" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Überprüfen" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Wird überprüft" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Versuche SFV-Überprüfung" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "rest" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Dieser Server erlaubt kein SSL auf diesem Port" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "Zertifikat ungültig: Der Server-Host ist nicht im angegeben Zertifikat " "enthalten. Dies ist ein Serverproblem." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" "Zertifikat ist nicht gültig. Dies ist wahrscheinlich ein Serverproblem." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Der Server %s verwendet ein nicht vertrauenswürdiges Zertifikat [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "Verbindung fehlgeschlagen: %s %s@%s:%s(%s)" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Starten/Beenden" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Anhalten" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Fortsetzen" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "Hinzugefügte NZB" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Nachbearbeitung gestartet" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Auftrag ausgeführt" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Auftrag fehlgeschlagen" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Warteschlange abgearbeitet" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Andere Nachrichten" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "Ordner öffnen" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Öffne Zielverzeichnis" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Nicht verfügbar" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "Senden von macOS Benachrichtigung fehlgeschlagen" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Prowl-Nachricht konnte nicht versendet werden" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Fehlerhafte Antwort von Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Konnte Pushover-Nachricht nicht versenden" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Fehlerhafte Antwort von Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Pushbullet-Nachricht konnte nicht versendet werden" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Skript gab Fehlercode %s und Ausgabe \"%s\" zurück" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Benachrichtigungsskript \"%s\" existiert nicht" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Windows Benachrichtigung konnte nicht gesendet werden" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Temporäre Datei für %s konnte nicht angelegt werden" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Fehler beim Hinzufügen von %s. Entferne." #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Fehler beim Entfernen von %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Importieren von %s Dateien von %s fehlgeschlagen" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Inkompatible Warteschlangen-Datei gefunden. Fortsetzen nicht möglich." #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Fehler beim Laden von %s. Beschädigte Datei gefunden." #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB zur Warteschlange hinzugefügt" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Doppelte NZB \"%s\" wird ignoriert" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "kopieren der NZB \"%s\" fehlgeschlagen" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "Doppelte NZB" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "Ungültige NZB-Datei %s wird übersprungen (Fehler: %s)" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Leere NZB-Datei %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" "Das Vorwarteschlangen (pre-queue) Skript hat die Downloadaufgabe als " "gescheitert markiert" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "Ungewollte Dateiendung in der Datei %s (%s)" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Abgebrochen, kann nicht fertiggestellt werden" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Fehler beim Importieren von %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLIKAT" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "ALTERNATIVE" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "VERSCHLÜSSELT" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "ZU GROSS" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "UNVOLLSTÄNDIG" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "UNERWÜNSCHT" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "WARTE %s Sek" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "AUSBREITUNG %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "" "Heruntergeladen in %s mit einer Durchschnittsgeschwindigkeit von %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Alter" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s Artikel hatten ein ungültiges Format" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s Artikel fehlten" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s Artikel hatten nicht übereinstimmende Duplikate" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Doppelt vorhandene NZB \"%s\" angehalten" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Warnungen" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Leerlauf" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Warteschlange" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Warteschlange leeren" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Verlauf" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Verlauf leeren" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Geschwindigkeit begrenzen" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "Minuten" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Überwachter Ordner lesen" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Alle RSS-Feeds lesen" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Fertige Downloads" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Unfertige Download" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Fehler suchen" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Neu starten" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Neustart ohne Anmeldung" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Beenden" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Warteschlange mit den 10 obersten Einträgen" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Leer" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Verlauf mit den letzten 10 Einträgen" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Assistent öffnen" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Wird angehalten …" #: sabnzbd/panic.py msgid "Problem with" msgstr "Problem mit" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " Für seinen internen Web-Server benötigt SABnzbd einen freien TCP/IP-Port.
\n" " Port %s auf %s wurde probiert, ist aber nicht verfügbar.
\n" " Entweder verwendet eine andere Software den Port oder SABnzbd läuft bereits.
\n" "
\n" " Starten Sie SABnzbd bitte mit einer anderen Portnummer neu." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Wenn Sie diesen Fehler wieder erhalten, probieren Sie eine andere " "Nummer.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " Für seinen internen Web-Server benötigt SABnzbd eine gültige Rechner-Adresse.
\n" " Sie haben eine ungültige Adresse angegeben.
\n" " Sichere Werte sind localhost und 0.0.0.0
\n" "
\n" " Starten Sie SABnzbd bitte mit einer gültigen Rechner-Adresse neu." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd hat die gespeicherten Daten einer anderen SABnzbd-Version erkannt,
\n" " kann diese aber nicht wiederverwenden.

\n" " Es wird empfohlen, die ausstehenden Downloads mit der anderen Version fertigzustellen.

\n" " Starten Sie dieses Programm danach mit der \"--clean\"-Option.
\n" " Dies löscht die Download-Warteschlange und den Download-Verlauf!
\n" " SABnzbd hat die Datei \"%s\" gelesen." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd kann die Dateien für die Web-Oberfläche in %s nicht finden.
\n" " Installieren Sie bitte das Programm erneut.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd hat einen schwerwiegenden Fehler erkannt:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd hat erkannt, dass die Datei sqlite3.dll fehlt.

\n" " Manche unausgereiften Viren-Scanner löschen diese Datei.
\n" " Bitte überprüfen Sie den Viren-Scanner, versuchen Sie eine Neuinstallation von SABnzbd und beschweren Sie sich beim Hersteller des Viren-Scanners.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Drücken Sie Start+R und geben Sie folgenden Zeile ein (Beispiel):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Öffnen Sie ein Terminal und geben Sie folgende Zeile ein (Beispiel):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Programm wurde nicht gestartet!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Schwerwiegender Fehler" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" "Konnte nicht an Port %s auf %s starten. Eine andere Software nutzt diesen " "Port oder SABnzbd läuft bereits." #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "" "Der Standard-Browser konnte nicht gestartet werden, da er wahrscheinlich " "nicht gefunden wurde." #: sabnzbd/panic.py msgid "Access denied" msgstr "Zugriff verweigert" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "" "Fehler %s: Sie müssen einen gültigen Benutzername und ein Passwort angeben." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" "Alte Warteschlangen-Version erkannt, über Status->Reparieren ins neue Format" " konvertieren" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "" "Kompilieren des regulären Ausdrucks für den Suchbegriff %s fehlgeschlagen." #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" "Download-Ordner %s für abgeschlossene Downloads auf FAT Dateisystem, ist " "auf maximale Dateigröße von 4GB begrenzt." #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" "Download wahrscheinlich fehlgeschlagen, nur %s von benötigten %s verfügbar" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Download fehlgeschlagen - Nicht auf deinem/n Server/n vorhanden" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Nachbearbeitung" #: sabnzbd/postproc.py msgid "Moving" msgstr "Verschiebevorgang" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "%s wurde an die Warteschlange gesendet" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Fehler beim Umbenennen von \"%s\" nach \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Dateien verschieben fehlgeschlagen" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Ausführen des Benutzer-Skripts %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Exit-Code des Skripts ist %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "%s ausgeführt" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Mehr" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Nachbearbeitung von %s fehlgeschlagen (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "Nachbearbeitung wurde abgebrochen" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Download Fehlgeschlagen" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Aufräumen von %s fehlgeschlagen" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Download fertig" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Konnte Download-Ordner %s nicht anlegen" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Keine PAR2-Sätze" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Überprüfung einiger Dateien mittels %s fehlgeschlagen" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Überprüfung mit SFV-Datei(en) erfolgreich" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "RAR-basierte Überprüfung versuchen" #: sabnzbd/postproc.py msgid "Passworded" msgstr "passwortgeschützt" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] RAR-basierte Überprüfung ist fehlgeschlagen: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "RAR-Datei erfolgreich überprüft" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "RAR-Datei konnten nicht überprüft werden" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "Versuche RAR-Umbenenner" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "Keine zugehörige frühere RAR-Datei für %s" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Entfernen von %s fehlgeschlagen" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Fehler beim Wechsel in den Ruhezustand" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Fehler beim Wechsel in den Bereitschaftsmodus" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Fehler beim Herunterfahren des Systems" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "DBus-Ausnahmefehler empfangen %s " #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Ungültige RSS-Feed-Beschreibung \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Keine gültige Berechtigung für Feed %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Server-Fehler (Code %s); konnte %s von %s nicht laden" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Abrufen des RSS-Feeds von %s fehlgeschlagen: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Der Server %s nutzt ein nicht vertrauenswürdiges HTTPS-Zertifikat" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS-Feed %s war leer" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Inkompatibeler RSS-Feed" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Leerer RSS-Feed gefunden: %s" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Interface anzeigen" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Anhalten für" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "5 Minuten anhalten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "15 Minuten anhalten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "30 Minuten anhalten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Eine Stunde anhalten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "3 Stunden anhalten" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "6 Stunden anhalten" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Beenden" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Verbleibend" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "NZB hinzufügen" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Ungültige Regel %s um %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Unbekannte Aktion: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Regel für nicht existierenden Server %s." #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Status für nicht vorhandenen Server wird versucht %s einzustellen" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Herunterladen" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Dateien zusammenfügen" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Entpacken" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "Entschleiern" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Skript" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Quelle" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Server" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Fehlgeschlagen" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Warten" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Wird repariert …" #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Wird entpackt …" #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Wird verschoben …" #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Skripts wird ausgeführt …" #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Zusätzliche Blöcke werden abgerufen …" #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Schnelle Überprüfung …" #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Überprüfung läuft …" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "Server deaktivieren" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "Server aktivieren" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Geschwindigkeitsbegrenzung" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Alle anhalten" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Nachbearbeiten anhalten" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Nachbearbeiten fortsetzen" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "RSS-Feeds lesen" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Entferne fehlgeschlagene Aufträge" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Abgeschlossene Aufträge entfernen" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Aufträge mit niedriger Priorität pausieren" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Aufträge mit normaler Priorität pausieren" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Aufträge mit hoher Priorität pausieren" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Aufträge mit niedriger Priorität fortsetzen" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Aufträge mit normaler Priorität fortsetzen" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Aufträge mit hoher Priorität fortsetzen" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Quoten-Management einschalten" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Quoten-Management ausschalten" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "Aufträge mit Kategorie pausieren" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "Aufträge mit Kategorie fortsetzen" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Nein" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Sehr niedrig" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Mittel" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Hoch" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Notfall" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Gering" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "Stunde" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "Stunden" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "Minuten" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "Sekunde" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "Sekunden" #: sabnzbd/skintext.py msgid "day" msgstr "Tag" #: sabnzbd/skintext.py msgid "days" msgstr "Tage" #: sabnzbd/skintext.py msgid "week" msgstr "Woche" #: sabnzbd/skintext.py msgid "Month" msgstr "Monat" #: sabnzbd/skintext.py msgid "Year" msgstr "Jahr" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Tag im Monat" #: sabnzbd/skintext.py msgid "This week" msgstr "Diese Woche" #: sabnzbd/skintext.py msgid "This month" msgstr "Dieser Monat" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "Ausgewählter Datumsbereich" #: sabnzbd/skintext.py msgid "Today" msgstr "Heute" #: sabnzbd/skintext.py msgid "Total" msgstr "Gesamt" #: sabnzbd/skintext.py msgid "on" msgstr "An" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parameter" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python Version" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Startseite" #: sabnzbd/skintext.py msgid "or" msgstr "oder" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Adresse" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Abbrechen" #: sabnzbd/skintext.py msgid "Log in" msgstr "Anmelden" #: sabnzbd/skintext.py msgid "Log out" msgstr "Abmelden" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Automatische Anmeldung" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Speichern" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Speichervorgang …" #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Sind Sie sicher?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Startseite" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Einstellungen" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Status" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Hilfe" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "Echtzeit Chat" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Probleme" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Bitte unterstützen Sie das Projekt durch eine Spende!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Allgemein" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Ordner" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Schalter" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Planung" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Benachrichtigungen" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "E-Mail" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategorien" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sortierung" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Spezial" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Suchen" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Möchten Sie SABnzbd wirklich beenden?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Hinzufügen einer" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategorie" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Priorität" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparieren" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Entpacken" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Löschen" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Erzwingen" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Abbrechen" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Rechner ausschalten" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Rechner in Bereitschaft versetzen" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Rechner in den Ruhezustand versetzen" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "SABnzbd beenden" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Verarbeiten" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Name" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Erneut versuchen" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Skripte" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Alle Elemente in der Warteschlange löschen?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "NZBs löschen" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "NZBs und Dateien löschen" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "NZB löschen" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "NZBs und Dateien löschen" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Fehlende Artikel" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Verbleibendes Kontingent" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "Manuell" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Kontingent jetzt zurücksetzen" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Details verbergen" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Details anzeigen" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Nur Fehlgeschlagene" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Alle anzeigen" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Grösse" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Fehlgeschlagene NZBs löschen" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Fehlgeschlagene NZBs und Dateien löschen" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Fertige NZBs löschen" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Lösche NZBs auf der aktuellen Seite" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Optionale ergänzende NZB-Datei" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Pfad" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Fehlgeschlagene Aufträge neustarten" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Verbindung trennen" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" "Alle aktiven Verbindungen zu Usenet-Servern trennen. Verbindungen werden " "nach ein paar Sekunden wiederhergestellt, falls sich noch Artikel in der " "Warteschlange befinden." #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Sendet eine Test-E-Mail an Ihr Konto." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Protokoll anzeigen" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "E-Mail testen" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Protokoll" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Fehler/Warnungen" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Fehlersuche" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Verbindungen" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Artikelbezeichner" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Dateimenge" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Aktiv" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Verbindung fehlgeschlagen!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokale IPv4-Adresse" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Öffentliche IPv4-Adresse" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6-Adresse" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "DNS-Server" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "Downloadgeschwindigkeit begrenzt durch" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "Festplattengeschwindigkeit" #: sabnzbd/skintext.py msgid "System load" msgstr "Systemlast" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "System Performance" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Zielverzeichnis Geschwindigkeit" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Zielverzeichnis Geschwindigkeit" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "Internet Bandbreite" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Test wiederholen" #: sabnzbd/skintext.py msgid "Test download" msgstr "Test Download" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" "Fügt eine verifizierte NZB-Testdatei mit der angegebenen Dateigröße hinzu. " "Die Datei ist zufallsgeneriert und dient dem Prüfen der Einstellungen." #: sabnzbd/skintext.py msgid "Config File" msgstr "Konfigurationsdatei" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Verwendeter Cache" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Ein Klick auf den Knopf \\\"Neu starten\\\" startet SABnzbd neu.
\r\n" "Benutzen Sie ihn, falls ein Stabilitätsproblem vorliegt.
\r\n" "Die Downloads werden vor dem Neustart angehalten und danach fortgesetzt." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" "
Wenn Anmeldung aktiviert ist, müssen sie sich danach noch mal " "anmelden." #: sabnzbd/skintext.py msgid "Advanced" msgstr "Erweitert" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Der Download-Ordner enthält verwaiste Aufträge.
Diese können gelöscht " "(zusammen mit den Dateien) oder zurück in die Warteschlange verschoben " "werden." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "Ein Klick auf den Knopf \"Reparieren\" startet SABnzbd neu
und baut die" " Warteschlange neu auf, wobei bereits
heruntergeladene Dateien bestehen" " bleiben. Die Reihenfolge
der Warteschlange wird dabei verändert." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Die Änderungen wurden nicht gespeichert und werden verloren gehen." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" "Falls sich deine IP Adresse ändert oder SABnzbd neu startet, wird deine " "Session ungültig" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "7zip aktivieren" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" "Erhöhe Reparaturgeschwindigkeit durch installation von Multicore Par2, " "verfügbar auf vielen Plattformen." #: sabnzbd/skintext.py msgid "Version" msgstr "Version" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Zeit seit Start" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Sicherheitskopie" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Lesen Sie dazu die Hilfe im Wiki!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "SABnzbd wird neu gestartet …" #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Änderungen benötigen einen Neustart von SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd-Webserver" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd-Host" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Host, auf dem SABnzbd auf Anfragen warten soll." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd-Port" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Port, auf dem SABnzbd auf Anfragen warten soll." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd-Benutzername" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Optionale Anmeldung mit Benutzername" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd-Passwort" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Optionale Anmeldung mit Passwort" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" "Wenn der SABnzbd Host oder Port im Netz freigegeben ist, lassen die " "gegenwärtigen Einstellung vollen zugriff auf die SABnzbd Oberfläche zu." #: sabnzbd/skintext.py msgid "Security" msgstr "Sicherheit" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "HTTPS aktivieren" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Zugriff auf die Oberfläche über HTTPS-Adressen erlauben" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" "Moderne Webbrowser und andere Clients akzeptieren keine selbst signierten " "Zertifikate und geben eine Warnung aus und/oder stellen gar keine Verbindung" " her." #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS-Port" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Wenn leer, hört der Standard-Port nur auf HTTPS-Anfragen." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS-Zertifikat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Dateiname oder Pfad des HTTPS-Zertifikats." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" "Neues selbstzertifiziertes Zertifikat und Schlüssel generieren. SABnzbd muss" " neugestartet werden!" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS-Schlüssel" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Dateiname oder Pfad des HTTPS-Schlüssels." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS-Kette Zertifikat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Dateiname oder Pfad zur HTTPS-Kette." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Feinabstimmung" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS-Überprüfung" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Überprüfungs-Intervall (in Minuten, mindestens 15). Nicht aktive wenn Regeln" " aktiv sind!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maximale Downloadgeschwindigkeit" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Prozentsatz der Downloadgeschwindigkeit" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Welchen Prozentsatz deiner Downloadgeschwindigkeit SABnzbd nutzen soll, z.B." " 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Begrenzung des Artikel-Caches" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Artikel werden zwischengespeichert, um die Anzahl der Zugriffe auf die " "Festplatte zu reduzieren.
In Bytes, gefolgt von einem optionalen K, " "M oder G. Zum Beispiel: \"64M\" oder \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "Backup erstellen" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" "Erstelle eine Sicherungskopie der Konfigurationsdatei und der Datenbanken im" " Backup-Ordner.
Wenn der Backup-Ordner nicht festgelegt ist, wird die " "Sicherungskopie im Ordner der abgeschlossenen Downloads " "erstellt.
Wiederkehrende Sicherungen können auf der Seite Planung " "konfiguriert werden." #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Unerwünschte Dateien" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Liste der Dateiendungen, die nach dem Download gelöscht werden sollen.
Zum Beispiel:nfo or nfo,sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "Verlaufsgröße" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "Alle Aufträge behalten" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "Aufträge" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Änderungen speichern" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Werkseinstellung wiederherstellen" #: sabnzbd/skintext.py msgid "Reset" msgstr "Zurücksetzen" #: sabnzbd/skintext.py msgid "Language" msgstr "Sprache" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Wählen Sie die Sprache der Weboberfläche." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "Hilf uns beim Übersetzen von SABnzbd in deiner Sprache!
Neue " "Übersetzungen hinzufügen oder bestehende verbessern kannst du hier:" #: sabnzbd/skintext.py msgid "API Key" msgstr "API-Schlüssel" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Dieser Schlüssel gibt Drittprogrammen uneingeschränkten Zugriff auf SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB-Schlüssel" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Dieser Schlüssel erlaubt Drittprogrammen das Hinzufügen von NZB-Dateien zu " "SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Neuen Schlüssel generieren" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API-Key OR-Code" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Externer Internetzugriff" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" "Es können Zugriffsrechte für Systeme außerhalb des Netzwerkes gesetzt " "werden." #: sabnzbd/skintext.py msgid "No access" msgstr "Kein Zugriff" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "NZB Dateien hinzufügen " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (ohne Einstellungen)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Ganze API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Volles Webinterface" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Nur externer Zugriff benötigt eine Anmeldung" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "HINWEIS: Ordner werden beim Speichern automatisch erstellt. Sie " "können absolute Pfade angeben, um Ordner ausserhalb der standardmässigen " "Ordner zu verwenden." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Benutzer-Ordner" #: sabnzbd/skintext.py msgid "Browse" msgstr "Durchsuchen" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Temporärer Download-Ordner" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Hier werden noch nicht verarbeitete Downloads abgelegt.
Kann nur " "geändert werden wenn die Warteschlange leer ist." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimaler freier Speicherplatz im temporären Ordner" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "SABnzbd hält automatisch an, wenn der freie Speicherplatz unter diesen Wert " "fällt.
In Bytes, gefolgt von einem optionalen K, M oder G. Zum " "Beispiel: \"800M\" or \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Ordner für fertige Downloads" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Hier werden fertige, verarbeitete Downloads abgelegt.
Kann von " "benutzerdefinierten Kategorien ausser Kraft gesetzt werden." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "Benutze Sortieren um deine Dateien zu orgenisieren und umzubennenen" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "Minimaler freier Speicherplatz des abgeschlossene Downloads-Ordners" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" "Funktioniert nicht, wenn sich der Kategorie-Ordner auf einer anderen " "Festplatte befindet." #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Automatisch fortsetzen" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" "Das Herunterladen wird automatisch fortgesetzt, wenn der minimale freie " "Speicherplatz wieder verfügbar ist.
Gilt sowohl für den temporären als " "auch für den abgeschlossene Downloads-Ordner.
Dies wird alle paar " "Minuten überprüft." #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Rechte für fertige Downloads" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Rechte für Dateien und Ordner festlegen.
In oktaler Notation. Zum " "Beispiel: \"755\" oder \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Überwachter Ordner" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Ordner, der auf neue .nzb Dateien überwacht werden soll." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Geschwindigkeit der Ordner-Überwachung" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Anzahl der Sekunden zwischen zwei Überprüfungen." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "Skript Ordner" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "Ordner enthält Benutzer Skripte" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Ordner mit E-Mail-Vorlagen" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Ordner, der benutzerdefinierte E-Mail-Vorlagen enthält." #: sabnzbd/skintext.py msgid "Password file" msgstr "Passwortdatei" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Datei mit allen Passwörtern, die bei verschlüsselten RAR-Dateien probiert " "werden sollen." #: sabnzbd/skintext.py msgid "System Folders" msgstr "System-Ordner" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "Versteckte Ordner" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Administrativer Ordner" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Ordner, der die für die Warteschlange und den Verlauf verwendeten " "Datenbanken enthält.
Kann nur geändert werden, wenn die " "Warteschlange leer ist." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "Backup Ordner" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" "Pfad, an dem die Sicherungen der Konfigurationsdatei und der Datenbanken " "gespeichert werden.
Wenn diese Option leer bleibt, wird die Sicherung " "im Ordner der abgeschlossenen Downloads erstellt." #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Es werden keine Dateien entfernt. Benötigt einen Neustart von " "SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Protokoll-Ordner" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Hier werden Protokoll-Dateien von SABnzbd abgelegt.
Benötigt einen " "Neustart von SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "NZB-Backup-Ordner" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Hier werden NZB-Dateien abgelegt." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Standardmässiger Basis-Ordner" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Alle Par2-Dateien herunterladen" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" "Dies verhindert mehrfache Reparaturversuche, durch herunterladen aller par2 " "Dateien, wenn notwendig." #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Rekursives Entpacken aktivieren" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Archive (rar, zip, 7z) innerhalb von Archiven entpacken." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Alle Ordner innerhalb Archiven ignorieren" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Alle Dateien werden in einen einzelnen Ordner gespeichert." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Nur Artikel für obersten Warteschlangen-Eintrag herunterladen" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Für geringere Speicher-Verwendung aktivieren.
Deaktivieren, um zu " "verhindern, dass langsame Aufträge
die anderen Einträge in der " "Warteschlange blockieren." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Nur überprüfte Aufträge nachbearbeiten" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" "Entpacken und starten von Skripten nur bei verifizierten Jobs. Wenn " "ausgeschaltet, werden alle Jobs als vollständig markiert, selbst wenn sie " "unvollständig sind." #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Aktion wenn eine verschlüsselte RAR Datei geladen wird" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Im Fall von \"Pause\" müssen Sie ein Kennwort setzen und den Aufgabe " "fortsetzen." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "Erkennung identischer Downloads" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" "Erkenne identische Downloads anhand des Dateinamens oder des NZB-Inhalts." #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "Intelligente Duplikat Erkennung" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "Erkenne Duplikate durch Analyse der Dateinamen." #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "Erlaube \"Proper\" Releases" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" "Umgehe intelligente Duplikat-Erkennung, wenn PROPER, REAL oder REPACK im " "Download-Namen erkannt wird" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Verwerfen" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "Markiere Auftrag" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "Aufgabe abgebrochen (verschoben in die Historie)" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Aktion bei ungewollter Dateienendung" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "Aktion bei ungewollter Dateiendung" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Ungewollte Dateiendungen" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "Sperrliste" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "Erlaubtliste" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" "Modus auswählen, und alle (nicht-)erwünschten Erweiterungen auflisten. Zum " "Beispiel: exe oder exe, com" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "SFV-basierte Überprüfung aktivieren" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Zusätzliche Überprüfung mittels SFV-Dateien durchführen" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Benutzerskript kann Auftrag als fehlgeschlagen markieren" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Wenn das Benutzerskript einen Exit-Code ausgibt, der nicht \"0\" ist, wird " "der Auftrag als fehlgeschlagen markiert." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Ordner-Umbenennung aktivieren" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Temporäre Namen während der Nachbearbeitung verwenden. Deaktivieren, wenn " "das System nicht damit klar kommt." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Benutzer-Skript vor Warteschlange" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "" "Wird verwendet, bevor eine NZB-Datei zur Warteschlange hinzugefügt wird." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" "Wurde nach Fertigstellung des Downloads der eingereihten Aufträge " "ausgeführt." #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Zusätzliche PAR2-Parameter" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Nice-Parameter" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "IONice-Parameter" #: sabnzbd/skintext.py msgid "External process priority" msgstr "Priorität von externem Prozess" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Bei leerer Warteschlange Verbindung trennen" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Verbindung zu Usenet-Servern trennen,
wenn die Warteschlange leer ist " "oder SABnzbd angehalten wurde." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "Automatische Sortierung der Warteschlange" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" "Warteschlange automatisch sortieren wenn ein neuer Job hinzugefügt wird." #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" "Die Warteschlange wird alle 30 Sekunden neu sortiert, wenn % " "heruntergeladen, ausgewählt ist." #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Ausbreitungsverzögerung" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Artikel werden angehalten bis sie mindestens das gewählte alter erreicht " "haben. Ändern der Job Priorität auf Erzwingen wird die Verzögerung " "überspringen." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Auf neue Version prüfen" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Auch Test-Veröffentlichungen" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Leerzeichen in Ordnernamen ersetzen" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Leerzeichen in Ordnernamen durch Unterstriche ersetzen." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "Ersetze Unterstriche in Ordnernamen" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "Ersetze Unterstriche mit Punkte in Ordnernamen." #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Punkte in Ordner-Namen ersetzen" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Punkte in Ordner-Namen durch Leerzeichen ersetzen." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Für Windows kompatibel machen" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" "Für Server: stell sicher, dass die Dateinamen mit Windows kompatibel sind." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Browser beim Start öffnen" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Den Standard-Browser öffnen, wenn SABnzbd gestartet wird." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Downloads während der Nachbearbeitung anhalten" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Hält die Downloads zu Beginn der Nachbearbeitung an
und setzt sie " "danach fort." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Beispieldateien ignorieren" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Beispieldateien herausfiltern (z.B. Videoausschnitte)" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Nach dem Download löschen" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "Entschleiere finale Dateinamen" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" "Dateinamen von (großen) Dateien im Zielordner werden in den Auftragsnamen " "umbenannt, wenn sie verschleiert oder bedeutungslos aussehen." #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" "Zusätzlich wird versucht, die korrekte Dateierweiterung mithilfe der " "Dateisignatur zu ermitteln, falls noch keine Dateierweiterung vorhanden, " "oder sie sinnlos sein sollte." #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "HTTPS Zertifikat Überprüfung" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" "Überprüfe Zertifikate bei Verbindungen zu Indexern und RSS-Quellen über " "HTTPS." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "SOCKS5 Proxy" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" "Benutze den angegebenen SOCKS5 Proxy für alle ausgehenden Verbindungen." #: sabnzbd/skintext.py msgid "Server" msgstr "Server" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Nachbearbeitung" #: sabnzbd/skintext.py msgid "Naming" msgstr "Benennung" #: sabnzbd/skintext.py msgid "Quota" msgstr "Kontingent" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Wie viel kann in diesem Monat heruntergeladen werden (K/M/G)?" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Tag zurücksetzen" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "An welchem Tag des Monats oder der Woche (1=Montag) setzt Ihr ISP das " "Kontingent zurück (optional mit hh:mm)?" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "" "Soll wieder Heruntergeladen werden, nachdem das Kontingent zurückgesetzt " "wurde?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Kontingents-Periode" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "" "Wird das Kontingent jeden Tag, jede Woche oder jeden Monat zurückgesetzt?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Vor dem Herunterladen überprüfen" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Versuche die erfolgreiche Fertigstellung noch vor dem Herunterladen " "vorherzusagen (langsamer!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "SSL-Verschlüsselung" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" "Die Performanz verbessern, indem eine schwächere SSL-Verschlüsselung " "erzwungen wird." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Maximale Wiederholungen" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Maximale Anzahl wiederholter Versuche pro Server" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Aufträge abbrechen, die nicht abgeschlossen werden können" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Job abbrechen falls während des Downloads klar wird, dass zuviele Daten " "fehlen" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Server hinzufügen" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Serverbeschreibung" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Benutzername" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Passwort" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Zeitüberschreitung" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "Account Ablaufdatum" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "5 Tage vor dem Ablauf des Accounts warnen." #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" "Kontingent für dieses Konto, gezählt ab dem Zeitpunkt, an dem es festgelegt " "wird. In Bytes, optional gefolgt von K, M, G.
Warne, wenn es 0 " "erreicht, wird alle paar Minuten überprüft." #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Rückhaltezeit" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "Sichere Verbindung zum Server" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "Zertifikat überprüfung" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" "Minimum: Wenn SSL aktiviert, prüft die Serveridentität und Benutzung seiner " "Zertifikate. Strikt: Prüft und stelle sicher das der Hostname stimmt." #: sabnzbd/skintext.py msgid "Disabled" msgstr "Deaktiviert" #: sabnzbd/skintext.py msgid "Minimal" msgstr "Minimum" #: sabnzbd/skintext.py msgid "Strict" msgstr "Strikt" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 ist die höchste, 99 die niedrigste Priorität" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "Erforderlich" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" "Im Fall von Verbindungsausfällen wird die Download-Warteschlange für ein " "paar Minuten pausiert, anstatt diesen Server zu überspringen" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Optional" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "Für unzuverlässige Server, wird bei Fehlern länger ignoriert" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Aktivieren" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Server entfernen" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Server überprüfen" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Zähler zurücksetzen" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Server-Angaben werden überprüft …" #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Bandbreite" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Persönliche Notizen" #: sabnzbd/skintext.py msgid "Article availability" msgstr "Verfügbarkeit der Artikel" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "%f vorhanden von %d angefragten Artikeln" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Regel hinzufügen" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Häufigkeit" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Aktion" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argumente" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Aktuelle Regeln" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Aktivieren Sie das Feld neben dem Feed-Namen, wenn automatisch auf neue " "Einträge geprüft werden soll.
Wenn ein Feed hinzugefügt wird, werden " "nur neue Einträge verarbeitet und nicht diejenigen, die bereits im RSS-Feed " "enthalten waren, ausser Sie klicken \"Download erzwingen\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "Trenne verschiedene URLs mit Komma" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Feed lesen" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Download erzwingen" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "Filter übernehmen" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "Bearbeiten" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "Nächster Scan um" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Reihenfolge" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Typ" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Akzeptieren" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Verwerfen" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Benötigt" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "Benötigt Kategorie" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Mindestens" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Höchstens" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Von SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "Von Show SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Entspricht" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Entspricht nicht" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Heruntergeladen" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Jetzt alle Feeds lesen" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" "Wenn nur die Standard-Kategorie ausgewählt ist, werden die " "Benachrichtigungen für Jobs in allen Kategorien aktiviert. " #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Email-Benachrichtigung beim Fertigstellen von Aufträgen" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Nie" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Immer" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Nur bei Fehlern" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Benachrichtigung bei voller Festplatte" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "E-Mail senden, wenn die Festplatte voll ist und SABnzbd angehalten wird." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "RSS-Benachrichtigungen senden" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "E-Mail senden, wenn ein RSS-Feed einen Auftrag zur Warteschlange hinzufügt." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP-Server" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "ISP-Server für ausgehende E-Mails angeben." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "E-Mail-Empfänger" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "E-Mail-Adresse, an die die E-Mails gesendet werden." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "E-Mail-Absender" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Wer soll die E-Mail versandt haben?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "Optionaler Konto-Benutzername" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Für authentifizierte E-Mails wird der Kontoname benötigt." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "Optionales Konto-Passwort" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Für authentifizierte E-Mails wird das Passwort benötigt." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Benachrichtigung gesendet!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "NotifyOSD aktivieren" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Benachrichtigungscenter" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Windows-Benachrichtigungen aktivieren" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows-Benachrichtigungen" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Prowl-Benachrichtigungen aktivieren" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Erfordert ein Prowl-Konto" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "API-Schlüssel für Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Dein API-Key für Prowl (benötigt)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Pushover-Benachrichtungen aktivieren" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Benötigt einen Pushover-Konto" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Anwendungs-Token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Anwendungs-Token (erforderlich)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Benutzer-Schlüssel" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Benutzer-Schlüssel (erforderlich)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Gerät(e)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Geräte, welche die Nachrichten empfangen sollen" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "Notfall Wiederanlauf" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" "Wie oft dieselbe Benachrichtigung (in Sekunden) geschickt werden soll." #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "Notfall Verfall" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" "Wie viele Sekunden soll versucht werden die Nachricht erneut zu versenden" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Pushbullet-Benachrichtigungen aktivieren" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Erfordert ein Pushbullet-Konto" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Persönlicher API-Schlüssel" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Dein Pushbullet API-Schlüssel (erforderlich)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Gerät" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Geräte, welche die Benachrichtigungen empfangen sollen" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Benachrichtigungs-Skript" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Aktiviere Benachrichtigungs-Skript" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Führt ein benutzerdefiniertes Skript aus" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "Welches Skript sollte für die Benachrichtigung ausgeführt werden" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "Indexer können eine Kategorie innerhalb des NZB liefern, welche SABnzbd " "versuchen wird, mit den unten definierten Kategorien entsprechen. Darüber " "hinaus kannst du Begriffe zu \"Indexer Kategorien / Gruppen\" hinzufügen, um" " mehreren Kategorien zu entsprechen. Verwende Kommas, um Begriffe zu " "trennen. Wildcards in den Begriffen werden unterstützt.
Weitere " "Informationen können im Wiki gefunden werden." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Ein Sternchen * am Pfad-Ende verhindert die Erzeugung von Auftrags-Ordnern." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Relative Ordner basieren auf" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Ordner/Pfad" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "Indexer Kategorien/Gruppen" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Muster-Schlüssel" #: sabnzbd/skintext.py msgid "Clear" msgstr "Löschen" #: sabnzbd/skintext.py msgid "Presets" msgstr "Voreinstellungen" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Betroffene Kategorien" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Bedeutung" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Muster" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Film Name" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Film.Name" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Film_Name" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Sendungs Name" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Sendungs.Name" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Sendungs_Name" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Staffel-Nummer" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Episoden-Nummer" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Episoden-Name" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Episoden.Name" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Episoden_Name" #: sabnzbd/skintext.py msgid "Extension" msgstr "Endung" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Teilnummer" #: sabnzbd/skintext.py msgid "Decade" msgstr "Jahrzehnt" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Ursprünglicher Dateiname" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "Ursprünglicher Aufgabe Name" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Kleinschreibung" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py msgid "text" msgstr "text" #: sabnzbd/skintext.py msgid "file" msgstr "Datei" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Sortieranweisung" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "Multi-part Kennzeichnung" #: sabnzbd/skintext.py msgid "Show folder" msgstr "Zeige Ordner" #: sabnzbd/skintext.py msgid "Season folder" msgstr "Staffelordner" #: sabnzbd/skintext.py msgid "In folders" msgstr "In Ordnern" #: sabnzbd/skintext.py msgid "No folders" msgstr "Keine Ordner" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "Aufgabe Name als Ordnername" #: sabnzbd/skintext.py msgid "Series" msgstr "Serien" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "Groß- / Kleinschreibung berücksichtigen" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Ergebnis" #: sabnzbd/skintext.py msgid "Any property" msgstr "Jede Eigenschaft" #: sabnzbd/skintext.py msgid "property" msgstr "Eigenschaft" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "GuessIt Eigenschaft" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "GuessIt.Eigenschaft" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "GuessIt_Eigenschaft" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "Minimale Dateigröße" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "Betroffener Aufgabentyp" #: sabnzbd/skintext.py msgid "All" msgstr "Alle" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "Serien mit Ausstrahlungsdatum" #: sabnzbd/skintext.py msgid "Movies" msgstr "Filme" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "Andere / Unbekannte" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" "

Benutze die Sortierer, um deine fertigen Downloads zu orgenisieren. Zum " "Beispiel verschiebe alle Seriendateien in den Serien eigenen Ordner oder " "Verschiege alle Filme in den Filme eigenen Ordner.

Die Sortierer " "werden der Reihe nach bearbeitet und könne durch ziehen und ablegen " "umsortiert werden.
Der erste Aktive Sortierer der sowohl zur Kategorie " "als auch zum Aufgabentyp passt wird angewendet.

Wenn erweiterte " "Einstellungen aktiviert sind, sind noch mehr Einstellungen möglich.
" "Weitere informationen sind in der WIki zu finden.

" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "Sortierer hinzufügen" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "Sortierer entfernen" #: sabnzbd/skintext.py msgid "Test Data" msgstr "Testdaten" #: sabnzbd/skintext.py msgid "Quick start" msgstr "Schnellstart" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" "Bennene alle Episodendateien in der Kategorie \"tv\" um und veschiebe sie in" " den Serien eigenen Ordner" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" "Bennene alle Filmdateien in der Kategorie \"filme\" um und veschiebe sie in " "den Filme eigenen Ordner" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Selten genutzte Funktionen. Bedeutung und Erklärungen finden Sie per klick " "auf den Hilfe-Button um auf die Wiki-Seite zu gelangen.
Änder nichts ohne" " vorher das Wiki gelesen zu haben, da sonst schwerwiegende Nebeneffekte " "auftreten können.
Die Ursprungswerte stehen zwischen den runden Klammern." #: sabnzbd/skintext.py msgid "Values" msgstr "Werte" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "NZB-Details bearbeiten" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Löschen" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Dateiname" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Freier Speicherplatz" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Temporärer Ordner" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Mehrfach-Funktionen" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Shift-Taste gedrückt halten, um einen ganzen Bereich auszuwählen" #: sabnzbd/skintext.py msgid "Check all" msgstr "Alle auswählen" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "SABnzbd neustarten" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Wenn fertig" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Status und Interface-Optionen" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Oder Dateien per Drag-und-Drop ins Fenster ziehen!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Verbindung zu SABnzbd verloren.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "Wenn SABnzbd neustartet, wird diese Anzeige automatisch verschwinden!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "WARNUNG:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Abrufen" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Web-Oberfläche" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Aktualisierungsrate" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "die globalen Interface-Einstellungen verwenden" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Limit der Objekte in der Warteschlange" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Limit der Objekte im Verlauf" #: sabnzbd/skintext.py msgid "Date format" msgstr "Datumsformat" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "Weitere Spalten bei der Warteschlange" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "Weitere Spalten bei der Verlaufsliste" #: sabnzbd/skintext.py msgid "page" msgstr "Seite" #: sabnzbd/skintext.py msgid "Loading" msgstr "Wird geladen..." #: sabnzbd/skintext.py msgid "articles" msgstr "Artikel" #: sabnzbd/skintext.py msgid "Rename" msgstr "Umbenennen" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Reparatur der Warteschlange" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Aktive Verbindungen anzeigen" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Freigeben" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Verwaiste Aufträge" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Zurück in die Warteschlange schicken" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Alle löschen" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Alle wiederholen" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "NZB aus URL laden" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "NZB hochladen" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Wahlweise einen Dateinamen angeben:" #: sabnzbd/skintext.py msgid "Submit" msgstr "Senden" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Alle ausgewählten Dateien entfernen" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Vollendete Dateien anzeigen/verstecken" #: sabnzbd/skintext.py msgid "Top" msgstr "Ganz nach oben" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Ganz nach unten" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Skript-Protokoll anzeigen" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "Das Umbenennen des Jobs wird das direkte entpacken abbrechen." #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "Lokale Speicherung (cookies) sind in ihrem Browser Deaktiviert, Oberflächen " "Einstellungen gehen Verloren wenn sie den Browser schließen." #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "Glitter hat ein paar (neue) Feature die du bestimmt magst!" #: sabnzbd/skintext.py msgid "Custom" msgstr "Benutzerdefiniert" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Kompaktes Layout" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "Benutze die volle Fensterbreite" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Tab Layout
(separate Warteschlange und Verlauf)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Geschwindigkeit" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Löschen von Downloads bestätigen" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Löschen von Verlaufeinträgen bestätigen" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "Tastaturkürzel" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "Shift+Pfeil-Taste: Durchsuche eingereihte Aufträge und Verlaufsseiten" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Wie lange oder bis wann möchtest du pausieren? (in Englisch!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Sorry, damit konnten wir nichts anfangen. Versuchs nochmal." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Anhalten für …" #: sabnzbd/skintext.py msgid "Refresh" msgstr "Neu laden" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" "Alle Benutzernamen, Passwörter und API-Schlüssel werden automatisch aus dem " "Log und der darin enthaltenen Kopie deiner Einstellungen entfernt." #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "Sortiere nach % heruntergeladen Viel→Wenig" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sortieren nach Alter Älteste→Neuste" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sortieren nach Alter Neuste→Älteste" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sortieren nach Name A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sortieren nach Name Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sortieren nach Grösse Kleinste→Grösste" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sortieren nach Grösse Grösste→Kleiste" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Wird hochgeladen" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Erzwinge Trennung" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Entferne Job" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Entferne Jobs" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd-Einrichtungsassistent" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd-Version" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Zurück" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Weiter" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Server-Details" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Geben Sie bitte die Informationen zu Ihrem Usenet-Provider an." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Die Anzahl der Verbindungen, die der Provider erlaubt." #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Z.B. 8 oder 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Nur auswählen, wenn der Provider SSL-Verbindungen erlaubt." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Klicken um die eingegebenen Informationen zu überprüfen." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Z. B." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Die Einrichtung ist nun abgeschlossen." #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd läuft nun im Hintergrund." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Das Schliessen des Browser-Fensters oder -Tabs beendet SABnzbd NICHT." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Es ist empfehlenswert, diese Seite mit einem Lesezeichen zu versehen und " "dieses verwenden, um SABnzbd aufzurufen, wenn es im Hintergrund läuft." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Weiterführende Informationen finden Sie in unserem" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "SABnzbd anzeigen" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "SABnzbd beenden" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Assistenten starten" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "Backup wiederherstellen" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "Für SABnzbd besteht KEINERLEI GARANTIE.\n" "SABnzbd ist freie Software, die Sie unter bestimmten Bedingungen weitergeben dürfen.\n" "Sie steht unter der GNU GENERAL PUBLIC LICENSE Version 2 oder (nach Ihrer Option) jeder späteren Version.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "Fehler beim umbennenen von %s nach %s" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Umbenennen der gleichen Datei von %s nach %s fehlgeschlagen." #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Unerlaubter Zugriff" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "Datei nicht auf dem Server" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "Server konnte nicht vollständig antworten" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER abgestürzt" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Ungültige NZB-Datei." #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Abrufen der URL fehlgeschlagen; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "NZB-Datei wird versucht von %s abzurufen" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2105157 SABnzbd-4.3.2/po/main/da.po0000644000000000000000000034155214625637207014523 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Advarsel" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Fejl" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Kunne ikke starte web-interface" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Kan ikke finde webskabeloner: %s, forsøger med standardskabelon" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" "SABCTools deaktiveret: Der blev ikke fundet nogen korrekt version (Fandt " "v%s, forventede v%s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 binær... IKKE fundet!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "Din Unrar version er %s, vi anbefaler version %s eller højere.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar binær... IKKE fundet" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za binær... IKKE fundet!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Vær opmærksom på at 0.0.0.0 værtsnavn har brug for en IPv6-adresse for " "ekstern adgang" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP og HTTPS porte kan ikke være de samme" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd blev startet med kodning %s, dette bør være UTF-8. Forvent problemer" " med Unicoded fil- og mappenavne i downloads." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS fejlede på grund af manglende CERT og KEY filer" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Kunne ikke starte web-grænseflade: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s startet" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd lukning udført" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s modtaget, gemmer og lukker..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Fatal fejl ved lagring af state" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "E-mail afsendelse mislykkedes" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Afprøv notifikation" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Værtsnavnet er ikke indstillet." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "Der er ingen forbindelser angivet. Angiv mindst én forbindelse." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Adgangskode maskeret med ******, forsøg igen" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Ugyldige serverdetaljer" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradressen \"%s:%s\" er ikke gyldigt." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Timeout: Forsøg at aktivere SSL eller tilslut via en anden port." #: sabnzbd/api.py msgid "Timed out" msgstr "Timeout" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Ukendt SSL protokol: Prøv at deaktivere SSL eller forbinder på en anden " "port." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Serveren kræver brugernavn og adgangskode." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Tilslutning lykkedes!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Godkendelse mislykkedes, kontrollere brugernavn/adgangskode." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Alt for mange forbindelser, pause en download eller forsøg igen senere" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Det lykkedes ikke at tilslutte (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Server løsning" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ingen" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Standard" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Disken er fuld! Pauser" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Diskfejl ved oprettelse af fil %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Fatal fejl i Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "For lidt diskplads tvinger system i PAUSE" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "Pauset job \"%s\" på grund af krypterede RAR fil (hvis oplyst, alle " "adgangskoder blev forsøgt)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" "Afbrudt job \"%s\" på grund af krypterede RAR fil (hvis oplyst, alle " "adgangskoder blev forsøgt)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Afbrudt, kryptering registreret" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "I \"%s\" uønsket extension i RAR fil. Uønsket fil er \"%s\" " #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Uønsket extension i rar fil %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Afbrudt, uønsket extension fundet" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Kvote brugt, pause downloading" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Fejl parameter" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s er ikke en godkendt e-mail adresse" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Kræver serveradresse" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Ugyldig server adresse." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s er ikke et korrekt ciffer værdi" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Køen er ikke tom, kan ikke skifte mappe." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Kan ikke skrive til INI fil %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Kan ikke oprette backup fil for %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Forkert kodet adgangskode%s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "Kan ikke skrive til historik database, kontroller adgangsrettigheder!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Beskadigede historik database, skabte tom udskiftning" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL Kommando mislykkedes, se log" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Det lykkedes ikke at lukke databasen, se log" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Forkert logning i historiken av %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "Dekoder fejl: Ikke mere hukommelse" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Ukendt fejl under afkodning af %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Færdig" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Udpakket %s filer/mapper i %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Kan ikke læse overvåget mappe %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Genoptager" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Sat på pause" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Du skal angive den maksimale båndbredde, før du kan angive en båndbredde " "begrænsning" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Kan ikke tilslutte til server %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Servernavnet løser ikke" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Server %s vil blive ignoreret for i %s minutter" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Det lykkedes ikke at initialisere %s@%s med begrundelse %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Alt for mange forbindelser til serveren %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Det lykkedes ikke at logge på serveren %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Forbindelse %s@%s mislykkedes, besked %s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Suspect fejl i downloader" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Påbegynder lukning af SABnzbd" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Det lykkedes ikke at tilslutte mailserver" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Det lykkedes ikke at initialisere TLS tilslutning" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Serveren svarede ikke korrekt til helo hilsen" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Godkendelse til mailserver mislykkedes" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Ingen egnet godkendelsesmetode blev fundet" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Ukendt godkendelsesfejl i mailserver" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Det lykkedes ikke at sende e-mail" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Det lykkedes ikke at lukke e-mail tilslutning" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Kan ikke sende, mangler nødvendige data" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Kan ikke finde e-mail skabeloner i %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Ingen modtagere givet, ingen e-mail sendt" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Kan ikke læse %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Ingen e-mail skabeloner fundet" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd rapportere Disk Fuld\n" "\n" "Hej,\n" "\n" "SABnzbd er stoppet med at downloade, fordi disken er næsten fuld.\n" "Vær venlig at give plads og genoptage SABnzbd manuelt.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Kan ikke oprette mappe %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s mappe: %s adgang mislykkedes" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Det lykkedes ikke at ændre rettigheder på %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Oprettelse af (%s) mislykkedes" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Det lykkedes ikke at flytte %s til %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Fejl i tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Gemmes %s mislykkedes" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Downloadning af %s mislykkedes" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Bruger logget på webgrænsefladen" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Bruger logget ind" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API-nøgle mangler, indtast api-nøglen fra Konfiguration->Generelt i dit " "tredjepartsprogram:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Forkert API-nøgle, anvend api-nøglen fra Konfiguration->Generelt i dit " "tredjepartsprogram:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "Mislykkede login forsøg fra %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py msgid "Daily" msgstr "Dagligt" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Mandag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Tirsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Onsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Torsdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Fredag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Lørdag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Søndag" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "slået fra" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Udefineret server!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "FEJL:" #: sabnzbd/interface.py msgid "Back" msgstr "Tilbage" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "h" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Opdatering tilgængelig!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Fejl ved oprettelse af SSL-nøgle og certifikat" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "Python script \"%s\" har ikke udfør (+x) tilladelsessæt" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Serie sortering" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Dato sortering" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "Film sortering" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Køre script" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Udpakning af nesting for dybt [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Sammenlægger" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Ufuldstændig sekvens af filsammenlægning" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Filsammenlægning af %s mislykkedes" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fejl \"%s\" under filsammenlægning" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Fejl \"%s\" når du køre file_join på %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Sammen lagte %s filer" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Udpakning mislykkedes, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fejl \"%s\" under udpakning af RAR filer" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fejl \"%s\" når du køre rar_unpack på %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Fjernelse af %s mislykkedes!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Forsøger unrar med adgangskode \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Udpakker" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Udpakning mislykkedes, kunne ikke finde %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Udpakning mislykkedes, CRC-fejl" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "Udpakningen fejlede, da filen er for stor til filsystemet (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Udpakning mislykkedes, skrivefejl eller disken fuld?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Udpakningen mislykkedes, stien er for lang" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Udpakning mislykkedes, arkivet kræver adgangskode" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Ubrugelig RAR fil" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Ødelagt RAR fil" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Forsøger 7zip med adgangskode \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "se logfil" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Hurtig kontrollerende" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Reparér" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Hurtig kontrol OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Starter reparation" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Reparation mislykkedes, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Fejl %s når du kører par2_repair på %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fejl \"%s\" mens par2_repair kørte på %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 modtog forkerte indstillinger, tjek din konfiguration->Skifter " "indstillinger" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Bekræftelse i %s, alle filer er ok" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Bekræftelse i %s, kræver reparation" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" "Invalide par2 filer eller invalide PAR2 parametre, kan ikke bekræfte eller " "reparere" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Henter %s block..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Henter" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparation mislykkedes, ikke nok reparation blokke (%s mangler)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Reparerer" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Repareret i %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Disk fuld" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "Tjekker ekstra filer" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Bekræfter" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Kontrollerer" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Forsøger SFV verifikation" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "tilbage" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Denne server tillader ikke SSL på denne port" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Server %s bruger et upålidelig certifikat [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Start/lukning" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Pause" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Genoptag" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "Tilføjet NZB" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Efterbehandling i gang" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Job afsluttet" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Jobbet misllykedes" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Kø færdig" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Andre beskeder" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Åben færdig mappe" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Ikke tilgængelig" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Kunne ikke sende Prowl besked" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Dårlig respons fra pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Det lykkedes ikke at sende pushover besked" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Dårlig respons fra pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Det lykkedes ikke at sende pushbullet besked" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Script returnerede exit kode %s og output \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Notification scriptet \"%s\" findes ikke" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Det lykkedes ikke at sende Windows notification" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Kan ikke oprette temp fil for %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Det lykkedes ikke at tilføje %s, slette" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Fejl ved fjernelse af %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Det lykkedes ikke at importere %s filer fra %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Ødelagt kø-fil fundet, kan ikke fortsætte" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Downloadnings fejl %s, ødelagt fil fundet" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB tilføjet i køen" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorerer identiske NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "Fejler dublet NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "Dublet NZB" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "Ødelagt NZB fil %s, springer over (årsag=%s)" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Tom NZB fil %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "Før-kø script job markeret som mislykkedet" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Afbrudt, kan ikke afsluttes" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Det lykkedes ikke at importere %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLIKERE" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "KRYPTEREDE" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "FOR STOR" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "UFULDSTÆNDIG" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "UØNSKET" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "VENT %s sekunder" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "PROPAGATING %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Hentede i %s med et gennemsnit på %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Alder" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artikler misdannede" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artikler manglede" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artikler havde ikke-matchende dubletter" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Pause duplikeret NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Advarsler" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Inaktiv" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Kø" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Rens køen" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historik" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Tøm historik" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Hastighedsbegrænsning" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "minut" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Scan overvåget mappe" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Læs alle RSS feeds" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Færdig mappe" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Ufuldstændig mappe" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Fejlfinding" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Genstart" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Genstart uden login" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Afslut" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Kø (de første 10 poster)" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Tom" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Historik (de 10 seneste poster)" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Gå til guiden" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Standser..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problem med" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd har brug for en ledig TCP-/IP-port til sine interne webserver.
\n" " Port %s på %s blev forsøgt, men den er ikke til rådighed .
\n" " Nogle andre programmer bruger porten eller SABnzbd kører allerede.
\n" "
\n" " Genstart venligst SABnzbd med et andet portnummer." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "Hvis du får denne fejlmeddelelse igen, prøv et andet portnummer.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd har brug for en gyldig vært adresse til intern webserver .
\n" " Du har angivet en ugyldig adresse.
\n" " Sikkert valg er localhost og 0.0.0.0
\n" "
\n" " Venligst genstart SABnzbd med en gyldig host adresse." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd har fundet gemt data fra en anden SABnzbd version
\n" " men kan ikke genbruge dataene fra det andet program.

\n" " Du ønsker måske at afslutte din kø først med det andet program.

\n" " Efter dette, start programmet med \"- rene\" valgmulighede.
\n" " Dette vil slette den nu værende kø og historik!
\n" " SABnzbd læser filen \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd kan ikke finde sin webgrænseflade filer i %s.
\n" " Venligst installer programmet igen.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd fandt en alvorlig fejl:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd opdagede, at filen sqlite3.dll mangler .

\n" " Nogle dårligt designet virus-scannere fjernede denne fil .
\n" " Tjek venligst din virus-scanner, du kan prøve at geninstallere SABnzbd og klage til din virus-scanner leverandør .
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Tryk Startkey + R og skriv linjen (eksempel):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Åben et terminalvindue og tast linjen (eksempel):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Programmet startede ikke!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Alvorlig fejl" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Kan ikke starte browseren, sandsynligvis ikke fundet" #: sabnzbd/panic.py msgid "Access denied" msgstr "Adgang nægtet" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Fejl %s: Du skal angive et gyldigt brugernavn og adgangskode." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Gamle kø opdaget, brug Status->Reparation for at konvertere kø" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Det lykkedes ikke at kompilere regex for søgestreng: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Overførslen kan mislykkes, kun %s af det krævede %s tilgængelig" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Download mislykkedes - ikke på din server (e)" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Efterbehandling" #: sabnzbd/postproc.py msgid "Moving" msgstr "Flytter" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Sendt %s til kø" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Det lykkedes ikke at omdøbe \"%s\" til \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Kunne ikke flytte filer" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Kør bruger script %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Script exit kode er %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Kørte %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Mere" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Efterbehandling mislykkedes for %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Download mislykkedes" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Fjernelse af %s mislykkedes." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Overførsel fuldført" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Kan ikke oprette endelig mappe %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Ingen par2 sæt" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Some files failed to verify against \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Kontrolleret korrekt ved hjælp af SFV filer" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "Forsøger RAR-baseret kontrol" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Behov adgangskode" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] RAR-baserede kontrollen mislykkedes: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "RAR filer kontrolleres med succes" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "RAR filer kunne ikke bekræfte" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Fjernelse af %s mislykkedes" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Det lykkedes ikke systemet at gå i dvale" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Det lykkedes ikke systemet at gå i standby" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Fejl ved lukning af system" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Forkert RSS-feed beskrivelse \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Har ikke gyldig godkendelse til feed %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Server fejl (server kode %s); kunne ikke få %s på %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Mislykkedes at hente RSS fra %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Server %s bruger et upålideligt HTTPS-certifikat" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS Feed %s er tom" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Inkompatibel feed" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Tom RSS post blev fundet (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Vis grænseflade" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Pause i" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Pause 5 minutter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Pause 15 minutter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Pause 30 minutter" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Pause 1 time" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Pause 3 timer" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Pause 6 timer" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Luk ned" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Tilbageværende" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Tilføj NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Forkert tidsplan %s ved %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Ukendt handling: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Tidsplan for ikke-eksisterende server %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Forsøger at sætte status på ikke eksisterende server %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Downloader" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Sammenlægger filer" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Udpak" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Script" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Kilde" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Server" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Mislykkedes" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Venter" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Reparerer..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Udpakning..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Flytter..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Kør script..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Henter ekstra block..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Hurtig kontrol..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Bekræftelse..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "deaktivere server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "aktivere server" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Hastighedsbegrænsning" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Pause alt" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Pause efterbehandling" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Genoptag efterbehandling" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Læs RSS feeds" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Fjern mislykkede jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Fjern fuldførte job" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Pause lav prioritets jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Pause normal prioritets jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Pause høj prioritets jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Genoptag lav prioritets jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Genoptag normal prioritets jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Genoptag høj prioritets jobs" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Aktivere kvota styring" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Deaktivere kvota styring" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "Pause jobs med kategori" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "Genoptag jobs med kategori" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Slået fra" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Meget lav" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Moderat" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normal" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Høj" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Nødsituation" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Lav" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "time" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "timer" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minutter" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sekund" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "sekunder" #: sabnzbd/skintext.py msgid "day" msgstr "dag" #: sabnzbd/skintext.py msgid "days" msgstr "dage" #: sabnzbd/skintext.py msgid "week" msgstr "uge" #: sabnzbd/skintext.py msgid "Month" msgstr "Måned" #: sabnzbd/skintext.py msgid "Year" msgstr "År" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Månedsdag" #: sabnzbd/skintext.py msgid "This week" msgstr "Denne uge" #: sabnzbd/skintext.py msgid "This month" msgstr "Denne måned" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "I dag" #: sabnzbd/skintext.py msgid "Total" msgstr "Totalt" #: sabnzbd/skintext.py msgid "on" msgstr "på" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parameter" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python-version" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Startside" #: sabnzbd/skintext.py msgid "or" msgstr "eller" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Vært" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Annullér" #: sabnzbd/skintext.py msgid "Log in" msgstr "Log in" #: sabnzbd/skintext.py msgid "Log out" msgstr "Log ud" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Husk mig" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Gem" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Gemmer.." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Er du sikker?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Hjem" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Konfiguration" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Status" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Hjælp" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Problemer" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Støt projektet, donér!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Generelt" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Mapper" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Parameter" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Planlægning" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Meddelelser" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "E-mail" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategorier" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sortering" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Speciel" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Søg" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Er du sikker på du vil lukke SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Tilføj" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategori" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioritet" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Reparere" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Udpakke" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Slette" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Tvinge" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Stop" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Luk computer" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Sæt computer i standby" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Sæt computer i dvale" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Afslut SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Forløb" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Navn" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Forsøg igen" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Scripts" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Fjern alt fra køen?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Rens NZB'er" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Rens NZB'er & slet filer" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Fjern NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Fjern NZB & slet filer" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Mangler artikler" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Kvota tilbage" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "manuelt" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Nulstil kvota nu" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Skjul detaljer" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Vis detaljer" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Vis mislykket" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Vis Alt" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Størrelse" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Rens mislykket NZB'er" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Rens mislykket NZB'er & slet filer" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Rens komplette NZB'er" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Rens NZBs på den aktuelle side" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Valgfri Supplerende NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Sti" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Prøv igen alle mislykkede job" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Gennemtving afbrydelse" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Dette vil sende en test e-mail til din konto." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Vis log" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Test E-mail" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Logning" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Fejl/Advarsel" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Info" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Fejlfinding" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Forbindelser" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Artikel identifikator" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Fil sæt" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Aktiveret" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Tilslutning mislykkedes!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokal IPv4 adressse" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Offentlig IPv4 adresse" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6 adresse" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nameserver/DNS Lookup" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "System Performance (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Download mappe hastighed" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Komplet mappe hastighed" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Gentagelse test" #: sabnzbd/skintext.py msgid "Test download" msgstr "Test overførsel" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Konfigurations fil" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Brugt chace" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Knappen vil genstarte SABnzbd.
Andvend den hvis du oplever stabilitets " "problem.
Downlodning vil blive sat på pause før genstart og genoptages " "automatisk igen efter genstart." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "
Hvis godkendelse er aktiveret, skal du logge ind igen." #: sabnzbd/skintext.py msgid "Advanced" msgstr "Avanceret" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Der er forældreløse jobs i download mappen.
Du kan vælge at slette dem " "(herunder filer) eller sende dem tilbage til køen." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "\"Reparation\" knappen vil genstarte SABnzbd og lave en komplet
rekonstruktion af køens indhold, bevare allerede downloadede filer.
Dette vil ændre køens orden." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Ændringerne er ikke gemt og vil blive mistet." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" "Når din IP-adresse ændres eller SABnzbd genstarter, udløber sessionen." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Aktivere 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Udgave" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Oppetid" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Sikkerhedskopi" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Læs mere om dette på Wiki Help!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Genstarter SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Ændringer kræver genstart af SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd Webserver" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd Adresse" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Adresse som SABnzbd ska lytte på." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd Port" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Port som SABnzbd ska lytte på." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd brugernavn" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Valgfrit brugernavn." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd adgangskode" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Valgfrit adgangskode." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "Sikkerhed" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "HTTPS Aktivering" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Aktiver adgang til interface fra en HTTPS-adresse." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS Port" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Hvis tom, vil standard-porten kun lytte til HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS Certifikat" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Filnavn eller sti til HTTPS Certifikat." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "Generer ny selvsigneret certifikat og nøgle. Kræver SABnzbd genstart!" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS Nøgle" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Filnavn eller sti til HTTPS Nøgle." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS kæde certifikater" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Filnavn eller sti til HTTPS kæde." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Justering" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS Opdaterings interval" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Kontrol af interval (i minutter, i hvert fald 15). Ikke aktiv, når du bruger" " skemaer!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maksimal linje hastighed" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Procentvis af linje hastighed" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "Hvilken procentdel af linje hastighed bør SABnzbd bruge, fx 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Cache størrelse af artikler" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Cache artikler i hukommelsen for at reducere diskadgang.
I bytes, " "efterfulgt af K,M,G. For eksempel: \"64M\" eller \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Ryd listen" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Listen over filtypenavne, der skal slettes efter download.
For " "eksempel: nfo eller nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "Behold alle jobs" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "Jobs" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Gem ændringer" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Gendan standardværdier" #: sabnzbd/skintext.py msgid "Reset" msgstr "Nulstil" #: sabnzbd/skintext.py msgid "Language" msgstr "Sprog" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Vælg et web-grænseflade sprog." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "Hjælp os med at oversætte SABnzbd på dit sprog!
Tilføj uoversatte " "tekster eller forbedrede eksisterende oversættelser her:" #: sabnzbd/skintext.py msgid "API Key" msgstr "API-nøgle" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Denne nøgle vil give 3. parts programmer fuld adgang til SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB nøgle" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Denne nøgle vil give 3. parts programmer til at tilføje NZBs til SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Generere Ny Nøgle" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API nøgle QR kode" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Eksterne internetadgang" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Ingen adgang" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Tilføj NZB filer " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (ingen konfiguration)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Fuld API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Fuld webinterface" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Kun ekstern adgang kræver login" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "OBS: Mapper vil blive oprettet automatisk, når du gemmer. Du kan " "bruge absolutte stier til at gemme uden for standardmapperne." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Brugermapper" #: sabnzbd/skintext.py msgid "Browse" msgstr "Gennemse" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Midlertidig download mappe" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Sted at gemme uforarbejdede downloads.
Kan kun ændres, når køen er " "tom." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimum fri plads til midlertidige download mappe" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pause, når ledig plads kommer under denne værdi.
I bytes, evt. " "efterfulgt af K, M, G, T. For eksempel: '800M 'eller '8 G'" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Færdig download mappe" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Sted at opbevare færdige, fuldt forarbejdede downloads.
Kan " "tilsidesættes af bruger-definerede kategorier." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Automatisk genoptag" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Tilladelser til fuldførte overførsler" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Angive tilladelses mønster for afsluttede filer.
Anvend ciffer. For " "eksempel: \"755\" eller \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Overvåget Mappe" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Mappe til at gennemsøge for .nzb filer." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Skannings interval for overvåget mappe" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Sekunder mellem skanninger for .nzb filer." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "Scripts mappe" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "Mappe, der indeholder bruger-scripts." #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "E-mail-mappe skabeloner" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Mappe, der indeholder brugerdefinerede e-mail-skabeloner." #: sabnzbd/skintext.py msgid "Password file" msgstr "Adgangskode-fil" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fil, der indeholder alle adgangskoder. Vil blive brugt på adgangskode " "beskyttede RAR filer." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Systemmapper" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Administrativ mappe" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Placering for kø administrativ og historik database.
Kan kun ændres," " når køen er tom." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "Data vil ikke blive flyttet. Kræver SABnzbd genstartet!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Log mappe" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Placering af logfiler for SABnzbd.
Kræver genstart af SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr ".nzb Backup mappe" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Sted hvor .nzb filer gemmes." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Standard Base Folder" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Download alle par2 filer" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" "Dette forhindrer flere reparationer kører ved at downloade alle par2 filer " "når det er nødvendigt." #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Aktivere rekursive udpakning" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Udpakke arkiver (rar, zip, 7z) i arkiver." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignorere hvilken som helst mappe indeni arkiv" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Alle filer vil ligges ind i en enkelt mappe." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Kun artiklerne fra starten af køen" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Aktiver til mindre brug af hukommelse. Deaktiver for at forhindre langsom " "job fra at blokerer køen." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Efterbehandling kun verificerede jobs" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Handling når krypteret RAR er downloadet" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "I tilfælde af \"Pause\", skal du angive en adgangskode og genoptage jobbet." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "Tillad reelle udgivelser" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Kassér" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "Marker job" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "Mislykkes job (flyt til historik)" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Aktion når uønsket extension er fundet" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Uønsket extension" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Aktiver SFV-baseret kontrol" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Udfør en ekstra kontrol baseret på SFV-filer." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Bruger-script kan markere et job som mislykket" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Når bruger scriptet returnerer et non-zero exit code, vil jobbet blive " "markeret som mislykkedes." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Aktiver mappe omdøbning" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Brug midlertidig navne under efterbehandling. Deaktiver når dit system ikke " "kan håndtere det ordentligt." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Før kø bruger script" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Brugt før, en NZB kommer ind i køen." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Ekstra PAR2 parameter" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "God parameter" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "IONice parametre" #: sabnzbd/skintext.py msgid "External process priority" msgstr "Ekstern proces prioritet" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Afbryd når køen er tom" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Afbryd fra usenet-serverne når køen er tom eller sat på pause." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Propagation delay" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Indlæg vil blive sat på pause indtil de har mindst denne alder. Indstilling " "af job prioritet til Tvang vil springe forsinkelsen over." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Kontroller for ny version" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Test også udgivelser" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Erstat mellemrum i mappenavn" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Erstat mellemrum med understreg i mappenavn." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Erstat punktummer i mappenavn" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Erstat punktum med mellemrum i mappenavn." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Gør Windows kompatibel" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "For servere: Kontroller navne er kompatibel med Windows." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Start web browser ved opstart" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Starter standard web browser når SABnzbd starter." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Pause downloading under efterbehandling" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Pauser downloadet i begyndelsen af efterbehandling og igen når den er " "færdig." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ignorer Sample-filer" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Filtrerer prøve filer (f.eks. video eksempler)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Fjern efter download" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "verifikation HTTPS certifikat" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" "Kontroller certifikater, når du opretter forbindelse til indeksører og RSS-" "kilder ved hjælp HTTPS." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Server" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Efterbehandling" #: sabnzbd/skintext.py msgid "Naming" msgstr "Navngivning" #: sabnzbd/skintext.py msgid "Quota" msgstr "Kvota" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Hvor meget der kan downloades i denne måned (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Nulstil dag" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "På hvilken dag i måneden eller ugen (1 = mandag) nulstiller din " "internetudbyder kvota? (Valgfrit med tt: mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Skal download genoptages efter kvotaen er nulstillet?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Kvota periode" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Bliver kvota nulstillet hver dag, uge ​​eller måned?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Tjek før download" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Prøv at forudsige en vellykket afslutning, før selve download (langsom!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "SSL-chifre" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "Øge ydeevnen ved at tvinge en lavere SSL-kryptering styrke." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Maksimalt antal forsøg" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Maksimalt antal forsøg per server" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Afbryd job, der ikke kan færdiggøres" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Når under download det bliver klart, at for meget data mangler, afbryd " "jobbet" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Tilføj server" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Serverbeskrivelse" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Brugernavn" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Adgangskode" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Tidsudløb" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Tilgængelighed i dage" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "Sikker forbindelse til server" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "Certifikatkontrol" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Deaktiveret" #: sabnzbd/skintext.py msgid "Minimal" msgstr "Minimal" #: sabnzbd/skintext.py msgid "Strict" msgstr "Streng" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 er højeste prioritet, 100 er den laveste prioritet" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Valgfri" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" "For upålidelige servere, vil blive ignoreret længere i tilfælde af fejl" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Aktivere" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Fjern server" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Testserver" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Nulstil tæller" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Tester serverdetaljer..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Båndbredde" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Personlige notater" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Opret planlægning" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Forekomst" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Udfør" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argumenter" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Aktuel planlægning" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Afkrydsningsfeltet ud for feed navn skal afkrydses for at feeds vil være " "aktiveret og automatisk kontrolleres for nye emner.
Når et feed er " "tilføjet, vil det kun hente nye informationer og ikke noget, der allerede " "findes i RSS-feed, medmindre du trykker på \"Force Download\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "Adskil flere URL-adresser med komma" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Læs Feed" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Gennemtving download" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "Anvend filtre" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Rækkefølge" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Type" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filter" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Acceptere" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Afvise" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Kræver" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "Kræver Cat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Mindst" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Højst" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Fra SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "Fra Show SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Matchede" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Matchede ikke" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Hentet" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Læs alle Feeds nu" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "E-mail påmindelse når job er fuldført" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Aldrig" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Altid" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Kun ved fejl" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Påmindelse når harddisk er fyldt" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Send e-mail når harddisken er fyldt og SABnzbd er pauset." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Send RSS meddelelser" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Send e-mail når en RSS-feed tilføjer job i køen." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP-server" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Indtast ISP's server for udgående e-mail." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "E-mail modtagere" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "E-mail adresse hvor den skal sendes til." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "E-mail sendere" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Hvem skal vi sige sendte e-mailen?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "VALGFRIT konto brugernavn" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Brugernavn for e-mail som kræver godkendelse." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "VALGFRIT Brugeradgangskode" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Adgangskode for e-mail som kræver godkendelse." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Notifikation sendt!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Aktiver NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Notification Center" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Aktiver Windows notifikationer" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows Notifikationer" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Aktivere Prowl notifikation" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Kræver en Prowl konto" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "API nøgle for Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Personlig API nøgle for Prowl (påkrævet)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Aktivere Pushover anmeldelser" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Kræver en Pushover konto" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Program token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Program token (krævet)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Bruger nøgle" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Bruger nøgle (krævet)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Enhed(er)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Enhed(er) som meddelelse skal sendes til" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Aktiver Pushbullet notifikationer" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Kæver en Pushbullet konto" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Personlig API nøgle" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Din personlige Pushbullet API nøgle (krævet)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Enhed" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Enhed som meddelse skal sendes til" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Notification Script" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Aktivere notification script" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Udfører et brugerdefineret script" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "Hvilke script skal vi udføre for notification?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "Indeksatorer kan levere en kategori inde NZB som SABnzbd vil forsøge at " "matche de kategorier defineret nedenfor. Derudover kan du føje betingelser " "til ' indekseringen kategorier/grupper til at matche flere kategorier. Brug " "kommaer til at adskille vilkår. Jokertegn i vilkårene er understøttet. " "
Der findes mere information i wikien." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Slutter stien med en stjerne *, vil forhindre oprettelse af ​​job mapper." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Relative mapper er baseret på" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Mappe/Søgesti" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "Indekseringen kategorier/grupper" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Hjælp til Sorteringsstræng" #: sabnzbd/skintext.py msgid "Clear" msgstr "Ryd" #: sabnzbd/skintext.py msgid "Presets" msgstr "Forudindstillinger" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Påvirkede Kategorier" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Betyder" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Mønster" #: sabnzbd/skintext.py msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Film Navn" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Film.Navn" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Film_Navn" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Vis navn" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Vis.Navn" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Vis_Navn" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Sæsonnummer" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Episodenummer" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Episodenavn" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Episode.Navn" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Episode_Navn" #: sabnzbd/skintext.py msgid "Extension" msgstr "Endelse" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Delnummer" #: sabnzbd/skintext.py msgid "Decade" msgstr "Årti" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Originalfilnavn" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "Oprindelig Job Navn" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Små bogstaver" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py msgid "text" msgstr "tekst" #: sabnzbd/skintext.py msgid "file" msgstr "fil" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Sorteringsstreng" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "I mappe" #: sabnzbd/skintext.py msgid "No folders" msgstr "Ingen mappe" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "Job Navn som Filnavn" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "sag-justeret" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Forarbejdede resultat" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Alle" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Sjældent anvendte indstillinger. Deres betydning og forklaring, klik på " "knappen Hjælp for at gå til siden Wiki.
Ændre ikke disse uden at " "kontrollere wiki'en først, da disse kan give alvorlige side " "følger.
Standardværdierne er mellem parenteserne." #: sabnzbd/skintext.py msgid "Values" msgstr "Værdier" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Ændre NZB detaljer" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Slet" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Filnavn" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Ledig diskplads" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Midlertidig mappe" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Multi-operationer" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Hold Skiftetasten nede for at vælge et område" #: sabnzbd/skintext.py msgid "Check all" msgstr "Tjek alle" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Genstart SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Når køen er færdig" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Status og grænseflade indstillinger" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Eller trække og slippe filer i vinduet!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Mistet forbindelsen til SABnzbd.." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "I tilfælde af SABnzbd genstart vil denne skærm forsvinde automatisk!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "ADVARSEL:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Hent" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Webgrænseflade" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Opdateringsfrekvens" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Brug globale grænseflade indstillinger" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Køen elementbegrænsning" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Historik elementbegrænsning" #: sabnzbd/skintext.py msgid "Date format" msgstr "Datoformat" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "side" #: sabnzbd/skintext.py msgid "Loading" msgstr "Indlæser" #: sabnzbd/skintext.py msgid "articles" msgstr "artikler" #: sabnzbd/skintext.py msgid "Rename" msgstr "Omdøbe" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Kø reparation" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Vis aktive forbindelser" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Ophæv blokering" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Forældreløse jobs" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Send tilbage til køen" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Fjern alle" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Prøv igen alle" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Hent NZB fra URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Upload NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Angiv et valgfrit filnavn" #: sabnzbd/skintext.py msgid "Submit" msgstr "Tilføj" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Fjern alle valgte filer" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Skjul/vis komplette filer" #: sabnzbd/skintext.py msgid "Top" msgstr "Øverst" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Bunden" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Vis scriptlog" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "LocalStorage (cookies) er deaktiveret i din browser, indstillinger for " "brugergrænsefladen vil gå tabt, når du lukker browseren!" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "Glitter har nogle (nye) egenskaber, du kan lide!" #: sabnzbd/skintext.py msgid "Custom" msgstr "Tilpasse" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Kompakt layout" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Tabbed layout
(separat kø og historie)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Hastighed" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Bekræft Kø-fjernelse" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Bekræft Historik-fjernelse" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Hvor længe eller indtil hvornår du vil standse? (på engelsk!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Vi kunne desværre ikke fortolke denne. Prøv igen." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Pause i..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Opdatere" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sortere efter alder Ældst→Nyeste" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sortere efter alder Nyeste→Ældst" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sortere efter navn A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sortere efter navn Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sortere efter størrelse Mindst→Størst" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sortere efter størrelse Størst→Mindst" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Uploader" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Tvinge afbrydelse" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Fjernelse af job" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Fjernelse af jobs" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Hurtigstart’s Guide" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd version" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Forrige" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Næste" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Serverdetaljer" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Angiv detaljerne fra din primære usenet udbyder." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Antallet af forbindelser tilladt af din udbyder" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "F.eks. 8 eller 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Vælg kun hvis din udbyder tillader SSL-forbindelser." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Klik for at teste de indtastede informationer." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Eks." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Installationen er nu fuldført!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd vil nu køre i baggrunden." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Lukning af alle browservinduer/faneblade vil ikke lukke SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Det anbefales, at du højreklikker og bogmærker denne placering, og bruger " "dette bogmærke for at få adgang SABnzbd, når det kører i baggrunden." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Øvrig hjælp kan du finde på vores" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Gå til SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Afslut SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Start guide" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd kommer med ABSOLUT INGEN GARANTI. \n" "Det er gratis software, og du er velkommen til at videredistribuere det under visse betingelser. \n" "Den er licenseret under GNU General Public License version 2 eller (efter eget valg) enhver senere version.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Kunne ikke omdøbe lignende fil: %s til %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Uautoriseret adgang" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "Fil ikke på server" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "Serveren kunne ikke fuldføre anmodningen" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "URLGRABBER CRASHED" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Fejl, Ubrugelig arkivfil" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "URL hentning mislykkedes; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Forsøger at hente NZB fra %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2095773 SABnzbd-4.3.2/po/main/SABnzbd.pot0000644000000000000000000025571714625637207015615 0ustar00runnerstaff# # SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.2RC1\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: team@sabnzbd.org\n" "Language-Team: SABnzbd \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" #. Error message #: SABnzbd.py msgid "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external access" msgstr "" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "" #. Warning message #: SABnzbd.py msgid "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads." msgstr "" #. Warning message #: SABnzbd.py msgid "Current umask (%o) might deny SABnzbd access to the files and folders it creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "" #: SABnzbd.py msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "" #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "" #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "" #: sabnzbd/api.py msgid "Invalid server details" msgstr "" #: sabnzbd/api.py msgid "Could not connect to %s on port %s. It appears that %s operates as a web server (port 80), possibly an indexer, not a usenet server. You have to fill a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "" #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Timed out" msgstr "" #: sabnzbd/api.py msgid "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "" #: sabnzbd/api.py msgid "Connection Successful!" msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "" #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "" #: sabnzbd/api.py msgid "Resolving address" msgstr "" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "" #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Permissions setting of %s might deny SABnzbd access to the files and folders it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "" #: sabnzbd/cfg.py msgid "The Completed Download Folder cannot be the same or a subfolder of the Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Do not use a folder in the application folder as your Scripts Folder, it might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Jobs will start unpacking during the downloading to reduce post-processing time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "" #: sabnzbd/downloader.py msgid "Resuming" msgstr "" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "" #: sabnzbd/downloader.py msgid "Login from too many different IP addresses to server %s [%s] - https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable with special character filenames. This can cause problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "API Key missing, please enter the api key from Config->General into your 3rd party program:" msgstr "" #: sabnzbd/interface.py msgid "API Key incorrect, Use the api key from Config->General in your 3rd party program:" msgstr "" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "" #: sabnzbd/interface.py msgid "Daily" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "" #: sabnzbd/interface.py msgid "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "" #: sabnzbd/interface.py msgid "Back" msgstr "" #: sabnzbd/misc.py msgid "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "" #: sabnzbd/misc.py msgid "h" msgstr "" #: sabnzbd/misc.py msgid "m" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Your password file contains more than 30 passwords, testing all these passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate hostname mismatch: the server hostname is not listed in the certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "" #. Notification - Pause downloading - Four way switch for duplicates - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Idle" msgstr "" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Restart" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "" #: sabnzbd/panic.py msgid "Problem with" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" #: sabnzbd/panic.py msgid "If you get this error message again, please try a different number.
" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "" #: sabnzbd/panic.py msgid "Fatal error" msgstr "" #: sabnzbd/panic.py msgid "Unable to bind to port %s on %s. Some other software uses the port or SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "" #: sabnzbd/panic.py msgid "Access denied" msgstr "" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "Completed Download Folder %s is on FAT file system, limiting maximum file size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "" #: sabnzbd/postproc.py msgid "Moving" msgstr "" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "" #: sabnzbd/postproc.py msgid "Download Completed" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "" #. Queue status "download" - Post processing pick list - Config->RSS button "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "" #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "" #: sabnzbd/skintext.py msgid "day" msgstr "" #: sabnzbd/skintext.py msgid "days" msgstr "" #: sabnzbd/skintext.py msgid "week" msgstr "" #: sabnzbd/skintext.py msgid "Month" msgstr "" #: sabnzbd/skintext.py msgid "Year" msgstr "" #: sabnzbd/skintext.py msgid "Day of month" msgstr "" #: sabnzbd/skintext.py msgid "This week" msgstr "" #: sabnzbd/skintext.py msgid "This month" msgstr "" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "" #: sabnzbd/skintext.py msgid "Total" msgstr "" #: sabnzbd/skintext.py msgid "on" msgstr "" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "" #: sabnzbd/skintext.py msgid "Python Version" msgstr "" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "" #: sabnzbd/skintext.py msgid "or" msgstr "" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "" #: sabnzbd/skintext.py msgid "Cancel" msgstr "" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "" #: sabnzbd/skintext.py msgid "Saving.." msgstr "" #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect all active connections to usenet servers. Connections will be reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "Adds a verified test NZB of the specified size, filled with random data. Can be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "" #: sabnzbd/skintext.py msgid "This will restart SABnzbd.
Use it when you think the program has a stability problem.
Downloading will be paused before the restart and resume afterwards." msgstr "" #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "There are orphaned jobs in the download folder.
You can choose to delete them (including files) or send them back to the queue." msgstr "" #: sabnzbd/skintext.py msgid "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded files.
This will modify the queue order." msgstr "" #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "" #: sabnzbd/skintext.py msgid "When your IP address changes or SABnzbd is restarted the session will expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "" #: sabnzbd/skintext.py msgid "Speed up repairs by installing par2cmdline-turbo, it is available for many platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "" #: sabnzbd/skintext.py msgid "Uptime" msgstr "" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "" #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "" #: sabnzbd/skintext.py msgid "If the SABnzbd Host or Port is exposed to the internet, your current settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "" #: sabnzbd/skintext.py msgid "Modern web browsers and other clients will not accept self-signed certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "" #: sabnzbd/skintext.py msgid "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py msgid "Tuning" msgstr "" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "" #: sabnzbd/skintext.py msgid "Checking interval (in minutes, at least 15). Not active when you use the Scheduler!" msgstr "" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "" #: sabnzbd/skintext.py msgid "Cache articles in memory to reduce disk access.
In bytes, optionally follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "Create a backup of the configuration file and databases in the Backup Folder.
If the Backup Folder is not set, the backup will be created in the Completed Download Folder.
Recurring backups can be configured on the Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "" #: sabnzbd/skintext.py msgid "List of file extensions that should be deleted after download.
For example: nfo or nfo, sfv" msgstr "" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "" #: sabnzbd/skintext.py msgid "Language" msgstr "" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "" #: sabnzbd/skintext.py msgid "Help us translate SABnzbd in your language!
Add untranslated texts or improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "NZB Key" msgstr "" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "" #: sabnzbd/skintext.py msgid "External internet access" msgstr "" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "" #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "" #: sabnzbd/skintext.py msgid "Full API" msgstr "" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders." msgstr "" #: sabnzbd/skintext.py msgid "User Folders" msgstr "" #: sabnzbd/skintext.py msgid "Browse" msgstr "" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location to store unprocessed downloads.
Can only be changed when queue is empty." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Auto-pause when free space is beneath this value.
In bytes, optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location to store finished, fully processed downloads.
Can be overruled by user-defined categories." msgstr "" #: sabnzbd/skintext.py msgid "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "" #: sabnzbd/skintext.py msgid "Downloading will automatically resume if the minimum free space is available again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "" #: sabnzbd/skintext.py msgid "Set permissions pattern for completed files/folders.
In octal notation. For example: \"755\" or \"777\"" msgstr "" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "" #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "" #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "" #: sabnzbd/skintext.py msgid "Password file" msgstr "" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" #: sabnzbd/skintext.py msgid "System Folders" msgstr "" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location for queue admin and history database.
Can only be changed when queue is empty." msgstr "" #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location where the backups of the configuration file and databases are stored.
If left empty, the backup will be created in the Completed Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "" #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "" #: sabnzbd/skintext.py msgid "This prevents multiple repair runs by downloading all par2 files when needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "" #: sabnzbd/skintext.py msgid "Enable for less memory usage. Disable to prevent slow jobs from blocking the queue." msgstr "" #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Only unpack and run scripts on jobs that passed the verification stage. If turned off, all jobs will be marked as Completed even if they are incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "Select a mode and list all (un)wanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "" #: sabnzbd/skintext.py msgid "When the user script returns a non-zero exit code, the job will be flagged as failed." msgstr "" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "" #: sabnzbd/skintext.py msgid "Use temporary names during post processing. Disable when your system doesn't handle that properly." msgstr "" #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "Posts will be paused untill they are at least this age. Setting job priority to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "" #: sabnzbd/skintext.py msgid "Pauses downloading at the start of post processing and resumes when finished." msgstr "" #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "If filenames of (large) files in the final folder look obfuscated or meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "Additionally, attempts to set the correct file extension based on the file signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "" #: sabnzbd/skintext.py msgid "Post processing" msgstr "" #: sabnzbd/skintext.py msgid "Naming" msgstr "" #: sabnzbd/skintext.py msgid "Quota" msgstr "" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "" #: sabnzbd/skintext.py msgid "On which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)" msgstr "" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "" #: sabnzbd/skintext.py msgid "Check before download" msgstr "" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py msgid "When during download it becomes clear that too much data is missing, abort the job" msgstr "" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "Quota for this account, counted from the time it is set. In bytes, optionally follow with K,M,G.
Warn when it reaches 0, checked every few minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "Minimal: when SSL is enabled, verify the identity of the server using its certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "In case of connection failures, the download queue will be paused for a few minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "" #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "" #: sabnzbd/skintext.py msgid "The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press \"Force Download\"." msgstr "" #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "" #: sabnzbd/skintext.py msgid "If only the Default category is selected, notifications are enabled for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "" #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "" #: sabnzbd/skintext.py msgid "Email Sender" msgstr "" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "" #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "" #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "Indexers can supply a category inside the NZB which SABnzbd will try to match to the categories defined below. Additionally, you can add terms to \"Indexer Categories / Groups\" to match more categories. Use commas to separate terms. Wildcards in the terms are supported.
More information can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "" #: sabnzbd/skintext.py msgid "Clear" msgstr "" #: sabnzbd/skintext.py msgid "Presets" msgstr "" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "" #: sabnzbd/skintext.py msgid "Meaning" msgstr "" #: sabnzbd/skintext.py msgid "Pattern" msgstr "" #: sabnzbd/skintext.py msgid "Result" msgstr "" #: sabnzbd/skintext.py msgid "Title" msgstr "" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "" #: sabnzbd/skintext.py msgid "Show Name" msgstr "" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "" #: sabnzbd/skintext.py msgid "Season Number" msgstr "" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "" #: sabnzbd/skintext.py msgid "Extension" msgstr "" #: sabnzbd/skintext.py msgid "Part Number" msgstr "" #: sabnzbd/skintext.py msgid "Decade" msgstr "" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "" #: sabnzbd/skintext.py msgid "TEXT" msgstr "" #: sabnzbd/skintext.py msgid "text" msgstr "" #: sabnzbd/skintext.py msgid "file" msgstr "" #: sabnzbd/skintext.py msgid "Sort String" msgstr "" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "" #: sabnzbd/skintext.py msgid "No folders" msgstr "" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "

Use Sorters to automatically organize your completed downloads. For example, put all episodes from a series in a season-specific folder. Or, put movies in a folder named after the movie.

Sorters are tried in order of appearance and can be reordered by dragging and dropping.
The first active sorter that matches both the affected category and job type is applied.

More options are available when Advanced Settings is checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "Move and rename all episodes in the \"tv\" category to a show-specific folder" msgstr "" #: sabnzbd/skintext.py msgid "Move and rename all movies in the \"movies\" category to a movie-specific folder" msgstr "" #: sabnzbd/skintext.py msgid "Rarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
Don't change these without checking the Wiki first, as some have serious side-effects.
The default values are between parentheses." msgstr "" #: sabnzbd/skintext.py msgid "Values" msgstr "" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "" #: sabnzbd/skintext.py msgid "Free Space" msgstr "" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "" #: sabnzbd/skintext.py msgid "Check all" msgstr "" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "" #: sabnzbd/skintext.py msgid "Fetch" msgstr "" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "" #: sabnzbd/skintext.py msgid "History item limit" msgstr "" #: sabnzbd/skintext.py msgid "Date format" msgstr "" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "" #: sabnzbd/skintext.py msgid "Loading" msgstr "" #: sabnzbd/skintext.py msgid "articles" msgstr "" #: sabnzbd/skintext.py msgid "Rename" msgstr "" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "" #: sabnzbd/skintext.py msgid "Unblock" msgstr "" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "" #: sabnzbd/skintext.py msgid "Delete All" msgstr "" #: sabnzbd/skintext.py msgid "Retry all" msgstr "" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "" #: sabnzbd/skintext.py msgid "Submit" msgstr "" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "" #: sabnzbd/skintext.py msgid "Top" msgstr "" #: sabnzbd/skintext.py msgid "Bottom" msgstr "" #: sabnzbd/skintext.py msgid "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "LocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "" #: sabnzbd/skintext.py msgid "Pause for..." msgstr "" #: sabnzbd/skintext.py msgid "Refresh" msgstr "" #: sabnzbd/skintext.py msgid "All usernames, passwords and API-keys are automatically removed from the log and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "" #: sabnzbd/skintext.py msgid "Server Details" msgstr "" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "" #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "" #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "" #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "" #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" #: sabnzbd/skintext.py msgid "It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background." msgstr "" #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.213153 SABnzbd-4.3.2/po/main/he.po0000644000000000000000000041216414625637207014531 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # ION, 2024 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: ION, 2024\n" "Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: he\n" "Plural-Forms: nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "אזהרה" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "שגיאה" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "כישלון בהתחלת ממשק רשת" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "לא ניתן למצוא תבניות רשת: %s, מנסה תבנית תקנית" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "SABCTools מושבת: גרסה נכונה לא נמצאה! (%s נמצאה, מצפה אל %s)" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 בינארי… לא נמצא!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "גרסת UNRAR שלך היא %s, אנחנו ממליצים על גרסה %s או גבוהה יותר.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar בינארי… לא נמצא!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za בינארי… לא נמצא!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "פירקנים חיוניים חסרים, הורדה אינה יכולה להתחיל." #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "אנא הייה מודע ששם המארח 0.0.0.0 יצטרך כתובת IPv6 לצורך גישה חיצונית" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "פתחות של HTTP ו־HTTPS אינן יכולות להיות אותו דבר" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd הותחל עם קידוד %s, הוא אמור להיות UTF-8. צפה לבעיות עם שמות Unicoded" " של קבצים וסיפריות בהורדות." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" "פקודת umask נוכחית (%o) עשויה לדחות גישה מן SABnzbd אל הקבצים והתיקיות שהוא " "יוצר." #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "לא היה ניתן לטעון תעודות נוספות מחבילת תעודות" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS הושבת בגלל קבצים חסרים של CERT ו־KEY" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "HTTPS הושבת בגלל קבצים בלתי תקפים של CERT ו־KEY" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "כישלון בהתחלת ממשק רשת: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s התחיל" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "כיבוי SABnzbd הסתיים" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "אות %s נתפס, שומר ויוצא…" #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "שגיאה חמורה במצב שמירה" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "מפעיל מחדש בגלל בתר־מעבד שקרס" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "מפעיל מחדש בגלל מורידן שקרס" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "מפעיל מחדש בגלל אסמבלר שקרס" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "לא ניתן להשיג גישה אל קובץ PID בשם %s" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "דוא״ל הצליח" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "בחן התראה" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "שם המארח לא נקבע." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "אין חיבורים שנקבעו. אנא קבע לפחות חיבור אחד." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "סיסמאות מוסוות באמצעות ******, אנא הכנס מחדש" #: sabnzbd/api.py msgid "Invalid server details" msgstr "פרטי שרת בלתי תקפים" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" "לא היה ניתן להתחבר אל %s על פתחה %s. נראה כי %s פועל כשרת רשת (פתחה 80), " "כנראה מדדן, לא שרת Usenet. אתה חייב למלא שרת Usenet." #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "כתובת השרת \"%s:%s\" אינה תקפה." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "פסק זמן חלף: נסה לאפשר SSL או להתחבר על פתחה שונה." #: sabnzbd/api.py msgid "Timed out" msgstr "אזל הזמן" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "פרוטוקול SSL בלתי ידוע: נסה להשבית SSL או להתחבר על פתחה שונה." #: sabnzbd/api.py msgid "Server requires username and password." msgstr ".השרת דורש שם משתמש וסיסמה" #: sabnzbd/api.py msgid "Connection Successful!" msgstr "חיבור מוצלח!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "אימות נכשל, בדוק שם משתמש/סיסמה." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "יותר מדי חיבורים, אנא השהה הורדה או נסה שוב מאוחר יותר" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "(%s) לא היה ניתן לקבוע תוצאת חיבור" #: sabnzbd/api.py msgid "Resolving address" msgstr "פותר כתובת" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "אין" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "ברירת מחדל" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "דיסק מלא! מאלץ השהיה" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "שגיאת דיסק ביצירת קובץ %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "שגיאה חמורה ב־Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "שטח דיסק קטן מדי, מאלץ השהיה" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" "העבודה \"%s\" הושהתה בגלל קובץ RAR מוצפן (במקרה שסיסמאות סופקו, כולן נוסו)" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "העבודה \"%s\" בוטלה בגלל קובץ RAR מוצפן (במקרה שסיסמאות סופקו, כולן נוסו)" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "בוטל, הצפנה התגלתה" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "בעבודה \"%s\" יש סיומת בלתי רצויה בתוך קובץ RAR. הקובץ הבלתי רצוי הוא %s" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "סיומת בלתי רצויה בקובץ rar %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "בוטל, סיומת בלתי רצויה התגלתה" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "העבודה \"%s\" כנראה מוצפנת עקב RAR עם אותו השם בתוך RAR זה" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "העבודה \"%s\" כנראה מוצפנת: \"סיסמה\" בשם הקובץ \"%s\"" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "מכסה נוצלה, משהה הורדה" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "פרמטר שגוי" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s אינה כתובת דוא״ל תקפה" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "כתובת שרת דרושה" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "כתובת שרת בלתי תקפה." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "%s הוא לא תסריט תקף" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s אינו ערך אוקטלי נכון" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" "הגדרת הרשאות של %s עשויה לדחות גישה מן SABnzbd אל הקבצים והתיקיות שהוא יוצר." #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "נתיב הרשת \"%s\" לא אמור להיות בשימוש כאן" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "התור אינו ריק, לא ניתן לשנות תיקייה." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" "תיקיית ההורדות השלמות אינה יכולה להיות אותה תיקייה או תת־תיקייה של תיקיית " "ההורדות הזמניות" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" "אל תשתמש בתיקייה בתוך תיקיית היישום כתיקיית התסריטים שלך, היא עשויה להתרוקן " "במהלך עדכונים." #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "התצורה נעולה, אי אפשר לשמור הגדרות" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "לא ניתן לכתוב אל קובץ INI %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "לא ניתן ליצור קובץ גיבוי עבור %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "לא היה ניתן לשחזר גיבוי" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "סיסמה מקודדת באופן שגוי %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "לא ניתן לכתוב במסד נתוני ההיסטוריה, בדוק זכויות גישה!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "מסד נתוני היסטוריה פגום, תחליף ריק נוצר" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "פקודת SQL נכשלה, ראה יומן" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "כישלון בסגירת מסד נתונים, ראה יומן" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "רישום של אירוע בלתי תקף בהיסטוריה עבור %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "כישלון מפענח: אין זיכרון" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "שגיאה בלתי ידועה בעת פענוח %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "אי־האפלה דולגה עקב תיקיות DVD/Blu-ray" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "אי־האפלה תיקנה את הסיומת של %d קבצים" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "אי־האפלה שינתה שם של %d קבצים" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "פריקה ישירה" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "הושלם" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "%s קבצים/תיקיות נפרקו תוך %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "פריקה ישירה אופשרה באופן אוטומטי." #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" "עבודות יתחילו להיפרק במהלך ההורדה כדי להפחית זמן בתר־עיבוד. עובד רק עבור " "עבודות שאינן צריכות תיקון." #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "לא ניתן לקרוא את התיקייה המושגחת %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "ממשיך" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "מושהה" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "אתה חייב לקבוע רוחב פס מרבי לפני שאתה קובע מגבלת רוחב פס" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "לא ניתן להתחבר אל השרת %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "שם השרת אינו פותר" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "השרת %s ייתקל בהתעלמות למשך %s דקות" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "אין שרתים פעילים!" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "כישלון באתחול %s@%s עם סיבה: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "שגיאה גורלית במורידן" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "%s@%s: קוד בלתי ידוע של מעמד התקבל %s עבור מאמר %s" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "יותר מדי חיבורים לשרת %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" "כניסה מיותר מדי כתובות IP שונות אל שרת %s [%s] - " "https://sabnzbd.org/multiple-adresses" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "כניסה נכשלה עבור שרת %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "התחברות אל %s@%s נכשלה, הודעה=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "הורדה חשודה במורידן" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "מכבה" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "השרת %s יפוג עוד %s ימים" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "השרת %s השתמש במכסה המצויינת" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "כישלון בהתחברות אל שרת דוא״ל" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "כישלון ביזימת חיבור TLS" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "השרת לא הגיב כראוי לברכת השלום" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "כישלון באימות שרת הדוא״ל" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "שיטת אימות הולמת לא נמצאה" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "כישלון בלתי ידוע של אימות בשרת דוא״ל" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "כישלון בשליחת דוא״ל" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "כישלון בסגירת חיבור דוא״ל" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "לא ניתן לשלוח, נתונים דרושים חסרים" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "לא ניתן למצוא תבניות דוא״ל ב־%s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "נמענים לא ניתנו, דוא״ל לא נשלח" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "לא ניתן לקרוא את %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "תבניות דוא״ל לא נמצאו" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "אל: %s\n" "מאת: %s\n" "תאריך: %s\n" "נושא: SABnzbd מדווח על דיסק מלא\n" "\n" "היי,\n" "\n" "SABnzbd הפסיק להוריד, מאחר שהדיסק כמעט מלא.\n" "אנא פנה מקום והמשך את SABnzbd באופן ידני.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "לא ניתן ליצור את התיקייה %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "תיקייה %s: שגיאת גישה %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "לא ניתן לשנות הרשאות של %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "כישלון בעשייה (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "כישלון בהעברת %s אל %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "ניסיון נחסם ליצור תיקייה %s" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "כישלון ב־tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "שמירת %s נכשלה" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "טעינת %s נכשלה" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "%s אינו בר־כתיבה בכלל. זה חוסם הורדות." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "בלתי ניתן לכתוב שם ארוך של קובץ אל %s. זה עשוי לגרום לבעיות." #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "בלתי ניתן לכתוב שם יוניקוד של קובץ אל %s. זה עשוי לגרום לבעיות." #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "%s אינו בר־כתיבה עם שמות קבצים עם תו מיוחד. זה יכול לגרום לבעיות." #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "חיבור מסורב מאת:" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "חיבור מסורב עם שם המארח \"%s\" מאת:" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "משתמש התחבר לממשק הרשת" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "משתמש התחבר" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "מפתח API חסר, אנא הכנס את מפתח ה־API מתצורה->כללי לתוך תוכנית הצד השלישי " "שלך:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "מפתח API שגוי, השתמש במפתח ה־API מתצורה->כללי בתוכנית הצד השלישי שלך:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "ניסיון כניסה בלתי מוצלח מן %s" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "ארכיון בלתי תקף של גיבוי" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "הזנה" #: sabnzbd/interface.py msgid "Daily" msgstr "יומי" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "יום שני" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "יום שלישי" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "יום רביעי" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "יום חמישי" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "יום שישי" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "שבת" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "יום ראשון" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "כבוי" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "שרת בלתי מוגדר!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "תיקיית קטגוריה אינה יכולה להיות תת־תיקייה של תיקיית ההורדות הזמניות." #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "שגיאה:" #: sabnzbd/interface.py msgid "Back" msgstr "הקודם" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" "כדי למנוע את כל האזהרות המועילות, השבת את ההגדרה המיוחדת 'helpful_warnings'." #: sabnzbd/misc.py msgid "d" msgstr "י" #: sabnzbd/misc.py msgid "h" msgstr "ש" #: sabnzbd/misc.py msgid "m" msgstr "ד" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "עדכון זמין!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "כישלון בהעלאת קובץ: %s" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "כישלון ביצירה של מפתח ותעודה של SSL" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" "קובץ הסיסמאות שלך מכיל יותר מ־30 סיסמאות, בחינת כל הסיסמאות האלו תיקח זמן " "רב. נסה לכתוב רק סיסמאות שימושיות." #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "כישלון בקריאת קובץ הסיסמה %s" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "[%s] הפקודה ב־build_command אינה מוגדרת." #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "לתסריט פייתון \"%s\" אין ערכת הרשאות ביצוע (+x)" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "מיון סדרות" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "מיון תאריכים" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "מיון סרטים" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "מריץ תסריט" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "פריקת קינון ארוכה מדי [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "מאחד" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "רצף בלתי שלם של קבצים ברי־איחוד" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "איחוד קבצים של %s נכשל" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] שגיאה \"%s\" בזמן איחוד קבצים" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "שגיאה \"%s\" בזמן הרצת file_join על %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] %s קבצים אוחדו" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "פריקה נכשלה, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] שגיאה \"%s\" בזמן פריקת קבצי RAR" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "שגיאה \"%s\" בזמן הרצת rar_unpack על %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "מחיקת %s נכשלה!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "מנסה לחלץ עם הסיסמה \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "פורק" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "פריקה נכשלה, לא היה ניתן למצוא את %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "פריקה נכשלה, שגיאת CRC" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "פריקה נכשלה, קובץ גדול מדי עבור מערכת הקבצים (FAT?)" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "פריקה נכשלה, שגיאת כתיבה או דיסק מלא?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "פריקה נכשלה, נתיב ארוך מדי" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "פריקה נכשלה, ארכיון דורש סיסמה" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "קובץ RAR בלתי שמיש" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "קובץ RAR פגום" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "מנסה 7zip עם הסיסמה \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "ראה קובץ יומן" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "בדיקה זריזה" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "תקן" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] בדיקה זריזה בסדר" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "מתחיל תיקון" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "תיקון נכשל, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "שגיאה %s בזמן הרצת par2_repair על הערכה %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "שגיאה \"%s\" בזמן הרצת par2_repair על הערכה %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "[%s] PAR2 קיבל אפשרויות שגויות, בדוק את הגדרות תצורה->מתגים שלך" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] וודאו ב־%s, כל הקבצים נכונים" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] וודאו ב־%s, תיקון דרוש" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "קבצי par2 בלתי תקפים או פרמטרי PAR2 בלתי תקפים, לא ניתן לוודא או לתקן" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "מושך %s גושים…" #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "מושך" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "תיקון נכשל, אין מספיק גושי תיקון (%s קצר)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "מתקן" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] תוקנו ב־%s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "מוודא תיקון" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "דיסק מלא" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "בודק קבצי תוספת" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "מוודא" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "בודק" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "מנסה וידוא SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "נותר" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "שרת זה אינו מתיר SSL על פתחה זו" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" "אי־התאמה בשם המארח של התעודה: שם המארח של השרת אינו כתוב בתעודה. זו סוגיית " "שרת." #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "תעודה בלתי תקפה. קרוב לוודאי שזו סוגית שרת." #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "השרת %s משתמש בתעודה בלתי מהימנה [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "וויקי" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "כישלון בהתחברות: %s %s@%s:%s (%s)" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "הזנק/כיבוי" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "השהה" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "המשך" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "NZB התווסף" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "בתר־עיבוד התחיל" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "עבודה הסתיימה" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "עבודה נכשלה" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "תור הסתיים" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "הודעות אחרות" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "פתח תיקייה" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "פתח תיקיית השלמה" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "לא זמין" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "כישלון בשליחת התראת macOS" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "כישלון בשליחת הודעת Prowl" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "כתובת Apprise אחת או יותר לא יכלו להיטען." #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "כישלון בשליחת התראת Apprise אחת או יותר" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "כישלון בשליחת הודעת Apprise" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "תגובה רעה מאת Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "כישלון בשליחת הודעת Pushover" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "תגובה רעה מאת Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "כישלון בשליחת הודעת Pushbullet" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "תסריט החזיר קוד יציאה %s ופלט \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "תסריט ההתראה \"%s\" אינו קיים" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "כישלון בשליחת התראת Windows" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "לא ניתן ליצור קובץ זמני עבור %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "שגיאה בזמן הוספת %s, מסיר" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "שגיאה בהסרת %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "כישלון ביבוא %s קבצים מן %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "קובץ תור בלתי תואם נמצא, לא יכול להמשיך" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "שגיאה בטעינת %s, קובץ פגום התגלה" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB התווסף לתור" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "מתעלם מן NZB כפול \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "מכשיל NZB כפול \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "NZB כפול" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "קובץ NZB בלתי תקף %s, מדלג (שגיאה: %s)" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "קובץ NZB ריק %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "תסריט קדם־תור סומן כנכשל" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "סיומת בלתי רצויה בקובץ %s (%s)" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "בוטל, לא יכול להיות שלם" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "שגיאה ביבוא %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "כפול" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "חלופה" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "מוצפן" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "גדול מדי" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "בלתי שלם" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "בלתי רצוי" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "המתן %s שניות" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "מפיץ %s דקות" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "ירד תוך %s בממוצע של %s ב/ש" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "גיל" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s מאמרים עוותו" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s מאמרים היו חסרים" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "אל %s מאמרים יש כפילויות בלתי תואמות" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "משהה NZB כפול \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "אזהרות" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "מנוחה" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "תור" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "טהר תור" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "היסטוריה" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "נקה היסטוריה" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "הגבל מהירות" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "דקה" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "סרוק תיקייה מושגחת" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "קרא את כל הזנות RSS" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "תיקייה שלמה" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "תיקייה בלתי שלמה" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "פתור בעיות" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "הפעל מחדש" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "הפעל מחדש ללא כניסה" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "צא" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "הוסף לתור 10 פריטים ראשונים" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "ריק" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "העבר להיסטוריה 10 פריטים אחרונים" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "לך לאשף" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "עוצר…" #: sabnzbd/panic.py msgid "Problem with" msgstr "בעיה עם" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd צריך פתחה חופשית של TCP/IP עבור שרת הרשת הפנימי שלו.
\n" " פתחה %s על %s נוסתה, אך היא אינה זמינה.
\n" " איזשהי תוכנה אחרת משתמשת בפתחה או SABnzbd כבר רץ.
\n" "
\n" " אנא הפעל מחדש את SABnzbd עם מספר פתחה אחר." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "אם אתה מקבל את הודעת השגיאה הזו שוב, אנא נסה מספר שונה.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd צריך כתובת מארח תקפה עבור שרת הרשת הפנימי שלו.
\n" " ציינת כתובת בלתי תקפה.
\n" " ערכים בטוחים הם localhost ו־0.0.0.0
\n" "
\n" " אנא הפעל מחדש את SABnzbd עם כתובת מארח תקינה." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd גילה נתונים שמורים מגרסה אחרת של SABnzbd
\n" " אבל אינו יכול להשתמש מחדש בנתונים של התוכנית האחרת.

\n" " ייתכן שתרצה לסיים תחילה את התור שלך עם התוכנית האחרת.

\n" " לאחר מכן, התחל תוכנית זו עם האפשרות \"--clean\".
\n" " זה ימחק את התור הנוכחי וההיסטוריה!
\n" " SABnzbd קרא את הקובץ \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd אינו יכול למצוא את קבצי ממשק הרשת שלו בנתיב %s.
\n" " אנא התקן את התוכנית שוב.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd גילה שגיאה חמורה:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd גילה שהקובץ sqlite3.dll חסר.

\n" " מספר סורקי נגיפים ירודים מסירים קובץ זה.
\n" " אנא בדוק את סורק הנגיפים שלך, נסה להתקין מחדש את SABnzbd והתלונן למוכר של סורק הנגיפים שלך.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "לחץ על מקש התחל+R והקלד את השורה (דוגמה):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "פתח חלון מסוף והקלד את השורה (דוגמה):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "התוכנית לא התחילה!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "שגיאה חמורה" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" "לא היה ניתן לקשר את פתחה %s על %s. איזשהי תוכנה אחרת משתמשת בפתחה או SABnzbd" " כבר רץ." #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "לא היה ניתן להפעיל את הדפדפן, כנראה שהוא לא נמצא" #: sabnzbd/panic.py msgid "Access denied" msgstr "גישה נדחתה" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "שגיאה %s: אתה צריך לספק שם משתמש וסיסמה תקפים." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "תור ישן התגלה, השתמש במעמד->תיקון כדי להמיר את התור" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "כישלון בליקוט ביטוי רגולרי עבור מונח חיפוש: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" "תיקיית ההורדות השלמות %s נמצאת במערכת קבצים FAT שמגבילה גודל מרבי של קובץ אל" " 4 ג״ב" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "הורדה עשויה להיכשל, רק %s מתוך %s דרושים זמינים" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "הורדה נכשלה - לא בשרת(ים) שלך" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "בתר־עיבוד" #: sabnzbd/postproc.py msgid "Moving" msgstr "מעביר" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "%s נשלח לתור" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "שגיאה בשינוי שם \"%s\" אל \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "כישלון בהעברת קבצים" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "מריץ תסריט משתמש %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "קוד יציאת תסריט הוא %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "הריץ את %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "עוד" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "בתר־עיבוד נכשל עבור %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "בתר־עיבוד בוטל" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "הורדה נכשלה" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "ניקוי של %s נכשל." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "הורדה הושלמה" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "לא ניתן ליצור תיקייה סופית %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] אין ערכות par2" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "מספר קבצים נכשלו בוידוא מול \"%s\"" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "וודא בהצלחה ע״י שימוש בקבצי SFV" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "מנסה וידוא מבוסס RAR" #: sabnzbd/postproc.py msgid "Passworded" msgstr "מוגן בסיסמה" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] וידוא מבוסס RAR נכשל: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "קבצי RAR וודאו בהצלחה" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "קבצי RAR נכשלו בוידוא" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "מנסה משנה שם של RAR" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "אין קובץ rar קודם תואם עבור %s" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "הסרת %s נכשלה" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "כישלון בחריפת מערכת" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "כישלון בהיכוננות מערכת" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "שגיאה בזמן כיבוי מערכת" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "חריגת DBus התקבלה %s" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "תיאור הזנת RSS לא נכון \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "אין אימות תקף עבור ההזנה %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "שגיאת צד שרת (קוד שרת %s); לא היה ניתן להשיג את %s על %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "כישלון באחזור RSS מן %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "השרת %s משתמש בתעודת HTTPS בלתי מהימנה" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "הזנת RSS %s הייתה ריקה" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "הזנה בלתי תואמת" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "כניסת RSS ריקה נמצאה (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "הראה ממשק" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "השהה למשך" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "השהה למשך 5 דקות" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "השהה למשך 15 דקות" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "השהה למשך 30 דקות" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "השהה למשך שעה" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "השהה למשך 3 שעות" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "השהה למשך 6 שעות" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "כבה" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "נותר" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "הוסף NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "תזמון גרוע %s ב־%s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "פעולה בלתי ידועה: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "תזמן עבור שרת בלתי קיים %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "מנסה לקבוע מעמד של שרת בלתי קיים %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "הורדה" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "אחד קבצים" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "פרוק" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "אי־האפלה" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "תסריט" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "מקור" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "שרתים" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "נכשל" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "ממתין" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "מתקן…" #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "מחלץ…" #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "מעביר…" #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "מריץ תסריט…" #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "מושך גושים נוספים…" #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "בדוק זריז…" #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "מוודא…" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "השבת שרת" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "אפשר שרת" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "מגבלת מהירות" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "השהה הכל" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "השהה בתר־עיבוד" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "המשך בתר־עיבוד" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "קרא הזנות RSS" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "הסר עבודות נכשלות" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "הסר עבודות נשלמות" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "השהה עבודות עם עדיפות נמוכה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "השהה עבודות עם עדיפות רגילה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "השהה עבודות עם עדיפות גבוהה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "המשך עבודות עם עדיפות נמוכה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "המשך עבודות עם עדיפות רגילה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "המשך עבודות עם עדיפות גבוהה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "אפשר ניהול מכסה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "השבת ניהול מכסה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "השהה עבודות עם קטגוריה" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "המשך עבודות עם קטגוריה" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "כבוי" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "נמוכה מאוד" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "בינונית" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "רגילה" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "גבוהה" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "חירום" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "נמוכה" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "שעה" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "שעות" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "דקות" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "שניה" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "שניות" #: sabnzbd/skintext.py msgid "day" msgstr "יום" #: sabnzbd/skintext.py msgid "days" msgstr "ימים" #: sabnzbd/skintext.py msgid "week" msgstr "שבוע" #: sabnzbd/skintext.py msgid "Month" msgstr "חודש" #: sabnzbd/skintext.py msgid "Year" msgstr "שנה" #: sabnzbd/skintext.py msgid "Day of month" msgstr "יום בחודש" #: sabnzbd/skintext.py msgid "This week" msgstr "השבוע הזה" #: sabnzbd/skintext.py msgid "This month" msgstr "החודש הזה" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "טווח נתונים נבחר" #: sabnzbd/skintext.py msgid "Today" msgstr "היום" #: sabnzbd/skintext.py msgid "Total" msgstr "סה״כ" #: sabnzbd/skintext.py msgid "on" msgstr "פועל" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "פרמטרים" #: sabnzbd/skintext.py msgid "Python Version" msgstr "גרסת פייתון" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "דף הבית" #: sabnzbd/skintext.py msgid "or" msgstr "או" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "מארח" #: sabnzbd/skintext.py msgid "Cancel" msgstr "ביטול" #: sabnzbd/skintext.py msgid "Log in" msgstr "התחבר" #: sabnzbd/skintext.py msgid "Log out" msgstr "התנתק" #: sabnzbd/skintext.py msgid "Remember me" msgstr "זכור אותי" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "שמור" #: sabnzbd/skintext.py msgid "Saving.." msgstr "שומר…" #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "האם אתה בטוח?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "בית" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "תצורה" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "מעמד" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "עזרה" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "פורום" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "צ'אט חי" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "סוגיות" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "תמוך במיזם, תרום!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "כללי" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "תיקיות" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "מתגים" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "תזמון" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "התראות" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "דוא״ל" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "קטגוריות" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "מיון" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "מיוחד" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "חיפוש" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "האם אתה בטוח שאתה רוצה לכבות את SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "הוסף" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "קטגוריה" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "עדיפות" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+תיקון" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+פריקה" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+מחיקה" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "אילוץ" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "עצירה" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "הכנס כתובת" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "כבה מחשב" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "היכון מחשב" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "חרוף מחשב" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "כבה את SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "מעבד" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "שם" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "נסה שוב" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "תסריטים" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "למחוק את כל הפריטים מהתור?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "האם אתה בטוח שאתה רוצה להסיר עבודות אלו?" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "טהר הורדות" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "טהר הורדות ומחק קבצים" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "הסר NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "הסר NZB ומחק קבצים" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "מחק לצמיתות (דלג על ארכיון)" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "מאמרים חסרים" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "מכסה שנותרה" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "ידני" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "אפס מכסה כעת" #: sabnzbd/skintext.py msgid "Archive" msgstr "ארכיון" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "הסתר פרטים" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "הראה פרטים" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "הראה נכשלים" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "הראה הכל" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "הראה ארכיון" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "גודל" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "נקה הורדות כושלות" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "נקה הורדות כושלות ומחק קבצים" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "נקה הורדות שלמות" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "טהר הורדות בדף הנוכחי" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "קובץ NZB משלים רשותי" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "נתיב" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "נסה שוב את כל העבודות הנכשלות" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "אלץ ניתוק" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" "נתק את כל החיבורים הפעילים אל שרתי Usenet. חיבורים ייפתחו מחדש לאחר מספר " "שניות אם יש פריטים בתור." #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "זה ישלח דוא״ל בדיקה אל החשבון שלך." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "הראה יומן" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "בחן דוא״ל" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "רושם ביומן" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "שגיאות/אזהרות" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ מידע" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ ניפוי תקלים" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "חיבורים" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "מזהי מאמר" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "ערכת קבצים" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "מאופשר" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "חיבור נכשל!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "כתובת IPv4 מקומית" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "כתובת IPv4 ציבורית" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "כתובת IPv6" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "שם שרת / חיפוש DNS" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "מהירות הורדה מוגבלת ע״י" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "מהירות דיסק" #: sabnzbd/skintext.py msgid "System load" msgstr "טעינת מערכת" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "ביצועי מערכת (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "מהירות תיקיית הורדות" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "מהירות תיקיית שלמים" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "רוחב־פס אינטרנט" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "חזור על בחינה" #: sabnzbd/skintext.py msgid "Test download" msgstr "בחן הורדה" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" "מוסיף בחינה מוודאת של הגודל המצוין, ממולא בנתונים אקראיים. יכול לשמש כדי " "לוודא ההגדרה שלך" #: sabnzbd/skintext.py msgid "Config File" msgstr "קובץ תצורה" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "מטמון בשימוש" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" ".SABnzbd זה יפעיל מחדש את
השתמש בזה כשאתה חושב שלתוכנית יש בעית " "יציבות.
הורדה תושהה לפני ההפעלה מחדש ותומשך לאחר מכן." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "
אם אימות מאופשר, תצטרך להיכנס שוב." #: sabnzbd/skintext.py msgid "Advanced" msgstr "מתקדם" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "יש עבודות יתומות בתיקיית ההורדות.
אתה יכול לבחור למחוק אותן (כולל " "קבצים) או לשלוח אותן חזרה לתור." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "הכפתור \"תקן\" יפעיל מחדש את SABnzbd ויעשה בנייה מחדש
מלאה של תוכן " "התור, תוך שימור קבצים שהורדו כבר.
זה ישנה את סדר התור." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "שינויים לא נשמרו, ויאבדו." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "כאשר כתובת ה־IP שלך משתנה או כאשר SABnzbd מופעל מחדש, השיח יפוג." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "אפשר חילוץ 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" "האץ תיקונים ע״י התקנת par2cmdline-turbo, הוא זמין עבור פלטפורמות רבות." #: sabnzbd/skintext.py msgid "Version" msgstr "גרסה" #: sabnzbd/skintext.py msgid "Uptime" msgstr "זמן פעולה" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "גיבוי" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "קרא את עזרת וויקי על זה!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "מפעיל מחדש את SABnzbd…" #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "שינויים ידרשו הפעלה מחדש של SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "שרת רשת SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "מארח SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "מארח אשר SABnzbd צריך להאזין אליו." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "פתחת SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "פתחה אשר SABnzbd צריך להאזין אליה." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "ערכת נושא של ממשק רשת" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "בחר ערכת נושא." #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "שם משתמש SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "שם משתמש רשותי של אימות" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "סיסמת SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "סיסמת אימות רשותית" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" "אם המארח או הפתחה של SABnzbd חשופים לאינטרנט, ההגדרות הנוכחיות שלך מאפשרות " "גישה חיצונית מלאה אל ממשק SABnzbd." #: sabnzbd/skintext.py msgid "Security" msgstr "אבטחה" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "אפשר HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "אפשר מתן גישה אל הממשק מכתובת HTTPS." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" "דפדפנים חדישים ולקוחות אחרים לא יקבלו תעודות חתומות עצמית ויתנו אזהרה או לא " "יתחברו בכלל." #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "פתחת HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "אם ריק, הפתחה התקנית תאזין רק אל HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "תעודת HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "שם קובץ או נתיב אל תעודת HTTPS." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "חולל תעודה חתומה־עצמית ומפתח. דורש הפעלה מחדש של SABnzbd!" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "מפתח HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "שם קובץ או נתיב אל מפתח HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "תעודות שרשרת של HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "שם קובץ או נתיב אל שרשרת HTTPS." #: sabnzbd/skintext.py msgid "Tuning" msgstr "כוונון" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "מרווח בדיקת RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "מרווח בדיקה (בדקות, לפחות 15). אינו פעיל כשאתה משתמש במתזמן!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "מהירות קו מרבית" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "אחוז של מהירות קו" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "איזה אחוז ממהירות הקו צריך SABnzbd להשתמש, למשל 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "מגבלת מטמון מאמרים" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "הטמן מאמרים בזיכרון כדי להפחית גישת דיסק.
בבתים, יכול לבוא עם K,M,G." " לדוגמה: \"64M\" או \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "צור גיבוי" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" "צור גיבוי של קובץ התצורה ומסדי הנתונים בתיקיית הגיבויים.
אם תיקיית " "הגיבויים לא הוגדרה, הגיבוי ייווצר בתיקיית ההורדות שהושלמו.
גיבויים חוזרים" " יכולים להיות מתוצרים בדף התזמון." #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "רשימת ניקוי" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "רשימת סיומות קבצים של קבצים שצריכים להימחק לאחר הורדה.
לדוגמה: " "nfo או nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "שימור היסטוריה" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "שמור את כל העבודות" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "העבר עבודות אל הארכיון אם ההיסטוריה חורגת ממספר מצוין של ימים" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "העבר עבודות אל הארכיון לאחר מספר מצוין של ימים" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "העבר את כל העבודות השלמות אל הארכיון" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "מחק את כל העבודות השלמות" #: sabnzbd/skintext.py msgid "Jobs" msgstr "עבודות" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "שמור שינויים" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "שחזר ברירות מחדל" #: sabnzbd/skintext.py msgid "Reset" msgstr "אפס" #: sabnzbd/skintext.py msgid "Language" msgstr "שפה" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "בחר שפת ממשק רשת." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "עזור לנו לתרגם את SABnzbd לעברית!
הוסף מלל לא מתורגם או שפר תרגומים " "קיימים כאן:" #: sabnzbd/skintext.py msgid "API Key" msgstr "מפתח API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "מפתח זה יתן לתוכניות צד שלישי גישה מלאה אל SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "מפתח NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "מפתח זה יתיר לתוכניות צד שלישי להוסיף קבצי NZB אל SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "חולל מפתח חדש" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "קוד QR של מפתח API" #: sabnzbd/skintext.py msgid "External internet access" msgstr "גישת אינטרנט חיצונית" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "אתה יכול להגדיר זכויות גישה עבור מערכות מחוץ אל הרשת המקומית שלך." #: sabnzbd/skintext.py msgid "No access" msgstr "אין גישה" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "הוסף קבצי NZB" #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (ללא תצורה)" #: sabnzbd/skintext.py msgid "Full API" msgstr "API מלא" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "ממשק רשת מלא" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "רק גישה חיצונית דורשת כניסה" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "הערה: תיקיות יווצרו באופן אוטומטי בעת שמירה. אתה יכול להשתמש " "בנתיבים מוחלטים כדי לשמור מחוץ לתיקיות ברירת המחדל." #: sabnzbd/skintext.py msgid "User Folders" msgstr "תיקיות משתמש" #: sabnzbd/skintext.py msgid "Browse" msgstr "עיין" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "תיקיית הורדות זמניות" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "מיקום לאחסון הורדות בלתי מעובדות.
ניתן לשינוי רק כאשר התור ריק." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "שטח פנוי מזערי עבור תיקיית הורדות זמניות" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "השהה באופן אוטומטי כששטח פנוי הוא מתחת לערך זה.
בבתים, יכול לבוא עם " "K,M,G,T. לדוגמה: \"800M\" או \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "תיקיית הורדות שלמות" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "מיקום לאחסון הורדות שהסתיימו, מעבודות במלואן.
ניתן להשתלטות ע״י " "קטגוריות מוגדרות־משתמש." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "השתמש במיון כדי לארגן ולשנות שם באופן אוטומטי את ההורדות השלמות שלך." #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "שטח פנוי מזערי עבור תיקיית הורדות שלמות" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "לא יעבוד אם תיקיית קטגוריה נמצאת בדיסק שונה." #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "המשך באופן אוטומטי" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" "ביצוע הורדה ימשיך באופן אוטומטי אם השטח הפנוי המזערי זמין שוב.
זה תקף " "על תיקיית ההורדות הזמניות ותיקיית ההורדות השלמות.
השטח נבדק כל כמה " "דקות." #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "הרשאות עבור הורדות שלמות" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "קבע דפוס הרשאות עבור קבצים ותיקיות שלמים.
בסימון אוקטלי. לדוגמה: " "\"755\" או \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "תיקייה מושגחת" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "תיקייה לניטור אחר קבצי nzb." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "מהירות סריקה של תיקייה מושגחת" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "מספר שניות בין סריקות אחר קבצי nzb." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "תיקיית תסריטים" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "תיקייה שמכילה תסריטי משתמש." #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "תיקיית תבניות דוא״ל" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "תיקייה שמכילה תבניות דוא״ל מוגדרות־משתמש." #: sabnzbd/skintext.py msgid "Password file" msgstr "קובץ סיסמה" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "קובץ שמכיל את כל הסיסמאות שינוסו על קבצי RAR מוצפנים." #: sabnzbd/skintext.py msgid "System Folders" msgstr "תיקיות מערכת" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "תיקיות מוסתרות" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "תיקייה מינהלית" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "מיקום עבור מנהלן התור ומסד נתוני ההיסטוריה.
ניתן לשינוי רק כאשר התור" " ריק." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "תיקיית גיבויים" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" "מיקום שבו הגיבויים של קובץ התצורה ומסדי הנתונים מאוחסנים.
אם נשאר ריק, " "הגיבוי ייווצר בתיקיית ההורדות שהושלמו." #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "נתונים לא יועברו. דורש הפעלה מחדש של SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "תיקיית יומן" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "מיקום של קבצי יומן עבור SABnzbd.
דורש הפעלה מחדש של SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "טהר יומנים" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "תיקיית גיבוי .nzb" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "מיקום שבו קבצי .nzb יאוחסנו." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "תיקיית יסוד ברירת מחדל" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "הורד את כל קבצי par2" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "זה מונע הרצות תיקון מרובות ע״י הורדת כל קבצי par2 בעת הצורך." #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "אפשר פריקה נסיגתית" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "פרוק ארכיונים (rar, zip, 7z) בתוך ארכיונים." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "התעלם מתיקיות כלשהן בתוך ארכיונים" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "כל הקבצים יעברו לתוך תיקייה יחידה." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "השג מאמרים רק עבור ראש התור" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "אפשר עבור פחות שימוש בזיכרון. השבת כדי למנוע מעבודות איטיות לחסום את התור." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "בצע בתר־עיבוד רק על עבודות שוודאו" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" "פרוק והרץ רק על עבודות שעברו את שלב הוידוא. אם מכובה, כל העבודות יסומנו " "כשלמות אפילו אם הן בלתי שלמות." #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "פעולה כאשר קובץ RAR יורד" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "במקרה של \"השהיה\", תצטרך לקבוע סיסמה ולהמשיך את העבודה." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "גילוי הורדה זהה" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "גלה הורדות זהות על סמך שם או תכני NZB." #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "גילוי שכפולים חכם" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "גלה שכפולים על סמך ניתוח של שם הקובץ." #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "התר שחרורים תקינים" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "עקוף גילוי שכפולים חכם אם PROPER, REAL או REPACK מתגלים בשם ההורדה." #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "השלך" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "הצמד תג לעבודה" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "הכשל עבודה (העבר להיסטוריה)" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "בטל בתר־עיבוד" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "פעולה כאשר סיומת בלתי רצויה מתגלה" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "פעולה כאשר סיומת בלתי רצויה מתגלה" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "סיומות בלתי רצויות" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "רשימה שחורה" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "רשימה לבנה" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" "בחר מצב וכתוב את כל הסיומות הבלתי רצויות. לדוגמה: exe או exe, " "com" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "אפשר בדיקות מבוססות SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "בצע וידוא נוסף שמבוסס על קבצי SFV." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "תסריט משתמש יכול לדגל עבודה כנכשלה" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "כאשר תסריט המשתמש מחזיר קוד יציאה בלתי אפסי, העבודה תדוגל כנכשלה." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "אפשר שינוי שם תיקייה" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "השתמש בשמות זמניים במהלך בתר־עיבוד. השבת כאשר המערכת שלך אינה מתמודדת עם זה " "כראוי." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "תסריט משתמש של קדם־תור" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "בשימוש לפני ש־NZB נכנס לתור." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "תסריט בסיום תור" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "מבוצע לאחר שהתור יסיים להוריד." #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "פרמטרי PAR2 נוספים" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "פרמטרי Nice" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "פרמטרי IONice" #: sabnzbd/skintext.py msgid "External process priority" msgstr "עדיפות תהליך חיצוני" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "התנתק בתור ריק" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "התנתק משרת(י) Usenet כאשר התור ריק או מושהה." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "מיין תור באופן אוטומטי" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "מיין עבודות בתור באופן אוטומטי כאשר עבודה חדשה מתווספת." #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "התור ימוין כל 30 שניות אם האפשרות % ירד נבחרה." #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "עיכוב רביה" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "רשומות יושהו עד שהן לפחות בגיל זה. הגדרת עדיפות עבודה אל אילוץ תדלג על " "העיכוב." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "בדוק אחר שחרור חדש" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "גם שחרורי בחינה" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "החלף רווחים בשמות תיקיות" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "החלף רווחים בקווים תחתונים בשמות תיקיות." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "החלף קווים תחתונים בשמות תיקייה" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "החלף קווים תחתונים בנקודות בשמות תיקייה" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "החלף נקודות בשמות תיקיות" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "החלף נקודות ברווחים בשמות תיקיות." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "עשה תואם Windows" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "עבור שרתים: וודא שהשמות תואמים עם Windows." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "הפעל דפדפן בהזנק" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "הפעל את דפדפן ברירת המחדל בעת התחלת SABnzbd." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "השהה הורדה במהלך בתר־עיבוד" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "משהה הורדה בתחילת בתר־עיבוד וממשיך בסיום." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "התעלם מדוגמיות" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "סנן החוצה קבצי דוגמית (לדוגמה, דוגמיות וידאו)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "מחק לאחר הורדה" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "בטל ערפול של שמות קובץ סופיים" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" "אם שמות קבצים של קבצים (גדולים) בתיקייה הסופית נראים מעורפלים או חסרי " "משמעות, שמותיהם ישונו אל שם העבודה." #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" "בנוסף, מנסה להגדיר את סיומת הקובץ הנכונה על סמך חתימת הקובץ אם הסיומת אינה " "נוכחת או חסרת משמעות." #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "וידוא תעודת HTTPS" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "וודא תעודות בעת התחברות אל מדדנים ומקורות RSS ע״י שימוש ב־HTTPS." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "ייפוי כוח SOCKS5" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "השתמש בייפוי הכוח SOCKS5 המצוין עבור כל החיבורים היוצאים." #: sabnzbd/skintext.py msgid "Server" msgstr "שרת" #: sabnzbd/skintext.py msgid "Post processing" msgstr "בתר־עיבוד" #: sabnzbd/skintext.py msgid "Naming" msgstr "מתן שמות" #: sabnzbd/skintext.py msgid "Quota" msgstr "מכסה" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "כמה ניתן להוריד החודש (ק״ב/מ״ב/ג״ב)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "יום איפוס" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "באיזה יום של החודש או השבוע (1=יום שני) ספק האינטרנט שלך מאפס את המכסה? (לא " "חובה עם שש:דד)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "האם ההורדה תמשיך לאחר שהמכסה תתאפס?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "תקופת מכסה" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "האם המכסה מתאפסת כל יום, שבוע או חודש?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "בדוק לפני הורדה" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "נסה לחזות השלמה מוצלחת לפני הורדה ממשית (איטי יותר!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "צפני SSL" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "הגבר ביצועים ע״י אילוץ חוזק הצפנת SSL חלש יותר." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "ניסיונות חוזרים מרביים" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "מספר מרבי של ניסיונות חוזרים לשרת" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "בטל עבודות שאינן יכולות להיות שלמות" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "כאשר במהלך הורדה מתבהר שיותר מדי נתונים חסרים, בטל את העבודה" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "הוסף שרת" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "תיאור שרת" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "פתחה" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "שם משתמש" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "סיסמה" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "פסק זמן" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "תאריך תפוגת חשבון" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "הזהר 5 ימים טרם תאריך תפוגת החשבון." #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" "מכסה עבור חשבון זה, נספרת מהזמן שהיא הוגדרה. בבתים, יכולה לבוא עם K,M,G.
הזהר כאשר המכסה מגיעה אל 0, היא נבדקת כל כמה דקות." #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "זמן שימור" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "חיבור מאובטח לשרת" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "וידוא תעודה" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" "מזערי: כאשר SSL מאופשר, וודא את זהות השרת ע״י שימוש בתעודותיו. קפדני: וודא " "ואכוף שם מארח תואם." #: sabnzbd/skintext.py msgid "Disabled" msgstr "מושבת" #: sabnzbd/skintext.py msgid "Minimal" msgstr "מזערי" #: sabnzbd/skintext.py msgid "Strict" msgstr "קפדני" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 הוא העדיפות הגבוהה ביותר, 100 הוא העדיפות הנמוכה ביותר" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "דרוש" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" "במקרה של כישלונות חיבור, תור ההורדות יושהה למשך כמה דקות במקום דילוג על השרת" " הזה" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "רשותי" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "עבור שרתים בלתי מהימנים, ייתקל בהתעלמות במקרה של כישלונות" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "אפשר" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "הסר שרת" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "בחן שרת" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "נקה מונים" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "בוחן פרטי שרת…" #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "רוחב פס" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "הערות אישיות" #: sabnzbd/skintext.py msgid "Article availability" msgstr "זמינות מאמר" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "%f% זמינים מתוך %d מאמרים מבוקשים" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "הוסף תזמון" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "תדירות" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "פעולה" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "טיעונים" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "תזמונים נוכחיים" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "תיבת הסימון ליד שם ההזנה צריכה להיות מסומנת כדי שההזנה תהיה מאופשרת ותסומן " "באופן אוטומטי עבור פריטים חדשים.
כאשר הזנה מתווספת, היא תאסוף רק פריטים" " חדשים ולא שום דבר שנמצא כבר בהזנת ה־RSS אלא אם תלחץ \"אלץ הורדה\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "הפרד כתובות רבות ע״י פסיק" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "קרא הזנה" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "אלץ הורדה" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "החל מסננים" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "ערוך" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "הסריקה הבאה במועד" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "סידור" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "סוג" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "מסנן" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "קבל" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "סרב" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "דורש" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "RequiresCat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "לפחות" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "לכל היותר" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "מן SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "מסדרה SxxEyy" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "תואם" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "בלתי תואם" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "הוּרד" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "קרא את כל ההזנות כעת" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" "אם רק קטגורית ברירת המחדל נבחרת, התראות מאופשרות עבור עבודות בכל " "הקטגוריות." #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "התראת דוא״ל בעת השלמת עבודה" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "אף פעם" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "תמיד" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "שגיאה בלבד" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "התראות דיסק מלא" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "שלח דוא״ל כשהדיסק מלא ו־SABnzbd מושהה." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "התראות שליחת RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "שלח דוא״ל כאשר הזנת RSS מוסיפה עבודות לתור." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "שרת SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "קבע את השרת של ספק האינטרנט שלך עבור דוא״ל יוצא." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "מקבל דוא״ל" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "כתובת דוא״ל לשלוח אליה את הדוא״ל." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "שולח דוא״ל" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "מי עלינו לומר ששלח את הדוא״ל?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "שם משתמש רשותי של חשבון" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "עבור דוא״ל מאומת, שם חשבון." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "סיסמת חשבון רשותית" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "עבור דוא״ל מאומת, סיסמה." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "התראה נשלחה!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "אפשר את NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "מרכז ההתראות" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "אפשר התראות Windows" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "התראות Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "אפשר התראות Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "דורש חשבון Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "מפתח API עבור Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "מפתח API אישי עבור Prowl (דרוש)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "אפשר התראות Pushover" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "דורש חשבון Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "אסימון יישום" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "אסימון יישום (דרוש)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "מפתח משתמש" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "מפתח משתמש (דרוש)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "מכשיר(ים)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "מכשירים אליהם הודעה תישלח" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "ניסיון חוזר חרום" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "באיזו תדירות (בשניות) אותה ההתראה תישלח" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "תפוגת חרום" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "כמה שניות ההתראה שלך תמשיך להיות מנוסה שוב" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "אפשר התראות Pushbullet" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "דורש חשבון Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "מפתח API אישי" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "מפתח Pushbullet API האישי שלך (דרוש)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "התקן" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "מכשיר אליו הודעה תישלח" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "אפשר התראות Apprise" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "שלח התראות ע״י שימוש בשירות Apprise אל כמעט כל שירות התראות" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "כתובות Apprise ברירות מחדל" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "השתמש בפסיק, ברווח או בשניהם כדי לזהות יותר מכתובת אחת." #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" "דרוס את כתובות ברירות המחדל עבור סוגי התראה מסויימים שמצויינים למטה, אם תרצה" " בכך." #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "תסריט התראות" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "אפשר תסריט התראות" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "מבצע תסריט מותאם אישית" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "איזה תסריט עלינו לבצע עבור התראות?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "מדדנים יכולים לספק קטגוריה בתוך NZB אשר SABnzbd ינסה להתאים לקטגוריות " "המוגדרות למטה. בנוסף, אתה יכול להוסיף תנאים אל \"קטגוריות/קבוצות של מדדן\" " "כדי להתאים עוד קטגוריות. השתמש בפסיקים כדי להפריד תנאים. תווים כללים נתמכים " "בתנאים.
עוד מידע יכול להימצא בוויקי." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "סיום הנתיב עם כוכבית * תמנע יצירת תיקיות עבודה." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "תיקיות קרובות משפחה מבוססות על" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "תיקייה/נתיב" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "קטגוריות / קבוצות של מדדן" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "מפתח דפוס" #: sabnzbd/skintext.py msgid "Clear" msgstr "נקה" #: sabnzbd/skintext.py msgid "Presets" msgstr "קדם־קביעות" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "קטגוריות מושפעות" #: sabnzbd/skintext.py msgid "Meaning" msgstr "משמעות" #: sabnzbd/skintext.py msgid "Pattern" msgstr "דפוס" #: sabnzbd/skintext.py msgid "Result" msgstr "תוצאה" #: sabnzbd/skintext.py msgid "Title" msgstr "כותר" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "שם סרט" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "שם.סרט" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "שם_סרט" #: sabnzbd/skintext.py msgid "Show Name" msgstr "שם סדרה" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "שם.סדרה" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "שם_סדרה" #: sabnzbd/skintext.py msgid "Season Number" msgstr "מספר עונה" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "מספר פרק" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "שם פרק" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "שם.פרק" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "שם_פרק" #: sabnzbd/skintext.py msgid "Extension" msgstr "סיומת" #: sabnzbd/skintext.py msgid "Part Number" msgstr "מספר חלקי" #: sabnzbd/skintext.py msgid "Decade" msgstr "עשור" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "שם מקורי של קובץ" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "שם עבודה מקורי" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "רישיות קטנה" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py msgid "text" msgstr "text" #: sabnzbd/skintext.py msgid "file" msgstr "קובץ" #: sabnzbd/skintext.py msgid "Sort String" msgstr "מחרוזת מיון" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "תווית מרובת־חלקים" #: sabnzbd/skintext.py msgid "Show folder" msgstr "תיקיית סדרה" #: sabnzbd/skintext.py msgid "Season folder" msgstr "תיקיית עונה" #: sabnzbd/skintext.py msgid "In folders" msgstr "בתיקיות" #: sabnzbd/skintext.py msgid "No folders" msgstr "אין תיקיות" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "שם עבודה בתור שם קובץ" #: sabnzbd/skintext.py msgid "Series" msgstr "סדרות" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "מותאם־רישיות" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "תוצאה מעובדת" #: sabnzbd/skintext.py msgid "Any property" msgstr "קניין כלשהו" #: sabnzbd/skintext.py msgid "property" msgstr "קניין" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "קניין GuessIt" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "GuessIt.Property" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "GuessIt_Property" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "גודל מזערי של קובץ" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "סוגי עבודה מושפעים" #: sabnzbd/skintext.py msgid "All" msgstr "הכול" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "סדרות עם תאריכי שידור" #: sabnzbd/skintext.py msgid "Movies" msgstr "סרטים" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "אחר / בלתי ידוע" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" "

השתמש בממיינים כדי לארגן באופן אוטומטי את ההורדות השלמות שלך. לדוגמה, שים" " את כל הפרקים מסדרה בתיקייה של עונה מסויימת.

ממיינים מנוסים לפי סדר " "הופעתם ויכולים להסתדר מחדש על ידי גרירה ושחרור.
הממיין הפעיל הראשון " "שתואם אל הקטגוריה המושפעת ואל סוג העבודה הוא זה שמוחל.

עוד אפשרויות " "זמינות כאשר האפשרות הגדרות מתקדמות מסומנת.
מידע מפורט נמצא בוויקי.

" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "הוסף ממיין" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "הסר ממיין" #: sabnzbd/skintext.py msgid "Test Data" msgstr "בחן נתונים" #: sabnzbd/skintext.py msgid "Quick start" msgstr "התחלה זריזה" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "העבר ושנה שם את כל הפרקים בקטגוריה \"טלוויזיה\" אל תיקייה של סדרה מסויימת" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "העבר ושנה שם את כל הסרטים בקטגוריה \"סרטים\" אל תיקייה של סרט מסויים" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "אפשרויות אשר בשימוש לעיתים רחוקות. עבור משמעותן והסברן, לחץ על כפתור העזרה " "ולך אל דף הוויקי.
אל תשנה אותן ללא בדיקת הוויקי תחילה, מאחר שלכמה מהן יש " "תופעות לוואי רציניות.
ערכי ברירת המחדל הם בין הסוגריים." #: sabnzbd/skintext.py msgid "Values" msgstr "ערכים" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "ערוך פרטי NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "מחק" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "שם קובץ" #: sabnzbd/skintext.py msgid "Free Space" msgstr "שטח פנוי" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "תיקייה זמנית" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "רב־תפעולים" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "החזק את מקש Shift כדי לבחור טווח" #: sabnzbd/skintext.py msgid "Check all" msgstr "סמן הכל" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "הפעל מחדש את SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "בסיום תור" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "אפשרויות של מעמד וממשק" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "או גרור ושחרר קבצים בחלון!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "חיבור אל SABnzbd אבד…" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "במקרה של הפעלה מחדש של SABnzbd המסך ייעלם באופן אוטומטי!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "אזהרה:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "משוך" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "ממשק רשת" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "קצב רענון" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "השתמש בהגדרות ממשק עולמיות" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "מגבלת פריטי תור" #: sabnzbd/skintext.py msgid "History item limit" msgstr "מגבלת פריטי היסטוריה" #: sabnzbd/skintext.py msgid "Date format" msgstr "תסדיר תאריך" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "יותר עמודות תור" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "יותר עמודות היסטוריה" #: sabnzbd/skintext.py msgid "page" msgstr "דף" #: sabnzbd/skintext.py msgid "Loading" msgstr "טוען" #: sabnzbd/skintext.py msgid "articles" msgstr "מאמרים" #: sabnzbd/skintext.py msgid "Rename" msgstr "שנה שם" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "תקן תור" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "הראה חיבורים פעילים" #: sabnzbd/skintext.py msgid "Unblock" msgstr "בטל חסימה" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "עבודות יתומות" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "שלח חזרה לתור" #: sabnzbd/skintext.py msgid "Delete All" msgstr "מחק הכל" #: sabnzbd/skintext.py msgid "Retry all" msgstr "נסה שוב הכל" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "משוך NZB מכתובת" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "העלה NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "ציין באופן רשותי שם קובץ" #: sabnzbd/skintext.py msgid "Submit" msgstr "הגש" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "הסר את כל הקבצים הנבחרים" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "הסתר/הראה קבצים שלמים" #: sabnzbd/skintext.py msgid "Top" msgstr "ראש" #: sabnzbd/skintext.py msgid "Bottom" msgstr "תחתית" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" "כשאתה מנסה שוב עבודה, העבודות 'גילוי שכפולים' ו'בטל עבודות שאינן יכולות " "להיות שלמות' מושבתות." #: sabnzbd/skintext.py msgid "View Script Log" msgstr "הצג יומן תסריטים" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "שינוי השם של העבודה יבטל פריקה ישירה." #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "אחסון מקומי (עוגיות) מושבת בדפדפן שלך, הגדרות ממשק יאבדו לאחר שתסגור את " "הדפדפן!" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "אל Glitter יש מספר מאפיינים (חדשים) שאתה עשוי לאהוב!" #: sabnzbd/skintext.py msgid "Custom" msgstr "מותאם אישית" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "פריסה צפופה" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "השתמש תמיד ברוחב של מסך מלא" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "פריסה בלשוניות
(תור והיסטוריה נפרדים)" #: sabnzbd/skintext.py msgid "Speed" msgstr "מהירות" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "אשר מחיקות תור" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "אשר מחיקות היסטוריה" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "קיצורי דרך במקלדת" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "Shift+מקש חץ: עיין בתור ובדפי היסטוריה" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "כמה זמן או עד מתי תרצה להשהות? (באנגלית!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "סליחה, לא יכולנו לפרש את זה. נסה שוב." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "השהה למשך…" #: sabnzbd/skintext.py msgid "Refresh" msgstr "רענן" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" "כל שמות המשתמש, הסיסמאות ומפתחות API מוסרים באופן אוטומטי מהיומן ומהעותק " "הכלול של ההגדרות שלך." #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "מיין לפי % ירד הכי הרבה→הכי מעט" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "מיין לפי גיל החדש ביותר←הישן ביותר" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "מיין לפי גיל הישן ביותר←החדש ביותר" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "מיין לפי שם א←ת" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "מיין לפי שם ת←א" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "מיין לפי גודל הקטן ביותר←הגדול ביותר" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "מיין לפי גודל הגדול ביותר←הקטן ביותר" #: sabnzbd/skintext.py msgid "Uploading" msgstr "מעלה" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "מאלץ ניתוק" #: sabnzbd/skintext.py msgid "Removing job" msgstr "מסיר עבודה" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "מסיר עבודות" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "אשף התחלה זריזה של SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "גרסת SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "הקודם" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "הבא" #: sabnzbd/skintext.py msgid "Server Details" msgstr "פרטי שרת" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "אנא הכנס את הפרטים של ספק Usenet העיקרי שלך." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "מספר החיבורים המותרים ע״י הספק שלך" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "לדוגמה 8 או 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "בחר רק אם הספק שלך מתיר חיבורי SSL." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "לחץ כדי לבחון את הפרטים שהוכנסו." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "לדוגמה" #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "ההתקנה שלמה כעת!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd ירוץ כעת ברקע." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "סגירה של חלונות/לשוניות כלשהם/כלשהן לא תסגור את SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "מומלץ ללחוץ לחיצה ימנית וליצור סימנייה למיקום זה ולהשתמש בסימנייה זו כדי " "להשיג גישה אל SABnzbd כאשר הוא רץ ברקע." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "עזרה נוספת יכולה להימצא ב" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "לך אל SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "צא מן SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "התחל אשף" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "שחזר גיבוי" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd מגיע ללא אחריות מוחלטת.\n" "זו תוכנה חינמית, ואתה מוזמן להפיצה מחדש תחת תנאים מסוימים.\n" "היא ברישיון תחת רישיון ציבורי כללי GNU גרסה 2 או (לבחירתך) כל גרסה שהיא מאוחרת יותר.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "כישלון בשינוי שם %s אל %s" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "כישלון בשינוי שם של קובץ דומה: %s אל %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "גישה בלתי מורשת" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "קובץ לא על השרת" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "השרת לא היה יכול להשלים בקשה" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "תופס כתובות קרס" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "קובץ NZB בלתי שמיש" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "משיכת כתובת נכשלה; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "מנסה למשוך קובץ NZB מן %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2145672 SABnzbd-4.3.2/po/main/pl.po0000644000000000000000000034077614625637207014561 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Ostrzeżenie" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Błąd" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Nie udało się uruchomić interfejsu WWW" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Nie znaleziono szablonu: %s, próbuję użyć standardowego szablonu" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "Program par2 ... NIE znaleziono!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "Twoja wersja unrar to %s, zalecana jest wersja %s lub wyższa.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "Program unrar ... NIE znaleziono!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "Program 7za... NIE znaleziono!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "Nazwa hosta 0.0.0.0 wymaga adresu IPv6 do dostępu z zewnątrz" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "Porty dla HTTP i HTTPS nie mogą być takie same" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Wyłączono HTTPS z powodu braku plików CERT oraz KEY" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Nie udało się uruchomić interfejsu WWW: " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "Uruchomiono SABnzbd %s" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd został wyłączony" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Odebrano sygnał %s, zapisywanie i zamykanie programu..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Błąd krytyczny podczas zapisywania stanu" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Wiadomość wysłana" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Powiadomienie testowe" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Nie ustawiono nazwy hosta." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "" "Nie ustawiono maksymalnej liczby połączeń. Proszę umożliwić przynajmniej " "jedno połączenie." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Hasło ukryte za ******, proszę wprowadzić je ponownie" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Niewłaściwe dane serwera" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Nieprawidłowy adres serwera \"%s:%s\"." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Upłynął limit czasu odpowiedzi: spróbuj włączyć SSL lub połącz się z innym " "portem." #: sabnzbd/api.py msgid "Timed out" msgstr "Upłynął limit czasu odpowiedzi." #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Serwer wymaga podania nazwy użytkownika i hasła." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Połączenie udane!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Błąd połączenia, sprawdź nazwę użytkownika i hasło." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Zbyt wiele połączeń, proszę wstrzymać pobieranie lub spróbować ponownie " "później" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Nie można określić wyniku połączenia (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Rozwiązywanie adresu" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Brak" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Domyślne" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Dysk pełny! Wstrzymuję pobieranie" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Błąd dysku podczas tworzenia pliku %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Błąd krytyczny w module składającym" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Zbyt mało miejsca na dysku, wymuszanie WSTRZYMANIA" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Przerwano, wykryto szyfrowanie" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Niepożądane rozszerzenie w pliku RAR %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Przerwano, wykryto niepożądane rozszerzenie" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Przekroczono limit, wstrzymywanie pobierania" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Błędny parametr" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s nie jest prawidłowym adresem email" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Wymagane jest podanie adresu serwera" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Nieprawidłowy adres serwera." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s nie jest prawidłową wartością w systemie ósemkowym" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Kolejka nie jest pusta, nie można zmienić katalogu." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Nie można zapisać pliku INI %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Nie można utworzyć kopii zapasowej %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Nieprawidłowo zakodowane hasło %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "Nie można zapisać bazy danych historii, sprawdź prawa dostępu!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Uszkodzona baza danych historii, utworzono w jej miejscu nową, pustą" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Błąd polecenia SQL, sprawdź logi" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Błąd zamykania bazy danych, sprawdź logi" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Nieprawidłowy log etapu w historii dla %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Nieznany błąd podczas dekodowania %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Ukończone" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Rozpakowano %s plików/katalogów w %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Nie można odczytać obserwowanego katalogu %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Wznawianie" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Wstrzymano" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Przed ustawieniem limitu przepustowości należy ustawić maksymalną " "przepustowość" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Nie można połączyć się z serwerem %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Nie udało się rozwiązać nazwy serwera" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Serwer %s będzie ignorowany przez %s minut" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Błąd podczas inicjalizacji %s@%s: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Zbyt wiele połączeń do serwera %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Błąd logowania do serwera %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Błąd połączenia %s@%s, komunikat=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Nieobsługiwany błąd w module pobierania" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Wyłączanie" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Błąd połączenia z serwerem pocztowym" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Błąd połączenia TLS" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Serwer nie odpowiedział poprawnie na polecenie HELO" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Błąd uwierzytelnienia na serwerze pocztowym" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Nie znaleziono odpowiedniej metody uwierzytelnienia" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "" "Uwierzytelnienie na serwerze pocztowym nie powiodło się z nieznanej " "przyczyny" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Błąd wysyłania wiadomości email" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Nie udało się zamknąć połączenia z serwerem pocztowym" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Nie można wysłać wiadomości, brak wymaganych danych" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Brak szablonów wiadomości email w %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Nie podano adresatów, wiadomość nie została wysłana" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Nie można odczytać %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Nie znaleziono szablonów wiadomości email" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd zgłasza przekroczenie dopuszczalnej zajętości dysku\n" "\n" "Cześć,\n" "\n" "SABnzbd przestał pobierać pliki, ponieważ dysk jest prawie pełen.\n" "Opróżnij trochę miejsca i wznów działanie SABnzbd ręcznie.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Nie można utworzyć katalogu %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "Katalog %s: błąd dostępu do %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Nie można zmienić uprawnień %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Nie udało się utworzyć (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Nie udało się przenieść %s do %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Błąd w tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Nie udało się zapisać %s" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Nie udało się wczytać %s" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Brak klucza API, należy wprowadzić klucz API z sekcji Konfiguracja->Ogólne " "do zewnętrznego programu:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Klucz API jest nieprawidłowy, użyj klucza API z sekcji Konfiguracja->Ogólne " "w zewnętrznym programie:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Kanał" #: sabnzbd/interface.py msgid "Daily" msgstr "Codziennie" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Poniedziałek" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Wtorek" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Środa" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Czwartek" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Piątek" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Sobota" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Niedziela" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "wyłączone" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Niezdefiniowany serwer!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "BŁĄD:" #: sabnzbd/interface.py msgid "Back" msgstr "Powrót" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "d" #: sabnzbd/misc.py msgid "h" msgstr "g" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Dostępna aktualizacja!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Błąd tworzenia klucza i certyfikatu SSL" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Sortowanie seriali" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Sortowanie według daty" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Uruchamianie skryptu" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Zbyt głęboki poziom zagnieżdżenia podczas rozpakowywania [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Łączenie" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Niekompletna sekwencja plików do połączenia" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Łączenie pliku %s nie powiodło się" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Błąd \"%s\" podczas łączenia plików" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Błąd \"%s\" podczas uruchamiania file_join na %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Połączono %s plików" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Rozpakowywanie nie powiodło się, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Błąd \"%s\" podczas rozpakowywania plików RAR" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Błąd \"%s\" podczas uruchamiania rar_unpack na %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Usuwanie %s nie powiodło się!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Próba rozpakowania archiwum RAR z użyciem hasła \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Rozpakowywanie" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Rozpakowywanie nie powiodło się, nie można znaleźć %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Rozpakowywanie nie powiodło się, błąd CRC" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Rozpakowywanie nie powiodło się, błąd zapisu lub zapełniony dysk?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Rozpakowywanie nie powiodło się, zbyt długa ścieżka" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Rozpakowywanie nie powiodło się, archiwum wymaga podania hasła" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Bezużyteczny plik RAR" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Próba rozpakowania archiwum 7zip z użyciem hasła \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "sprawdź logi" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Szybkie sprawdzanie" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Naprawa" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Szybkie sprawdzenie OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Rozpoczynanie naprawy" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Naprawa nie powiodła się, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Błąd %s podczas uruchamiania par2_repair na zestawie %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Błąd \"%s\" podczas wykonywania par2_repair na zestawie %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 otrzymał nieprawidłowe opcje, sprawdź ustawienia w sekcji " "Konfiguracja->Przełączniki" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Zweryfikowano w %s, wszystkie pliki prawidłowe" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Zweryfikowano w %s, wymagana naprawa" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Pobieranie %s bloków..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Pobieranie" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Naprawa nie powiodła się, brak wystarczającej ilości bloków naprawczych " "(brakuje %s)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Naprawianie" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Naprawiono w %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Dysk pełny" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Weryfikowanie" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Sprawdzanie" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Próba weryfikacji SFV" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "pozostało" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Serwer nie obsługuje SSL na tym porcie" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Uruchomienie/Wyłączenie" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Wstrzymaj" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Wznów" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "Dodano NZB" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Uruchomiono przetwarzanie końcowe" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Zadanie ukończone" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Zadanie nie powiodło się" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Kolejka ukończona" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Inne komunikaty" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Otwórz katalog zakończonych" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Niedostępne" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Błąd wysyłania wiadomości Prowl" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Zła odpowiedź od Pushover (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Nie udało się wysłać wiadomości Pushover" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Zła odpowiedź od Pushbullet (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Nie udało się wysłać wiadomości Pushbullet" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Nie można utworzyć tymczasowego pliku dla %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Błąd podczas dodawania %s, usuwanie" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Błąd podczas usuwania %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Nie udało się zaimportować %s plików z %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Znaleziono niekompatybilny plik kolejki, nie można kontynuować" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Błąd ładowania %s, wykryto uszkodzony plik" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB dodany do kolejki" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignoruję zduplikowany NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Pusty plik NZB %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Przerwano, nie można ukończyć" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Błąd importu %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "DUPLIKAT" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "ZASZYFROWANY" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "ZA DUŻY" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "NIEKOMPLETNY" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "NIEPOŻĄDANY" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "CZEKAM %s s" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Pobrano w %s ze średnią %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Wiek" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artykułów było uszkodzonych" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "Brakowało %s artykułów" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artykułów posiadało niepasujące duplikaty" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Wstrzymuję zduplikowany NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Ostrzeżenia" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Bezczynny" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Kolejka" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Czyszczenie kolejki" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historia" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Wyczyść historię" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Ogranicz prędkość" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "minuta" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Przeszukaj obserwowany katalog" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Czytaj wszystkie kanały RSS" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Katalog zakończonych" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Katalog niezakończonych" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Rozwiązywanie problemów" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Uruchom ponownie" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Restart bez logowania" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Zakończ" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Zakolejkuj 10 pierwszych" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Brak" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "10 ostatnich" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Uruchom kreatora konfiguracji" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Zatrzymywanie..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Problem z" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd wymaga wolnego portu TCP/IP dla wewnętrznego serwera WWW.
\n" " Próbowano użyć portu %s na %s, ale nie jest on dostępny.
\n" " Inny program używa tego portu lub SABnzbd jest już uruchomiony.
\n" "
\n" " Uruchom ponownie SABnzbd używając innego numeru portu." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Jeśli ponownie otrzymasz ten sam błąd, spróbuj zmienić numer portu.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd wymaga prawidłowego adresu hosta dla wewnętrznego serwera WWW.
\n" " Podano nieprawidłowy adres.
\n" " Bezpieczne wartości to localhost i 0.0.0.0
\n" "
\n" " Uruchom ponownie SABnzbd używając prawidłowego adresu hosta." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd wykrył dane zapisane w innej wersji SABnzbd
\n" " lecz nie może ponownie użyć tych danych.

\n" " Zaleca się zakończenie pobierania kolejki w innym programie.

\n" " Następnie należy uruchomić SABnzbd z opcją \"--clean\".
\n" " Spowoduje to wymazanie aktualnej kolejki i historii!
\n" " SABnzbd czyta plik \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd nie może znaleźć plików interfejsu WWW w %s.
\n" " Proszę ponownie zainstalować SABnzbd.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd wykrył krytyczny błąd:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd wykrył brak pliku sqlite3.dll.

\n" " Niektóre źle działające programy antywirusowe usuwają ten plik.
\n" " Sprawdź swój program antywirusowy, spróbuj ponownie zainstalować SABnzbd i zgłoś problem dostawcy programu antywirusowego.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Naciśnij Klawisz start+R i podaj linię (przykład):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Otwórz okno terminala i podaj linię (przykład):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Program się nie uruchomił!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Błąd krytyczny" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "" "Nie można uruchomić przeglądarki, prawdopodobnie nie została znaleziona" #: sabnzbd/panic.py msgid "Access denied" msgstr "Brak dostępu" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Błąd %s: należy podać prawidłową nazwę użytkownika i hasło." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" "Wykryto kolejkę w starszej wersji, użyj funkcji Status->Naprawa, aby ją " "przekonwertować" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Błąd kompilacji wyrażenia regularnego dla wyszukiwania: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Pobieranie może się nie udać, dostępne jedynie %s z wymaganych %s" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Pobieranie nieudane - Dane niedostępne na skonfigurowanych serwerach" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Przetwarzanie końcowe" #: sabnzbd/postproc.py msgid "Moving" msgstr "Przenoszenie" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Wysłano %s do kolejki" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Błąd zmiany nazwy \"%s\" na \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Nie udało się przenieść plików" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Uruchamianie skryptu użytkownika %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Kod zakończenia skryptu: %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Uruchomiono %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Więcej" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Przetwarzanie końcowe nie powiodło się dla %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Pobieranie nie powiodło się" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Czyszczenie %s nie powiodło się." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Zakończono pobieranie" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Nie można utworzyć ostatecznego katalogu %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s} Brak zestawów par2" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Weryfikacja niektórych plików względem \"%s\" nie powiodła się" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Poprawnie zweryfikowano z użyciem plików SFV" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Zabezpieczone hasłem" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Usuwanie %s nie powiodło się" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Hibernacja systemu nie powiodła się" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Wstrzymanie systemu nie powiodło się" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Wyłączenie systemu nie powiodło się" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Nieprawidłowy opis kanału RSS \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Brak poprawnego uwierzytelnienia dla kanału %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Błąd po stronie serwera (kod: %s); nie udało się pobrać %s z %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Nie udało się pobrać RSS z %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Serwer %s używa niezaufanego certyfikatu HTTPS" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "Kanał RSS %s był pusty" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Niekompatybilny kanał" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Znaleziono pusty wpis RSS (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Pokaż interfejs" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Wstrzymaj na" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Wstrzymaj na 5 minut" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Wstrzymaj na 15 minut" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Wstrzymaj na 30 minut" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Wstrzymaj na 1 godzinę" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Wstrzymaj na 2 godziny" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Wstrzymaj na 6 godzin" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Zakończ" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Pozostało" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Dodaj NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Zły harmonogram %s o %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Nieznane działanie: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Harmonogram dla nieistniejącego serwera %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Próba ustawienia statusu nieistniejącego serwera %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Pobierz" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Połącz pliki" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Rozpakuj" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Skrypt" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Źródło" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Serwery" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Nieudane" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Oczekuje" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Naprawianie..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Rozpakowywanie..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Przenoszenie..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Wykonywanie skryptu..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Pobieranie dodatkowych bloków..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Szybkie sprawdzanie..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Weryfikowanie..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "wyłącz serwer" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "włącz serwer" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Ogranicz prędkość" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Wstrzymaj wszystkie" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Wstrzymaj przetwarzanie końcowe" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Wznów przetwarzanie końcowe" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Czytaj kanały RSS" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Usuń nieudane zadania" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Usuń ukończone zadania" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Wstrzymaj zadania o niskim priorytecie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Wstrzymaj zadania o normalnym priorytecie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Wstrzymaj zadania o wysokim priorytecie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Wznów zadania o niskim priorytecie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Wznów zadania o normalnym priorytecie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Wznów zadania o wysokim priorytecie" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Włącz zarządzanie limitem" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Wyłącz zarządzanie limitem" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Brak" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Bardzo niski" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Średni" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normalny" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Wysoki" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Awaryjny" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Niski" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "godzina" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "godziny" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minut" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sekunda" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "sekund" #: sabnzbd/skintext.py msgid "day" msgstr "dzień" #: sabnzbd/skintext.py msgid "days" msgstr "dni" #: sabnzbd/skintext.py msgid "week" msgstr "tydzień" #: sabnzbd/skintext.py msgid "Month" msgstr "Miesiąc" #: sabnzbd/skintext.py msgid "Year" msgstr "Rok" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Dzień miesiąca" #: sabnzbd/skintext.py msgid "This week" msgstr "Ten tydzień" #: sabnzbd/skintext.py msgid "This month" msgstr "Ten miesiąc" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Dzisiaj" #: sabnzbd/skintext.py msgid "Total" msgstr "Razem" #: sabnzbd/skintext.py msgid "on" msgstr "włączone" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametry" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Wersja Pythona" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Strona projektu" #: sabnzbd/skintext.py msgid "or" msgstr "lub" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Host" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Anuluj" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Zapisz" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Zapisywanie..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Czy jesteś pewien?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Start" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Konfiguracja" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Status" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Pomoc" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Forum" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Wspomóż projekt!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Ogólne" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Katalogi" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Przełączniki" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Harmonogram" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Powiadomienia" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Email" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategorie" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Sortowanie" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Specjalne" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Szukaj" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Czy na pewno wyłączyć SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Dodaj" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategoria" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Priorytet" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Napraw" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Rozpakuj" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Usuń" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Wymuś" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Stop" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Wprowadź URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Wyłącz komputer" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Uśpij komputer" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Hibernuj komputer" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Wyłącz SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Przetwarzanie" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Nazwa" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Ponów" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Skrypty" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Usunąć wszystkie obiekty z kolejki?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Wyczyść NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Wyczyść NZB i usuń pliki" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Usuń NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Usuń NZB i pliki" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Brakujące artykuły" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Pozostało limitu" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "ręcznie" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Resetuj limit" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Ukryj szczegóły" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Pokaż szczegóły" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Pokaż nieudane" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Pokaż wszystko" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Rozmiar" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Wyczyść nieudane NZB" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Wyczyść nieudane NZB i usuń pliki" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Wyczyść ukończone NZB" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Opcjonalne dodatkowe NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Ścieżka" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Ponów wszystkie nieudane zadania" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Wymuś rozłączenie" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Nastąpi wysłanie testowej wiadomości na twoje konto." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Pokaż logi" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Przetestuj email" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Logowanie" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Błędy/Ostrzeżenia" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Informacje" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Debugowanie" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Połączenia" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Identyfikator artykułu" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Zestaw plików" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Włączony" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Połączenie nie powiodło się!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Lokalny adres IPv4" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Publiczny adres IPv4" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "Adres IPv6" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Serwer DNS" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Wydajność systemu (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Szybkość zapisu w katalogu pobierania" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Szybkość zapisu w katalogu zakończonych" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Powtórz test" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Plik konfiguracyjny" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Użyta pamięć podręczna" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "SABnzbd zostanie zrestartowane.
Użyj tej funkcji jeśli uważasz, że " "program ma problemy ze stabilnością.
Pobieranie zostanie wstrzymane " "przed restartem i wznowione po ponownym uruchomieniu." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "W katalogu pobierania istnieją porzucone zadania.
Możesz je usunąć " "(razem z plikami) lub wysłać z powrotem do kolejki." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "Przycisk \"Napraw\" ponownie uruchomi SABnzbd i spowoduje kompletne
odtworzenie zawartości kolejki, z zachowaniem już pobranych plików.
Kolejność elementów kolejki zostanie zmieniona." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Nie zachowano zmian, zostaną one utracone." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "Włącz 7zip" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Wersja" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Czas działania" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Zapasowy" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Przeczytaj o tym w Wiki!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Restartowanie SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Zmiany wymagają restartu SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Serwer WWW SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Adres hosta SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Host, na którym ma nasłuchiwać SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Port, na którym ma nasłuchiwać SABnzbd" #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Użytkownik SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Opcjonalna nazwa użytkownika" #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Hasło SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Opcjonalne hasło" #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Włącz HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Włącz dostęp do interfejsu przez HTTPS" #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "" "Jeśli pole będzie puste, standardowy port będzie obsługiwał tylko HTTPS" #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "Certyfikat HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Nazwa pliku lub ścieżka do certyfikatu HTTPS" #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "Klucz HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Nazwa pliku lub ścieżka do klucza HTTPS" #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "Łańcuch certyfikatów HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Nazwa pliku lub ścieżka do łańcucha certyfikatów HTTPS" #: sabnzbd/skintext.py msgid "Tuning" msgstr "Strojenie" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Interwał sprawdzania RSS" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Interwał sprawdzania (w minutach, co najmniej 15). Nieużywany podczas " "korzystania z harmonogramu!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Maksymalna przepustowość łącza" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Procent przepustowości łącza" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Jaki procent dostępnej przepustowości ma wykorzystywać SABnzbd, np. 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Limit pamięci podręcznej artykułów" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Umieszcza artykuły w pamięci podręcznej, aby ograniczyć częstotliwość " "dostępu do dysku.
W bajtach, opcjonalnie z przyrostkiem K, M, G. " "Przykład: \"64M\" lub \"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Lista czyszczenia" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Lista rozszerzeń plików, które mają zostać usunięte po pobraniu.
Na " "przykład: nfo lub nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Zapisz zmiany" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Resetuj" #: sabnzbd/skintext.py msgid "Language" msgstr "Język" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Wybierz język interfejsu WWW" #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "Klucz API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Ten klucz umożliwi innym programom dostęp do SABnzbd" #: sabnzbd/skintext.py msgid "NZB Key" msgstr "Klucz NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "Ten klucz umożliwi innym programom dodawanie plików NZB do SABnzbd" #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Utwórz nowy klucz" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "Kod QR klucza API" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Dostęp z zewnątrz" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Brak dostępu" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Dodawanie plików NZB " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (bez Konfiguracji)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Pełne API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Pełny interfejs WWW" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "UWAGA: Katalogi zostaną automatycznie utworzone po zapisaniu zmian." " Możesz użyć ścieżek absolutnych, aby wskazać lokalizację poza domyślnym " "katalogiem bazowym." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Katalogi użytkownika" #: sabnzbd/skintext.py msgid "Browse" msgstr "Przeglądaj" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Tymczasowy katalog pobierania" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Miejsce przechowywania nieprzetworzonych plików.
Można zmienić tylko" " kiedy kolejka jest pusta." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimalna ilość wolnego miejsca w tymczasowym katalogu pobierania" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Automatycznie wstrzymaj pobieranie, jeśli pozostanie mniej miejsca niż " "podano.
W bajtach, opcjonalnie z przyrostkiem K, M, G, T. Przykład: " "\"800M\" lub \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Katalog dla ukończonych plików" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Miejsce przechowywania ukończonych, przetworzonych plików.
Może " "zostać zmienione przez ustawienia kategorii." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Automatyczne wznawianie" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Uprawnienia dla ukończonych plików" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Ustawienia podane uprawnienia dla pobranych plików/katalogów.
W " "notacji ósemkowej. Przykład: \"775\" lub \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Obserwowany katalog" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Katalog monitorowany w poszukiwaniu plików .nzb." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Częstotliwość skanowania katalogu obserwowanego" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Ilość sekund pomiędzy kolejnymi skanami w poszukiwaniu plików .nzb" #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Katalog szablonów email" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "" "Katalog zawierający zdefiniowane przez użytkownika szablony powiadomień " "email" #: sabnzbd/skintext.py msgid "Password file" msgstr "Plik z hasłami" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Plik zawierający wszystkie hasła, które będą używane do rozpakowywania " "zaszyfrowanych plików RAR" #: sabnzbd/skintext.py msgid "System Folders" msgstr "Katalogi systemowe" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Katalog administracyjny" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Lokalizacja bazy danych administracyjnych i historycznych kolejki.
Można zmienić tylko kiedy kolejka jest pusta." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "Dane nie zostaną przeniesione. Wymaga restartu SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Katalog logów" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "Lokalizacja logów SABnzbd.
Wymaga restartu SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Katalog kopii zapasowych .nzb" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Miejsce przechowywania plików .nzb" #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Domyślny katalog bazowy" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Pobierz wszystkie pliki par2" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Włącz rekursywne rozpakowywanie" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Rozpakowuj archiwa (rar, zip, 7z) wewnątrz archiwów" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ignoruj foldery wewnątrz archiwów" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Wszystkie pliki zostaną rozpakowane do jednego folderu" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Pobieraj artykuły tylko dla pierwszego pliku w kolejce" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Włącz, aby zmniejszyć użycie pamięci. Wyłącz, aby zapobiec blokowaniu " "kolejki przez powolne zadania." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Przetwarzanie końcowe tylko dla zweryfikowanych zadań" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Działanie dla zaszyfrowanych plików RAR" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Jeśli wybrano \"Wstrzymaj\", będzie trzeba ustawić hasło i wznowić zadanie" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Odrzuć" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Działanie dla niepożądanych rozszerzeń" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Niepożądane rozszerzenia" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Włącz sprawdzanie przy użyciu SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Wykonuj dodatkową weryfikację na podstawie plików SFV" #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Skrypty użytkownika mogą oznaczyć zadanie jako nieudane" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Jeśli skrypt użytkownika zwróci niezerowy kod zakończenia, zadanie zostanie " "oznaczone jako nieudane" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Włącz zmianę nazw katalogów" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Używaj tymczasowych nazw podczas przetwarzania końcowego. Należy wyłączyć tę" " opcję, jeśli system nie obsługuje jej prawidłowo." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Skrypt użytkownika przed zakolejkowaniem" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Uruchamiany zanim plik NZB zostanie umieszczony w kolejce" #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Dodatkowe parametry PAR2" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Parametry nice" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Parametry IONice" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Rozłącz przy pustej kolejce" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Rozłącz serwer(y) Usenet kiedy kolejka jest pusta lub wstrzymana" #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Sprawdzaj aktualizacje" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "także wydania testowe" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Zastąp spacje w nazwach katalogów" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Zastąp spacje w nazwach katalogów podkreśleniami" #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Zastąp kropki w nazwach katalogów" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Zastąp kropki w nazwach katalogów spacjami" #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Kompatybilność z Windows" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "Dla serwerów: zapewnij zgodność nazw z Windows" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Uruchom przeglądarkę podczas uruchamiania" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Uruchom domyślną przeglądarkę podczas uruchamiania SABnzbd" #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Wstrzymaj pobieranie podczas przetwarzania końcowego" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Wstrzymuje pobieranie po rozpoczęciu przetwarzania końcowego i wznawia je po" " zakończeniu" #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Działanie dla próbek" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Działania, które zostaną podjęte dla plików próbek (np. próbek wideo)" #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Usuń po pobraniu" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Serwer" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Przetwarzanie końcowe" #: sabnzbd/skintext.py msgid "Naming" msgstr "Nazwy" #: sabnzbd/skintext.py msgid "Quota" msgstr "Limit pobierania" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Ile danych można pobrać w miesiącu (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Dzień resetu" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "W którym dniu miesiąca lub tygodnia (1=poniedziałek) twój dostawca resetuje " "limit pobierania (opcjonalnie z gg:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Czy pobieranie powinno zostać automatycznie wznowione w dniu resetu" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Okres limitu" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Czy limit jest kasowany dziennie, tygodniowo czy miesięcznie?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Sprawdź przed pobraniem" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Spróbuj przewidzieć, czy pobieranie będzie udane przed jego rozpoczęciem " "(wolne!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Maksymalna ilość prób" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Maksymalna ilość prób połączenia z serwerem" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Przerwij zadania, które nie mogą zostać ukończone" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Jeśli podczas pobierania okaże się, że brakuje zbyt dużej ilości danych, " "przerwij zadanie" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Dodaj serwer" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Opis serwera" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Port" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Nazwa użytkownika" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Hasło" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Limit czasu odpowiedzi" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Czas przechowywania" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Wyłączone" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 oznacza najwyższy priorytet, 99 - najniższy" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Opcjonalny" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Włączony" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Usuń serwer" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Testuj serwer" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Wyzeruj liczniki" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Testuję serwer..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Przepustowość" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Notatki osobiste" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Dodaj harmonogram" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Częstotliwość" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Działanie" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Argumenty" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Obecne harmonogramy" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Pole wyboru obok nazwy kanału musi być zaznaczone, aby kanał był włączony i " "automatycznie sprawdzany w poszukiwaniu nowych wpisów.
Po dodaniu " "kanału będą pobierane tylko nowe wpisy - żaden istniejący już w kanale RSS " "wpis nie zostanie pobrany, chyba że klikniesz przycisk \"Wymuś pobranie\"." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Pobierz kanał" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Wymuś pobranie" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Kolejność" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Typ" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Filtr" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Akceptuj" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Odrzuć" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Wymaga" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "WymagaKat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Przynajmniej" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Najwyżej" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Od SxxEyy" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Dopasowano" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Nie dopasowano" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Pobrane" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Czytaj teraz wszystkie kanały" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Powiadomienia email po zakończeniu zadania" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Nigdy" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Zawsze" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Tylko błędy" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Powiadomienie o pełnym dysku" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Powiadom, kiedy dysk jest pełen, a SABnzbd wstrzymany" #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Powiadomienia RSS" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Powiadom, kiedy kanał RSS dodaje zadanie do kolejki" #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "Serwer SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Ustaw serwer swojego ISP dla poczty wychodzącej" #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Adresat wiadomości email" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Adres email, na który będą wysyłane powiadomienia" #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Nadawca wiadomości email" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Kto powinien być nadawcą wiadomości email?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "OPCJONALNA nazwa konta" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Nazwa konta dla kont z uwierzytelnieniem" #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "OPCJONALNE hasło do konta" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Hasło dla kont z uwierzytelnieniem" #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Wysłano powiadomienie!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Włącz NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Centrum powiadomień" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Włącz powiadomienia Windows" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Powiadomienia Windows" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "NotifyOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Włącz powiadomienia Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Wymaga konta Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Klucz API Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Prywatny klucz API Prowl (wymagany)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Włącz powiadomienia Pushover" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Wymaga konta Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Token aplikacji" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Token aplikacji (wymagany)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Klucz użytkownika" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Klucz użytkownika (wymagany)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Urządzenie(-a)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Urządzenie(-a), do którego(-ych) mają być wysyłane powiadomienia" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Włącz powiadomienia Pushbullet" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Wymaga konta Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Prywatny klucz API" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Prywatny klucz API Pushbullet (wymagany)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Urządzenie" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Urządzenie, do którego mają być wysyłane powiadomienia" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Zakończenie ścieżki znakiem gwiazdki (*) zapobiegnie tworzeniu katalogów dla" " zadań." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Ścieżki względne w stosunku do" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Katalog/Ścieżka" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Zastępowane ciągi" #: sabnzbd/skintext.py msgid "Clear" msgstr "Wyczyść" #: sabnzbd/skintext.py msgid "Presets" msgstr "Predefiniowane" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Dotyczy kategorii" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Znaczenie" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Ciąg" #: sabnzbd/skintext.py msgid "Result" msgstr "Wynik" #: sabnzbd/skintext.py msgid "Title" msgstr "Tytuł" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Tytuł filmu" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Tytuł.Filmu" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Tytuł_Filmu" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Tytuł serialu" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Tytuł.serialu" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Tytuł_serialu" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Numer sezonu" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Numer odcinka" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Tytuł odcinka" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Tytuł.odcinka" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Tytuł_odcinka" #: sabnzbd/skintext.py msgid "Extension" msgstr "Rozszerzenie" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Numer fragmentu" #: sabnzbd/skintext.py msgid "Decade" msgstr "Dekada" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Oryginalna nazwa pliku" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Małe litery" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py msgid "text" msgstr "tekst" #: sabnzbd/skintext.py msgid "file" msgstr "plik" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Wzorzec sortowania" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "W katalogach" #: sabnzbd/skintext.py msgid "No folders" msgstr "Brak katalogów" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "z dostosowaniem wielkości liter" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Przetworzony ciąg" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Wszystko" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Rzadko używane opcje. Jeśli chcesz się dowiedzieć, co oznaczają, kliknij " "przycisk Pomoc, aby przejść do strony Wiki.
Nie zmieniaj tych opcji bez " "uprzedniego przeczytania Wiki, ponieważ niektóre mają poważne skutki " "uboczne.
Domyślne wartości zostały umieszczone w nawiasach." #: sabnzbd/skintext.py msgid "Values" msgstr "Wartości" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Edytuj szczegóły NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Usuń" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Nazwa pliku" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Wolne miejsce" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Folder tymczasowy" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Operacje na wielu" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Przytrzymaj klawisz Shift, aby zaznaczyć zakres" #: sabnzbd/skintext.py msgid "Check all" msgstr "Sprawdź wszystkie" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Uruchom ponownie SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Po ukończeniu kolejki" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Stan i opcje interfejsu" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Lub przeciągnij i upuść pliki do okna!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Utracono połączenie z SABnzbd..." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "W razie ponownego uruchomienia SABnzbd ten ekran zniknie automatycznie!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "UWAGA:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Pobierz" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Interfejs WWW" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Częstotliwość odświeżania" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Użyj globalnych ustawień interfejsu" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Limit wyświetlanych pozycji kolejki" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Limit wyświetlanych pozycji historii" #: sabnzbd/skintext.py msgid "Date format" msgstr "Format daty" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "strona" #: sabnzbd/skintext.py msgid "Loading" msgstr "Ładowanie" #: sabnzbd/skintext.py msgid "articles" msgstr "artykułów" #: sabnzbd/skintext.py msgid "Rename" msgstr "Zmień nazwę" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Naprawa kolejki" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Pokaż aktywne połączenia" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Odblokuj" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Porzucone zadania" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Wyślij z powrotem do kolejki" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Usuń wszystko" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Ponów wszystkie" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Pobierz NZB z URL" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Wczytaj NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Opcjonalnie podaj nazwę pliku" #: sabnzbd/skintext.py msgid "Submit" msgstr "Wyślij" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Usuń wszystkie zaznaczone pliki" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Pokaż/ukryj ukończone pliki" #: sabnzbd/skintext.py msgid "Top" msgstr "Na górę" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Na dół" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Zobacz log skryptu" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Własny" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Prędkość" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Potwierdzaj usuwanie z kolejki" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Potwierdzaj usuwanie z historii" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Jak długo lub do kiedy chcesz wstrzymać? (po angielsku!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Przykro mi, nie rozumiem. Spróbuj ponownie." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Wstrzymaj na..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Odśwież" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Sortuj według wieku Najstarsze→Najnowsze" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Sortuj według wieku Najnowsze→Najstarsze" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Sortuj według nazwy A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Sortuj według nazwy Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Sortuj według rozmiaru Najmniejsze→Największe" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Sortuj według rozmiaru Największe→Najmniejsze" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Szybki kreator konfiguracji SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Wersja SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Wstecz" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Dalej" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Szczegóły serwera" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Podaj szczegóły swojego głównego dostawcy Usenet" #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Ilość połączeń dopuszczanych przez twojego dostawcę" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "np. 8 lub 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Zaznacz tylko jeśli twój dostawca zezwala na połączenia SSL" #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Kliknij, aby przetestować wprowadzone dane" #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Np." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Konfiguracja ukończona!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd będzie uruchomiony w tle." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Zamknięcie okna przeglądarki lub karty NIE zamknie SABnzbd." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Zalecamy dodanie tej strony do zakładek i używanie tej zakładki do " "późniejszego dostępu do SABnzbd uruchomionego w tle." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Dalszą pomoc można uzyskać na naszej" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Przejdź do SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Wyjście z SABnzbd" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Uruchom kreatora konfiguracji" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd wydawany jest ABSOLUTNIE BEZ ŻADNEJ GWARANCJI.\n" "To jest wolne oprogramowanie i mile widziane jest dalsze rozpowszechnianie go przez ciebie na określonych warunkach.\n" "Program jest wydawany na licencji GNU GENERAL PUBLIC LICENSE w wersji 2 lub (według twojego wyboru) którejś z późniejszych wersji.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Nie udało się zmienić nazwy podobnego pliku %s na %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Dostęp zabroniony" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "Działanie modułu pobierania URL zostało przerwane" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Bezużyteczny plik NZB" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Pobieranie URL nie powiodło się; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Próba pobrania NZB z %s" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.216181 SABnzbd-4.3.2/po/main/ru.po0000644000000000000000000036133414625637207014565 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Предупреждение" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Не удалось запустить веб-интерфейс" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "" "Не удаётся найти шаблон веб-интерфейса: %s. Выполняется попытка использовать" " стандартный шаблон" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "Исполняемый файл par2... НЕ найден" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "Исполняемый файл unrar... НЕ найден" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Учтите, что для имени компьютера 0.0.0.0 потребуется IPv6-адрес для внешнего" " доступа" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS отключён, поскольку отсутствуют файлы CERT и KEY" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "" #: SABnzbd.py msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "Завершение работы SABnzbd закончено" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Получен сигнал %s. Выполняется сохранение и выход..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Электронное письмо успешно отправлено" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Тестовое уведомление" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Не задано имя компьютера." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "Подключения не настроены. Добавьте хотя бы одно подключение." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Пароль скрыт под ******. Повторите пароль." #: sabnzbd/api.py msgid "Invalid server details" msgstr "Недопустимые данные сервера" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Адрес сервера «%s:%s» является недопустимым." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Тайм-аут. Попробуйте включить SSL или использовать другой порт." #: sabnzbd/api.py msgid "Timed out" msgstr "Время ожидания истекло" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Для сервера требуется имя пользователя и пароль." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Подключение установлено!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Ошибка проверки подлинности. Проверьте имя и пароль." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "" "Слишком много подключений. Приостановите загрузку или повторите попытку " "позже" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Не удалось определить результат подключения (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Разрешение адреса" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ничего" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "по умолчанию" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "На диске нет места Принудительная приостановка" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Ошибка диска при создании файла %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Приостановка из-за нехватки места на диске" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Квота исчерпана. Загрузка приостановлена" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Неправильный параметр" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s не является допустимым адресом электронной почты" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Требуется адрес сервера" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Недопустимый адрес сервера." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s не является правильным восьмеричным значением" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Очередь не пустая, папку нельзя изменить." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Не удаётся записать INI-файл %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Не удаётся создать файл резервной копии для %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Неправильно закодированный пароль %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "Ошибка команды SQL (см. журнал)" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Не удалось закрыть базу данных (см. журнал)" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Недопустимый этап ведения журнала для %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Неизвестная ошибка декодирования %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Завершено" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Распаковка %s файлов или папок в %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Не удаётся прочитать наблюдаемую папку %s" #: sabnzbd/downloader.py msgid "Resuming" msgstr "" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Приостановлено" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Не удаётся подключиться к серверу %s [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Сервер %s будет игнорироваться %s мин." #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Ошибка входа на сервер %s [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Завершение работы" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Не удалось подключиться к почтовому серверу" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "Не удалось установить TLS-соединение" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "" #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Ошибка входа на почтовый сервер" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "" #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Не удалось отправить электронное письмо" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Не удалось разорвать соединение с почтовым сервером" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Не удаётся найти шаблонны электронных писем в %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Получатели не указаны. Электронное письмо не отправлено" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Не удаётся прочитать %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Не найдены шаблоны электронных писем" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd: на диске нет места\n" "\n" "Привет.\n" "\n" "Система SABnzbd остановила загрузку, поскольку на диске почти не осталось свободного места.\n" "Освободите место на диске и возобновите работу SABnzbd вручную.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Не удаётся создать каталог %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "Каталог %s: ошибка доступа %s" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Не удаётся изменить права доступа %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Не удалось создать (%s)" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Не удалось переместить %s в %s" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Ошибка в tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Ошибка сохранения %s" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Ошибка загрузки %s" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "Отсутствует ключ API. Введите в сторонней программе ключ API из раздела " "«Настройка -> Общие»:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Неправильный ключ API. Используйте в сторонней программе ключ API из раздела" " «Настройка -> Общие»:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Лента" #: sabnzbd/interface.py msgid "Daily" msgstr "ежедневно" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "понедельник" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "вторник" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "среда" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "четверг" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "пятница" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "суббота" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "воскресенье" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "выкл." #: sabnzbd/interface.py msgid "Undefined server!" msgstr "" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "ОШИБКА" #: sabnzbd/interface.py msgid "Back" msgstr "Назад" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "д" #: sabnzbd/misc.py msgid "h" msgstr "ч" #: sabnzbd/misc.py msgid "m" msgstr "м" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Доступно обновление!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Не удалось создать ключ SSL и сертификат" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Сортировка сериалов" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Сортировка даты" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Запуск сценария" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Объединение" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Неполная последовательность файлов, которые можно объединить" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Не удалось объединить файлы %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Ошибка объединения файлов: %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Ошибка «%s» выполнения file_join для %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Объединено файлов: %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Не удалось распаковать: %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Ошибка распаковки RAR-файлов: %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Ошибка «%s» выполнения rar_unpack для %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Не удалось удалить %s!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Попытка распаковки RAR-архива с паролем «%s»" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Распаковка" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Ошибка распаковки: не удаётся найти %s" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Не удалось распаковать: ошибка CRC" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Не удалось распаковать: ошибка записи или на диске нет места?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Ошибка распаковки: архив защищён паролем" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "см. журнал" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Быстрая проверка" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Исправить" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Быстрая проверка прошла успешно" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "запуск исправления" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Не удалось исправить: %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Ошибка %s выполнения par2_repair для набора %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Ошибка «%s» выполнения par2_repair для набора %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] Программе PAR2 переданы неправильные параметры. Проверьте параметры в " "разделе «Настройка -> Переключатели»" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Проверено за %s. Ошибок нет" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Проверено за %s. Требуется исправление" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "загрузка %s блоков..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Загрузка" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Ошибка исправления: недостаточно блоков восстановления (не хватает %s)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Исправление" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Исправлено за %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Проверка" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Проверка" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Проверка SFV-суммы" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "осталось" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Вики-сайт" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Запуск/остановка" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Приостановить" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Возобновить" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "Добавлен NZB" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Запущена пост-обработка" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Задание завершено" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Другие сообщения" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Не удаётся создать временный файл для %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Не удалось добавить %s: удалён" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Ошибка удаления %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Не удалось импортировать %s файлов из %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Найден несовместимый файл очереди. Продолжение работы невозможно" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Ошибка загрузки %s: обнаружен повреждённый файл" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB-файл добавлен в очередь" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Пропущен повторяющийся NZB-файл «%s»" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Пустой NZB-файл %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Ошибка импорта %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "ПОВТОР" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "ЗАШИФРОВАН" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "СЛИШКОМ БОЛЬШОЙ" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "НЕПОЛНЫЙ" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "ОЖИДАНИЕ %s с" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Загружено за %s со средней скоростью %sБ/с" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Возраст" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s статей с ошибками" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s статей отсутствует" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s статей содержат несовпадающие повторы" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Приостановлен повторяющийся NZB-файл «%s»" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "предупреждений" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Бездействие" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Очередь" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Очистить очередь" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "История" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Очистить историю" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Ограничение скорости" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "мин" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Сканировать наблюдаемую папку" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Полная папка" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Неполная папка" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Устранение неполадок" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Перезапустить" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Перезапустить без входа" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Выйти" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Первые 10 элементов очереди" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Пусто" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Последние 10 элементов истории" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Запустить мастер" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Остановка..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Проблема с" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " Службе SABnzbd требуется свободный порт TCP/IP для встроенного веб-сервера.
\n" " Был проверен порт %s на %s, но он оказался недоступен.
\n" " Возможно, этот порт используется другой программой, или служба SABnzbd уже запущена.
\n" "
\n" " Перезапустите службу SABnzbd, указав другой номер порта." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "" "Если снова появляется это сообщение об ошибке, попробуйте указать другой " "номер порта." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " Службе SABnzbd требуется действительный адрес сервера для встроенного веб-сервера.
\n" " Указан недействительный адрес.
\n" " Допустимые значения: localhost и 0.0.0.0
\n" "
\n" " Перезапустите службу SABnzbd, указав действительный адрес сервера." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " Обнаружены сохранённые данные из другой версии SABnzbd,
\n" " но данные другой программы нельзя повторно использовать.

\n" " Возможно, стоит сначала завершить очередь в другой программе.

\n" " После этого запустите данную программу с параметром «--clean».
\n" " При этом текущая очередь и журнал будут удалены!
\n" " Служба SABnzbd читает файл «%s»." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " Не удаётся найти файлы веб-интерфейса SABnbzd в %s.
\n" " Переустановите программу.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "Обнаружена критическая ошибка:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " Обнаружено, что отсутствует файл sqlite3.dll.

\n" " Этот файл мог быть удалён плохо настроенной антивирусной программой.
\n" " Попробуйте проверить параметры своей антивирусной программы, переустановите SABnzbd и сообщите о проблеме поставщику этого антивирусного ПО.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Нажмите клавиши STARTKEY+R и введите команду (пример):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Откройте окно командной сроки и введите команду (пример):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Программа не запустилась!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Критическая ошибка" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Не удаётся запустить браузер. Возможно, он не было найден" #: sabnzbd/panic.py msgid "Access denied" msgstr "Доступ запрещён" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Ошибка %s: укажите действительное имя пользователя и пароль." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Не удалось составить регулярное выражение поиска: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Пост-обработка" #: sabnzbd/postproc.py msgid "Moving" msgstr "Перемещение" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "%s отправлено в очередь" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Ошибка переименования «%s» и «%s»" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Не удалось переместить файлы" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Запуск пользовательского сценария %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Запущено %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Подробнее" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Ошибка пост-обработки для %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Не удалось загрузить" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "Не удалось очистить %s." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Загрузка завершена" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Не удаётся создать конечную папку %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Нет PAR2-файлов" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Некоторые файлы не прошли проверку «%s»" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Проверка SFV-сумм прошла успешно" #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "" #: sabnzbd/postproc.py msgid "Passworded" msgstr "" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "Не удалось удалить %s" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Не удалось перевести систему в состояние гибернации" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Не удалось перевести систему в состояние сна" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Не удалось завершить работу системы" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Неправильное описание RSS-ленты «%s»" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Неправильные учётные данные для ленты %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "Не удалось получить RSS-ленту из %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS-лента %s была пустой" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Несовместимая лента" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Обнаружена пустая запись RSS (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Показать интерфейс" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Приостановить на" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Приостановить на 5 минут" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Приостановить на 15 минут" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Приостановить на 30 минут" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Приостановить на 1 час" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Приостановить на 3 часа" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Приостановить на 6 часов" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Выключить" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "осталось" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Добавить NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Недопустимое расписание %s в %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Неизвестное действие: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Расписание для несуществующего сервера %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Попытка установить статус для несуществующего сервера %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Загрузить" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Объединить файлы" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Распаковать" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Сценарий" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Источник" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Серверы" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Ошибка" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "ожидание" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Исправление..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Извлечение..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Перемещение..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Запуск сценария..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Загрузка дополнительных блоков..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Быстрая проверка..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Проверка..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "отключить сервер" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "включить сервер" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Ограничить скорость" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Приостановить все" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Приостановить пост-обработку" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Возобновить пост-обработку" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Читать RSS-ленты" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Выкл." #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "обычный" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "высокий" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "низкий" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "час" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "часов" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "минут" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "с" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "секунд" #: sabnzbd/skintext.py msgid "day" msgstr "день" #: sabnzbd/skintext.py msgid "days" msgstr "дней" #: sabnzbd/skintext.py msgid "week" msgstr "неделя" #: sabnzbd/skintext.py msgid "Month" msgstr "Месяц" #: sabnzbd/skintext.py msgid "Year" msgstr "Год" #: sabnzbd/skintext.py msgid "Day of month" msgstr "День месяца" #: sabnzbd/skintext.py msgid "This week" msgstr "за эту неделю" #: sabnzbd/skintext.py msgid "This month" msgstr "за этот месяц" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "за сегодня" #: sabnzbd/skintext.py msgid "Total" msgstr "всего" #: sabnzbd/skintext.py msgid "on" msgstr "на" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "" #: sabnzbd/skintext.py msgid "Python Version" msgstr "" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "" #: sabnzbd/skintext.py msgid "or" msgstr "" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Адрес" #: sabnzbd/skintext.py msgid "Cancel" msgstr "" #: sabnzbd/skintext.py msgid "Log in" msgstr "" #: sabnzbd/skintext.py msgid "Log out" msgstr "" #: sabnzbd/skintext.py msgid "Remember me" msgstr "" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Сохранить" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Сохранение..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Уверены?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Главная" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Настройка" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Состояние" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Справка" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Форум" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Поддержите проект. Сделайте пожертвование!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Общие" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Папки" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Переключатели" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Расписание" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Уведомления" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Эл. почта" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Категории" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Сортировка" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Особая" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Остановить SABnzbd?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Добавить" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Категория" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Приоритет" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+исправить" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+распаковать" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+удалить" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "принудительный" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Остановить" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Введите URL" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "выключить ПК" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "перевести ПК в режим ожидания" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "перевести ПК в спящий режим" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Закрыть SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Обработка" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Название" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Повторить" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Сценарии" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Удалить из очереди все элементы?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Удалить NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Удалить NZB и стереть файлы" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Удалить NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Удалить NZB и стереть файлы" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Отсутствуют статьи" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Осталось квоты" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "вручную" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Сбросить квоту" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Скрыть подробности" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Показать подробности" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Показать неудачные" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Показать все" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Размер" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Удалить неудачные NZB" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Удалить неудачные NZB и стереть файлы" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Удалить завершённые NZB" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Дополнительный NZB (необязательно)" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Путь" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Принудительно отключить" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Отправка тестового письма на указанный почтовый ящик" #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Показать журнал" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Проверить электронную почту" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Журнал" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Ошибки и предупреждения" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ информация" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ отладка" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Соединения" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Идентификатор статьи" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Набор файлов" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Включен" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Файл конфигурации" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Используемый кэш" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Эта кнопка перезапустит SABnzbd.
Используйте её, когда программа " "работает нестабильно.
Загрузка будет приостановлена до перезапуска и " "снова возобновлена после запуска." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "В папке загрузки есть осиротевшие задания.
Их можно удалить (вместе с " "файлами) или поставить обратно в очередь." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "Эта кнопка перезапустит SABnzbd и полностью
перестроит содержимое " "очереди, не трогая уже загруженные файлы.
При этом порядок очереди " "будет изменён." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Изменения не были сохранены и будут потеряны." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Версия" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Время работы" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Резервный" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Описание см. на вики-странице." #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Перезапуск SABnzbd..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Для применения изменений необходимо перезапустить SABnzbd!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "Веб-сервер SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "Сервер SABnzbd" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Адрес, по которому будет доступна служба SABnzbd." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "Порт SABnzbd" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Порт, по которому будет доступна служба SABnzbd." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "Имя пользователя SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Необязательное имя пользователя для входа." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "Пароль SABnzbd" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Необязательный пароль для входа." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "Включить HTTPS" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Доступ к интерфейсу по протоколу HTTPS." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "Порт HTTPS" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Если не указать, будет доступен только стандартный порт с HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "Сертификат HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Название файла или путь к сертификату HTTPS." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "Ключ HTTPS" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Название файла или путь к ключу HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py msgid "Tuning" msgstr "Тонкая настройка" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "Интервал опроса RSS-лент" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Интервал проверки (в минутах, не менее 15). Если используется планировщик, " "этот параметр не отключён." #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Ограничить кэш статей" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Кэширование статей в памяти для уменьшения количества обращений к диску.
В байтах, после числа можно добавить K, M или G. Пример: «64M» или " "«128M»" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Список очистки" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Сохранить изменения" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "" #: sabnzbd/skintext.py msgid "Reset" msgstr "Сбросить" #: sabnzbd/skintext.py msgid "Language" msgstr "Язык" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Выберите язык веб-интерфейса." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" #: sabnzbd/skintext.py msgid "API Key" msgstr "Ключ API" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "По этому ключу сторонние программы смогут получить полный доступ к SABnzbd." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "Ключ NZB" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "По этому ключу сторонние программы смогут загружать файлы в доступ к " "SABnzbd." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Создать новый ключ" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "QR-код ключа API" #: sabnzbd/skintext.py msgid "External internet access" msgstr "" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "" #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "" #: sabnzbd/skintext.py msgid "Full API" msgstr "" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "ПРИМЕЧАНИЕ. Папки будут созданы автоматически при сохранении. Можно" " использовать абсолютные пути для сохранения за пределами папок по " "умолчанию." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Пользовательские папки" #: sabnzbd/skintext.py msgid "Browse" msgstr "" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Папка временной загрузки" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Место для хранения необработанных загрузок.
Изменить можно только " "тогда, когда очередь пуста." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Минимальное свободное место в папке временной загрузки" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Загрузка останавливается при уменьшении свободного места до этого " "значения.
В байтах, после числа можно добавить K, M, G или T. " "Пример: «800M» или «8G»" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Папка завершённых загрузок" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Место для сохранения готовых, полностью обработанных загрузок.
Можно" " переопределить в пользовательских категориях." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Автоматически возобновлять" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Права доступа для завершённых загрузок" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Шаблон прав доступа для завершенных файлов и/или папок.
В " "восьмеричном формате. Пример: «755» или «777»" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Наблюдаемая папка" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Папка для поиска NZB-файлов." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Частота сканирования наблюдаемой папки" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Число секунд между для поисками NZB-файлов." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Папка шаблонов электронных писем" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Папка, содержащая пользовательские шаблоны электронной почты." #: sabnzbd/skintext.py msgid "Password file" msgstr "Файл паролей" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Файл, содержащий все пароли, которые будут испробованы для зашифрованных " "RAR-файлов." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Системные папки" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Административная папка" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Место для хранения и базы данных очереди и журнала.
Изменить можно " "только тогда, когда очередь пуста." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Данные не будут перемещены. Требуется перезапуск SABnzbd!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Папка журнала" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Место для хранения файлов журнала SABnzbd.
Требуется перезапуск " "SABnzbd!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr "Папка для хранения копий NZB" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Место, где будут сохраняться NZB-файлы" #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Базовая папка по умолчанию" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "" #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "" #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Загружать статьи только из начала очереди" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Включите, что уменьшить использование памяти. Отключите, чтобы медленные " "задания не блокировали очередь." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Обрабатывать только проверенные задания" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Отменить" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "Использовать проверку по SFV" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Выполнять дополнительную проверку по SFV-файлам." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Переименовывать папки" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Использовать временные названия при пост-обработке. Отключите, если ваша " "система обрабатывает это неправильно." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Пользовательский сценарий до помещения в очередь" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Используется до того, как NZB помещается в очередь." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Дополнительные параметры PAR2" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Параметры Nice" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "Параметры IONice" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Отключаться, если очередь пуста" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Отключаться от серверов Usenet, если очередь пуста или приостановлена." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Проверять наличие обновлений" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Заменять пробелы в названиях папок" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Заменять пробелы на символы подчёркивания в названиях папок." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Заменять точки в названиях папок" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Заменять точки на пробелы в названиях папок." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "" #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Открывать браузер при запуске" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Открывать веб-браузер по умолчанию при запуске SABnzbd." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Приостановить загрузку во время пост-обработки" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Приостановить загрузку с началом пост-обработки и возобновить по её " "окончании." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Игнорировать образцы" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Отфильтровывать файлы образцов (например, образцы видео)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Удалить после загрузки" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Сервер" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Пост-обработка" #: sabnzbd/skintext.py msgid "Naming" msgstr "Именование" #: sabnzbd/skintext.py msgid "Quota" msgstr "Квота" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Объем, который можно загрузить в месяц (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "День сброса трафика" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "День месяца или недели (1 — понедельник), когда провайдер сбрасывает квоту. " "(дополнительно можно указать чч:мм)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Возобновлять загрузку после сброса квоты?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Период квоты" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Сбрасывается ли квота каждый день, неделю или месяц?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Проверять перед загрузкой" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Попытаться спрогнозировать успешное завершение до фактической загрузки " "(медленнее!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "" #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Число попыток" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Максимальное число повторных попыток для каждого сервера" #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Добавить сервер" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Порт" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Имя пользователя" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Пароль" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Время ожидания" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Срок хранения" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "отключено" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Дополнительный" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Включить" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Удалить сервер" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Проверить сервер" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Сбросить счётчики" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Данные проверки сервера..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Трафик" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Добавить задание" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Частота" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Действие" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Аргументы" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Текущие задания" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Чтобы включить ленту и автоматически проверять обновление её содержимого, " "установите флажок напротив её названия.
После добавления ленты " "загружаться будут только новые её элементы, а не те, что были опубликованы " "раньше (если только на нажать кнопку «Загрузить принудительно»)." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Прочитать ленту" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Загрузить принудительно" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Порядок" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Тип" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Фильтр" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Принять" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Отклонить" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Требуется" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "Требуется категория" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Соответствующие" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Нет соответствий" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Загружено" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Прочитать все ленты" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Уведомление по электронной почте после завершения задания" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Никогда" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Всегда" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Только при ошибках" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Уведомления о нехватке места на диске" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Отправлять электронное письмо, когда на диске нет места и загрузка SABnbzd " "приостановлена." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Отправлять RSS-уведомления" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "Отправлять электронное письмо, когда в очередь добавляется задание из RSS-" "ленты." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "Сервер SMTP" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Укажите сервер своего провайдера для исходящей почты." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Получатель" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Адрес электронной почты получателя уведомлений." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Отправитель" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "От кого будут отправляться уведомления" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "НЕОБЯЗАТЕЛЬНОЕ имя пользователя" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "" "Имя пользователя учётной записи (для электронной почты с проверкой " "подлинности)." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "НЕОБЯЗАТЕЛЬНЫЙ пароль" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "" "Пароль учётной записи (для электронной почты с проверкой подлинности)." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Уведомление отправлено" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "Использовать NotifyOSD" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Если завершить путь звёздочкой (*), папки заданий не будут создаваться." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Относительный путь для папок" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Папка или путь" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Ключи шаблона" #: sabnzbd/skintext.py msgid "Clear" msgstr "Очистить" #: sabnzbd/skintext.py msgid "Presets" msgstr "Готовые шаблоны" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Задействованные категории" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Значение" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Шаблон" #: sabnzbd/skintext.py msgid "Result" msgstr "Результат" #: sabnzbd/skintext.py msgid "Title" msgstr "Название" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Название фильма" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Название.фильма" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Название_фильма" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Название сериала" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Название.сериала" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Название_сериала" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Номер сезона" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Номер эпизода" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Название эпизода" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Название.эпизода" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Название_эпизода" #: sabnzbd/skintext.py msgid "Extension" msgstr "Расширение" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Номер части" #: sabnzbd/skintext.py msgid "Decade" msgstr "Десятки" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Исходное название файла" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Нижний регистр" #: sabnzbd/skintext.py msgid "TEXT" msgstr "ТЕКСТ" #: sabnzbd/skintext.py msgid "text" msgstr "текст" #: sabnzbd/skintext.py msgid "file" msgstr "файл" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Строка сортировки" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "В папках" #: sabnzbd/skintext.py msgid "No folders" msgstr "Без папок" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "case-adjusted" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Обработанный результат" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Все" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Редко используемые параметры. Их описание можно просмотреть на вики-" "странице, доступной по кнопке «Справка».
Не изменяйте эти параметры, не " "изучив сначала вики-страницу, поскольку их изменение может иметь серьезные " "последствия.
В скобках показаны значения по умолчанию." #: sabnzbd/skintext.py msgid "Values" msgstr "Значения" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "Изменить данные NZB" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Удалить" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Название файла" #: sabnzbd/skintext.py msgid "Free Space" msgstr "свободно на диске" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Пакетные операции" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "" #: sabnzbd/skintext.py msgid "Check all" msgstr "" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "По окончании очереди" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "" #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "ПРЕДУПРЕЖДЕНИЕ" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Загрузить" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Веб-интерфейс" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Частота обновления" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "" #: sabnzbd/skintext.py msgid "History item limit" msgstr "" #: sabnzbd/skintext.py msgid "Date format" msgstr "" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "стр." #: sabnzbd/skintext.py msgid "Loading" msgstr "" #: sabnzbd/skintext.py msgid "articles" msgstr "" #: sabnzbd/skintext.py msgid "Rename" msgstr "Переименовать" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Исправление очереди" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Разблокировать" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Удалить всё" #: sabnzbd/skintext.py msgid "Retry all" msgstr "" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Имя файла (необязательно)" #: sabnzbd/skintext.py msgid "Submit" msgstr "" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "" #: sabnzbd/skintext.py msgid "Top" msgstr "В начало" #: sabnzbd/skintext.py msgid "Bottom" msgstr "В конец" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Просмотреть журнал сценария" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" #: sabnzbd/skintext.py msgid "Custom" msgstr "Другой" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "" #: sabnzbd/skintext.py msgid "Speed" msgstr "Скорость" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Подтвердите удаление очереди" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Подтвердите удаление журнала" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "" #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Приостановить на..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Обновить" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Сортировать по возрасту от старых к новым" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Сортировать по возрасту от новых к старым" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Сортировать по названию от А до Я" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Сортировать по названию от Я до А" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Сортировать по размеру от мелких к крупным" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Сортировать по размеру от крупных к мелким" #: sabnzbd/skintext.py msgid "Uploading" msgstr "" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "" #: sabnzbd/skintext.py msgid "Removing job" msgstr "" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "Мастер быстрого запуска SABnzbd" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "Версия SABnzbd" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Назад" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Следующая" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Данные сервера" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Введите данные своего основного поставщика услуг Usenet." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Количество подключений, разрешённое провайдером" #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Например, 8 или 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Включайте, только если вашим провайдером разрешены SSL-соединения." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Нажмите, чтобы проверить введённые данные." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Например," #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Настройка завершена." #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "Служба SABnzbd теперь будет выполняться в фоновом режиме." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "Если закрыть окна или вкладки браузера, служба SABnzbd НЕ будет остановлена." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Рекомендуется щёлкнуть страницу правой кнопкой мыши и добавить этот адрес в " "закладки, а затем использовать эту закладку для доступа к службе SABnzbd, " "работающей в фоновом режиме." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Дополнительные сведения доступны на нашем" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Перейти к SABnzbd" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd предоставляется БЕЗ КАКОЙ-ЛИБО ГАРАНТИИ.\n" "Это свободное программное обеспечение, и его можно распространять при соблюдении определённых условий.\n" "Она распространяется по лицензии GNU GENERAL PUBLIC LICENSE версии 2 или (по вашему выбору) любой более поздней версии.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Не удалось переименовать похожий файл: %s в %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "Пустой NZB-файл" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Не удалось загрузить URL: %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Попытка загрузить NZB с %s" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.212196 SABnzbd-4.3.2/po/main/fi.po0000644000000000000000000034570714625637207014543 0ustar00runnerstaff# SABnzbd Translation Template file MAIN # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2023 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:49+0000\n" "Last-Translator: Safihre , 2023\n" "Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Notification - Status page, table column header, actual message #: SABnzbd.py, sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Warning" msgstr "Varoitus" #. Notification #: SABnzbd.py, sabnzbd/notifier.py msgid "Error" msgstr "Virhe" #. Error message #: SABnzbd.py msgid "Failed to start web-interface" msgstr "Web-käyttöliittymän käynnistys epäonnistui" #. Warning message #: SABnzbd.py msgid "Cannot find web template: %s, trying standard template" msgstr "Web-mallia %s ei löydy, yritetään käyttää oletusmallia" #. Error message #: SABnzbd.py msgid "" "SABCTools disabled: no correct version found! (Found v%s, expecting v%s)" msgstr "" #. Error message #: SABnzbd.py msgid "par2 binary... NOT found!" msgstr "par2 ohjelmaa... EI löydy!" #. Warning message #: SABnzbd.py msgid "Your UNRAR version is %s, we recommend version %s or higher.
" msgstr "" "UNRAR-versiosi on %s, suosittelemme käyttämään versiota %s tai uudempaa.
" #. Error message #: SABnzbd.py msgid "unrar binary... NOT found" msgstr "unrar-ohjelmaa... EI löydy!" #. Warning message #: SABnzbd.py msgid "7za binary... NOT found!" msgstr "7za-ohjelmaa... EI löydy!" #. Error message #: SABnzbd.py msgid "Essential modules are missing, downloading cannot start." msgstr "" #. Warning message #: SABnzbd.py msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Huomioithan, että 0.0.0.0 isäntänimi vaatii IPv6 osoitteen jotta pääset " "ulkoverkkoon" #. Error message #: SABnzbd.py msgid "HTTP and HTTPS ports cannot be the same" msgstr "HTTP- ja HTTPS-portit eivät voi olla samoja" #. Warning message #: SABnzbd.py msgid "" "SABnzbd was started with encoding %s, this should be UTF-8. Expect problems " "with Unicoded file and directory names in downloads." msgstr "" "SABnzbd käynnistettiin %s merkistökoodauksella. Tämän pitäisi olla UTF-8. " "Unicode-merkkejä tiedosto- ja kansionimissä sisältävät lataukset voivat " "aiheuttaa ongelmia." #. Warning message #: SABnzbd.py msgid "" "Current umask (%o) might deny SABnzbd access to the files and folders it " "creates." msgstr "" #. Warning message #: SABnzbd.py msgid "Could not load additional certificates from certifi package" msgstr "" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "" "HTTPS on poistettu käytöstä puuttuvien CERT- ja KEY-tiedostojen vuoksi" #. Warning message #: SABnzbd.py msgid "Disabled HTTPS because of invalid CERT and KEY files" msgstr "" #. Error message #: SABnzbd.py msgid "Failed to start web-interface: " msgstr "Web-käyttöliittymän käynnistys epäonnistui : " #: SABnzbd.py msgid "SABnzbd %s started" msgstr "SABnzbd %s käynnistetty" #: SABnzbd.py, sabnzbd/interface.py msgid "SABnzbd shutdown finished" msgstr "SABnzbd sammutus valmis" #. Warning message #: sabnzbd/__init__.py msgid "Signal %s caught, saving and exiting..." msgstr "Signaali %s kaapattu, tallennetaan ja lopetetaan..." #. Error message #: sabnzbd/__init__.py msgid "Fatal error at saving state" msgstr "Vakava virhe tallennettaessa tilaa" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed postprocessor" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed downloader" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Restarting because of crashed assembler" msgstr "" #. Warning message #: sabnzbd/__init__.py msgid "Cannot access PID file %s" msgstr "" #: sabnzbd/api.py, sabnzbd/emailer.py msgid "Email succeeded" msgstr "Sähköpostitus onnistui" #: sabnzbd/api.py, sabnzbd/skintext.py msgid "Test Notification" msgstr "Testaa ilmoitusta" #: sabnzbd/api.py msgid "The hostname is not set." msgstr "Isäntänimeä ei ole asetettu." #: sabnzbd/api.py msgid "There are no connections set. Please set at least one connection." msgstr "Yhteyksiä ei ole asetettu. Aktivoi ainakin yksi yhteys." #: sabnzbd/api.py msgid "Password masked in ******, please re-enter" msgstr "Salasana on piilotettu ******, syötä uudelleen" #: sabnzbd/api.py msgid "Invalid server details" msgstr "Virheelliset palvelimen tiedot" #: sabnzbd/api.py msgid "" "Could not connect to %s on port %s. It appears that %s operates as a web " "server (port 80), possibly an indexer, not a usenet server. You have to fill" " a usenet server." msgstr "" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Server address \"%s:%s\" is not valid." msgstr "Palvelimen osoite \"%s:%s\" ei ole kelvollinen." #: sabnzbd/api.py msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Aikakatkaistu: Yritä laittaa SSL päälle tai yhdistä toiseen porttiin." #: sabnzbd/api.py msgid "Timed out" msgstr "Aikakatkaistiin" #: sabnzbd/api.py msgid "" "Unknown SSL protocol: Try disabling SSL or connecting on a different port." msgstr "" "Tuntematon SSL protokolla: Kokeile ottaa SSL käytöstä tai vaihda porttia." #: sabnzbd/api.py msgid "Server requires username and password." msgstr "Palvelin vaatii käyttäjänimen ja salasanan." #: sabnzbd/api.py msgid "Connection Successful!" msgstr "Yhdistäminen onnistui!" #: sabnzbd/api.py, sabnzbd/interface.py msgid "Authentication failed, check username/password." msgstr "Varmennus epäonnistui, tarkista käyttäjänimi/salasana." #: sabnzbd/api.py msgid "Too many connections, please pause downloading or try again later" msgstr "Liikaa yhteyksiä, keskeytä lataaminen tai yritä myöhemmin uudelleen" #: sabnzbd/api.py msgid "Could not determine connection result (%s)" msgstr "Yhteystestin lopputulosta ei voitu määrittää (%s)" #: sabnzbd/api.py msgid "Resolving address" msgstr "Selvitetään osoitetta" #. No value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/skintext.py msgid "None" msgstr "Ei mitään" #. Default value, used in dropdown menus #: sabnzbd/api.py, sabnzbd/interface.py, sabnzbd/skintext.py msgid "Default" msgstr "Oletus" #. Error message #: sabnzbd/assembler.py msgid "Disk full! Forcing Pause" msgstr "Levy täynnä! Pakotetaan keskeytys" #. Error message #: sabnzbd/assembler.py msgid "Disk error on creating file %s" msgstr "Levyvirhe luotaessa tiedostoa %s" #. Error message #: sabnzbd/assembler.py msgid "Fatal error in Assembler" msgstr "Vakava virhe kohteessa Assembler" #. Warning message #: sabnzbd/assembler.py msgid "Too little diskspace forcing PAUSE" msgstr "Levytilaa ei ole tarpeeksi, pakotetaan KESKEYTYS" #. Warning message #: sabnzbd/assembler.py msgid "" "Paused job \"%s\" because of encrypted RAR file (if supplied, all passwords " "were tried)" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "" "Aborted job \"%s\" because of encrypted RAR file (if supplied, all passwords" " were tried)" msgstr "" #: sabnzbd/assembler.py msgid "Aborted, encryption detected" msgstr "Peruutettu, salattu arkisto tunnistettu" #. Warning message #: sabnzbd/assembler.py msgid "In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py msgid "Unwanted extension is in rar file %s" msgstr "Ei toivottu tiedostopääte on rar arkistossa %s" #: sabnzbd/assembler.py, sabnzbd/nzbstuff.py msgid "Aborted, unwanted extension detected" msgstr "Peruutettu, ei toivottu tiedostopääte havaittu" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted due to RAR with same name inside this RAR" msgstr "" #. Warning message #: sabnzbd/assembler.py msgid "Job \"%s\" is probably encrypted: \"password\" in filename \"%s\"" msgstr "" #. Warning message #: sabnzbd/bpsmeter.py msgid "Quota spent, pausing downloading" msgstr "Latausrajoitus saavutettu, keskeytetään lataukset" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Incorrect parameter" msgstr "Virheellinen parametri" #: sabnzbd/cfg.py msgid "%s is not a valid email address" msgstr "%s ei ole kelvollinen sähköpostiosoite" #: sabnzbd/cfg.py, sabnzbd/interface.py msgid "Server address required" msgstr "Palvelimen osoite vaaditaan" #: sabnzbd/cfg.py, sabnzbd/newswrapper.py msgid "Invalid server address." msgstr "Virheellinen palvelimen osoite." #: sabnzbd/cfg.py msgid "%s is not a valid script" msgstr "" #: sabnzbd/cfg.py msgid "%s is not a correct octal value" msgstr "%s ei ole oikea oktaalinen arvo" #. Warning message #: sabnzbd/cfg.py msgid "" "Permissions setting of %s might deny SABnzbd access to the files and folders" " it creates." msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "Network path \"%s\" should not be used here" msgstr "" #: sabnzbd/cfg.py msgid "Queue not empty, cannot change folder." msgstr "Jono ei ole tyhjä, kansiota ei voida vaihtaa." #: sabnzbd/cfg.py msgid "" "The Completed Download Folder cannot be the same or a subfolder of the " "Temporary Download Folder" msgstr "" #. Warning message #: sabnzbd/cfg.py msgid "" "Do not use a folder in the application folder as your Scripts Folder, it " "might be emptied during updates." msgstr "" #. Warning message #: sabnzbd/config.py msgid "Configuration locked, cannot save settings" msgstr "" #. Error message #: sabnzbd/config.py msgid "Cannot write to INI file %s" msgstr "Ei voitu kirjoittaa INI tiedostoa %s" #. Error message #: sabnzbd/config.py msgid "Cannot create backup file for %s" msgstr "Ei voitu luoda varmuuskopiotiedostoa kohteelle %s" #. Warning message #: sabnzbd/config.py msgid "Could not restore backup" msgstr "" #. Error message #: sabnzbd/config.py msgid "Incorrectly encoded password %s" msgstr "Virheellisesti koodattu salasana %s" #. Error message #: sabnzbd/database.py msgid "Cannot write to History database, check access rights!" msgstr "Historian tietokantaan ei voida kirjoittaa, tarkista käyttöoikeudet!" #. Error message #: sabnzbd/database.py msgid "Damaged History database, created empty replacement" msgstr "Historian tietokanta on vahingoittunut, luotiin uusi tyhjä tietokanta" #. Error message #: sabnzbd/database.py msgid "SQL Command Failed, see log" msgstr "SQL komento epäonnistui, katso loki" #. Error message #: sabnzbd/database.py msgid "Failed to close database, see log" msgstr "Tietokannan sulkeminen epäonnistui, katso loki" #. Warning message #: sabnzbd/database.py msgid "Invalid stage logging in history for %s" msgstr "Virheellinen tila lokihistoriassa kohteelle %s" #. Warning message #: sabnzbd/decoder.py msgid "Decoder failure: Out of memory" msgstr "" #. Warning message #: sabnzbd/decoder.py msgid "Unknown Error while decoding %s" msgstr "Tuntematon virhe dekoodattaessa %s" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate skipped due to DVD/Bluray directories" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate corrected the extension of %d file(s)" msgstr "" #: sabnzbd/deobfuscate_filenames.py msgid "Deobfuscate renamed %d file(s)" msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Direct Unpack" msgstr "" #. PP status #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "Completed" msgstr "Valmistunut" #: sabnzbd/directunpacker.py, sabnzbd/newsunpack.py msgid "Unpacked %s files/folders in %s" msgstr "Purettiin %s tiedostoa/kansiota kohteeseen %s" #. Warning message #: sabnzbd/directunpacker.py msgid "Direct Unpack was automatically enabled." msgstr "" #: sabnzbd/directunpacker.py, sabnzbd/skintext.py msgid "" "Jobs will start unpacking during the downloading to reduce post-processing " "time. Only works for jobs that do not need repair." msgstr "" #. Error message #: sabnzbd/dirscanner.py msgid "Cannot read Watched Folder %s" msgstr "Vahdittua kansiota %s ei voida lukea" #: sabnzbd/downloader.py msgid "Resuming" msgstr "Jatketaan" #. PP status - Priority pick list #: sabnzbd/downloader.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Paused" msgstr "Keskeytetty" #. Warning message #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "You must set a maximum bandwidth before you can set a bandwidth limit" msgstr "" "Sinun täytyy määrittää enimmäiskaista ennen kaistarajoituksen käyttöönottoa." #: sabnzbd/downloader.py msgid "Cannot connect to server %s [%s]" msgstr "Palvelimeen %s ei voida yhdistää [%s]" #: sabnzbd/downloader.py, sabnzbd/urlgrabber.py msgid "Server name does not resolve" msgstr "Palvelimen osoitetta ei voitu selvittää" #. Warning message #: sabnzbd/downloader.py msgid "Server %s will be ignored for %s minutes" msgstr "Palvelin %s ohitetaan %s minuutiksi" #. Warning message #: sabnzbd/downloader.py msgid "There are no active servers!" msgstr "" #. Error message #: sabnzbd/downloader.py msgid "Failed to initialize %s@%s with reason: %s" msgstr "Alustaminen epäonnistui kohteessa %s@%s syy: %s" #. Error message #: sabnzbd/downloader.py msgid "Fatal error in Downloader" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "%s@%s: Received unknown status code %s for article %s" msgstr "" #: sabnzbd/downloader.py msgid "Too many connections to server %s [%s]" msgstr "Liikaa yhteyksiä palvelimelle %s [%s]" #: sabnzbd/downloader.py msgid "" "Login from too many different IP addresses to server %s [%s] - " "https://sabnzbd.org/multiple-adresses" msgstr "" #: sabnzbd/downloader.py msgid "Failed login for server %s [%s]" msgstr "Kirjautuminen palvelimelle %s epäonnistui [%s]" #. Error message #: sabnzbd/downloader.py msgid "Connecting %s@%s failed, message=%s" msgstr "Yhdistäminen %s@%s epäonnistui, viesti=%s" #. Error message #: sabnzbd/downloader.py msgid "Suspect error in downloader" msgstr "Mahdollinen virhe lataajassa" #: sabnzbd/downloader.py, sabnzbd/skintext.py msgid "Shutting down" msgstr "Sammutetaan" #. Warning message #: sabnzbd/downloader.py msgid "Server %s is expiring in %s day(s)" msgstr "" #. Warning message #: sabnzbd/downloader.py msgid "Server %s has used the specified quota" msgstr "" #: sabnzbd/emailer.py msgid "Failed to connect to mail server" msgstr "Postipalvelimeen yhdistäminen epäonnistui" #: sabnzbd/emailer.py msgid "Failed to initiate TLS connection" msgstr "TLS yhteyden aloittaminen epäonnistui" #: sabnzbd/emailer.py msgid "The server didn't reply properly to the helo greeting" msgstr "Palvelin ei vastannut oikein hello-pyyntöön." #: sabnzbd/emailer.py msgid "Failed to authenticate to mail server" msgstr "Postipalvelimen varmennus epäonnistui" #: sabnzbd/emailer.py msgid "No suitable authentication method was found" msgstr "Yhteensopivan varmennustavan löytäminen epäonnistui" #: sabnzbd/emailer.py msgid "Unknown authentication failure in mail server" msgstr "Tuntematon varmennusvirhe sähköpostipalvelimelta." #: sabnzbd/emailer.py msgid "Failed to send e-mail" msgstr "Sähköpostin lähetys epäonnistui" #: sabnzbd/emailer.py msgid "Failed to close mail connection" msgstr "Sähköpostiyhteyden sulkeminen epäonnistui" #: sabnzbd/emailer.py, sabnzbd/notifier.py msgid "Cannot send, missing required data" msgstr "Ei voida lähettää, vaaditut tiedot ovat puutteelliset" #. Error message #: sabnzbd/emailer.py msgid "Cannot find email templates in %s" msgstr "Sähköpostipohjia ei löydy hakemistosta %s" #: sabnzbd/emailer.py msgid "No recipients given, no email sent" msgstr "Vastaanottajaa ei määritelty, sähköpostia ei lähetetty" #. Error message - Warning message #: sabnzbd/emailer.py, sabnzbd/nzbparser.py, sabnzbd/rss.py msgid "Cannot read %s" msgstr "Ei voida lukea %s" #: sabnzbd/emailer.py msgid "No email templates found" msgstr "Sähköpostipohjia ei löydy" #: sabnzbd/emailer.py msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd raportoi levy täynnä\n" "\n" "Hei,\n" "\n" "SABnzbd on lopettanut lataamasta, koska levy on lähes täynnä.\n" "Ole hyvä ja tee lisää tilaa ja jatka SABnzbd käsin.\n" "\n" #: sabnzbd/filesystem.py msgid "Cannot create directory %s" msgstr "Ei voi luoda kansiota %s" #: sabnzbd/filesystem.py msgid "%s directory: %s error accessing" msgstr "%s kansio: %s virhe käytettäessä" #. Error message #: sabnzbd/filesystem.py msgid "Cannot change permissions of %s" msgstr "Käyttöoikeuksien muuttaminen epäonnistui kohteelle %s" #. Error message #: sabnzbd/filesystem.py msgid "Failed making (%s)" msgstr "Kohteen (%s) luominen epäonnistui" #. Error message #: sabnzbd/filesystem.py, sabnzbd/postproc.py msgid "Failed moving %s to %s" msgstr "Kohteen %s siirtäminen kohteeseen %s epäonnistui" #. Error message #: sabnzbd/filesystem.py msgid "Blocked attempt to create directory %s" msgstr "" #. Error message #: sabnzbd/filesystem.py msgid "Failure in tempfile.mkstemp" msgstr "Virhe tiedostossa tempfile.mkstemp" #. Error message #: sabnzbd/filesystem.py msgid "Saving %s failed" msgstr "Kohteen %s tallentaminen epäonnistui" #. Error message #: sabnzbd/filesystem.py msgid "Loading %s failed" msgstr "Kohteen %s lataaminen epäonnistui" #. Warning message #: sabnzbd/filesystem.py msgid "%s is not writable at all. This blocks downloads." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a long filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "Cannot write a unicode filename to %s. This can cause problems." msgstr "" #. Warning message #: sabnzbd/filesystem.py msgid "" "%s is not writable with special character filenames. This can cause " "problems." msgstr "" #: sabnzbd/interface.py msgid "Refused connection from:" msgstr "" #: sabnzbd/interface.py msgid "Refused connection with hostname \"%s\" from:" msgstr "" #: sabnzbd/interface.py msgid "User logged in to the web interface" msgstr "Käyttäjä kirjautui sisään web-käyttöliittymään" #. Notification #: sabnzbd/interface.py, sabnzbd/notifier.py msgid "User logged in" msgstr "Käyttäjä kirjautui sisään" #: sabnzbd/interface.py msgid "" "API Key missing, please enter the api key from Config->General into your 3rd" " party program:" msgstr "" "API avain puuttuu, ole hyvä ja syötä Asetukset->Yleiset löytyvä api avain " "käyttämääsi kolmannen osapuolen ohjelmaan:" #: sabnzbd/interface.py msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API avain virheellinen, käytä Asetukset->Yleiset löytyvää api avainta " "käyttämääsi kolmannen osapuolen ohjelmaan:" #. Warning message #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" #: sabnzbd/interface.py msgid "Invalid backup archive" msgstr "" #. Config->RSS, tab header #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Feed" msgstr "Syöte" #: sabnzbd/interface.py msgid "Daily" msgstr "Päivittäin" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Monday" msgstr "Maanantai" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Tuesday" msgstr "Tiistai" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Wednesday" msgstr "Keskiviikko" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Thursday" msgstr "Torstai" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Friday" msgstr "Perjantai" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Saturday" msgstr "Lauantai" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "Sunday" msgstr "Sunnuntai" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "off" msgstr "ei käytössä" #: sabnzbd/interface.py msgid "Undefined server!" msgstr "Määrittämätön palvelin!" #: sabnzbd/interface.py msgid "" "Category folder cannot be a subfolder of the Temporary Download Folder." msgstr "" #: sabnzbd/interface.py, sabnzbd/skintext.py msgid "ERROR:" msgstr "VIRHE:" #: sabnzbd/interface.py msgid "Back" msgstr "Takaisin" #: sabnzbd/misc.py msgid "" "To prevent all helpful warnings, disable Special setting 'helpful_warnings'." msgstr "" #: sabnzbd/misc.py msgid "d" msgstr "pv" #: sabnzbd/misc.py msgid "h" msgstr "t" #: sabnzbd/misc.py msgid "m" msgstr "m" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Update Available!" msgstr "Päivitys saatavilla!" #. Error message #: sabnzbd/misc.py msgid "Failed to upload file: %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "Error creating SSL key and certificate" msgstr "Virhe luotaessa SSL avainta ja sertifikaattia" #. Warning message #: sabnzbd/misc.py msgid "" "Your password file contains more than 30 passwords, testing all these " "passwords takes a lot of time. Try to only list useful passwords." msgstr "" #. Warning message #: sabnzbd/misc.py msgid "Failed to read the password file %s" msgstr "" #. Error message #: sabnzbd/misc.py msgid "[%s] The command in build_command is undefined." msgstr "" #. Error message #: sabnzbd/misc.py msgid "Python script \"%s\" does not have execute (+x) permission set" msgstr "" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Series Sorting" msgstr "Sarjojen lajittelu" #: sabnzbd/misc.py msgid "Date Sorting" msgstr "Päivämäärän lajittelu" #: sabnzbd/misc.py, sabnzbd/skintext.py msgid "Movie Sorting" msgstr "" #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "Running script" msgstr "Ajetaan skripti" #: sabnzbd/newsunpack.py msgid "Unpack nesting too deep [%s]" msgstr "Purkaessa havaittiin liikaa pakkauskerroksia [%s]" #: sabnzbd/newsunpack.py msgid "Joining" msgstr "Yhdistetään" #: sabnzbd/newsunpack.py msgid "Incomplete sequence of joinable files" msgstr "Puutteellinen joukko yhdistettäviä tiedostoja" #: sabnzbd/newsunpack.py msgid "File join of %s failed" msgstr "Tiedostoliitos %s epäonnistui" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Virhe \"%s\" yhdistettäessä tiedostoja" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running file_join on %s" msgstr "Virhe \"%s\" ajettaessa file_join kohteelle %s" #: sabnzbd/newsunpack.py msgid "[%s] Joined %s files" msgstr "[%s] Liitetty %s tiedostoa" #: sabnzbd/newsunpack.py msgid "Unpacking failed, %s" msgstr "Purkaminen epäonnistui, %s" #: sabnzbd/newsunpack.py msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Virhe \"%s\" purettaessa RAR tiedostoja" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Virhe \"%s\" ajettaessa rar_unpack kohteelle %s" #. Warning message #: sabnzbd/newsunpack.py msgid "Deleting %s failed!" msgstr "Kohteen %s poisto epäonnistui!" #: sabnzbd/newsunpack.py msgid "Trying unrar with password \"%s\"" msgstr "Yritetään purkaa rar arkistoa salasanalla \"%s\"" #: sabnzbd/newsunpack.py msgid "Unpacking" msgstr "Puretaan" #: sabnzbd/newsunpack.py msgid "Unpacking failed, unable to find %s" msgstr "Purkaminen epäonnistui, %s ei löydy" #: sabnzbd/newsunpack.py msgid "Unpacking failed, CRC error" msgstr "Purkaminen epäonnistui, CRC virhe" #: sabnzbd/newsunpack.py msgid "Unpacking failed, file too large for filesystem (FAT?)" msgstr "" #: sabnzbd/newsunpack.py msgid "Unpacking failed, write error or disk is full?" msgstr "Purkaminen epäonnistui, kirjoitusvirhe tai levy täynnä?" #: sabnzbd/newsunpack.py msgid "Unpacking failed, path is too long" msgstr "Purkaminen epäonnistui, polku on liian pitkä" #: sabnzbd/newsunpack.py msgid "Unpacking failed, archive requires a password" msgstr "Purkaminen epäonnistui, arkisto vaatii salasanan" #: sabnzbd/newsunpack.py msgid "Unusable RAR file" msgstr "Käyttökelvoton RAR arkisto" #: sabnzbd/newsunpack.py msgid "Corrupt RAR file" msgstr "Korruptoitunut RAR arkisto" #: sabnzbd/newsunpack.py msgid "Trying 7zip with password \"%s\"" msgstr "Yritetään purkaa 7zip arkistoa salasanalla \"%s\"" #. Error message #: sabnzbd/newsunpack.py, sabnzbd/postproc.py msgid "see logfile" msgstr "katso lokitiedosto" #: sabnzbd/newsunpack.py msgid "Quick Checking" msgstr "Pikatarkistetaan" #. PP phase "repair" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Repair" msgstr "Korjaa" #: sabnzbd/newsunpack.py msgid "[%s] Quick Check OK" msgstr "[%s] Pikatarkistus OK" #: sabnzbd/newsunpack.py msgid "Starting Repair" msgstr "Aloitetaan korjaus" #: sabnzbd/newsunpack.py msgid "Repairing failed, %s" msgstr "Korjaus epäonnistui, %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error %s while running par2_repair on set %s" msgstr "Virhe %s ajettaessa par2_repair setille %s" #. Error message #: sabnzbd/newsunpack.py msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Virhe \"%s\" ajettaessa par2_repair setille %s" #: sabnzbd/newsunpack.py msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 vastaanotti vääränlaiset asetukset, tarkista Asetukset->Muuttujat" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Varmennettiin ajassa %s, kaikki tiedostot kelvollisia" #: sabnzbd/newsunpack.py msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Varmennetiin ajassa %s, vaatii korjauksen" #: sabnzbd/newsunpack.py msgid "Invalid par2 files or invalid PAR2 parameters, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py msgid "Fetching %s blocks..." msgstr "Noudetaan %s lohkoa..." #: sabnzbd/newsunpack.py msgid "Fetching" msgstr "Noudetaan" #: sabnzbd/newsunpack.py msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Korjaaminen epäonnistui, ei tarpeeksi korjauslohkoja (%s puuttuu)" #: sabnzbd/newsunpack.py msgid "Repairing" msgstr "Korjataan" #: sabnzbd/newsunpack.py msgid "[%s] Repaired in %s" msgstr "[%s] Korjattiin ajassa %s" #: sabnzbd/newsunpack.py msgid "Verifying repair" msgstr "" #. Notification #: sabnzbd/newsunpack.py, sabnzbd/notifier.py msgid "Disk full" msgstr "Levy täynnä" #: sabnzbd/newsunpack.py msgid "Checking extra files" msgstr "" #: sabnzbd/newsunpack.py msgid "Verifying" msgstr "Varmennetaan" #. PP status #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "Checking" msgstr "Tarkistetaan" #: sabnzbd/newsunpack.py msgid "Trying SFV verification" msgstr "Yritetään SFV varmennusta" #: sabnzbd/newsunpack.py, sabnzbd/skintext.py msgid "left" msgstr "jäljellä" #: sabnzbd/newswrapper.py msgid "This server does not allow SSL on this port" msgstr "Tämä palvelin ei salli SSL yhteyksiä tähän porttiin" #: sabnzbd/newswrapper.py msgid "" "Certificate hostname mismatch: the server hostname is not listed in the " "certificate. This is a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Certificate not valid. This is most probably a server issue." msgstr "" #: sabnzbd/newswrapper.py msgid "Server %s uses an untrusted certificate [%s]" msgstr "Palvelin %s käyttää epäluotettavaa sertifikaattia [%s]" #. Main menu item #: sabnzbd/newswrapper.py, sabnzbd/skintext.py msgid "Wiki" msgstr "Wiki" #: sabnzbd/newswrapper.py msgid "Failed to connect: %s %s@%s:%s (%s)" msgstr "" #. Notification #: sabnzbd/notifier.py msgid "Startup/Shutdown" msgstr "Käynnistys/Sammutus" #. Notification - Pause downloading - Four way switch for duplicates - #. Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Pause" msgstr "Keskeytä" #. Notification - Resume downloading - Config->Scheduling #: sabnzbd/notifier.py, sabnzbd/osxmenu.py, sabnzbd/sabtray.py, #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Resume" msgstr "Jatka" #. Notification - Config->RSS after adding to queue #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Added NZB" msgstr "Lisätty NZB" #: sabnzbd/notifier.py msgid "Post-processing started" msgstr "Jälkikäsittely aloitettu" #. Notification #: sabnzbd/notifier.py msgid "Job finished" msgstr "Lataus valmistunut" #. Notification #: sabnzbd/notifier.py msgid "Job failed" msgstr "Lataus epäonnistui" #. Notification #: sabnzbd/notifier.py, sabnzbd/postproc.py msgid "Queue finished" msgstr "Jono valmistunut" #. Notification #: sabnzbd/notifier.py msgid "Other Messages" msgstr "Muut viestit" #. Notification action #: sabnzbd/notifier.py msgid "Open folder" msgstr "" #. Notification action #: sabnzbd/notifier.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Open complete folder" msgstr "Avaa valmistuneet-kansio" #: sabnzbd/notifier.py, sabnzbd/skintext.py msgid "Not available" msgstr "Ei saatavilla" #: sabnzbd/notifier.py msgid "Failed to send macOS notification" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "Prowl viestin lähetys epäonnistui" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message - no URLs defined" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "One or more Apprise URLs could not be loaded." msgstr "" #: sabnzbd/notifier.py msgid "Failed to send one or more Apprise Notifications" msgstr "" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send Apprise message" msgstr "" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushover (%s): %s" msgstr "Virheellinen vastaus Pushoverilta (%s): %s" #. Error message - Warning message #: sabnzbd/notifier.py msgid "Failed to send pushover message" msgstr "Pushover viestin lähetys epäonnistui" #. Error message #: sabnzbd/notifier.py msgid "Bad response from Pushbullet (%s): %s" msgstr "Virheellinen vastaus Pushbulletilta (%s): %s" #. Warning message #: sabnzbd/notifier.py msgid "Failed to send pushbullet message" msgstr "Pushbullet viestin lähetys epäonnistui" #. Error message #: sabnzbd/notifier.py msgid "Script returned exit code %s and output \"%s\"" msgstr "Skripti palautti lopetuskoodin %s ja tulosteen \"%s\"" #: sabnzbd/notifier.py msgid "Notification script \"%s\" does not exist" msgstr "Ilmoitusskriptiä \"%s\" ei ole olemassa" #: sabnzbd/notifier.py msgid "Failed to send Windows notification" msgstr "Windows-ilmoituksen lähetys epäonnistui" #. Error message #: sabnzbd/nzbparser.py msgid "Cannot create temp file for %s" msgstr "Väliaikaistiedostoa ei voida luoda kohteelle %s" #. Error message #: sabnzbd/nzbparser.py msgid "Error while adding %s, removing" msgstr "Virhe lisättäessä %s, poistetaan" #. Error message #: sabnzbd/nzbparser.py msgid "Error removing %s" msgstr "Virhe poistettaessa %s" #. Warning message #: sabnzbd/nzbparser.py msgid "Failed to import %s files from %s" msgstr "Virhe tuotaessa %s tiedostoa kohteesta %s" #. Error message #: sabnzbd/nzbqueue.py msgid "Incompatible queuefile found, cannot proceed" msgstr "Ei-tuettu jonotiedosto löytyi, ei voida jatkaa" #. Error message #: sabnzbd/nzbqueue.py msgid "Error loading %s, corrupt file detected" msgstr "Virhe ladattaessa %s, korruptoitunut tiedosto havaittu" #: sabnzbd/nzbqueue.py msgid "NZB added to queue" msgstr "NZB lisätty jonoon" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ohitetaan kaksoiskappale NZB \"%s\"" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Failing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py msgid "Duplicate NZB" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Invalid NZB file %s, skipping (error: %s)" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py, sabnzbd/urlgrabber.py msgid "Empty NZB file %s" msgstr "Tyhjä NZB tiedosto %s" #: sabnzbd/nzbstuff.py msgid "Pre-queue script marked job as failed" msgstr "" #. Warning message #: sabnzbd/nzbstuff.py msgid "Unwanted Extension in file %s (%s)" msgstr "" #: sabnzbd/nzbstuff.py msgid "Aborted, cannot be completed" msgstr "Peruutettu, ei voi valmistua" #. Error message #: sabnzbd/nzbstuff.py msgid "Error importing %s" msgstr "Virhe tuotaessa %s" #: sabnzbd/nzbstuff.py msgid "DUPLICATE" msgstr "KAKSOISKAPPALE" #: sabnzbd/nzbstuff.py msgid "ALTERNATIVE" msgstr "" #: sabnzbd/nzbstuff.py msgid "ENCRYPTED" msgstr "SALATTU" #: sabnzbd/nzbstuff.py msgid "TOO LARGE" msgstr "LIIAN SUURI" #: sabnzbd/nzbstuff.py msgid "INCOMPLETE" msgstr "KESKENERÄINEN" #: sabnzbd/nzbstuff.py msgid "UNWANTED" msgstr "EI TOIVOTTU" #: sabnzbd/nzbstuff.py msgid "WAIT %s sec" msgstr "ODOTA %s sekuntia" #: sabnzbd/nzbstuff.py msgid "PROPAGATING %s min" msgstr "LEVITETÄÄN %s min" #: sabnzbd/nzbstuff.py msgid "Downloaded in %s at an average of %sB/s" msgstr "Ladattiin ajassa %s keskilatausnopeudella %sB/s" #. Job details page, file age column header #: sabnzbd/nzbstuff.py, sabnzbd/skintext.py msgid "Age" msgstr "Ikä" #: sabnzbd/nzbstuff.py msgid "%s articles were malformed" msgstr "%s artikkelia oli väärin muotoiltuja" #: sabnzbd/nzbstuff.py msgid "%s articles were missing" msgstr "%s artikkelia puuttui" #: sabnzbd/nzbstuff.py msgid "%s articles had non-matching duplicates" msgstr "%s artikkelissa oli ei-vastaavia kaksoiskappaleita" #: sabnzbd/nzbstuff.py msgid "Pausing duplicate NZB \"%s\"" msgstr "Keskeytetään kaksoiskappale NZB \"%s\"" #. Footer: indicator of warnings #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Warnings" msgstr "Varoitukset" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Idle" msgstr "Toimeton" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Queue" msgstr "Jono" #. Queue page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge Queue" msgstr "Tyhjennä jono" #. Main menu item #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "History" msgstr "Historia" #. History page button #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Purge History" msgstr "Tyhjennä historia" #: sabnzbd/osxmenu.py msgid "Limit Speed" msgstr "Nopeusrajoitus" #. One minute #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "min" msgstr "minuutti" #. #: Config->Scheduler #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Scan watched folder" msgstr "Tarkista vahdittu kansio" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Read all RSS feeds" msgstr "Lue kaikki RSS syötteet" #: sabnzbd/osxmenu.py msgid "Complete Folder" msgstr "Valmistuneet-kansio" #: sabnzbd/osxmenu.py msgid "Incomplete Folder" msgstr "Lataukset-kansio" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Troubleshoot" msgstr "Vianmääritys" #. Config->Scheduling #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, #: sabnzbd/skintext.py msgid "Restart" msgstr "Käynnistä uudelleen" #: sabnzbd/osxmenu.py, sabnzbd/sabtray.py msgid "Restart without login" msgstr "Käynnistä uudelleen ilman kirjautumista" #: sabnzbd/osxmenu.py msgid "Quit" msgstr "Lopeta" #: sabnzbd/osxmenu.py msgid "Queue First 10 Items" msgstr "Vie ensimmäiset 10 kohdetta jonoon" #: sabnzbd/osxmenu.py, sabnzbd/skintext.py msgid "Empty" msgstr "Tyhjä" #: sabnzbd/osxmenu.py msgid "History Last 10 Items" msgstr "Vie viimeiset 10 kohdetta historiaan" #: sabnzbd/osxmenu.py msgid "Go to wizard" msgstr "Mene velhoon" #: sabnzbd/osxmenu.py msgid "Stopping..." msgstr "Pysäytetään..." #: sabnzbd/panic.py msgid "Problem with" msgstr "Ongelma" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
\n" " Port %s on %s was tried , but it is not available.
\n" " Some other software uses the port or SABnzbd is already running.
\n" "
\n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
\n" " Porttia %s kohteessa %s yritettiin käyttää , mutta se ei ollut vapaana.
\n" " Jokin toinen ohjelmisto käyttää porttia tai SABnzbd on jo käynnissä.
\n" "
\n" " Ole hyvä ja uudelleenkäynnistä SABnzbd toisella porttinumerolla." #: sabnzbd/panic.py msgid "" "If you get this error message again, please try a different number.
" msgstr "Jos saat tämän virhesanoman uudestaan, kokeile toista numeroa.
" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
\n" " You have specified an invalid address.
\n" " Safe values are localhost and 0.0.0.0
\n" "
\n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
\n" " Olet määritellyt epäkelvon osoitteen.
\n" " Turvalliset arvot ovat localhost ja 0.0.0.0
\n" "
\n" " Ole hyvä ja uudelleenkäynnistä SABnzbd kunnollisella isäntäosoitteella." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
\n" " but cannot re-use the data of the other program.

\n" " You may want to finish your queue first with the other program.

\n" " After that, start this program with the \"--clean\" option.
\n" " This will erase the current queue and history!
\n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd havaitsi tallennettua tietoa toisesta SABnzbd versiosta
\n" " mutta ei voi uudelleenkäyttää tietoja toisesta ohjelmasta.

\n" " Haluat ehkä ladata jonon loppuun toisella ohjelmallasi.

\n" " Tämän jälkeen, käynnistä ohjelma \"--clean\" muuttujalla.
\n" " Tämä tyhjentää nykyisen jonon ja historiasi!
\n" " SABnzbd luki tiedostoa \"%s\"." #: sabnzbd/panic.py msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
\n" " Please install the program again.
\n" "
\n" msgstr "" "\n" " SABnzbd ei löydä sen web-käyttöliittymän tiedostoja polusta %s.
\n" " Ole hyvä ja asenna ohjelma uudelleen.
\n" "
\n" #: sabnzbd/panic.py msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd havaitsi vakavan virheen:" #: sabnzbd/panic.py msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

\n" " Some poorly designed virus-scanners remove this file.
\n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
\n" "
\n" msgstr "" "\n" " SABnzbd havaitsi, että tiedosto sqlite3.dll puuttuu.

\n" " Jotkin huonosti suunnitellut viruksentorjunta ohjelmistot poistavat tämän tiedoston.
\n" " Tarkista virustorjunta ohjelmistosi, yritä asentaa SABnzbd uudelleen ja valita virustorjunta ohjelmistosi valmistajalle.
\n" "
\n" #: sabnzbd/panic.py msgid "Press Startkey+R and type the line (example):" msgstr "Paina Windows-nappia+R ja kirjoita seuraava rivi (esimerkki):" #: sabnzbd/panic.py msgid "Open a Terminal window and type the line (example):" msgstr "Avaa pääte ja kirjoita rivi (esimerkki):" #: sabnzbd/panic.py msgid "Program did not start!" msgstr "Ohjelma ei käynnistynyt!" #: sabnzbd/panic.py msgid "Fatal error" msgstr "Vakava virhe" #: sabnzbd/panic.py msgid "" "Unable to bind to port %s on %s. Some other software uses the port or " "SABnzbd is already running." msgstr "" #. Warning message #: sabnzbd/panic.py msgid "Cannot launch the browser, probably not found" msgstr "Selainta ei voida käynnistää, todennäköisesti ei löydy" #: sabnzbd/panic.py msgid "Access denied" msgstr "Ei käyttöoikeutta" #: sabnzbd/panic.py msgid "Error %s: You need to provide a valid username and password." msgstr "Virhe %s: Syötä kelvollinen käyttäjänimi ja salasana." #. Warning message #: sabnzbd/postproc.py msgid "Old queue detected, use Status->Repair to convert the queue" msgstr "Vanhan version jono havaittiin, käytä Tila->Korjaa muuntaaksesi jonon" #. Error message #: sabnzbd/postproc.py msgid "Failed to compile regex for search term: %s" msgstr "Regex käännös epäonnistui hakutermille: %s" #. Warning message #: sabnzbd/postproc.py msgid "" "Completed Download Folder %s is on FAT file system, limiting maximum file " "size to 4GB" msgstr "" #: sabnzbd/postproc.py msgid "Download might fail, only %s of required %s available" msgstr "Lataaminen saattaa epäonnistua, vain %s osaa %s osasta saatavilla" #: sabnzbd/postproc.py msgid "Download failed - Not on your server(s)" msgstr "Lataus epäonnistui - Ei ole palvelimilla" #: sabnzbd/postproc.py msgid "Post-processing" msgstr "Jälkikäsittely" #: sabnzbd/postproc.py msgid "Moving" msgstr "Siirretään" #: sabnzbd/postproc.py msgid "Sent %s to queue" msgstr "Lähetettiin %s jonoon" #. Error message #: sabnzbd/postproc.py msgid "Error renaming \"%s\" to \"%s\"" msgstr "Virhe uudelleennimettäessä \"%s\" nimelle \"%s\"" #: sabnzbd/postproc.py msgid "Failed to move files" msgstr "Tiedostojen siirto epäonnistui" #: sabnzbd/postproc.py msgid "Running user script %s" msgstr "Ajetaan käyttäjän skripti %s" #: sabnzbd/postproc.py msgid "Script exit code is %s" msgstr "Skriptin lopetuskoodi on %s" #: sabnzbd/postproc.py msgid "Ran %s" msgstr "Ajettiin %s" #: sabnzbd/postproc.py, sabnzbd/skintext.py msgid "More" msgstr "Lisää" #. Error message #: sabnzbd/postproc.py msgid "Post Processing Failed for %s (%s)" msgstr "Jälkikäsittely epäonnistui kohteelle %s (%s)" #: sabnzbd/postproc.py msgid "Post-processing was aborted" msgstr "" #: sabnzbd/postproc.py msgid "Download Failed" msgstr "Lataus epäonnistui" #. Error message #: sabnzbd/postproc.py msgid "Cleanup of %s failed." msgstr "%s puhdistaminen epäonnistui." #: sabnzbd/postproc.py msgid "Download Completed" msgstr "Lataus valmistui" #. Error message #: sabnzbd/postproc.py msgid "Cannot create final folder %s" msgstr "Ei voitu luoda lopullista kansiota %s" #: sabnzbd/postproc.py msgid "[%s] No par2 sets" msgstr "[%s] Ei par2 arkistoja" #: sabnzbd/postproc.py msgid "Some files failed to verify against \"%s\"" msgstr "Jotkin tiedostot eivät varmentuneet \"%s\" kanssa" #: sabnzbd/postproc.py msgid "Verified successfully using SFV files" msgstr "Varmennettiin onnistuneesti SFV tiedostojen avulla." #: sabnzbd/postproc.py msgid "Trying RAR-based verification" msgstr "Yritetään RAR-pohjaista varmennusta" #: sabnzbd/postproc.py msgid "Passworded" msgstr "Salasanasuojattu" #: sabnzbd/postproc.py msgid "[%s] RAR-based verification failed: %s" msgstr "[%s] RAR-pohjainen varmennus epäonnistui: %s" #: sabnzbd/postproc.py msgid "RAR files verified successfully" msgstr "RAR arkistot varmennettiin onnistuneesti" #: sabnzbd/postproc.py msgid "RAR files failed to verify" msgstr "RAR arkistoja ei voitu varmentaa" #: sabnzbd/postproc.py msgid "Trying RAR renamer" msgstr "" #. Warning message #: sabnzbd/postproc.py msgid "No matching earlier rar file for %s" msgstr "" #. Error message #: sabnzbd/postproc.py msgid "Removing %s failed" msgstr "%s poistaminen epäonnistui" #. Error message #: sabnzbd/powersup.py msgid "Failed to hibernate system" msgstr "Järjestelmän lepotilaan laittaminen epäonnistui" #. Error message #: sabnzbd/powersup.py msgid "Failed to standby system" msgstr "Järjestelmän valmiustilaan laittaminen epäonnistui" #. Error message #: sabnzbd/powersup.py msgid "Error while shutting down system" msgstr "Virhe sammutettaessa järjestelmää" #. Error message #: sabnzbd/powersup.py msgid "Received a DBus exception %s" msgstr "" #. Error message #: sabnzbd/rss.py msgid "Incorrect RSS feed description \"%s\"" msgstr "Virheellinen RSS syötteen kuvaus \"%s\"" #: sabnzbd/rss.py msgid "Do not have valid authentication for feed %s" msgstr "Ei ole käyttöoikeutta syötteeseen %s" #: sabnzbd/rss.py msgid "Server side error (server code %s); could not get %s on %s" msgstr "Palvelinpään virhe (virhekoodi %s); ei voitu noutaa %s kohteesta %s" #: sabnzbd/rss.py msgid "Failed to retrieve RSS from %s: %s" msgstr "RSS noutaminen epäonnistui kohteesta %s: %s" #: sabnzbd/rss.py, sabnzbd/urlgrabber.py msgid "Server %s uses an untrusted HTTPS certificate" msgstr "Palvelin %s käyttää epäluotettavaa HTTPS sertifikaattia" #. Warning message #: sabnzbd/rss.py msgid "RSS Feed %s was empty" msgstr "RSS syöte %s oli tyhjä" #: sabnzbd/rss.py msgid "Incompatible feed" msgstr "Puutteellinen syöte" #. Warning message #: sabnzbd/rss.py msgid "Empty RSS entry found (%s)" msgstr "Tyhjä RSS kohde löytyi (%s)" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Show interface" msgstr "Näytä käyttöliittymä" #. Queue page button or entry box #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for" msgstr "Keskeytä ajaksi" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 5 minutes" msgstr "Keskeytä 5:ksi minuutiksi" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 15 minutes" msgstr "Keskeytä 15:ksi minuutiksi" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 30 minutes" msgstr "Keskeytä 30:ksi minuutiksi" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 1 hour" msgstr "Keskeytä tunniksi" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 3 hours" msgstr "Keskeytä 3:ksi tunniksi" #: sabnzbd/sabtray.py, sabnzbd/skintext.py msgid "Pause for 6 hours" msgstr "Keskeytä 6:ksi tunniksi" #. Config->Scheduling #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Shutdown" msgstr "Sammuta" #: sabnzbd/sabtray.py, sabnzbd/sabtraylinux.py msgid "Remaining" msgstr "Jäljellä" #: sabnzbd/sabtraylinux.py, sabnzbd/skintext.py msgid "Add NZB" msgstr "Lisää NZB" #. Warning message #: sabnzbd/scheduler.py msgid "Bad schedule %s at %s:%s" msgstr "Virheellinen ajastus %s kohteessa %s:%s" #. Warning message #: sabnzbd/scheduler.py msgid "Unknown action: %s" msgstr "Tuntematon toiminto: %s" #. Warning message #: sabnzbd/scheduler.py msgid "Schedule for non-existing server %s" msgstr "Ajastettu tuntemattomalle palvelimelle %s" #. Warning message #: sabnzbd/scheduler.py msgid "Trying to set status of non-existing server %s" msgstr "Yritettiin asettaa tila ei olemassa olevalle palvelimelle %s" #. Queue status "download" - Post processing pick list - Config->RSS button #. "download item" #: sabnzbd/skintext.py msgid "Download" msgstr "Lataa" #. PP phase "filejoin" #: sabnzbd/skintext.py msgid "Join files" msgstr "Yhdistä tiedostot" #. PP phase "unpack" #: sabnzbd/skintext.py msgid "Unpack" msgstr "Pura" #. PP phase "deobfuscate" #: sabnzbd/skintext.py msgid "Deobfuscate" msgstr "" #. PP phase "script" - Notification Script settings #: sabnzbd/skintext.py msgid "Script" msgstr "Skripti" #. PP RSS feed of the NZB - Main menu item #: sabnzbd/skintext.py msgid "RSS" msgstr "RSS" #. PP Source of the NZB (path or URL) - Where to find the SABnzbd sourcecode #: sabnzbd/skintext.py msgid "Source" msgstr "Lähde" #. PP Distribution over servers - Main menu item #: sabnzbd/skintext.py msgid "Servers" msgstr "Palvelimet" #. PP status #: sabnzbd/skintext.py msgid "Failed" msgstr "Epäonnistunut" #. Queue and PP status #: sabnzbd/skintext.py msgid "Waiting" msgstr "Odotetaan" #. PP status #: sabnzbd/skintext.py msgid "Repairing..." msgstr "Korjataan..." #. PP status #: sabnzbd/skintext.py msgid "Extracting..." msgstr "Puretaan..." #. PP status #: sabnzbd/skintext.py msgid "Moving..." msgstr "Siirretään..." #. PP status #: sabnzbd/skintext.py msgid "Running script..." msgstr "Ajetaan skripti..." #. PP status #: sabnzbd/skintext.py msgid "Fetching extra blocks..." msgstr "Noudetaan ylimääräiset lohkot..." #. PP status #: sabnzbd/skintext.py msgid "Quick Check..." msgstr "Pikatarkistus..." #. PP status #: sabnzbd/skintext.py msgid "Verifying..." msgstr "Varmennetaan..." #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "disable server" msgstr "poista palvelin käytöstä" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "enable server" msgstr "ota palvelin käyttöön" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Speedlimit" msgstr "Nopeusrajoitus" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause All" msgstr "Keskeytä kaikki" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Pause post-processing" msgstr "Keskeytä jälkikäsittely" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Resume post-processing" msgstr "Jatka jälkikäsittelyä" #. #: Config->Scheduler #: sabnzbd/skintext.py msgid "Read RSS feeds" msgstr "Lue RSS syötteet" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove failed jobs" msgstr "Poista epäonnistuneet lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Remove completed jobs" msgstr "Poista valmistuneet lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause low priority jobs" msgstr "Keskeytä alhaisen prioriteetin lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause normal priority jobs" msgstr "Keskeytä normaalin prioriteetin lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause high priority jobs" msgstr "Keskeytä korkean prioriteetin lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume low priority jobs" msgstr "Jatka alhaisen prioriteetin lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume normal priority jobs" msgstr "Jatka normaalin prioriteetin lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume high priority jobs" msgstr "Jatka korkean prioriteetin lataukset" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Enable quota management" msgstr "Ota latausrajoituksen hallinta käyttöön" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Disable quota management" msgstr "Ota latausrajoituksen hallinta pois käytöstä" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Pause jobs with category" msgstr "" #. Config->Scheduler #: sabnzbd/skintext.py msgid "Resume jobs with category" msgstr "" #. Prowl priority - Three way switch for duplicates #: sabnzbd/skintext.py msgid "Off" msgstr "Ei käytössä" #. Prowl priority #: sabnzbd/skintext.py msgid "Very Low" msgstr "Erittäin vähäinen" #. Prowl priority #: sabnzbd/skintext.py msgid "Moderate" msgstr "Kohtalainen" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Normal" msgstr "Normaali" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "High" msgstr "Korkea" #. Prowl priority #: sabnzbd/skintext.py msgid "Emergency" msgstr "Hälytys" #. Prowl priority - Priority pick list #: sabnzbd/skintext.py msgid "Low" msgstr "Matala" #. One hour #: sabnzbd/skintext.py msgid "hour" msgstr "tunti" #. Multiple hours #: sabnzbd/skintext.py msgid "hours" msgstr "tuntia" #. Multiple minutes #: sabnzbd/skintext.py msgid "mins" msgstr "minuuttia" #. One second #: sabnzbd/skintext.py msgid "sec" msgstr "sekunti" #. Multiple seconds #: sabnzbd/skintext.py msgid "seconds" msgstr "sekuntia" #: sabnzbd/skintext.py msgid "day" msgstr "päivä" #: sabnzbd/skintext.py msgid "days" msgstr "päivää" #: sabnzbd/skintext.py msgid "week" msgstr "viikko" #: sabnzbd/skintext.py msgid "Month" msgstr "Kuukausi" #: sabnzbd/skintext.py msgid "Year" msgstr "Vuosi" #: sabnzbd/skintext.py msgid "Day of month" msgstr "Kuukauden päivä" #: sabnzbd/skintext.py msgid "This week" msgstr "Tällä viikolla" #: sabnzbd/skintext.py msgid "This month" msgstr "Tässä kuussa" #: sabnzbd/skintext.py msgid "Selected date range" msgstr "" #: sabnzbd/skintext.py msgid "Today" msgstr "Tänään" #: sabnzbd/skintext.py msgid "Total" msgstr "Yhteensä" #: sabnzbd/skintext.py msgid "on" msgstr "käytössä" #. Config: startup parameters of SABnzbd - Notification Script settings #: sabnzbd/skintext.py msgid "Parameters" msgstr "Parametrit" #: sabnzbd/skintext.py msgid "Python Version" msgstr "Python versio" #. Home page of the SABnzbd project #: sabnzbd/skintext.py msgid "Home page" msgstr "Kotisivu" #: sabnzbd/skintext.py msgid "or" msgstr "tai" #. Server hostname or IP #: sabnzbd/skintext.py msgid "Host" msgstr "Isäntä" #: sabnzbd/skintext.py msgid "Cancel" msgstr "Peruuta" #: sabnzbd/skintext.py msgid "Log in" msgstr "Kirjaudu sisään" #: sabnzbd/skintext.py msgid "Log out" msgstr "Kirjaudu ulos" #: sabnzbd/skintext.py msgid "Remember me" msgstr "Muista minut" #. "Save" button #: sabnzbd/skintext.py msgid "Save" msgstr "Tallenna" #: sabnzbd/skintext.py msgid "Saving.." msgstr "Tallennetaan..." #. Used in confirmation popups #: sabnzbd/skintext.py msgid "Are you sure?" msgstr "Oletko varma?" #. Main menu item #: sabnzbd/skintext.py msgid "Home" msgstr "Alkuun" #. Main menu item #: sabnzbd/skintext.py msgid "Config" msgstr "Asetukset" #. Main menu item - History table header #: sabnzbd/skintext.py msgid "Status" msgstr "Tila" #. Main menu item #: sabnzbd/skintext.py msgid "Help" msgstr "Ohje" #. Main menu item #: sabnzbd/skintext.py msgid "Forum" msgstr "Foorumi" #. Main menu item #: sabnzbd/skintext.py msgid "Live Chat" msgstr "" #. Main menu item #: sabnzbd/skintext.py msgid "Issues" msgstr "Ongelmat" #. Main menu item #: sabnzbd/skintext.py msgid "Support the project, Donate!" msgstr "Tue projektia, lahjoita!" #. Main menu item #: sabnzbd/skintext.py msgid "General" msgstr "Yleiset" #. Main menu item #: sabnzbd/skintext.py msgid "Folders" msgstr "Kansiot" #. Main menu item #: sabnzbd/skintext.py msgid "Switches" msgstr "Muuttujat" #. Main menu item #: sabnzbd/skintext.py msgid "Scheduling" msgstr "Ajastus" #. Main menu item #: sabnzbd/skintext.py msgid "Notifications" msgstr "Ilmoitukset" #. Main menu item #: sabnzbd/skintext.py msgid "Email" msgstr "Sähköposti" #. Main menu item #: sabnzbd/skintext.py msgid "Categories" msgstr "Kategoriat" #. Main menu item #: sabnzbd/skintext.py msgid "Sorting" msgstr "Lajittelu" #. Main menu item #: sabnzbd/skintext.py msgid "Special" msgstr "Erikoisasetukset" #. Main menu item #: sabnzbd/skintext.py msgid "Search" msgstr "Etsi" #: sabnzbd/skintext.py msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Oletko varma, että haluat sammuttaa SABnzbdn?" #. Add NZB to queue (button) - Add NZB to queue (header) #: sabnzbd/skintext.py msgid "Add" msgstr "Lisää" #. Job category #: sabnzbd/skintext.py msgid "Category" msgstr "Kategoria" #. Server priority #: sabnzbd/skintext.py msgid "Priority" msgstr "Prioriteetti" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Repair" msgstr "+Korjaa" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Unpack" msgstr "+Pura" #. Post processing pick list #: sabnzbd/skintext.py msgid "+Delete" msgstr "+Poista" #. Priority pick list #: sabnzbd/skintext.py msgid "Force" msgstr "Pakota" #. Priority pick list #: sabnzbd/skintext.py msgid "Stop" msgstr "Pysäytä" #. Add NZB Dialog #: sabnzbd/skintext.py msgid "Enter URL" msgstr "Syötä osoite" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown PC" msgstr "Sammuta tietokone" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Standby PC" msgstr "Lepotila" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Hibernate PC" msgstr "Horrostila" #. Queue page end-of-queue action #: sabnzbd/skintext.py msgid "Shutdown SABnzbd" msgstr "Sammuta SABnzbd" #. Queue page table column header #: sabnzbd/skintext.py msgid "Processing" msgstr "Käsitellään" #. Queue page table column header #: sabnzbd/skintext.py msgid "Name" msgstr "Nimi" #. Queue page button #: sabnzbd/skintext.py msgid "Retry" msgstr "Yritä uudelleen" #. Queue page table, script selection menu #: sabnzbd/skintext.py msgid "Scripts" msgstr "Skriptit" #. Confirmation popup #: sabnzbd/skintext.py msgid "Delete all items from the queue?" msgstr "Poistetaanko kaikki kohteet jonosta?" #. Delete confirmation popup #: sabnzbd/skintext.py msgid "Are you sure you want to remove these jobs?" msgstr "" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs" msgstr "Puhdista NZBt" #. Queue page button #: sabnzbd/skintext.py msgid "Purge NZBs & Delete Files" msgstr "Puhdista NZBt & poista tiedostot" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB" msgstr "Poista NZB" #. Queue page button #: sabnzbd/skintext.py msgid "Remove NZB & Delete Files" msgstr "Poista NZB ja tiedostot" #. Checkbox if job should be added to Archive #: sabnzbd/skintext.py msgid "Permanently delete (skip archive)" msgstr "" #. Caption for missing articles in Queue #: sabnzbd/skintext.py msgid "Missing articles" msgstr "Puuttuvat artikkelit" #. Remaining quota (displayed in Queue) #: sabnzbd/skintext.py msgid "Quota left" msgstr "Latausrajoitusta jäljellä" #. Manual reset of quota #: sabnzbd/skintext.py msgid "manual" msgstr "käsikäyttöinen" #: sabnzbd/skintext.py msgid "Reset Quota now" msgstr "Resetoi latausrajoitus nyt" #: sabnzbd/skintext.py msgid "Archive" msgstr "" #. Button/link hiding History job details #: sabnzbd/skintext.py msgid "Hide details" msgstr "Piilota yksityiskohdat" #. Button/link showing History job details #: sabnzbd/skintext.py msgid "Show details" msgstr "Näytä yksityiskohdat" #. Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! #: sabnzbd/skintext.py msgid "Show Failed" msgstr "Näytä epäonnistuneet" #. Button or link showing all History jobs #: sabnzbd/skintext.py msgid "Show All" msgstr "Näytä kaikki" #. Button showing all archived jobs #: sabnzbd/skintext.py msgid "Show Archive" msgstr "" #. History table header - Size of the download quota #: sabnzbd/skintext.py msgid "Size" msgstr "Koko" #. Button to delete all failed jobs in History #: sabnzbd/skintext.py msgid "Purge Failed NZBs" msgstr "Puhdista epäonnistuneet NZBt" #: sabnzbd/skintext.py msgid "Purge Failed NZBs & Delete Files" msgstr "Puhdista epäonnistuneet NZBt & poista tiedostot" #. Button to delete all completed jobs in History #: sabnzbd/skintext.py msgid "Purge Completed NZBs" msgstr "Puhdista valmistuneet NZBt" #. Button to delete jobs on current page in History #: sabnzbd/skintext.py msgid "Purge NZBs on the current page" msgstr "Puhdista NZBt nykyiseltä sivulta" #. Button to add NZB to failed job in History #: sabnzbd/skintext.py msgid "Optional Supplemental NZB" msgstr "Vaihtoehtoinen täyte-NZB" #. Path as displayed in History details #: sabnzbd/skintext.py msgid "Path" msgstr "Polku" #. Retry all failed jobs in History #: sabnzbd/skintext.py msgid "Retry all failed jobs" msgstr "Yritä uudelleen kaikki epäonnistuneet lataukset" #. Status page button #: sabnzbd/skintext.py msgid "Force Disconnect" msgstr "Pakota yhteyden katkaisu" #: sabnzbd/skintext.py msgid "" "Disconnect all active connections to usenet servers. Connections will be " "reopened after a few seconds if there are items in the queue." msgstr "" #: sabnzbd/skintext.py msgid "This will send a test email to your account." msgstr "Tämä lähettää testiviestin sähköpostiosoitteeseesi." #. Status page button #: sabnzbd/skintext.py msgid "Show Logging" msgstr "Näytä loki" #. Status page button #: sabnzbd/skintext.py msgid "Test Email" msgstr "Testaa sähköpostia" #. Status page selection menu #: sabnzbd/skintext.py msgid "Logging" msgstr "Lokiinkirjaus" #. Status page table header #: sabnzbd/skintext.py msgid "Errors/Warning" msgstr "Virheet/varoitukset" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Info" msgstr "+ Tiedot" #. Status page logging selection value #: sabnzbd/skintext.py msgid "+ Debug" msgstr "+ Debug" #. Status page tab header - Server: amount of connections #: sabnzbd/skintext.py msgid "Connections" msgstr "Yhteydet" #. Status page, article identifier #: sabnzbd/skintext.py msgid "Article identifier" msgstr "Artikkelin tunniste" #. Status page, par-set that article belongs to #: sabnzbd/skintext.py msgid "File set" msgstr "Tiedostojoukko" #. Status page, indicator that server is enabled #: sabnzbd/skintext.py msgid "Enabled" msgstr "Käytössä" #: sabnzbd/skintext.py msgid "Connection failed!" msgstr "Yhteys epäonnistui!" #: sabnzbd/skintext.py msgid "Local IPv4 address" msgstr "Paikallinen IPv4 osoite" #: sabnzbd/skintext.py msgid "Public IPv4 address" msgstr "Julkinen IPv4 osoite" #: sabnzbd/skintext.py msgid "IPv6 address" msgstr "IPv6 osoite" #: sabnzbd/skintext.py msgid "Nameserver / DNS Lookup" msgstr "Nimipalvelin / DNS-selvitys" #: sabnzbd/skintext.py msgid "Download speed limited by" msgstr "" #: sabnzbd/skintext.py msgid "Disk speed" msgstr "" #: sabnzbd/skintext.py msgid "System load" msgstr "" #. Do not translate Pystone #: sabnzbd/skintext.py msgid "System Performance (Pystone)" msgstr "Järjestelmän suorituskyky (Pystone)" #: sabnzbd/skintext.py msgid "Download folder speed" msgstr "Latauskansion nopeus" #: sabnzbd/skintext.py msgid "Complete folder speed" msgstr "Valmistuneet-kansion nopeus" #: sabnzbd/skintext.py msgid "Internet Bandwidth" msgstr "" #: sabnzbd/skintext.py msgid "Repeat test" msgstr "Toista testi" #: sabnzbd/skintext.py msgid "Test download" msgstr "" #: sabnzbd/skintext.py msgid "" "Adds a verified test NZB of the specified size, filled with random data. Can" " be used to verify your setup." msgstr "" #: sabnzbd/skintext.py msgid "Config File" msgstr "Asetustiedosto" #. Main config page, how much cache is in use #: sabnzbd/skintext.py msgid "Used cache" msgstr "Käytetty välimuisti" #: sabnzbd/skintext.py msgid "" "This will restart SABnzbd.
Use it when you think the program has a " "stability problem.
Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Tämä uudelleenkäynnistää SABnzbdn.
Käytä sitä kun luulet ohjelman " "toimivan epävakaasti.
Lataaminen keskeytyy uudelleenkäynnistyksen " "ajaksi ja jatkuu ohjelman käynnistyttyä." #: sabnzbd/skintext.py msgid "
If authentication is enabled, you will need to login again." msgstr "" "
Jos tunnistautuminen on käytössä, sinun täytyy kirjautua sisään " "uudestaan." #: sabnzbd/skintext.py msgid "Advanced" msgstr "" #: sabnzbd/skintext.py msgid "" "There are orphaned jobs in the download folder.
You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Latauskansiossa on orpoja latauksia.
Voit valita niiden poistamisen " "(sisältäen tiedostot) tai voit lähettää ne takaisin jonoon." #: sabnzbd/skintext.py msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
reconstruction of the queue content, preserving already downloaded " "files.
This will modify the queue order." msgstr "" "\"Korjaa\" painike käynnistää SABnzbd uudelleen ja luo jonon
sisällön " "täydellisesti uudelleen, säilyttäen jo ladatut tiedostot.
Tämä muuttaa " "jonon järjestystä." #: sabnzbd/skintext.py msgid "Changes have not been saved, and will be lost." msgstr "Muutoksia ei ole tallennettu ja ne menetetään." #: sabnzbd/skintext.py msgid "" "When your IP address changes or SABnzbd is restarted the session will " "expire." msgstr "" "Istunto vanhenee kun IP-osoite vaihtuu tai SABnzbd käynnistetään uudelleen." #: sabnzbd/skintext.py msgid "Enable 7zip" msgstr "7zip käytössä" #: sabnzbd/skintext.py msgid "" "Speed up repairs by installing par2cmdline-turbo, it is available for many " "platforms." msgstr "" #: sabnzbd/skintext.py msgid "Version" msgstr "Versio" #: sabnzbd/skintext.py msgid "Uptime" msgstr "Käynnissäoloaika" #. Indicates that server is Backup server in Status page #: sabnzbd/skintext.py msgid "Backup" msgstr "Varmuuskopioi" #: sabnzbd/skintext.py msgid "Read the Wiki Help on this!" msgstr "Lue Wikin ohjeet tähän!" #: sabnzbd/skintext.py msgid "Restarting SABnzbd..." msgstr "Käynnistetään SABnzbd uudelleen..." #: sabnzbd/skintext.py msgid "Changes will require a SABnzbd restart!" msgstr "Muutokset vaativat SABnzbdn uudelleenkäynnistyksen!" #: sabnzbd/skintext.py msgid "SABnzbd Web Server" msgstr "SABnzbd web-palvelin" #: sabnzbd/skintext.py msgid "SABnzbd Host" msgstr "SABnzbd isäntä" #: sabnzbd/skintext.py msgid "Host SABnzbd should listen on." msgstr "Osoite jota SABnzbdn tulisi kuunnella." #: sabnzbd/skintext.py msgid "SABnzbd Port" msgstr "SABnzbd portti" #: sabnzbd/skintext.py msgid "Port SABnzbd should listen on." msgstr "Portti jota SABnzbdn tulisi kuunnella." #: sabnzbd/skintext.py msgid "Web Interface Theme" msgstr "" #: sabnzbd/skintext.py msgid "Choose a theme." msgstr "" #: sabnzbd/skintext.py msgid "SABnzbd Username" msgstr "SABnzbd käyttäjänimi" #: sabnzbd/skintext.py msgid "Optional authentication username." msgstr "Vaihtoehtoinen käyttäjänimi todennukseen." #: sabnzbd/skintext.py msgid "SABnzbd Password" msgstr "SABnzbd salasana" #: sabnzbd/skintext.py msgid "Optional authentication password." msgstr "Vaihtoehtoinen salasana todennukseen." #: sabnzbd/skintext.py msgid "" "If the SABnzbd Host or Port is exposed to the internet, your current " "settings allow full external access to the SABnzbd interface." msgstr "" #: sabnzbd/skintext.py msgid "Security" msgstr "" #: sabnzbd/skintext.py msgid "Enable HTTPS" msgstr "HTTPS käytössä" #: sabnzbd/skintext.py msgid "Enable accessing the interface from a HTTPS address." msgstr "Ota käyttöön käyttöliittymän käyttäminen HTTPS-osoitteesta." #: sabnzbd/skintext.py msgid "" "Modern web browsers and other clients will not accept self-signed " "certificates and will give a warning and/or won't connect at all." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS Port" msgstr "HTTPS portti" #: sabnzbd/skintext.py msgid "If empty, the standard port will only listen to HTTPS." msgstr "Jos tyhjä, oletusportti kuuntelee ainoastaan HTTPS." #: sabnzbd/skintext.py msgid "HTTPS Certificate" msgstr "HTTPS sertifikaatti" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Certificate." msgstr "Tiedostonimi tai polku HTTPS sertifikaattiin." #: sabnzbd/skintext.py msgid "" "Generate new self-signed certificate and key. Requires SABnzbd restart!" msgstr "" "Luo uusi itse allekirjoitettu sertifikaatti ja avain. Vaatii SABnzbd " "uudelleenkäynnistyksen!" #: sabnzbd/skintext.py msgid "HTTPS Key" msgstr "HTTPS avain" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Key." msgstr "Tiedostonimi tai polku HTTPS avaimeen." #: sabnzbd/skintext.py msgid "HTTPS Chain Certifcates" msgstr "HTTPS ketjun sertifikaatit" #: sabnzbd/skintext.py msgid "File name or path to HTTPS Chain." msgstr "Tiedostonimi tai polku HTTPS ketjuun." #: sabnzbd/skintext.py msgid "Tuning" msgstr "Hienosäätö" #: sabnzbd/skintext.py msgid "RSS Checking Interval" msgstr "RSS tarkistusväli" #: sabnzbd/skintext.py msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Tarkistusväli (minuutteina, vähintään 15). Ei ole aktiivinen jos käytät " "Ajastinta!" #: sabnzbd/skintext.py msgid "Maximum line speed" msgstr "Suurin latausnopeus" #: sabnzbd/skintext.py msgid "Percentage of line speed" msgstr "Latausnopeuden prosenttiosuus" #: sabnzbd/skintext.py msgid "Which percentage of the linespeed should SABnzbd use, e.g. 50" msgstr "" "Kuinka monta prosenttia latausnopeudesta SABnzbd saa käyttää, esim. 50" #: sabnzbd/skintext.py msgid "Article Cache Limit" msgstr "Välimuistirajoitus artikkeleille" #: sabnzbd/skintext.py msgid "" "Cache articles in memory to reduce disk access.
In bytes, optionally" " follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Välimuistita artikkelit muistissa levytapahtumien vähentämiseksi.
Tavuina, vaihtoehtoisesti lisää pääte K,M,G. Esimerkiksi: \"64M\" tai " "\"128M\"" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Create backup" msgstr "" #: sabnzbd/skintext.py msgid "" "Create a backup of the configuration file and databases in the Backup " "Folder.
If the Backup Folder is not set, the backup will be created in " "the Completed Download Folder.
Recurring backups can be configured on the" " Scheduling page." msgstr "" #: sabnzbd/skintext.py msgid "Cleanup List" msgstr "Puhdistuslista" #: sabnzbd/skintext.py msgid "" "List of file extensions that should be deleted after download.
For " "example: nfo or nfo, sfv" msgstr "" "Lista tiedostopäätteistä jotka poistetaan latauksen valmistuttua.
Esimerkiksi: nfo tai nfo, sfv" #: sabnzbd/skintext.py msgid "History Retention" msgstr "" #: sabnzbd/skintext.py msgid "Keep all jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Move jobs to the archive if the history exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs if the history and archive exceeds specified number of jobs" msgstr "" #: sabnzbd/skintext.py msgid "Move jobs to the archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "" "Delete jobs from the history and archive after specified number of days" msgstr "" #: sabnzbd/skintext.py msgid "Move all completed jobs to archive" msgstr "" #: sabnzbd/skintext.py msgid "Delete all completed jobs" msgstr "" #: sabnzbd/skintext.py msgid "Jobs" msgstr "" #: sabnzbd/skintext.py msgid "Save Changes" msgstr "Tallenna muutokset" #: sabnzbd/skintext.py msgid "Restore Defaults" msgstr "Palauta oletusasetukset" #: sabnzbd/skintext.py msgid "Reset" msgstr "Nollaa" #: sabnzbd/skintext.py msgid "Language" msgstr "Kieli" #: sabnzbd/skintext.py msgid "Select a web interface language." msgstr "Valitse web-käyttöliittymän kieli." #: sabnzbd/skintext.py msgid "" "Help us translate SABnzbd in your language!
Add untranslated texts or " "improved existing translations here:" msgstr "" "Auta meitä kääntämään SABnzbd sinun kielellesi!
Käännä tai muokkaa " "olemassaolevia käännöksiä täällä:" #: sabnzbd/skintext.py msgid "API Key" msgstr "API avain" #: sabnzbd/skintext.py msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Tämä avain antaa kolmannen osapuolen ohjelmille täyden pääsyn SABnzbd-" "ohjelmaan." #: sabnzbd/skintext.py msgid "NZB Key" msgstr "NZB avain" #: sabnzbd/skintext.py msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Tämä avain antaa kolmannen osapuolen ohjelmille oikeudet lisätä NZB-" "tiedostoja SABnzbd-ohjelmaan." #: sabnzbd/skintext.py msgid "Generate New Key" msgstr "Luo uusi avain" #. Explanation for QR code of APIKEY #: sabnzbd/skintext.py msgid "API Key QR Code" msgstr "API avaimen QR-koodi" #: sabnzbd/skintext.py msgid "External internet access" msgstr "Ulkoinen ohjelman käyttö" #: sabnzbd/skintext.py msgid "You can set access rights for systems outside your local network." msgstr "" #: sabnzbd/skintext.py msgid "No access" msgstr "Ei pääsyä" #: sabnzbd/skintext.py msgid "Add NZB files " msgstr "Lisää NZB tiedostot " #: sabnzbd/skintext.py msgid "API (no Config)" msgstr "API (ei asetuksia)" #: sabnzbd/skintext.py msgid "Full API" msgstr "Täysi API" #: sabnzbd/skintext.py msgid "Full Web interface" msgstr "Täysi Web-käyttöliittymä" #: sabnzbd/skintext.py msgid "Only external access requires login" msgstr "Vain ulkoinen käyttö vaatii kirjautumisen" #: sabnzbd/skintext.py msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "HUOM: Kansiot luodaan automaattisesti tallennuksen yhteydessä. Voit" " käyttää täydellisiä polkuja jos haluat tallentaa oletuskansioiden " "ulkopuolelle." #: sabnzbd/skintext.py msgid "User Folders" msgstr "Käyttäjähakemistot" #: sabnzbd/skintext.py msgid "Browse" msgstr "Selaa" #: sabnzbd/skintext.py msgid "Temporary Download Folder" msgstr "Väliaikaiset lataukset kansio" #: sabnzbd/skintext.py msgid "" "Location to store unprocessed downloads.
Can only be changed when " "queue is empty." msgstr "" "Sijainti jonne tallennetaan latauksessa olevat kohteet ennen käsittelyä.
Voidaan muuttaa vain kun jono on tyhjä." #: sabnzbd/skintext.py msgid "Minimum Free Space for Temporary Download Folder" msgstr "Pienin vapaan tilan määrä väliaikaisille latauksille" #: sabnzbd/skintext.py msgid "" "Auto-pause when free space is beneath this value.
In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Keskeytä automaattisesti kun vapaan tilan määrä on vähemmän kuin tämä " "arvo.
Tavuina, mutta voit laittaa perään K,M,G,T kirjaimen. " "Esimerkiksi: \"800M\" tai \"8G\"" #: sabnzbd/skintext.py msgid "Completed Download Folder" msgstr "Valmistuneet kansio" #: sabnzbd/skintext.py msgid "" "Location to store finished, fully processed downloads.
Can be " "overruled by user-defined categories." msgstr "" "Sijainti jonne tallennetaan valmistuneet ja täysin käsitellyt ladatut " "kohteet.
Käyttäjän asettamat kategoriat voivat kumota tämän." #: sabnzbd/skintext.py msgid "" "Use Sorting to automatically organize and rename your completed downloads." msgstr "" #: sabnzbd/skintext.py msgid "Minimum Free Space for Completed Download Folder" msgstr "" #: sabnzbd/skintext.py msgid "Will not work if a category folder is on a different disk." msgstr "" #. Auto-resume download on the reset day #: sabnzbd/skintext.py msgid "Auto resume" msgstr "Jatka automaattisesti" #: sabnzbd/skintext.py msgid "" "Downloading will automatically resume if the minimum free space is available" " again.
Applies to both the Temporary and Complete Download Folder.
Checked every few minutes." msgstr "" #: sabnzbd/skintext.py msgid "Permissions for completed downloads" msgstr "Käyttöoikeudet valmistuneille latauksille" #: sabnzbd/skintext.py msgid "" "Set permissions pattern for completed files/folders.
In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Aseta käyttöoikeusmalli valmistuneille tiedostoille/kansioille.
Oktaalilukuna. Esimerkiksi: \"755\" tai \"777\"" #: sabnzbd/skintext.py msgid "Watched Folder" msgstr "Vahdittu kansio" #: sabnzbd/skintext.py msgid "Folder to monitor for .nzb files." msgstr "Kansio jota vahditaan .nzb tiedostojen varalta." #: sabnzbd/skintext.py msgid "Watched Folder Scan Speed" msgstr "Vahditun kansion tarkistusväli" #: sabnzbd/skintext.py msgid "Number of seconds between scans for .nzb files." msgstr "Skannausväli sekunteina .nzb tiedostoille." #: sabnzbd/skintext.py msgid "Scripts Folder" msgstr "" #: sabnzbd/skintext.py msgid "Folder containing user scripts." msgstr "" #: sabnzbd/skintext.py msgid "Email Templates Folder" msgstr "Sähköpostipohjien kansio" #: sabnzbd/skintext.py msgid "Folder containing user-defined email templates." msgstr "Kansio joka sisältää käyttäjän luomat sähköpostipohjat." #: sabnzbd/skintext.py msgid "Password file" msgstr "Salasanatiedosto" #: sabnzbd/skintext.py msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Tiedosto joka sisältää kaikki salasanat joita kokeillaan salattuihin RAR " "tiedostoihin." #: sabnzbd/skintext.py msgid "System Folders" msgstr "Järjestelmäkansio" #: sabnzbd/skintext.py msgid "Hidden Folders" msgstr "" #: sabnzbd/skintext.py msgid "Administrative Folder" msgstr "Hallinnollinen kansio" #: sabnzbd/skintext.py msgid "" "Location for queue admin and history database.
Can only be changed " "when queue is empty." msgstr "" "Sijainti jonne tallennetaan jonon hallinnan ja historian tietokannat.
Voidaan muuttaa vain jonon ollessa tyhjä." #: sabnzbd/skintext.py msgid "Backup Folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Location where the backups of the configuration file and databases are " "stored.
If left empty, the backup will be created in the Completed " "Download Folder." msgstr "" #: sabnzbd/skintext.py msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Tiedostoja ei tulla siirtämään. Vaatii SABnzbd " "uudelleenkäynnistyksen!" #: sabnzbd/skintext.py msgid "Log Folder" msgstr "Lokikansio" #: sabnzbd/skintext.py msgid "" "Location of log files for SABnzbd.
Requires SABnzbd restart!" msgstr "" "Sijainti jonne SABnzbd ohjelman lokitiedostot tallennetaan.
Vaatii " "SABnzbd uudelleenkäynnistyksen!" #: sabnzbd/skintext.py msgid "Purge Logs" msgstr "" #: sabnzbd/skintext.py msgid ".nzb Backup Folder" msgstr ".nzb varmuuskopiokansio" #: sabnzbd/skintext.py msgid "Location where .nzb files will be stored." msgstr "Sijainti jonne .nzb tiedostot tallennetaan." #: sabnzbd/skintext.py msgid "Default Base Folder" msgstr "Oletuskansio" #: sabnzbd/skintext.py msgid "Download all par2 files" msgstr "Lataa kaikki par2 tiedostot" #: sabnzbd/skintext.py msgid "" "This prevents multiple repair runs by downloading all par2 files when " "needed." msgstr "" #: sabnzbd/skintext.py msgid "Enable recursive unpacking" msgstr "Rekursiivinen purkaminen käytössä" #: sabnzbd/skintext.py msgid "Unpack archives (rar, zip, 7z) within archives." msgstr "Purkaa arkistot (rar, zip, 7z) arkistojen sisältä." #: sabnzbd/skintext.py msgid "Ignore any folders inside archives" msgstr "Ohita kansiot arkistojen sisällä" #: sabnzbd/skintext.py msgid "All files will go into a single folder." msgstr "Kaikki tiedostot menevät yhteen kansioon." #: sabnzbd/skintext.py msgid "Only Get Articles for Top of Queue" msgstr "Hae artikkelit vain jonon huipulta" #: sabnzbd/skintext.py msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the" " queue." msgstr "" "Laita päälle jos haluat ohjelman käyttävän vähemmän muistia. Ota pois päältä" " jos haluat estää hitaiden latauksien aiheuttavan ruuhkaa jonossa." #: sabnzbd/skintext.py msgid "Post-Process Only Verified Jobs" msgstr "Jälkikäsittele vain onnistuneet lataukset" #: sabnzbd/skintext.py msgid "" "Only unpack and run scripts on jobs that passed the verification stage. If " "turned off, all jobs will be marked as Completed even if they are " "incomplete." msgstr "" #: sabnzbd/skintext.py msgid "Action when encrypted RAR is downloaded" msgstr "Toiminto kun salattu RAR havaitaan" #: sabnzbd/skintext.py msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Jos valitsit \"Keskeytä\", sinun täytyy antaa salasana ja jatkaa sen jälkeen" " lataamista." #: sabnzbd/skintext.py msgid "Identical download detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect identical downloads based on name or NZB contents." msgstr "" #: sabnzbd/skintext.py msgid "Smart duplicate detection" msgstr "" #: sabnzbd/skintext.py msgid "Detect duplicates based on analysis of the filename." msgstr "" #: sabnzbd/skintext.py msgid "Allow proper releases" msgstr "" #: sabnzbd/skintext.py msgid "" "Bypass smart duplicate detection if PROPER, REAL or REPACK is detected in " "the download name." msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Discard" msgstr "Hylkää" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Tag job" msgstr "" #. Four way switch for duplicates #: sabnzbd/skintext.py msgid "Fail job (move to History)" msgstr "" #: sabnzbd/skintext.py msgid "Abort post-processing" msgstr "" #: sabnzbd/skintext.py msgid "Action when unwanted extension detected" msgstr "Toiminto kun havaitaan ei toivottu tiedostopääte" #: sabnzbd/skintext.py msgid "Action when an unwanted extension is detected" msgstr "" #: sabnzbd/skintext.py msgid "Unwanted extensions" msgstr "Ei toivotut tiedostopäätteet" #: sabnzbd/skintext.py msgid "Blacklist" msgstr "" #: sabnzbd/skintext.py msgid "Whitelist" msgstr "" #: sabnzbd/skintext.py msgid "" "Select a mode and list all (un)wanted extensions. For example: exe or" " exe, com" msgstr "" #: sabnzbd/skintext.py msgid "Enable SFV-based checks" msgstr "SFV-pohjaiset tarkistukset käytössä" #: sabnzbd/skintext.py msgid "Do an extra verification based on SFV files." msgstr "Suorittaa ylimääräisen varmennuksen SFV tiedostojen avulla." #: sabnzbd/skintext.py msgid "User script can flag job as failed" msgstr "Käyttäjän skripti voi merkitä latauksen epäonnistuneeksi" #: sabnzbd/skintext.py msgid "" "When the user script returns a non-zero exit code, the job will be flagged " "as failed." msgstr "" "Kun käyttäjän skripti palauttaa nollasta poikkeavan koodin, lataus merkitään" " epäonnistuneeksi." #: sabnzbd/skintext.py msgid "Enable folder rename" msgstr "Kansion uudelleennimeäminen käytössä" #: sabnzbd/skintext.py msgid "" "Use temporary names during post processing. Disable when your system doesn't" " handle that properly." msgstr "" "Käyttää väliaikaisia nimiä kun jälkikäsittely on käynnissä. Poista käytöstä " "jos järjestelmäsi ei toimi oikein asetuksen ollessa päällä." #: sabnzbd/skintext.py msgid "Pre-queue user script" msgstr "Esijonon käyttäjän skripti" #: sabnzbd/skintext.py msgid "Used before an NZB enters the queue." msgstr "Käytetään ennen NZB lisäämistä jonoon." #: sabnzbd/skintext.py msgid "On queue finish script" msgstr "" #: sabnzbd/skintext.py msgid "Executed after the queue finishes downloading." msgstr "" #: sabnzbd/skintext.py msgid "Extra PAR2 Parameters" msgstr "Ylimääräiset PAR2 parametrit" #: sabnzbd/skintext.py msgid "Nice Parameters" msgstr "Nice muuttujat" #: sabnzbd/skintext.py msgid "IONice Parameters" msgstr "IONice muuttujat" #: sabnzbd/skintext.py msgid "External process priority" msgstr "" #: sabnzbd/skintext.py msgid "Disconnect on Empty Queue" msgstr "Katkaise yhteys kun jono on tyhjä" #: sabnzbd/skintext.py msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Katkaise yhteys Usenet palvelimeen/palvelimiin kun jono on tyhjä tai tila on" " keskeytetty." #: sabnzbd/skintext.py msgid "Automatically sort queue" msgstr "" #: sabnzbd/skintext.py msgid "Automatically sort jobs in the queue when a new job is added." msgstr "" #: sabnzbd/skintext.py msgid "The queue will resort every 30 seconds if % downloaded is selected." msgstr "" #: sabnzbd/skintext.py msgid "Propagation delay" msgstr "Levitysviive" #: sabnzbd/skintext.py msgid "" "Posts will be paused untill they are at least this age. Setting job priority" " to Force will skip the delay." msgstr "" "Lähetykset tauotetaan kunnes ne ovat vähintään näin vanhoja. Prioriteetin " "asettaminen pakottamiselle ohittaa asetetun viiveen." #: sabnzbd/skintext.py msgid "Check for New Release" msgstr "Tarkista uusi versio" #. Pick list for weekly test for new releases #: sabnzbd/skintext.py msgid "Also test releases" msgstr "Myös testiversiot" #: sabnzbd/skintext.py msgid "Replace Spaces in Foldername" msgstr "Korvaa välilyönnit kansionimessä" #: sabnzbd/skintext.py msgid "Replace spaces with underscores in folder names." msgstr "Korvaa välilyönnit alaviivoilla kansionimissä." #: sabnzbd/skintext.py msgid "Replace underscores in folder name" msgstr "" #: sabnzbd/skintext.py msgid "Replace underscores with dots in folder names." msgstr "" #: sabnzbd/skintext.py msgid "Replace dots in Foldername" msgstr "Korvaa pisteet kansionimessä" #: sabnzbd/skintext.py msgid "Replace dots with spaces in folder names." msgstr "Korvaa pisteet välilyönneillä kansionimissä." #: sabnzbd/skintext.py msgid "Make Windows compatible" msgstr "Windows yhteensopivuus" #: sabnzbd/skintext.py msgid "For servers: make sure names are compatible with Windows." msgstr "Palvelimille: varmistaa että nimet ovat Windows yhteensopivia." #: sabnzbd/skintext.py msgid "Launch Browser on Startup" msgstr "Käynnistä selain käynnistyksen yhteydessä" #: sabnzbd/skintext.py msgid "Launch the default web browser when starting SABnzbd." msgstr "Käynnistää oletusselaimen kun SABnzbd käynnistetään." #: sabnzbd/skintext.py msgid "Pause Downloading During Post-Processing" msgstr "Keskeytä lataus jälkikäsittelyn ajaksi" #: sabnzbd/skintext.py msgid "" "Pauses downloading at the start of post processing and resumes when " "finished." msgstr "" "Keskeyttää lataamisen kun jälkikäsittely alkaa ja jatkaa lataamista kun se " "lopetetaan." #: sabnzbd/skintext.py msgid "Ignore Samples" msgstr "Ohita näytteet" #: sabnzbd/skintext.py msgid "Filter out sample files (e.g. video samples)." msgstr "Ohittaa näytetiedostot (esim. videonäytteet)." #: sabnzbd/skintext.py msgid "Delete after download" msgstr "Poista lataamisen jälkeen" #: sabnzbd/skintext.py msgid "Deobfuscate final filenames" msgstr "" #: sabnzbd/skintext.py msgid "" "If filenames of (large) files in the final folder look obfuscated or " "meaningless they will be renamed to the job name." msgstr "" #: sabnzbd/skintext.py msgid "" "Additionally, attempts to set the correct file extension based on the file " "signature if the extension is not present or meaningless." msgstr "" #: sabnzbd/skintext.py msgid "HTTPS certificate verification" msgstr "HTTPS sertfikaatin varmennus" #: sabnzbd/skintext.py msgid "" "Verify certificates when connecting to indexers and RSS-sources using HTTPS." msgstr "" "Varmenna sertifikaatit yhdistettäessä indeksoijiin ja RSS-lähteisiin HTTPS " "protokollan avulla." #: sabnzbd/skintext.py msgid "SOCKS5 Proxy" msgstr "" #: sabnzbd/skintext.py msgid "Use the specified SOCKS5 proxy for all outgoing connections." msgstr "" #: sabnzbd/skintext.py msgid "Server" msgstr "Palvelin" #: sabnzbd/skintext.py msgid "Post processing" msgstr "Jälkikäsittely" #: sabnzbd/skintext.py msgid "Naming" msgstr "Nimeäminen" #: sabnzbd/skintext.py msgid "Quota" msgstr "Latausrajoitus" #: sabnzbd/skintext.py msgid "How much can be downloaded this month (K/M/G)" msgstr "Kuinka paljon voidaan ladata tässä kuussa (K/M/G)" #. Reset day of the download quota #: sabnzbd/skintext.py msgid "Reset day" msgstr "Resetointipäivä" #: sabnzbd/skintext.py msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Minä päivänä kuusta tai viikosta (1=Maanantai) palveluntarjoajasi resetoi " "rajoituksen? (Voit syöttää kellonajan perään hh:mm)" #: sabnzbd/skintext.py msgid "Should downloading resume after the quota is reset?" msgstr "Pitäisikö latauksia jatkaa kun latausrajoitus on resetoitu?" #. Does the quota get reset every day, week or month? #: sabnzbd/skintext.py msgid "Quota period" msgstr "Latausrajoituksen pituus" #: sabnzbd/skintext.py msgid "Does the quota get reset each day, week or month?" msgstr "Resetoidaanko rajoitus joka päivä, viikko vai kuukausi?" #: sabnzbd/skintext.py msgid "Check before download" msgstr "Tarkista ennen lataamista" #: sabnzbd/skintext.py msgid "Try to predict successful completion before actual download (slower!)" msgstr "Yritä ennustaa latauksen valmistuminen ennen lataamista (hitaampi!)" #: sabnzbd/skintext.py msgid "SSL Ciphers" msgstr "SSL-salaus" #: sabnzbd/skintext.py msgid "Increase performance by forcing a lower SSL encryption strength." msgstr "Lisää suorituskykyä pakottamalla alhaisempi SSL-suojaustaso." #: sabnzbd/skintext.py, sabnzbd/urlgrabber.py msgid "Maximum retries" msgstr "Enimmäismäärä uudelleenyrityksille" #: sabnzbd/skintext.py msgid "Maximum number of retries per server" msgstr "Enimmäismäärä uudelleenyrityksiä yksittäiselle palvelimelle." #: sabnzbd/skintext.py msgid "Abort jobs that cannot be completed" msgstr "Peruuta lataukset jotka eivät voi valmistua" #: sabnzbd/skintext.py msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Peruutetaan lataus, jos ladattaessa huomataan liikaa tiedostoja puuttuvan" #. Caption - Button: Add server #: sabnzbd/skintext.py msgid "Add Server" msgstr "Lisää palvelin" #. User defined name for server #: sabnzbd/skintext.py msgid "Server description" msgstr "Palvelimen kuvaus" #. Server port #: sabnzbd/skintext.py msgid "Port" msgstr "Portti" #. Server username #: sabnzbd/skintext.py msgid "Username" msgstr "Käyttäjänimi" #. Server password #: sabnzbd/skintext.py msgid "Password" msgstr "Salasana" #. Server timeout #: sabnzbd/skintext.py msgid "Timeout" msgstr "Aikakatkaisu" #: sabnzbd/skintext.py msgid "Account expiration date" msgstr "" #: sabnzbd/skintext.py msgid "Warn 5 days in advance of account expiration date." msgstr "" #: sabnzbd/skintext.py msgid "" "Quota for this account, counted from the time it is set. In bytes, " "optionally follow with K,M,G.
Warn when it reaches 0, checked every few" " minutes." msgstr "" #. Server's retention time in days #: sabnzbd/skintext.py msgid "Retention time" msgstr "Säilytysaika" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "SSL" msgstr "SSL" #. Server SSL tickbox #: sabnzbd/skintext.py msgid "Secure connection to server" msgstr "" #: sabnzbd/skintext.py msgid "Certificate verification" msgstr "Sertifikaatin varmennus" #: sabnzbd/skintext.py msgid "" "Minimal: when SSL is enabled, verify the identity of the server using its " "certificates. Strict: verify and enforce matching hostname." msgstr "" #: sabnzbd/skintext.py msgid "Disabled" msgstr "Ei käytössä" #: sabnzbd/skintext.py msgid "Minimal" msgstr "" #: sabnzbd/skintext.py msgid "Strict" msgstr "Tiukka" #. Explain server priority #: sabnzbd/skintext.py msgid "0 is highest priority, 100 is the lowest priority" msgstr "0 on suurin prioriteetti, 99 on pienin prioriteetti" #. Server required tickbox #: sabnzbd/skintext.py msgid "Required" msgstr "" #: sabnzbd/skintext.py msgid "" "In case of connection failures, the download queue will be paused for a few " "minutes instead of skipping this server" msgstr "" #. Server optional tickbox #: sabnzbd/skintext.py msgid "Optional" msgstr "Vaihtoehtoinen" #: sabnzbd/skintext.py msgid "For unreliable servers, will be ignored longer in case of failures" msgstr "" #. Enable server tickbox #: sabnzbd/skintext.py msgid "Enable" msgstr "Ota käyttöön" #. Button: Remove server #: sabnzbd/skintext.py msgid "Remove Server" msgstr "Poista palvelin" #. Button: Test server - Wizard step #: sabnzbd/skintext.py msgid "Test Server" msgstr "Testaa palvelinta" #. Button: Clear server's byte counters #: sabnzbd/skintext.py msgid "Clear Counters" msgstr "Nollaa laskurit" #: sabnzbd/skintext.py msgid "Testing server details..." msgstr "Testataan pavelimen tietoja..." #: sabnzbd/skintext.py msgid "Bandwidth" msgstr "Kaista" #: sabnzbd/skintext.py msgid "Personal notes" msgstr "Henkilökohtaiset huomautukset" #: sabnzbd/skintext.py msgid "Article availability" msgstr "" #: sabnzbd/skintext.py msgid "%f% available of %d requested articles" msgstr "" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Add Schedule" msgstr "Lisää ajastus" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Frequency" msgstr "Toisto" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Action" msgstr "Toiminto" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Arguments" msgstr "Parametrit" #. Config->Scheduling #: sabnzbd/skintext.py msgid "Current Schedules" msgstr "Nykyiset ajastukset" #: sabnzbd/skintext.py msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Valintaruutu syötteen nimen vieressä täytyy olla valittuna jotta syöte on " "päällä ja uusia kohteita tarkistetaan automaattisesti.
Kun syöte " "lisätään, siitä lisätään vain uusia kohteita eikä niitä jotka ovat jo " "julkaistu syötteessä ellet paina \"Pakota lataus\" -painiketta." #. Config->RSS, placeholder (cannot be too long) #: sabnzbd/skintext.py msgid "Seperate multiple URLs by a comma" msgstr "" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read Feed" msgstr "Lue syöte" #. Config->RSS button #: sabnzbd/skintext.py msgid "Force Download" msgstr "Pakota lataus" #: sabnzbd/skintext.py msgid "Apply filters" msgstr "" #. Config->RSS edit button #: sabnzbd/skintext.py msgid "Edit" msgstr "" #. Config->RSS when will be the next RSS scan #: sabnzbd/skintext.py msgid "Next scan at" msgstr "" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Order" msgstr "Järjestys" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Type" msgstr "Tyyppi" #. Config->RSS table column header #: sabnzbd/skintext.py msgid "Filter" msgstr "Suodata" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Accept" msgstr "Hyväksy" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Reject" msgstr "Hylkää" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "Requires" msgstr "Vaatii" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "RequiresCat" msgstr "VaadittuCat" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At least" msgstr "Vähintään" #. Config->RSS filter-type selection menu #: sabnzbd/skintext.py msgid "At most" msgstr "Enintään" #. Config->RSS filter-type selection menu "From Season/Episode" #: sabnzbd/skintext.py msgid "From SxxEyy" msgstr "Alkaen SxxExx" #. Config->RSS filter-type selection menu "From Show Season/Episode" #: sabnzbd/skintext.py msgid "From Show SxxEyy" msgstr "" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Matched" msgstr "Vastaa" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Not Matched" msgstr "Ei vastaavuutta" #. Config->RSS section header #: sabnzbd/skintext.py msgid "Downloaded" msgstr "Ladattu" #. Config->RSS button #: sabnzbd/skintext.py msgid "Read All Feeds Now" msgstr "Lue kaikki syötteet nyt" #: sabnzbd/skintext.py msgid "" "If only the Default category is selected, notifications are enabled" " for jobs in all categories." msgstr "" #: sabnzbd/skintext.py msgid "Email Notification On Job Completion" msgstr "Sähköposti-ilmoitus onnistuneesta latauksesta" #. When to send email #: sabnzbd/skintext.py msgid "Never" msgstr "Ei koskaan" #. When to send email #: sabnzbd/skintext.py msgid "Always" msgstr "Aina" #. When to send email #: sabnzbd/skintext.py msgid "Error-only" msgstr "Vain virheet" #: sabnzbd/skintext.py msgid "Disk Full Notifications" msgstr "Levy täynnä ilmoitukset" #: sabnzbd/skintext.py msgid "Send email when disk is full and SABnzbd is paused." msgstr "Lähetä sähköposti kun levy on täynnä ja SABnzbd on keskeytetty." #: sabnzbd/skintext.py msgid "Send RSS notifications" msgstr "Lähetä RSS ilmoitukset" #: sabnzbd/skintext.py msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Lähetä sähköpostia kun RSS syötteestä lisätään latauksia jonoon." #: sabnzbd/skintext.py msgid "SMTP Server" msgstr "SMTP-palvelin" #: sabnzbd/skintext.py msgid "Set your ISP's server for outgoing email." msgstr "Sähköpostin lähtevän postin palvelimen osoite." #: sabnzbd/skintext.py msgid "Email Recipient" msgstr "Sähköpostin vastaanottaja" #: sabnzbd/skintext.py msgid "Email address to send the email to." msgstr "Sähköpostiosoite johon viestit lähetetään." #: sabnzbd/skintext.py msgid "Email Sender" msgstr "Sähköpostin lähettäjä" #: sabnzbd/skintext.py msgid "Who should we say sent the email?" msgstr "Kuka näytetään viestin lähettäjänä?" #: sabnzbd/skintext.py msgid "OPTIONAL Account Username" msgstr "VAIHTOEHTOINEN tilin käyttäjänimi" #: sabnzbd/skintext.py msgid "For authenticated email, account name." msgstr "Kirjautumisen vaativalle sähköpostille, tilin käyttäjänimi." #: sabnzbd/skintext.py msgid "OPTIONAL Account Password" msgstr "VAIHTOEHTOINEN tilin salasana" #: sabnzbd/skintext.py msgid "For authenticated email, password." msgstr "Kirjautumisen vaativalle sähköpostille, tilin salasana." #: sabnzbd/skintext.py msgid "Notification Sent!" msgstr "Ilmoitus lähetetty!" #. Don't translate "NotifyOSD" #: sabnzbd/skintext.py msgid "Enable NotifyOSD" msgstr "NotifyOSD käytössä" #. Header for macOS Notfication Center section #: sabnzbd/skintext.py msgid "Notification Center" msgstr "Ilmoituskeskus" #: sabnzbd/skintext.py msgid "Enable Windows Notifications" msgstr "Windows-ilmoitukset käytössä" #: sabnzbd/skintext.py msgid "Windows Notifications" msgstr "Windows-ilmoitukset" #. Header for Ubuntu's NotifyOSD notifications section #: sabnzbd/skintext.py msgid "NotifyOSD" msgstr "IlmoitusOSD" #. Header for Prowl notification section #: sabnzbd/skintext.py msgid "Prowl" msgstr "Prowl" #. Prowl settings #: sabnzbd/skintext.py msgid "Enable Prowl notifications" msgstr "Prowl ilmoitukset käytössä" #. Prowl settings #: sabnzbd/skintext.py msgid "Requires a Prowl account" msgstr "Vaatii Prowl-tilin" #. Prowl settings #: sabnzbd/skintext.py msgid "API key for Prowl" msgstr "Prowl API avain" #. Prowl settings #: sabnzbd/skintext.py msgid "Personal API key for Prowl (required)" msgstr "Prowlin henkilökohtainen API avain (pakollinen)" #. Header for Pushover notification section #: sabnzbd/skintext.py msgid "Pushover" msgstr "Pushover" #. Pushover settings #: sabnzbd/skintext.py msgid "Enable Pushover notifications" msgstr "Pushover ilmoitukset käytössä" #. Pushoversettings #: sabnzbd/skintext.py msgid "Requires a Pushover account" msgstr "Vaatii Pushover tilin" #. Pushover settings #: sabnzbd/skintext.py msgid "Application Token" msgstr "Ohjelman token" #. Pushover settings #: sabnzbd/skintext.py msgid "Application token (required)" msgstr "Ohjelman token (pakollinen)" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key" msgstr "Käyttäjän avain" #. Pushover settings #: sabnzbd/skintext.py msgid "User Key (required)" msgstr "Käyttäjän avain (pakollinen)" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s)" msgstr "Laitteet" #. Pushover settings #: sabnzbd/skintext.py msgid "Device(s) to which message should be sent" msgstr "Laitteet joihin viesti lähetetään" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency retry" msgstr "" #: sabnzbd/skintext.py msgid "How often (in seconds) the same notification will be sent" msgstr "" #. Pushover settings #: sabnzbd/skintext.py msgid "Emergency expire" msgstr "" #: sabnzbd/skintext.py msgid "How many seconds your notification will continue to be retried" msgstr "" #. Header for Pushbullet notification section #: sabnzbd/skintext.py msgid "Pushbullet" msgstr "Pushbullet" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Enable Pushbullet notifications" msgstr "Pushbullet ilmoitukset käytössä" #. Pushbulletsettings #: sabnzbd/skintext.py msgid "Requires a Pushbullet account" msgstr "Vaatii Pushbullet tilin" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Personal API key" msgstr "Henkilökohtainen API avain" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Your personal Pushbullet API key (required)" msgstr "Henkilökohtainen Pushbullet API avain (pakollinen)" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device" msgstr "Laite" #. Pushbullet settings #: sabnzbd/skintext.py msgid "Device to which message should be sent" msgstr "Laite johon viesti lähetetään" #. Apprise settings #: sabnzbd/skintext.py msgid "Enable Apprise notifications" msgstr "" #: sabnzbd/skintext.py msgid "Send notifications using Apprise to almost any notification service" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Default Apprise URLs" msgstr "" #. Apprise settings #: sabnzbd/skintext.py msgid "Use a comma and/or space to identify more than one URL." msgstr "" #: sabnzbd/skintext.py msgid "" "Override the default URLs for specific notification types below, if desired." msgstr "" #. Header for Notification Script notification section #: sabnzbd/skintext.py msgid "Notification Script" msgstr "Ilmoitusskripti" #. Notification Script settings #: sabnzbd/skintext.py msgid "Enable notification script" msgstr "Ilmoitusskripti päällä" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Executes a custom script" msgstr "Suorittaa käyttäjän skriptin" #. Notification Scriptsettings #: sabnzbd/skintext.py msgid "Which script should we execute for notification?" msgstr "Mikä skripti suoritetaan ilmoitukselle?" #: sabnzbd/skintext.py msgid "" "Indexers can supply a category inside the NZB which SABnzbd will try to " "match to the categories defined below. Additionally, you can add terms to " "\"Indexer Categories / Groups\" to match more categories. Use commas to " "separate terms. Wildcards in the terms are supported.
More information " "can be found on the Wiki." msgstr "" "Indeksoijat voivat tarjota kategorian NZB tiedoston sisällä jonka SABnzbd " "yrittää vastata johonkin esimääriteltyyn kategoriaan. Voit lisäksi lisätä " "sanoja \"Indeksoijan kategoriat / ryhmä\" -kohtaan vastaamaan useampia " "kategorioita. Käytä pilkkuja sanojen erottamiseen. Jokerimerkit ovat " "tuettuna.
Lisätietoja löytyy Wikistä." #: sabnzbd/skintext.py msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Polun päättäminen tähteen * estää latauskohtaisten kansioiden luomisen." #: sabnzbd/skintext.py msgid "Relative folders are based on" msgstr "Suhteelliset kansiot jotka perustuvat" #: sabnzbd/skintext.py msgid "Folder/Path" msgstr "Kansio/Polku" #: sabnzbd/skintext.py msgid "Indexer Categories / Groups" msgstr "Indeksoijan kategoriat / ryhmä" #: sabnzbd/skintext.py msgid "Pattern Key" msgstr "Mallin avain" #: sabnzbd/skintext.py msgid "Clear" msgstr "Tyhjennä" #: sabnzbd/skintext.py msgid "Presets" msgstr "Esiasetukset" #: sabnzbd/skintext.py msgid "Affected Categories" msgstr "Kategoriat joita koskee" #: sabnzbd/skintext.py msgid "Meaning" msgstr "Merkitys" #: sabnzbd/skintext.py msgid "Pattern" msgstr "Malli" #: sabnzbd/skintext.py msgid "Result" msgstr "Tulos" #: sabnzbd/skintext.py msgid "Title" msgstr "Nimi" #: sabnzbd/skintext.py msgid "Movie Name" msgstr "Elokuvan nimi" #: sabnzbd/skintext.py msgid "Movie.Name" msgstr "Elokuvan.nimi" #: sabnzbd/skintext.py msgid "Movie_Name" msgstr "Elokuvan_nimi" #: sabnzbd/skintext.py msgid "Show Name" msgstr "Ohjelman nimi" #: sabnzbd/skintext.py msgid "Show.Name" msgstr "Ohjelman.nimi" #: sabnzbd/skintext.py msgid "Show_Name" msgstr "Ohjelman_nimi" #: sabnzbd/skintext.py msgid "Season Number" msgstr "Tuotantokauden numero" #: sabnzbd/skintext.py msgid "Episode Number" msgstr "Jakson numero" #: sabnzbd/skintext.py msgid "Episode Name" msgstr "Jakson nimi" #: sabnzbd/skintext.py msgid "Episode.Name" msgstr "Jakson.nimi" #: sabnzbd/skintext.py msgid "Episode_Name" msgstr "Jakson_nimi" #: sabnzbd/skintext.py msgid "Extension" msgstr "Tunniste" #: sabnzbd/skintext.py msgid "Part Number" msgstr "Osan numero" #: sabnzbd/skintext.py msgid "Decade" msgstr "Vuosikymmen" #: sabnzbd/skintext.py msgid "Original Filename" msgstr "Alkuperäinen tiedostonimi" #: sabnzbd/skintext.py msgid "Original Job Name" msgstr "" #: sabnzbd/skintext.py msgid "Lower Case" msgstr "Pienaakkoset" #: sabnzbd/skintext.py msgid "TEXT" msgstr "TEKSTI" #: sabnzbd/skintext.py msgid "text" msgstr "teksti" #: sabnzbd/skintext.py msgid "file" msgstr "tiedosto" #: sabnzbd/skintext.py msgid "Sort String" msgstr "Lajittelumerkkijono" #: sabnzbd/skintext.py msgid "Multi-part Label" msgstr "" #: sabnzbd/skintext.py msgid "Show folder" msgstr "" #: sabnzbd/skintext.py msgid "Season folder" msgstr "" #: sabnzbd/skintext.py msgid "In folders" msgstr "Kansioissa" #: sabnzbd/skintext.py msgid "No folders" msgstr "Ei kansioita" #: sabnzbd/skintext.py msgid "Job Name as Filename" msgstr "" #: sabnzbd/skintext.py msgid "Series" msgstr "" #. Note for title expression in Sorting that does case adjustment #: sabnzbd/skintext.py msgid "case-adjusted" msgstr "kirjainkokoa säätävä" #: sabnzbd/skintext.py msgid "Processed Result" msgstr "Käsitellyt tulokset" #: sabnzbd/skintext.py msgid "Any property" msgstr "" #: sabnzbd/skintext.py msgid "property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt.Property" msgstr "" #: sabnzbd/skintext.py msgid "GuessIt_Property" msgstr "" #: sabnzbd/skintext.py msgid "Minimum Filesize" msgstr "" #: sabnzbd/skintext.py msgid "Affected Job Types" msgstr "" #: sabnzbd/skintext.py msgid "All" msgstr "Kaikki" #: sabnzbd/skintext.py msgid "Series with air dates" msgstr "" #: sabnzbd/skintext.py msgid "Movies" msgstr "" #: sabnzbd/skintext.py msgid "Other / Unknown" msgstr "" #: sabnzbd/skintext.py msgid "" "

Use Sorters to automatically organize your completed downloads. For " "example, put all episodes from a series in a season-specific folder. Or, put" " movies in a folder named after the movie.

Sorters are tried in order " "of appearance and can be reordered by dragging and dropping.
The first " "active sorter that matches both the affected category and job type is " "applied.

More options are available when Advanced Settings is " "checked.
Detailed information can be found on the Wiki.

" msgstr "" #: sabnzbd/skintext.py msgid "Add Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Remove Sorter" msgstr "" #: sabnzbd/skintext.py msgid "Test Data" msgstr "" #: sabnzbd/skintext.py msgid "Quick start" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all episodes in the \"tv\" category to a show-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Move and rename all movies in the \"movies\" category to a movie-specific " "folder" msgstr "" #: sabnzbd/skintext.py msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
Don't change these without checking the " "Wiki first, as some have serious side-effects.
The default values are " "between parentheses." msgstr "" "Harvoin käytetyt asetukset. Paina Ohje-painiketta Wiki-sivustolle " "päästäksesi, jotta saat tietää näiden tarkoituksen ja ohjeet " "käyttöön.
Älä muuta ennen Wikin lukemista, koska näiden muuttamisella voi" " olla vakavia sivuvaikutuksia.
Oletusarvot ovat kirjoitettuna sulkeiden " "sisään." #: sabnzbd/skintext.py msgid "Values" msgstr "Arvot" #. Job details page #: sabnzbd/skintext.py msgid "Edit NZB Details" msgstr "NZB tietojen muokkaus" #. Job details page, delete button #: sabnzbd/skintext.py msgid "Delete" msgstr "Poista" #. Job details page, filename column header #: sabnzbd/skintext.py msgid "Filename" msgstr "Tiedostonimi" #: sabnzbd/skintext.py msgid "Free Space" msgstr "Vapaa tila" #: sabnzbd/skintext.py msgid "Temp Folder" msgstr "Väliaikaiskansio" #: sabnzbd/skintext.py msgid "Multi-Operations" msgstr "Monioperaatiot" #: sabnzbd/skintext.py msgid "Hold shift key to select a range" msgstr "Paina vaihto-näppäintä pohjassa valitaksesi alueen" #: sabnzbd/skintext.py msgid "Check all" msgstr "Valitse kaikki" #: sabnzbd/skintext.py msgid "Restart SABnzbd" msgstr "Uudelleenkäynnistä SABnzbd" #: sabnzbd/skintext.py msgid "On queue finish" msgstr "Kun jono on tyhjä" #: sabnzbd/skintext.py msgid "Status and interface options" msgstr "Tilan ja käyttöliittymän asetukset" #: sabnzbd/skintext.py msgid "Or drag and drop files in the window!" msgstr "Tai vedä ja pudota tiedostot tähän ikkunaan!" #: sabnzbd/skintext.py msgid "Lost connection to SABnzbd.." msgstr "Menetettiin yhteys SABnzbd:hen..." #: sabnzbd/skintext.py msgid "In case of SABnzbd restart this screen will disappear automatically!" msgstr "" "Mikäli SABnzbd käynnistetään uudelleen, tämä ruutu häviää automaattisesti!" #: sabnzbd/skintext.py msgid "WARNING:" msgstr "VAROITUS:" #: sabnzbd/skintext.py msgid "Fetch" msgstr "Nouda" #: sabnzbd/skintext.py msgid "Web Interface" msgstr "Web-käyttöliittymä" #: sabnzbd/skintext.py msgid "Refresh rate" msgstr "Päivitysväli" #: sabnzbd/skintext.py msgid "Use global interface settings" msgstr "Käytä yleisiä käyttöliittymän asetuksia" #: sabnzbd/skintext.py msgid "Queue item limit" msgstr "Jonon pituusrajoitus" #: sabnzbd/skintext.py msgid "History item limit" msgstr "Historian pituusrajoitus" #: sabnzbd/skintext.py msgid "Date format" msgstr "Päivämäärän muoto" #: sabnzbd/skintext.py msgid "Extra queue columns" msgstr "" #: sabnzbd/skintext.py msgid "Extra history columns" msgstr "" #: sabnzbd/skintext.py msgid "page" msgstr "sivu" #: sabnzbd/skintext.py msgid "Loading" msgstr "Ladataan" #: sabnzbd/skintext.py msgid "articles" msgstr "artikkeleita" #: sabnzbd/skintext.py msgid "Rename" msgstr "Uudelleennimeä" #: sabnzbd/skintext.py msgid "Queue repair" msgstr "Jonon korjaus" #: sabnzbd/skintext.py msgid "Show active connections" msgstr "Näytä aktiiviset yhteydet" #: sabnzbd/skintext.py msgid "Unblock" msgstr "Poista esto" #: sabnzbd/skintext.py msgid "Orphaned jobs" msgstr "Orvot lataukset" #: sabnzbd/skintext.py msgid "Send back to queue" msgstr "Lähetä takaisin jonoon" #: sabnzbd/skintext.py msgid "Delete All" msgstr "Poista kaikki" #: sabnzbd/skintext.py msgid "Retry all" msgstr "Yritä uudelleen kaikki" #: sabnzbd/skintext.py msgid "Fetch NZB from URL" msgstr "Nouda NZB osoitteesta" #: sabnzbd/skintext.py msgid "Upload NZB" msgstr "Lähetä NZB" #: sabnzbd/skintext.py msgid "Optionally specify a filename" msgstr "Vaihtoehtoisesti anna tiedostonimi" #: sabnzbd/skintext.py msgid "Submit" msgstr "Lähetä" #: sabnzbd/skintext.py msgid "Remove all selected files" msgstr "Poista kaikki valitut tiedostot" #: sabnzbd/skintext.py msgid "Hide/show completed files" msgstr "Piilota/näytä valmistuneet tiedostot" #: sabnzbd/skintext.py msgid "Top" msgstr "Ylin" #: sabnzbd/skintext.py msgid "Bottom" msgstr "Alin" #: sabnzbd/skintext.py msgid "" "When you Retry a job, 'Duplicate Detection' and 'Abort jobs that cannot be " "completed' are disabled." msgstr "" #: sabnzbd/skintext.py msgid "View Script Log" msgstr "Näytä skriptien loki" #: sabnzbd/skintext.py msgid "Renaming the job will abort Direct Unpack." msgstr "" #: sabnzbd/skintext.py msgid "" "LocalStorage (cookies) are disabled in your browser, interface settings will" " be lost after you close the browser!" msgstr "" "LocalStorage (evästeet) on pois käytöstä selaimen asetuksista. " "Käyttöliittymän asetukset menetetään kun selain suljetaan!" #: sabnzbd/skintext.py msgid "Glitter has some (new) features you might like!" msgstr "" "Glitter-teemassa on muutamia (uusia) ominaisuuksia joista saatat pitää!" #: sabnzbd/skintext.py msgid "Custom" msgstr "Mukautettu" #: sabnzbd/skintext.py msgid "Compact layout" msgstr "Tiivis käyttöliittymä" #: sabnzbd/skintext.py msgid "Always use full screen width" msgstr "" #: sabnzbd/skintext.py msgid "Tabbed layout
(separate queue and history)" msgstr "Välilehditetty käyttöliittymä
(erillinen jono ja historia)" #: sabnzbd/skintext.py msgid "Speed" msgstr "Nopeus" #: sabnzbd/skintext.py msgid "Confirm Queue Deletions" msgstr "Varmista jonon poistot" #: sabnzbd/skintext.py msgid "Confirm History Deletions" msgstr "Varmista historian poistot" #: sabnzbd/skintext.py msgid "Keyboard shortcuts" msgstr "" #: sabnzbd/skintext.py msgid "Shift+Arrow key: Browse Queue and History pages" msgstr "" #: sabnzbd/skintext.py msgid "How long or untill when do you want to pause? (in English!)" msgstr "Kuinka pitkään tai mihin asti haluat keskeyttää? (englanniksi!)" #: sabnzbd/skintext.py msgid "Sorry, we could not interpret that. Try again." msgstr "Valitettavasti emme ymmärtäneet tuota. Yritä uudelleen." #: sabnzbd/skintext.py msgid "Pause for..." msgstr "Keskeytä ajaksi..." #: sabnzbd/skintext.py msgid "Refresh" msgstr "Päivitä" #: sabnzbd/skintext.py msgid "" "All usernames, passwords and API-keys are automatically removed from the log" " and the included copy of your settings." msgstr "" #: sabnzbd/skintext.py msgid "Sort by % downloaded Most→Least" msgstr "" #: sabnzbd/skintext.py msgid "Sort by Age Oldest→Newest" msgstr "Järjestä iän mukaan Vanhin→Uusin" #: sabnzbd/skintext.py msgid "Sort by Age Newest→Oldest" msgstr "Järjestä iän mukaan Uusin→Vanhin" #: sabnzbd/skintext.py msgid "Sort by Name A→Z" msgstr "Järjestä nimen mukaan A→Z" #: sabnzbd/skintext.py msgid "Sort by Name Z→A" msgstr "Järjestä nimen mukaan Z→A" #: sabnzbd/skintext.py msgid "Sort by Size Smallest→Largest" msgstr "Järjestä koon mukaan Pienin→Suurin" #: sabnzbd/skintext.py msgid "Sort by Size Largest→Smallest" msgstr "Järjestä koon mukaan Suurin→Pienin" #: sabnzbd/skintext.py msgid "Uploading" msgstr "Lähetetään" #: sabnzbd/skintext.py msgid "Forcing disconnect" msgstr "Pakotetaan yhteyden katkaisu" #: sabnzbd/skintext.py msgid "Removing job" msgstr "Poistetaan lataus" #: sabnzbd/skintext.py msgid "Removing jobs" msgstr "Poistetaan lataukset" #: sabnzbd/skintext.py msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd pika-aloitus velho" #: sabnzbd/skintext.py msgid "SABnzbd Version" msgstr "SABnzbd versio" #. Button to go to previous Wizard page #: sabnzbd/skintext.py msgid "Previous" msgstr "Edellinen" #. Button to go to next Wizard page #: sabnzbd/skintext.py msgid "Next" msgstr "Seuraava" #: sabnzbd/skintext.py msgid "Server Details" msgstr "Palvelimen tiedot" #: sabnzbd/skintext.py msgid "Please enter in the details of your primary usenet provider." msgstr "Syötä pääasiallisen usenet tarjoajasi tiedot." #: sabnzbd/skintext.py msgid "The number of connections allowed by your provider" msgstr "Tarjoajasi sallimien yhteyksien lukumäärä." #. Wizard: examples of amount of connections #: sabnzbd/skintext.py msgid "E.g. 8 or 20" msgstr "Esim. 8 tai 20" #: sabnzbd/skintext.py msgid "Select only if your provider allows SSL connections." msgstr "Valitse vain jos tarjoajasi sallii SSL yhteydet." #: sabnzbd/skintext.py msgid "Click to test the entered details." msgstr "Klikkaa testataksesi syötettyjä tietoja." #. Abbreviation for "for example" #: sabnzbd/skintext.py msgid "E.g." msgstr "Esim." #. Wizard step #: sabnzbd/skintext.py msgid "Setup is now complete!" msgstr "Asennus on nyt valmis!" #. Wizard tip #: sabnzbd/skintext.py msgid "SABnzbd will now be running in the background." msgstr "SABnzbd on nyt käynnissä taustalla." #. Wizard tip #: sabnzbd/skintext.py msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Selaimen tai sen välilehtien sulkeminen EI sammuta SABnzbd:tä." #: sabnzbd/skintext.py msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "On suositeltavaa, että painat linkistä hiiren oikealla ja lisäät sen " "kirjanmerkkeihin. Sitten voit käyttää kirjanmerkkiä kun haluat käyttää " "SABnzbd ohjelmaa sen ollessa käynnissä taustalla." #: sabnzbd/skintext.py msgid "Further help can be found on our" msgstr "Lisää ohjeita löytyy" #. Wizard step #: sabnzbd/skintext.py msgid "Go to SABnzbd" msgstr "Siirry SABnzbd:hen" #. Wizard EXIT button on first page #: sabnzbd/skintext.py msgid "Exit SABnzbd" msgstr "Poistu SABnzbd:stä" #. Wizard START button on first page #: sabnzbd/skintext.py msgid "Start Wizard" msgstr "Käynnistä velho" #: sabnzbd/skintext.py msgid "Restore backup" msgstr "" #: sabnzbd/skintext.py msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" "\n" "SABnzbd ohjelmalla EI OLE MINKÄÄNLAISTA TAKUUTA.\n" "Tämä on ilmainen ohjelma ja olet vapaa levittämään sitä tiettyjen ehtojen ollessa voimassa.\n" "Se on lisensoitu GNU GENERAL PUBLIC LICENSE Versio 2 alaiseksi ja (oman valinnan mukaan) myös myöhempien versioiden.\n" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename %s to %s" msgstr "" #. Error message #: sabnzbd/sorting.py msgid "Failed to rename similar file: %s to %s" msgstr "Samankaltaisen tiedoston uudelleennimeäminen epäonnistui: %s %s" #: sabnzbd/urlgrabber.py msgid "Unauthorized access" msgstr "Luvaton käyttö" #: sabnzbd/urlgrabber.py msgid "File not on server" msgstr "Tiedostoa ei ole palvelimella" #: sabnzbd/urlgrabber.py msgid "Server could not complete request" msgstr "" #. Error message #: sabnzbd/urlgrabber.py msgid "URLGRABBER CRASHED" msgstr "OSOITTEENNOUTAJA KAATUI" #: sabnzbd/urlgrabber.py msgid "Unusable NZB file" msgstr "NZB tiedostoa ei voida käyttää" #: sabnzbd/urlgrabber.py msgid "URL Fetching failed; %s" msgstr "Osoitteen nouto epäonnistui; %s" #: sabnzbd/urlgrabber.py msgid "Trying to fetch NZB from %s" msgstr "Yritetään noutaa NZB osoitteesta %s" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2091708 SABnzbd-4.3.2/po/email/sr.po0000644000000000000000000001443414625637207014722 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sr\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" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Основни шаблон ел. поште за САБнзбд\n" "## Ово је Гепард шаблон\n" "## Документација: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Нови редови и размаци су важни!\n" "##\n" "## Ово су заглавља ел. поште\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: САБнзбд је посао „$name“\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## После тога долази разрада, празни редови су потребни!\n" "\n" "Здраво,\n" "\n" "САБнзбд је преузео „$name“ \n" "\n" "САБнзбд није успео да преузме „$name“ \n" "\n" "Завршено је у $end_time\n" "Преузето је $size\n" "\\n\n" "Резултат рада:\n" "\n" "Фаза $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Излаз корисничке скрипте „$script“ (Шифра излаза = $script_ret):\n" "$script_output\n" "\n" "\n" "Уживајте!\n" "\n" "Жао ми је!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## РСС шаблон ел. поште за САБнзбд\n" "## Ово је Гепард шаблон\n" "## Документација: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Нови редови и размаци су важни!\n" "##\n" "## Ово су заглавља ел. поште\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject САБнзбд је додао $amount посла у ред\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## После тога долази разрада, празни редови су потребни!\n" "\n" "Здраво,\n" "\n" "САБнзбд је додао $amount посао(ла) у ред.\n" "Долазе са РСС довода „$feed“.\n" "\n" " $job \n" "\n" "\n" "Поздрав\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Шаблон ел. поште лошег набављања адресе за САБнзбд\n" "## Ово је Гепард шаблон\n" "## Документација: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Нови редови и размаци су важни!\n" "##\n" "## Ово су заглавља ел. поште\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: САБнзбд није успео да преузме НЗБ\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## После тога долази разрада, празни редови су потребни!\n" "\n" "Здраво,\n" "\n" "САБнзбд није успео да преузме НЗБ са „$url“.\n" "Порука грешке је: $msg\n" "\n" "Поздрав\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2077928 SABnzbd-4.3.2/po/email/cs.po0000644000000000000000000000604614625637207014703 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2083626 SABnzbd-4.3.2/po/email/fr.po0000644000000000000000000001327214625637207014704 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "#encoding UTF-8\n" "##\n" "## Template Email pour SABnzbd\n" "## Ceci est un template Cheetah\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Les retours à la ligne et les espaces sont importants !\n" "##\n" "## Entêtes de l'email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd SuccèsEchec du téléchargement $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Après cela vient le contenu, la ligne vide est nécessaire! \n" "\n" "Bonjour,\n" "\n" "SABnzbd a téléchargé avec succès \"$name\" \n" "\n" "SABnzbd a téléchargé sans succès \"$name\" \n" "\n" "Terminé à $end_time\n" "Téléchargé $size\n" "\n" "Résultat du téléchargement :\n" "\n" "Etape $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Sortie du script utilisateur \"$script\" (Code Retour = $script_ret):\n" "$script_output\n" "\n" "\n" "A bientôt !\n" "\n" "Désolé !\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Template Email pour SABnzbd\n" "## Ceci est un template Cheetah\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Les retours à la ligne et les espaces sont importants !\n" "##\n" "## Entêtes de l'email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a ajouté $amount fichier(s) à la file d'attente\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Après cela vient le contenu, la ligne vide est nécessaire!\n" "\n" "Bonjour,\n" "\n" "SABnzbd a ajouté $amount fichier(s) à la file d'attente.\n" "Ils proviennent du Flux RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Au Revoir\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2087567 SABnzbd-4.3.2/po/email/nl.po0000644000000000000000000001311214625637207014677 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Standaard Email sjabloon voor SABnzbd\n" "## Dit is een Cheetah sjabloon\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Lege regels en witruimte zijn belangrijk!\n" "##\n" "## Dit zijn de email koppen\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd: opdracht $name is \n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Hier onder volgt de hoofdtekst, de lege regel is noodzakelijk!\n" "\n" "Hallo,\n" "\n" "SABnzbd heeft \"$name\" gedownload\n" "\n" "SABnzbd is niet geslaagd in het downloaden van \"$name\" \n" "\n" "Klaar om $end_time\n" "Hoeveelheid gedownload $size\n" "\n" "Resultaat van de opdracht:\n" "\n" "Fase $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Bericht van het script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Veel plezier!\n" "\n" "Sorry!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email sjabloon voor SABnzbd\n" "## Dit is een Cheetah sjabloon\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Lege regels en spaties zijn belangrijk!\n" "##\n" "## Dit zijn de email koppen\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Hierna komt de inhoud, de lege regel is benodigd!\n" "\n" "Hallo,\n" "\n" "SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd.\n" "Ze komen van de RSS bron \"$feed\".\n" "\n" " $job \n" "\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Ongeldige URL Ophaal Email sjabloon voor SABnzbd\n" "## Dit is een Cheetah sjabloon\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Lege regels en spaties zijn belangrijk!\n" "##\n" "## Dit zijn de email koppen\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: Ophalen van NZB door SABnzbd is mislukt\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Hierna komt het bericht, de lege regel is noodzakelijk!\n" "\n" "Hi,\n" "\n" "Het is SABnzbd niet gelukt om een NZB bestand op te halen van $url.\n" "De foutmelding was $msg\n" "\n" "Sorry\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2093225 SABnzbd-4.3.2/po/email/zh_CN.po0000644000000000000000000001260214625637207015272 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## SABnzbd 默认电子邮件模板\n" "## 这是一款 Cheetah 模板\n" "## 文档: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## 新行与空格均有重要意义!\n" "##\n" "## 这些是电子邮件头\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd 已任务 $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## 到主体部分时,必须要有空行!\n" "\n" "Hi,\n" "\n" "SABnzbd 已完成 \"$name\" 的下载 \n" "\n" "SABnzbd 下载 \"$name\" 失败 \n" "\n" "完成于 $end_time\n" "已下载 $size\n" "\n" "任务结果:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "用户脚本 \"$script\" 输出内容 (退出代码 = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "非常抱歉!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## SABnzbd RSS 电子邮件模板\n" "## 这是一款 Cheetah 模板\n" "## 文档: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## 新行及空格均有重要意义!\n" "##\n" "## 这些是电子邮件头\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd 已将 $amount 项任务加入队列\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## 到主体部分时,必须要有空行!\n" "\n" "Hi,\n" "\n" "SABnzbd 已将 $amount 项任务加入队列。\n" "它们出自 RSS feed \"$feed\"。\n" "\n" " $job \n" "\n" "\n" "Bye\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## SABnzbd 装取 URL 错误电子邮件模板\n" "## 这是一款 Cheetah 模板\n" "## 文档: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## 新行与空格均有重要意义!\n" "##\n" "## 这些是电子邮件头\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd 装取 NZB 失败\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## 到主体部分时必须要有空行!\n" "\n" "Hi,\n" "\n" "SABnzbd 从 $url 检索 NZB 失败。\n" "错误信息为: $msg\n" "\n" "Bye\n" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.208014 SABnzbd-4.3.2/po/email/en.po0000644000000000000000000000002314625637207014665 0ustar00runnerstaff# Dummy en.po file ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.209233 SABnzbd-4.3.2/po/email/sv.po0000644000000000000000000001310514625637207014720 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "## Translation by Andreas Lindberg andypandyswe@gmail.com\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hej,\n" "\n" "SABnzbd har laddat ned \"$name\" \n" "\n" "SABnzbd misslyckades med att ladda ned \"$name\" \n" "\n" "Färdig $end_time\n" "Nedladdat $size\n" "\n" "Resultat:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Utmatning från användarskript \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Lycka till!\n" "\n" "Beklagar!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har lagt till $amount jobb i kön\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hej,\n" "\n" "SABnzbd har lagt till $amount jobb i kön.\n" "De kommer från RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Hej då\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd misslyckades med att hämta en NZB -fil\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hej,\n" "\n" "SABnzbd har misslyckats med att hämta NZB -filen från $url.\n" "Felmeddelandet lyder: $msg\n" "\n" "Hej då\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2089326 SABnzbd-4.3.2/po/email/pt_BR.po0000644000000000000000000001342114625637207015277 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_BR\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Template padrão de e-mail para SABnzbd\n" "## Este é um template Cheetah\n" "## Documentação: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Novas linhas e espaços em branco são significativos!\n" "##\n" "## Estes são os cabeçalhos de e-mail\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a tarefa $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Depois daqui vem o corpo. A linha vazia é necessária!\n" "\n" "Olá,\n" "\n" "SABnzbd baixou \"$name\" \n" "\n" "SABnzbd falhou no download de \"$name\" \n" "\n" "Completado em $end_time\n" "Baixados $size\n" "\n" "Resultados da tarefa:\n" "\n" "Etapa $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Retorno do script de usuário \"$script\" (Código de retorno = $script_ret):\n" "$script_output\n" "\n" "\n" "Aproveite!\n" "\n" "Lamento!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Template de e-mail RSS para SABnzbd\n" "## Este é um template Cheetah\n" "## Documentação: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Novas linhas e espaços em branco são significativos!\n" "##\n" "## Estes são os cabeçalhos de e-mail\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd adicionou $amount à fila\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Depois daqui vem o corpo. A linha vazia é necessária!\n" "\n" "Olá,\n" "\n" "SABnzbd adicionou $amount à fila.\n" "Elas são do feed RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Tchau!\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Template de e-mail de busca em URL ruim para SABnzbd\n" "## Este é um template Cheetah\n" "## Documentação: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Novas linhas e espaços em branco são significativos!\n" "##\n" "## Estes são os cabeçalhos de e-mail\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd falhou ao buscar um NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Depois daqui vem o corpo. A linha vazia é necessária!\n" "\n" "Olá,\n" "\n" "SABnzbd não conseguiu obter o NZB de $url.\n" "A mensagem de erro foi: $msg\n" "\n" "Tchau!\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2090058 SABnzbd-4.3.2/po/email/ro.po0000644000000000000000000001330714625637207014714 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Șablon Email Original pentru SABnzbd\n" "## Acesta este un Șablon Cheetah\n" "## Documentație: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "##Rândurile noi și caracterele spațiu sunt importante!\n" "##\n" "## Acestea sunt antetele email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd sarcina $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## După acesta urmează conţinutul, este necesar o linie goală!\n" "\n" "Salut,\n" "\n" "SABnzbd a descărcat \"$name\" \n" "\n" "SABnzbd nu a reuşit să descarce \"$name\" \n" "\n" "Terminat la $end_time\n" "Mărime $size\n" "\n" "Rezultatele sarcinii:\n" "\n" "Stagiu $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Rezultatul script-ului utilizatorului \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Bucuraţi-vă!\n" "\n" "Ne pare rau!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "## Şablon Email RSS pentru SABnzbd\n" "## Acesta este un şablon Cheetah \n" "## Documentaţie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rândurile noi și caracterele spațiu sunt importante!\n" "##\n" "## Acestea sunt antetele email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a adăugat $amount sarcini în coadă\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## După acesta urmează conţinutul, este necesar o linie goală!\n" "\n" "Salut,\n" "\n" "SABnzbd a adăugat $amount sarcină(e) în coadă.\n" "Ele sunt din fluxuri RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "La revedere !\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Adresă URL Greşită şablon Email pentru SABnybd \n" "## Acesta este un şablon Cheetah\n" "## Documentaţie : http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Liniile noi şi spaţiile sunt importante!\n" "##\n" "## Acestea sunt headerele email\n" "Către: $to\n" "De la: $from\n" "Dată: $date\n" "Subiect: SABnzbd nu a reuşit să descarce un NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## După aceasta urmează corpul email, linia goală e necesară !\n" "\n" "Salut,\n" "\n" "SABnzbd nu a putut descărca NZB-ul de la adresa $url.\n" "Mesajul de eroare a fost: $msg\n" "\n" "La revedere!\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2085657 SABnzbd-4.3.2/po/email/it.po0000644000000000000000000000577714625637207014724 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Language-Team: Italian (https://app.transifex.com/sabnzbd/teams/111101/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2081003 SABnzbd-4.3.2/po/email/es.po0000644000000000000000000001340114625637207014676 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Spanish (https://app.transifex.com/sabnzbd/teams/111101/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Plantilla de correo predeterminada para SABnzbd\n" "## This a Cheetah template\n" "## Documentación: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## !Los saltos de línea y espacios en blanco son significativos¡\n" "##\n" "## Cabeceras de correo electrónico\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## !Después de esto viene el cuerpo del mensaje, la línea en blanco es necesaria!\n" "\n" "Hola,\n" "\n" "SABnzbd he bajado \"$name\" \n" "\n" "SABnzbd fallo en bajar \"$name\" \n" "\n" "Terminado a las $end_time\n" "$size bajado\n" "\n" "Resultado de la transferencia:\n" "\n" "Etapa $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Producción desde el script de usuario \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Que lo disfrutes!\n" "\n" "Perdon!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Plantilla de correo RSS para SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## !Los saltos de línea y espacios en blanco son significativos¡\n" "##\n" "## Cabeceras de correo electrónico\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd he añadido $amount transferencia(s) a la cola\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## !Después de esto viene el cuerpo del mensaje, la línea en blanco es necesaria!\n" "\n" "Hola,\n" "\n" "SABnzbd he añadido $amount transferencia(s) a la cola.\n" "Originaron desde el RSS \"$feed\".\n" "\n" "$job \n" "\n" "\n" "Adios\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Plantilla de correo para URLs incorrectas de SABnzbd\n" "## Esta es una plantilla Cheetah\n" "## Documentación: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Líneas nuevas y espacios en blanco IMPORTAN!\n" "##\n" "## Estas son las cabeceras del email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd ha encontrado un error al recuperar un NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hola,\n" "\n" "SABnzbd ha encontrado un error al descargar un NZB desde $url.\n" "El error ha sido: $msg\n" "\n" "Un saludo\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2086658 SABnzbd-4.3.2/po/email/nb.po0000644000000000000000000001305614625637207014674 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/sabnzbd/teams/111101/nb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nb\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "#encoding UTF-8\n" "## Translation by ProtX\n" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har jobb $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hei,\n" "\n" "SABnzbd har lastet ned \"$name\" \n" "\n" "SABnzbd mislyktes med å laste ned \"$name\" \n" "\n" "Ferdig $end_time\n" "Nedlastet $size\n" "\n" "Resultat av jobben:\n" "\n" "Steg $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Utskrift fra brukerskript \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Gratulerer!\n" "\n" "Synd!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har lagt $amount jobber til køen\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Etter dette kommer meldingen, den tomme linjen er nødvendig!\n" "\n" "Hei,\n" "\n" "SABnzbd har lagt $amount jobb(er) til køen.\n" "Disse er fra RSS feeden \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Hade\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd ikke klarte å hente en NZB fil\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Etter dette kommer meldingen, den tomme linjen er nødvendig!\n" "\n" "Hei,\n" "\n" "SABnzbd klarte ikke å hente NZB fra $url.\n" "Feilmeldingen var: $msg\n" "\n" "Hade\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2079523 SABnzbd-4.3.2/po/email/de.po0000644000000000000000000001335214625637207014664 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "#encoding UTF-8\n" "## Translation by Severin Heiniger\n" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd Auftrag $name \n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd hat \"$name\" heruntergeladen\n" "\n" "SABnzbd konnte \"$name\" nicht herunterladen\n" "\n" "Fertiggestellt: $end_time\n" "Heruntergeladen: $size\n" "\n" "Ergebnis des Auftrages:\n" "\n" "Stufe $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Ausgabe des Benutzerskripts \"$script\" (beendet mit Code $script_ret):\n" "$script_output\n" "\n" "\n" "Viel Spass!\n" "\n" "Entschuldigung!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hallo,\n" "\n" "SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt.\n" "Sie stammen vom RSS-Feed \"$feed\".\n" "\n" " $job \n" "\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "## Translation by Thomas Lucke (Lucky)\n" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd konnte eine NZB-Datei nicht herunterladen\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hallo,\n" "\n" "SABnzbd konnte die NZB-Datei von $url nicht herrunterladen.\n" "Die Fehlermeldung war: $msg\n" ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1716993671.20787 SABnzbd-4.3.2/po/email/da.po0000644000000000000000000001275314625637207014664 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Standard E-mail-skabelon til SABnzbd\n" "## Dette er en Cheetah-skabelon\n" "## Dokumentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Linjeskift og blanktegn har betydning!\n" "##\n" "## Dette er e-mail-headerne \n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Herefter kommer kroppen, den tomme linje skal være der!\n" "\n" "Hej,\n" "\n" "SABnzbd har hentet \"$name\" \n" "\n" "SABnzbd kunne ikke hente \"$name\" \n" "\n" "Færdig kl. $end_time\n" "Hentet $size\n" "\n" "Resultat af job:\n" "\n" "Etape $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output fra brugerscriptet \"$script\" (Afslutningskode = $script_ret):\n" "$script_output\n" "\n" "\n" "Hav det godt!\n" "\n" "Beklager!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS E-mail-skabelon til SABnzbd\n" "## Dette er en Cheetah-skabelon\n" "## Dokumentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Linjeskift og blanktegn har betydning!\n" "##\n" "## Dette er e-mai-headere\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har tilføjet $antal jobs til køen\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Herefter kommer kroppen, den tomme linje skal være der!\n" "\n" "Hej,\n" "\n" "SABnzbd har tilføjet $antal job(s) til køen.\n" "De er fra RSS-feedet \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Farvel\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Dårlig URL-hentning af E-mail-skabelon til SABnzbd\n" "## Dette er en Cheetah-skabelon\n" "## Dokumentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Linjeskift og blanktegn har betydning!\n" "##\n" "## Dette er e-mail-headere\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd kunne ikke hente en NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Herefter kommer kroppen, den tomme linje skal være der!\n" "\n" "Hej,\n" "\n" "SABnzbd kunne ikke hente NZB fra $url.\n" "Fejlmeddelelsen er: $msg\n" "\n" "Farvel\n" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.208478 SABnzbd-4.3.2/po/email/he.po0000644000000000000000000001330214625637207014663 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # ION, 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: ION, 2020\n" "Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: he\n" "Plural-Forms: nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## SABnzbd תבנית דוא״ל ברירת מחדל עבור\n" "## זאת תבנית ברדלס\n" "## http://sabnzbd.wikidot.com/email-templates :תיעוד\n" "##\n" "## !שורות חדשות ורווחים לבנים הם משמעותיים\n" "##\n" "## אלו כותרות הדוא״ל\n" "$to :אל\n" "$from :מאת\n" "תאריך: $date\n" " $name יש עבודה אשר SABnzbd-נושא: ל\n" "## !אחרי זה בא הגוף, השורה הריקה דרושה\n" "\n" ",היי\n" "\n" "SABnzbd הוריד את \"$name\" \n" "\n" "SABnzbd נכשל להוריד את \"$name\" \n" "\n" "הסתיים ב-$end_time\n" "הורדו $size\n" "\n" ":תוצאות העבודה\n" "\n" "שלב $stage \n" "\n" " $result \n" "\n" "\n" "\n" ":(קוד יציאה = $script_ret) \"$script\" פלט מתסריט משתמש\n" "$script_output\n" "\n" "\n" "!תהנה\n" "\n" "!סליחה\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## SABnzbd עבור RSS תבנית דוא״ל\n" "## זאת תבנית ברדלס\n" "## http://sabnzbd.wikidot.com/email-templates :תיעוד\n" "##\n" "## !שורות חדשות ורווחים לבנים הם משמעותיים\n" "##\n" "## אלו כותרות הדוא״ל\n" "$to :אל\n" "$from :מאת\n" "תאריך: $date\n" "הוסיף $amount עבודות לתור SABnzbd :נושא\n" "## !אחרי זה בא הגוף, השורה הריקה דרושה\n" "\n" ",היי\n" "\n" ".הוסיף $amount עבודות לתור SABnzbd\n" ".\"$feed\" בשם RSS הם מהזנת\n" "\n" " $job \n" "\n" "\n" "ביי\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## SABnzbd רעה עבור URL תבנית דוא״ל של משיכת\n" "## זאת תבנית ברדלס\n" "## http://sabnzbd.wikidot.com/email-templates :תיעוד\n" "##\n" "## !שורות חדשות ורווחים לבנים הם משמעותיים\n" "##\n" "## אלו כותרות הדוא״ל\n" "$to :אל\n" "$from :מאת\n" "תאריך: $date\n" "NZB נכשל במשיכת SABnzbd :נושא\n" "## !אחרי זה בא הגוף, השורה הריקה דרושה\n" "\n" ",היי\n" "\n" ".$url מתוך NZB-נכשל לאחזר את ה SABnzbd\n" "הודעת השגיאה הייתה: $msg\n" "\n" "ביי\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2088432 SABnzbd-4.3.2/po/email/pl.po0000644000000000000000000001327514625637207014713 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Domyślny szablon maila w SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znak nowego wiersza i spacji ma znaczenie!\n" "##\n" "## To są nagłowki maila\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd zadanie $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Następnie treść maila, wymagana jest pusta linia!\n" "\n" "Cześć,\n" "\n" "SABnzbd pobrał \"$name\" \n" "\n" "SABnzbd nie pobrał \"$name\" \n" "\n" "Zakończono o $end_time\n" "Pobrano $size\n" "\n" "Rezultat zadania:\n" "\n" "Etap $stage \n" "\n" "$result \n" "\n" "\n" "\n" "Odpowiedź od skryptu \"$script\" (kod wyjścia = $script_ret):\n" "$script_output\n" "\n" "\n" "Baw się dobrze!\n" "\n" "Przykro mi!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Szablon wiadomości RSS dla SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znak nowego wiersza i spacji ma znaczenie!\n" "##\n" "## To są nagłowki maila\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd dodał $amount zadań/zadania do kolejki\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Następnie treść maila, wymagana jest pusta linia!\n" "\n" "Cześć,\n" "\n" "SABnzbd dodał $amount zadanie/zadań do kolejki.\n" "Pochodzą one z wiadomości RSS \"$feed\".\n" "\n" "$job \n" "\n" "\n" "Nara\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Szablon wiadomości błędnego pobierania URL SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znaki nowego wiersza i białe znaki mają znaczenie!\n" "##\n" "## To są nagłówki wiadomości\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd nie udało się pobrać pliku NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Po tym następuje treść. Pusty wiersz jest wymagany!\n" "\n" "Cześć,\n" "\n" "SABnzbd nie udało się pobrać pliku NZB z $url.\n" "Komunikat błędu: $msg\n" "\n" "Do usłyszenia.\n" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.209081 SABnzbd-4.3.2/po/email/ru.po0000644000000000000000000001535414625637207014726 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Стандартный шаблон сообщения электронной почты\n" "## Это шаблон Cheetah\n" "## Документация: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Новые строки и пробелы имеют значение!\n" "##\n" "## Это заголовки электронной почты\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd: задание $name \n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Теперь следует тело сообщения. Пустая строка является обязательной!\n" "\n" "Привет.\n" "\n" "Системой SABnzbd загружено задание «$name» \n" "\n" "Системе SABnzbd не удалось загрузить «$name» \n" "\n" "Время окончания загрузки: $end_time\n" "Загруженный размер: $size\n" "\n" "Результаты задания:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Результат выполнения сценария «$script» (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Удачи!\n" "\n" "Сожалеем.\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Шаблон RSS для электронной почты\n" "## Это шаблон Cheetah\n" "## Документация: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Новые строки и пробелы имеют значение!\n" "##\n" "## Это заголовки электронной почты\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: В очередь загрузки SABnzbd добавлены задания: $amount \n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Теперь следует тело сообщения. Пустая строка является обязательной!\n" "\n" "Привет.\n" "\n" "В очередь загрузки SABnzbd были добавлены задания: $amount.\n" "Они были получены из RSS-ленты «$feed».\n" "\n" " $job \n" "\n" "\n" "До свидания\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Шаблон электронной почты для излечения неверного URL-адреса\n" "## Это шаблон Cheetah\n" "## Документация: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Новые строки и пробелы имеют значение!\n" "##\n" "## Это заголовки электронной почты\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: Службе SABnzbd не удалось загрузить NZB-файл\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Теперь следует тело сообщения. Пустая строка является обязательной!\n" "\n" "Привет.\n" "\n" "Службе SABnzbd не удалось загрузить NZB-файл по адресу $url.\n" "Сообщение об ошибке: $msg\n" "\n" "Конец сообщения\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2081852 SABnzbd-4.3.2/po/email/fi.po0000644000000000000000000001330214625637207014665 0ustar00runnerstaff# SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # # Translators: # Safihre , 2020 # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.1\n" "PO-Revision-Date: 2020-06-27 15:56+0000\n" "Last-Translator: Safihre , 2020\n" "Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Oletus sähköpostipohja SABnzbd:lle\n" "## Tämä on Cheetah pohja\n" "## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rivinvaihdot ja välilyönnit ovat merkitseviä!\n" "##\n" "## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa!\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd on työssä $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on pakollinen!\n" "\n" "Hei,\n" "\n" "SABnzbd on ladannut \"$name\" \n" "\n" "SABnzbd on epäonnistunut \"$name\" latauksessa\n" "\n" "Valmistui $end_time\n" "Ladattu $size\n" "\n" "Työn lopputulos:\n" "\n" "Tila $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Käyttäjän skriptin tuloste \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Nauti!\n" "\n" "Pahoittelut!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS sähköpostipohja SABnzbd:lle\n" "## Tämä on Cheetah pohja\n" "## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rivinvaihdot ja välilyönnit ovat merkitseviä!\n" "##\n" "## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa!\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd on lisännyt $amount työtä jonoon\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on pakollinen!\n" "\n" "Hei,\n" "\n" "SABnzbd on lisännyt $amount työtä jonoon.\n" "Ne ovat RSS syötteestä \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Heippa\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Virheellisen URL-noudon sähköpostin pohja SABnzbd ohjelmalle\n" "## Tämä on Cheetah pohja\n" "## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rivinvaihdot ja välilyönnit ovat merkitseviä!\n" "##\n" "## Tässä on sähköpostin otsikkotiedot\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd ei voinut hakea NZB tiedostoa\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Tämän jälkeen tulee viestin sisältö, tyhjä rivi on pakollinen!\n" "\n" "Hei,\n" "\n" "SABnzbd ei voinut hakea NZB tiedostoa osoitteesta $url.\n" "Virheviesti: $msg\n" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.2076216 SABnzbd-4.3.2/po/email/SABemail.pot0000644000000000000000000000564014625637207016076 0ustar00runnerstaff# # SABnzbd Translation Template file EMAIL # Copyright 2007-2024 by The SABnzbd-Team (sabnzbd.org) # msgid "" msgstr "" "Project-Id-Version: SABnzbd-4.3.2RC1\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: team@sabnzbd.org\n" "Language-Team: SABnzbd \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1828837 SABnzbd-4.3.2/linux/org.sabnzbd.sabnzbd.sharedmimeinfo0000644000000000000000000000054414625637207022134 0ustar00runnerstaff NewzBin Usenet index (compressed) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.183181 SABnzbd-4.3.2/linux/sabnzbd@.service0000644000000000000000000000143014625637207016465 0ustar00runnerstaff# copy or _hard_link to # Debian: /lib/systemd/system/sabnzbd@.service # others: /usr/lib/systemd/system/sabnzbd@.service # # To start SABNzbd once for USER use: # systemctl start sabnzbd@USER.service # # To start SABNzbd on boot for USER use: # systemctl enable sabnzbd@USER.service # # Config will be placed in ~USER/.sabnzbd/ [Unit] Description=SABnzbd binary newsreader Documentation=https://sabnzbd.org/wiki/ Wants=network-online.target After=network-online.target [Service] Environment="PYTHONIOENCODING=utf-8" ExecStart=/opt/sabnzbd/SABnzbd.py --disable-file-log --logging 1 --browser 0 User=%I Type=simple Restart=on-failure ProtectSystem=full DeviceAllow=/dev/null rw DeviceAllow=/dev/urandom r DevicePolicy=strict NoNewPrivileges=yes [Install] WantedBy=multi-user.target ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1828055 SABnzbd-4.3.2/linux/org.sabnzbd.sabnzbd.appdata.xml0000644000000000000000000000646414625637207021362 0ustar00runnerstaff org.sabnzbd.sabnzbd MIT SABnzbd Free and easy binary newsreader

SABnzbd is a free and Open Source web-based binary newsreader, with support for the popular nzb file format. It greatly simplifies the process of downloading from Usenet, thanks to a friendly web-based user interface and advanced built-in post-processing options including the ability to automatically verify, repair, extract and clean up downloaded posts. It runs anywhere, comes in over a dozen languages, and integrates with a host of tools, apps and services that help automate the download process.

Network FileTransfer https://sabnzbd.org https://github.com/sabnzbd/sabnzbd/issues https://github.com/sabnzbd/sabnzbd https://sabnzbd.org/wiki/translate https://sabnzbd.org/donate https://sabnzbd.org/wiki/ https://sabnzbd.org/wiki/faq https://sabnzbd.org/live-chat.html sabnzbd.desktop application/x-nzb application/x-compressed-nzb pointing keyboard touch 640 always GPL-2.0-or-later The SABnzbd-Team https://sabnzbd.org/images/landing/screenshots/interface.png Web interface https://sabnzbd.org/images/landing/screenshots/night-mode.png Night mode https://sabnzbd.org/images/landing/screenshots/config.png Easy configuration
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1830041 SABnzbd-4.3.2/linux/sabnzbd.bash-completion0000644000000000000000000000355014625637207020016 0ustar00runnerstaff# bash completion for sabnzbd _sabnzbd() { local cur prev words cword split # list all options here local all_options="-f --config-file --pidfile -t --templates --pid -l --logging -w --weblogging -d --daemon -h --help -v --version -c --clean -p --pause --repair --repair-all --no-login --log-all --console --disable-file-log --new -b --browser --ipv6_hosting --inet_exposure --https -s --server" _init_completion -s || return # handle options that take arguments case $prev in # 0..1 --browser|--ipv6_hosting|-!(-*)[b]) COMPREPLY=( $(compgen -W '{0..1}' -- "$cur") ) return ;; # -1..2 --logging|-!(-*)[l]) COMPREPLY=( $(compgen -W '{-1..2}' -- "$cur") ) return ;; # 0..5 --inet_exposure) COMPREPLY=( $(compgen -W '{0..5}' -- "$cur") ) return ;; # directory path --templates|--pid|-!(-*)[t]) compopt +o nospace _filedir -d return ;; # file path --config-file|--pidfile|-!(-*)[f]) compopt +o nospace _filedir return ;; # port number --https) COMPREPLY=( $(compgen -W '{0..65535}' -- "$cur") ) return ;; # host:port --server|-!(-*)[s]) # suggest possible formats COMPREPLY=( $(compgen -W 'hostname :port hostname:port ipv4 ipv4:port [ipv6] [ipv6]:port' -- "$cur") ) return ;; esac $split && return if [[ "$cur" == -* ]]; then COMPREPLY=( $(compgen -W "$all_options" -- "$cur") ) else _filedir '@(nzb|nzb.gz|nzb.bz2|zip|rar|7z)' fi } && complete -F _sabnzbd SABnzbd.py sabnzbd sabnzbdplus ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1831067 SABnzbd-4.3.2/linux/sabnzbd.desktop0000644000000000000000000000050214625637207016375 0ustar00runnerstaff[Desktop Entry] Name=SABnzbd GenericName=Binary newsreader Comment=Download from Usenet Exec=/opt/sabnzbd/SABnzbd.py --browser 1 %F Icon=sabnzbd Terminal=false Type=Application Categories=Network;FileTransfer; Keywords=usenet;binaries;download;nzb;nntp;newsreader; MimeType=application/x-nzb;application/x-compressed-nzb; ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1566806 SABnzbd-4.3.2/icons/sabnzbd_osx_idle.tiff0000644000000000000000000001314614625637207017526 0ustar00runnerstaffMM*r P8$aPd D@H|J?bh `gx`@&ǠRP!`X@| }p9fMNCNP0\ L0) M@H-$ h:kcY@pCGh0+Zt }@S*vhKC04FvT0| /͐6 -4+#bR2 廎jyP5O:[NBn@@԰6 Bʀxr`|8FH(P bVH\8έ$ JJdBjZ0fv+(hPHt|i(1=RS"s Ticon_18x18.pngHHtiffutil v254.1Z%Gxicon_18x18.pngappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l P8$ BaPd6DbQ8V-FcQv=HdR9$M'JeBxv oX͠S(5 *ϠOJ<n@@ eNİ4 3@uv`fn`LcY`Vxk[Wt]RdZ-V(cH|T,5g-&W09.oo|-`@l8Os;nVaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.156268 SABnzbd-4.3.2/icons/sabnzbd.ico0000644000000000000000000006053214625637207015463 0ustar00runnerstaff hV   F00 % D(  @afC_C_ ((((C_C_#(((("(((((((((((("((((((!(((((((((((((((((0 `  222222 (((((((((()((((($((((((#(((((((()(((((()$((((((((#(((((((((()(((((((()#((((((((((#(((((((((((')(((((((((()))))))))))))))( @ &&&&&&Z((((((ZZ%(((((($ZZ (((((((( ZZ((((((((Z%(((((((($ (((((((((( (((((((((($((((((((((# ((((((((((((((((((((((((#(((((((((((("(((((((((((((((((((((((((((("((((((((((((((!((((((((((((((((((((((((((((((((!(((((((((((((((( ((((((((((((((((('((((((((((((((((((((?(0` %   ! !!           (((((((((()((((((((()#(((((((((((((((((((((((()((((((((((((#((((((((((((()!'((((((((((((((' )(((((((((((((()"((((((((((((((((! '((((((((((((((((' )(((((((((((((((()!((((((((((((((((((  '((((((((((((((((((& )(((((((((((((((((((!((((((((((((((((((() '((((((((((((((((((((& )((((((((((((((((((((( ((((((((((((((((((((() &((((((((((((((((((((((& (((((((((((((((((((((((()(((((((((((((((((((((() &((((((((((((((((((((((((%(((((((((((((((((((((((((()(((((((((((((((((((((((()((((((((((((((((((((((((((((?@PNG  IHDR\rfIDATx eWYǿ7 3=[gBÌJA5@HBXdߔFUd!X*J%B)A,!df2az׋:=o99Lw{߹ݳҲ|gN~O4]_S 鬦k&Mg|gb@eM?ti@UMtBlX5 ![8Lߙ hw&\MG4];T˚^iwFlI鍾3AH4}V-3bCLGAߙ ĂOiUӺT#&Lk B,4MH5b^+}`d`vtH$6fe~iǎhz[J˚CdZaHl9*_hO]"&V)Tt@a@(:s"g)OT?FDzw+i6r_:z ar.Kzᆢ.D087ԂVg'wE66LGx6t  ˅ÿR;}Dgrۯ)&qXTܹR b:\=(.#z=ڻ| 'Ef~ZO?jحa0 A?Q^O]"CʬkRvkpRTP?SO`pHψ0 eIeRDEv$3PR@x~ XHp 45T7~G{5 dJ:١TVrP^IGmS%$!g^`!tiM`HMMP01}QJP^IOh@ E`y֌بQ  0$&J + ӴsiQrfW_8t+] Zl }\?/}J`0 hAY3+` M(/$ oF 2 h=J#f0ZUP^iڻ aorfO_،Gc,#a@g0 h!Nk6W#7*?HV੏.@xqa ZQ F.¦?'$ 7+1 h~-P^iR⤹S/VܷXt.#TL3+W+|W4+B)4V;}'iTk۞J[XFa@S1ɲ5 W/4Bx@ %-@aZ]4IV(d#2ݾ4s׹  " `s`STOJv7b:=,+uT)’01ə%o f Cfz4ɲGͿBx%[$a,=ej)GX: k0 ?ξ(d/zPTlT,? + ˇ'ˈ3 y'jpWkVfh[L(@*NI:=^P^#$ 8`%egL_evKÏpP?&W< @2H,~)Z30G®)@3/ZLW< @LS zvP^+ @k@s"Sg{ ~Q5 fv(10A~aF@xſ0CZHάQ/|H€q3YÀXQP^/i0k0 <'ظ^@>d#FU _C# ` 0 (OkpAx% 5I੟,z0Vf?7S^ GI0neG @@N v>'$?h4 +a aZ_3W >+ |}QK-h ~ Jx5/cem 80iArf/f+)'?V SPǼs}'0IөlVW_YU00 YFi!b/N3Z a ` fxL%W&| %~^ + SSÀ ș%򯇯 o/dW A  xuP^ [Ip, B^iSQӢVb bi?Mx%|`!,#i̴Jxș'[ Jt3 h&@_P^CIcOT %Q,"YJ(dX]὚鑚0 )p_#N)a@L_X2$~%i;`ktV3L0)M€!a"07 <пr^ *tcF+W8PzL IxP6KIQ(ygLP@0zˈ^?BV"@X0wŠJPH'҅0f(>igIN6 txHE' J=1@S| ]OB~G୚>X-^28`hp8' ;%YɉWE~9$NJ"W_n~D&W NIߌd`G=#CKZ{믉ܦ"lk`>ET<׸zlzy%߇f{l�F_UxP{oy]5Pc (( j3_ЇkPme#|%ˈkX-9%lTW;.jS"+Zyr-󆓽X譚{78 <0;Rx_[.rD^ 'R<%t[m=M+ .Ml53kH"o`0,04mx{!WPVBzD>Bo45k̿&shjzC^4YY_KXv$aYA'k;@I|Ěk.i}˜ Y+M"/ItValO|F(v`,Gm="\{?Y ~z^Q x?(9){:{ntNA\F,6`,@bVGcYkUrNZ)Ohmˮ?`NjP@:zե`ffFW%gfEuȜ})rz92_MePߩN߹LOO`cǫ.3[|,8myM/v6L"E"!@9:{ ˈ3 (P کi-9.?izA㭲e-W]"r7(䰌8À2P2&2Ϳ|Us+* h %P El~Ĕ^+rӖtmуȿP烾0`@ 9zioEK_&`ݧ9{ zW zsJP(aп#-y(vQ\\d/](`\@/ p7:šϥP,ƘTpv_$@$ 2AlP{=GInK1k6o 7]+v2&@BEӖ?!) n}_#,A&'a(,/z]9m|.xk*_聼TU0oȇoJ0`@v%^ּe=w Ⱂ&Sx D> im 0 FK Po|iK4 5L r RUWE2K9 YS7FX/m`ltd2-TPr#}q3![>0+ⷝ6E 4'(M+2㒉^}cD=pVD:Q?*.,w!&`jϥ}gE^19dNBuף B1cSWShlH9W|L|(ED(4Puo Ng$d.3s)Mw}!j8k@Bp` |Q!@C/ ({(TE`j(R=@BH5_@PP  |Q!@C/ ({(T2JOHPP+3,h\؀6Ʌj<ڵ+pT-kkkP+3`-q"v4N ۚ#N {4G2``aM7Slfި(({(PP+SjoQ@@TNM76SlCMn @@TgJPÏ8eZ]H.7*PVrēIC `O z4`H]@LYcbեz@+B%D  ==@$PPP@CCD`` ==@$PPP@CCD`` ==@$P `ffF|g  ؟ұ19y,{K/Y Pqadtxx8*ju)H2::*9(vd[ ̬߄D>3gTF޵LhB>׍jkz%uZ~Mo}m8Zg}|-!dr=ӾTl d1^:Wzżt@{_'At֍ko%3V.hj͞,vVYlbFoN qPvgj+ dz=EL) ?nts x#Ր5?b,k~N4mMH^w\/ Tahuk[v_^[NI6S{}X +j<$pV{TGJdX{1h]SGyT;:j+=“(7%0ǎ6^5*@n%VUuUuܞ2_G~Pxy 6 u/5j[~zFϝ\w9V^'i,amP}RdE! v[@K>?w͌FKy7b`u} $\d`]*LG4-Idվ Z@\Pbv Q [洎0a@gϝ}>"2Wh%~$/:[p|*W賅SOky/J8I]"wX%0,M|:4 .譐_0?~XRl}(0$@kWzxXӏy-g[cAËN-q{ =BÀ:+vgD};+pxI/@Gi ȝp^SL/-_xJ 9;_[N/< C[vVg'X51-rU} P$/;Γ@N vnF?o~F)ǽV@SS'NxAϿe:{b,2yT 9z[x?E/X8I/r h+b=Ys~x/E/ZYO e~P$?YC".^PGI/~a>A VTd\6{8PMqJ6k `d׊-*L<]"w/ӷ;'/``-,[yߍO[N\XK]/VVaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l P8$ BaPd6DbQ8V-FcQv=HdR9$M'JeA )i@p7L"`E'% @T9cÁ* d {07kcV+P* @V;, p+mVT` /uK0` (pNsy#C[60j[Mncx,| r+; `7M_yoqܟ/sW&kww;%f:yέc1J=S7C;+? (2H͠<恟:uf:jH:&@ұ@w fZp|b,f4$: p, Egz/: AIMV/lb)  Qj fgIB؁FhT <BL :VI+uS(1? fpTaJBGE(R-+ J2S*(PGW`o jj!hv"*ZU EP` fu̓!2X^(ze}cL)me L_RuJ$$ L$"(1*=RS:%Bshicon_18x18@2x.png  tiffutil v254.1Z%Gxicon_18x18@2x.pngappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1564224 SABnzbd-4.3.2/icons/sabnzbd16_32green.ico0000644000000000000000000001246614625637207017162 0ustar00runnerstaff h&  (  @=i././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1558435 SABnzbd-4.3.2/icons/logo-arrow.svg0000644000000000000000000000112214625637207016143 0ustar00runnerstaff././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1561265 SABnzbd-4.3.2/icons/nzb.ico0000644000000000000000000006161314625637207014632 0ustar00runnerstaff hV   F00 % D(  @#aCB|B|B|Je̜e̜e̜e̜B|"^AA-A-B|B|Ue̜e̜e̜e̜A-A-B|B|`Șe̜e̜e̜e̜`ȗB|B|B|Ie̜e̜e̜e̜e̜e̜HB|B|Te̜e̜e̜e̜e̜e̜SB|B|_ȗe̜e̜e̜e̜e̜e̜_ǖB|B|e̜e̜e̜e̜e̜e̜e̜d˛B|B|e̜e̜e̜e̜e̜e̜e̜e̜B|(0 ` AzAzAzAzAzAz,,,---&&& '''111,,,%%%111AzAzAzAzAzAzTgϟgϟgϟgϟ^AzAzAzAzAzAzAzAzTfϞfϞfϞfϞgϟgϟAzAzAzAzAzAzAzAzAzD}\Ɣe̜e̜e̜e̜e̜gϟAzAzAzAz@yAzIcʚe̜e̜e̜e̜e̜e͜`ƖBxu@xIbʙe̜e̜e̜e̜e̜e̜e̜e̜aɘG>u@xQe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜O>uAy[œf̜e̜e̜e̜e̜e̜e̜e̜e̜f̝Yđ?vF~bʙe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜aɘCyNe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜KYfΞf͝f͝f͝f͝f͝f͝f͝f͝f͝f͝fΞUfΞfΞfΞfΞfΞfΞfΞfΞfΞfΞfΞfΞfΞfΞ( @ &&&MM&&MMMM&ZB|B|B|B|B|B|B|C|cʚe̜e̜e̜e̜C|C|B|B|ZB|B|B|B|B|B|B|C|cʚe̜e̜e̜e̜e̜e̜C|B|B|B|ZB|B|B|B|B|B|B|B|Le̜e̜e̜e̜e̜e̜e̜LB|B|B|B|ZB|B|B|B|B|B|B|B|B|We̜e̜e̜e̜e̜e̜e̜e̜B|B|B|B|B|B|B|B|B|B|B|B|B|B|B|bʙe̜e̜e̜e̜e̜e̜e̜e̜aəB|B|B|B|B|B|B|B|B|B|B|B|B|B|Ke̜e̜e̜e̜e̜e̜e̜e̜e̜e̜JB|B|B|B|B|B|B|B|Ve̜e̜e̜e̜e̜e̜e̜e̜e̜e̜UB|B|B|B|B|B|B|B|aəe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜`ɘB|B|B|B|B|B|B|Je̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜IB|B|B|B|B|B|Ue̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜TB|B|B|B|B|B|aɘe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜`ȗB|B|B|B|B|Ie̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜HB|B|B|B|Ue̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜SB|B|B|B|`ȗe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜_ǖB|B|HHe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜d˛GHHTe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜RHH_ǖe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜^ǕHHd˛e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜d˛He̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜?(0` %   B|B|  B|B|B|B| B|B|b̚_ʗB|B|B|B|B|b̚b̚B|B|B|  &&&      """       B|C}C}C}C}C}C}C}C}C}C}C}C}fΝfΝfΝfΝfΝfΝfΝfΝfΝfΝC}C} B|B|B|B| B|C~C}C}C}C}C}C}C}C}C}B}D~\ǕfΞfΝfΝfΝfΝfΝfΝfΝfΝfΝfΞC} C}C}C}B|B|  B|C~C}B}B}B}B|B|B|B|B|B|B|Ibʚe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜C}  C}B}B}C}B|B| B|B|B|B|B|B|B|B|B|B|B|B|B|B|Re̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜dʛB|B|B|B|B|B|B|      C}B|B|B|B|C}[œf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜f͝C}B|B|B|B|Hbʙe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜fΝ_ȗD}AzAzAzAzB{C}B|B|B|B|Qe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜d˛MB|B|B|B|A{C}B|B|B|C}[Ēf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜VB|B|B|B|A{C}B|B|B|Hbʙe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜_ȖEB|B|B|A{C}B|B|A|Pe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜d˛LA|B|B|A{C}B|B|C}ZĒf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜UB|B|B|A{C}B|B|Gaɘe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜^ǖE~B|B|A{C}B|A|Oe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜d˛KB|B|A{C}B|C}YÑf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜UB|B|A{C}B|Gaɘe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜]ǕD~B|A{C}A|Oe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜c˚KB|A{C}B|XÐf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜TB|A{B}F`ȗe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜]ƔD~A{B}Nd̛e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜cʚJA{C~Wf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜SA{G`ȗe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜\ƔC}Nd˛e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜cʚIWĐf̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜Q`˙f͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝e͝f͝[œe̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜e̜?@PNG  IHDR\rfIDATx \Uǿ޻zKo& }322308((8ǃ0qA8@pΉCD a ($L/}[]}?BBH}9**uT!!ҰJϨtJߵ}A Rg^ߪt$SJe"IUؾMt d^Q鵶/ ~@Pt !āva__NB>ҏl_ ~!~aJ۾ /lTTA!Ɲ6 VHm}?fiKvq VYIJod>m_ %#CnVikixU$2;7-dk 8ZkOnuS~-'F'7dS 8 yU5R}XXX^mlN#kU4ևMv!Ęٹ%>ds ȹ aio`@İN5@16H]]t0 yc! ýR0?BXd!Df WSV0@BeU3 069"#*BU֣}uOWRp%@c]H0dO$Qث){@\5\U!=\ $[Хm3)AVZSkMv'ds+3`.WپvSƧdx|p=€jPYQiH- Y ZDohRPJحYZm_?}W Y @Z  P7/ӳr`쑵ttI]MaQ lN#kDf/Ȥ*PIU5- :>82 攠쑓ttKmMɡH3?쑓@YZB bf\G=`PSU+: p:)c!tSQY P}/ģ؟(_G͍-j}/ărfBύG^_P $2`5 H ?="ТB O@wELJRțjT)KLd?@` ̀]=w !C~Q!76 74۾' T?2%FG@DaB0rG^KSնX?sܖG^0KPSC}5`< aI02>$cSFR{ af = "Ю€FeǬ*_0, @\/#ˈ|(H>UEQGJX>J~?({L%P].'~ = &dzd~HqY= Z@?m')0ۯ3QPCkC J}){T8<$HJQj_ @T0dA#00OGT`?Dz( Fx5t jcPF zh0Z*xɁ?~="$0 (-0/fͶ({Eӄa0RJ?P(^cP:({M J, =&ECx) es<` F=z1Py E@@/#ޥ%f>յ` ` q,%NK@'t /ǣQtTր .#k :` BZğ߇h^Gأ*hV#@Êjկ߂ϜPU FlSP"jpc'n7Y5, .5}ؠ*c7 JXF\$D핹5֦6ij`z?>2` 둁!0`گ񩱼l`@^=aU]B: iU{_et6aт Ak@ς~1O@ú   eMJ3mPx,-9,C İN=< ˇc0#H~Q-9({xBCBuM\Fc C* 2}c]Ho?BBB~`aW>*P XH({xF%x4̀0Io?Th({xH[p]~] 9SCjCNAvޜ6LHa[ ({xL`l@%k$}zb|=<' Dk3 _( @" hVa@'ShgA!3a R\PǴߘX1`O a Ĝ KTPeMI61 (.*Y)kxVX/ `cى@óH* |'[ 5I1̸ 5<-`lV&3- @EB:Z P߲ߦP@sc4Z.X9?` Vݺ4@ bt){x^D@ G+ ({x^!BR/X (kBl2  z϶bx#cI޿8ḿh$C~Q1p!Rvf![#qԕpJ/Y:c'*Ud*]ҡb^K0siƧ췽B^DH>RJoe$P0 o?i>GT:fW0<ÄI>90⿾ Ti=-v>hr; B0QÀ3ĢcS#E{3R}S"t'ާhr;HX?3PpldZFzm_*]<(xIk`@E@ qyw/ɋdd`R$!*iWK!9Y*}](*ŚJ-t6a9*-WG ~ X]!G.7JEe@m_R@J ΒZ@!]=zAL+>tm~欒)PdH] A) 5_lrV[;&l_FGYa$Ơ\3=kXo&:rXҋ{?rOO.xypk`Bؼ釷hK%Y{ԅ䲻N{`p+~TN>EzwھGT> nm21LFvJ\-tnЏioP].TTVÛ_^S*V:\oRF7] 2).T[bjKwqH&T2?$@V@}w^'.n[u3Y߹Iq7l^>AR dN.dJ,#ޡJ!i7>syq禿bTbN󴽦^6w})󬫺tD>}|^Gj_ DUx ԫ0 0 Q%|&V%OX@2ye7b1KT{Xi6D F 'P@g 0`9;/mOJ;x+ll{h vE`tfP$׏}FjedT|V3N{Ćk G %a9 doOǭFA fZ:d|J`9րJ.#~3~7oxNEsG*NJt^IWU2mrRH]* h2[N$&|z^%t3j0w_qRBDukÀPIf_m)yY1|nDsy ,! o햳.},=+s2 H@a1v4]0ުGݜA}pyS4540ex O_wh$f'w{:75`0qǟZCGP"z.,#0@C,{U~yK27cT:],@W\ I>D<]K   ?ܿW~2;5f*}6vxBePBN=wK][%j2<?O~~23u*-s2_0,Rxߡrه$T*Q u%24VJW{ĸ_d^m"hF\P{=< gu5Vޜs TUi$p{_:*Nk?l/\sOe}۽"ZmFh9t앭w]_Ƌ"h _:9|c.4 7W TKAnDDf+"|̛/-bBy>U`΄;gD]U<.pJ-sY<*(eOeƳH.S"c^VU WO`~g6;f#WUz;&UNnpJ۾SRP٣!nwr# Ksl))O(ytn>t;nM9?Vq\MKKԲ_b!Oo]ի/q0EƭbX ̡|``(s(s(@CC   'PPP>00 99O̡̡|``  '@9?// (sE,:s)sF}}XwTUUI4L̡RA ``r 0P@&((s(s(sP2A8@CC(     @a(LP]IehhSDdp(VYnA#ٳG}B(_}Pi(r P.A>(4P@ (@Pr@( \H@}Pi(r @[qkA(djjsXx)4P!#@,(,3@( PP9(B8C @,(,3@( PP9(B8C @,(,3@( PP9QXo]rRFy1/. U(s2#9@9(CC?9@9(CC?9@9(CC?9@9(CC?9@9(CCT @78z]1iǍ/g&NT!W餌t˜ |*f]\gUPUJ0!˘WNnqJeN !xU5nwr+ *mQBbJɭ}El-!d 4tdcuQ4wMJՒqvW* <>C}!)$ʳ|VDTUQlC]Uj$*5-U:2+s*g4z,_Wڡ(X(@F/t$LdzoQdIT^WUM.1,\|$&.`AVyY(ΩmN]|V5b_6wl;Uz@qr~@x[b2~Wn~^zݽ/|Hb UpYŵ >rLM}P0Uo 037-}G3sgl~AnGd|p$J-‡ IAI3]_(;hL vP|!.#26*cLɱ:|BUr]'ޠÞAj푪sOQ9\ 7~t θtTоQyoJ M%*lwHc})fUʡw *tc2(TZ/<_p%Pk\z۩Kƺ HNK]wIيߜ&$OzJF W+eO?W@~o/Ļ@Kw\|%ЮJ["YG?qoSYW+F[$|)ƕ4n<1ۛW34{s` :;(|1Ǖ:mpR~ ('€6rp~2!7SH3Oq(*$~u㲒:tHcmhY0H.o}Ff>y$<ٓP ;.EqiK{xղǧFex|/<: T$h06~h$3p%Z~A@g t < @F铙n`_o<'O?f:I ~X ?$ǵyW$[0'5SdآtĈ'>q$Urޤ%&> j[ /_u3Uw[Qgtʻ8Jg`en }2=Ц=/Kl5De%—Ok_]\r֥o l$€]?yݻq=6]>/ο$g2 }[nlPĽ>v+vI43=\r"~C>/ߠ5 wrHZyo<=;en8'sOrFXc Trk嬏'l9LnS%\tL\H?Sv=3(SsnD,ZUHB7SBe7 /tɷ |M$D-}r/Jm|ZhFl~e_tN$1sǴ%M]F ͉IENDB`././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1565747 SABnzbd-4.3.2/icons/sabnzbd_osx_clicked.tiff0000644000000000000000000001373614625637207020214 0ustar00runnerstaffMM* P8$O,6B!pȄV"q` ?cq LJ_Ya/;&O$zA%m?[I PԴ0?OFTPz}_g!Hh=Q4trwZmTjMH3|OQ6zfOI0B,`ycdzG)$>>OVhs4&3sCPcDjvxA_͞3cK!zHXǵ1&"/߱rSJp6t  HyAP8T…Ly/#T< q~E E',dR=G"h. (nLE@RJ!3+(lzBa Ğ&aJF*}NOτ ?"=4(l;ȬYEE$T ,,B|P (1=RS("0sRicon_18x18.pngHHtiffutil v254.1Z%Gxicon_18x18.pngappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l P8$ BaPd6DbQ8V-FcQv=HdR9$M'Jdy`/.Aw??9 GO=4K}J65U*RoI_(lJՔuX՘a}onV@?*~y^fl!LJqkAmk|X<.#Xcq,W1g+ap،V3erٍUŚ6=֛{8ZC;v{.QuMׯ]';z~NSz4 OT.m;A @m7C/OVaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1559258 SABnzbd-4.3.2/icons/logo-arrow_gray.svg0000644000000000000000000000112214625637207017165 0ustar00runnerstaff././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1564858 SABnzbd-4.3.2/icons/sabnzbd16_32paused.ico0000644000000000000000000001246614625637207017343 0ustar00runnerstaff h&  (  @iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii?( @ ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ??././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1563554 SABnzbd-4.3.2/icons/sabnzbd16_32.ico0000644000000000000000000001246614625637207016141 0ustar00runnerstaff h&  (  @iiiii$$ii (( ii((ii$((#ia ((((iC_C_((((C_C_#(((("(((((((((((("((((((!((((((((((((((((?( @ ZZZZZZ ZZZ'&ZZ((ZZ((ZZ&((&ZZ(((( ZZ((((ZZ&((((%ZZ (((((( ZZ((((((ZP%(((((($JF (((((((( @<((((((((6%(((((((($ (((((((((( (((((((((($((((((((((# ((((((((((((((((((((((((#(((((((((((("(((((((((((((((((((((((((((("((((((((((((((!((((((((((((((((((((((((((((((((!(((((((((((((((( ((((((((((((((((('((((((((((((((((((??././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4507303 SABnzbd-4.3.2/scripts/Sample-PostProc.sh0000755000000000000000000000073214625637243017243 0ustar00runnerstaff#!/bin/sh # Example of a post processing script for SABnzbd echo echo Started as $0 echo echo "The first parameter (result-dir) =" "$1" echo "The second parameter (nzb-name) =" "$2" echo "The third parameter (nice name) =" "$3" echo "The fourth parameter (newzbin-id) =" "$4" echo "The fifth parameter (category) =" "$5" echo "The sixth parameter (group) =" "$6" echo "The seventh parameter (status) =" "$7" echo "The eight parameter (failure_url) =" "$8" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4508064 SABnzbd-4.3.2/scripts/Sample-PostProc.cmd0000644000000000000000000000071614625637243017373 0ustar00runnerstaff@echo off rem Example of a post processing script for SABnzbd echo. echo Running in directory "%~d0%~p0" echo. echo The first parameter (result-dir) = %1 echo The second parameter (nzb-name) = %2 echo The third parameter (nice name) = %3 echo The fourth parameter (newzbin #) = %4 echo The fifth parameter (category) = %5 echo The sixth parameter (group) = %6 echo The seventh parameter (status) = %7 echo The eight parameter (failure_url)= %8 echo. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4508774 SABnzbd-4.3.2/scripts/Sample-PostProc.py0000644000000000000000000000264714625637243017265 0ustar00runnerstaff#!/usr/bin/python3 # Example Post-Processing Script for SABnzbd (3.0.0 and higher), written in Python. # For Linux, MacOS, Windows and any other platform with Python # See https://sabnzbd.org/wiki/scripts/post-processing-scripts for details # # Example test run on Linux: # env SAB_VERSION=X.Y SAB_AVG_BPS=666 python3 ./Sample-PostProc.py somedir222 nzbname CleanJobName123 Index12 Cat88 MyGroup PP0 https://example.com/ import sys, os # Raw parsing of input parameters en SABnzbd environment variables counter = 0 print("INPUT from argv:") for item in sys.argv: print("Argument", counter, ":", item) counter += 1 print("INPUT from environment variables (only SAB specifics):") for item in os.environ: if item.find("SAB_") == 0: print(item, os.environ[item]) # More intelligent parsing: try: (scriptname, directory, orgnzbname, jobname, reportnumber, category, group, postprocstatus, url) = sys.argv except: print("No SAB compliant number of commandline parameters found (should be 8):", len(sys.argv) - 1) sys.exit(1) # non-zero return code # Some examples: print("Examples of some specific values:") print("jobname is:", jobname) try: sabversion = os.environ["SAB_VERSION"] print("SAB_VERSION is:", sabversion) except: pass """ your code here """ # We're done: print("Script done. All OK.") # the last line will appear in the SABnzb History GUI sys.exit(0) # The result code towards SABnzbd ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4509542 SABnzbd-4.3.2/email/email-zh_CN.tmpl0000644000000000000000000000204014625637243016272 0ustar00runnerstaff#encoding UTF-8 ## ## SABnzbd 默认电子邮件模板 ## 这是一款 Cheetah 模板 ## 文档: http://sabnzbd.wikidot.com/email-templates ## ## 新行与空格均有重要意义! ## ## 这些是电子邮件头 To: $to From: $from Date: $date Subject: SABnzbd 已任务 $name X-priority: 5 X-MS-priority: 5 ## 到主体部分时,必须要有空行! Hi, SABnzbd 已完成 "$name" 的下载 SABnzbd 下载 "$name" 失败 完成于 $end_time 已下载 $size 任务结果: Stage $stage $result 用户脚本 "$script" 输出内容 (退出代码 = $script_ret): $script_output Enjoy! 非常抱歉! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4510236 SABnzbd-4.3.2/email/email-cs.tmpl0000644000000000000000000000207714625637243015710 0ustar00runnerstaff#encoding UTF-8 ## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has job $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has downloaded "$name" SABnzbd has failed to download "$name" Finished at $end_time Downloaded $size Results of the job: Stage $stage $result Output from user script "$script" (Exit code = $script_ret): $script_output Enjoy! Sorry! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4510891 SABnzbd-4.3.2/email/rss-fi.tmpl0000644000000000000000000000117214625637243015414 0ustar00runnerstaff#encoding UTF-8 ## ## RSS sähköpostipohja SABnzbd:lle ## Tämä on Cheetah pohja ## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates ## ## Rivinvaihdot ja välilyönnit ovat merkitseviä! ## ## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa! To: $to From: $from Date: $date Subject: SABnzbd on lisännyt $amount työtä jonoon X-priority: 5 X-MS-priority: 5 ## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on pakollinen! Hei, SABnzbd on lisännyt $amount työtä jonoon. Ne ovat RSS syötteestä "$feed". $job Heippa ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4511542 SABnzbd-4.3.2/email/rss-ru.tmpl0000644000000000000000000000156114625637243015446 0ustar00runnerstaff#encoding UTF-8 ## ## Шаблон RSS для электронной почты ## Это шаблон Cheetah ## Документация: http://sabnzbd.wikidot.com/email-templates ## ## Новые строки и пробелы имеют значение! ## ## Это заголовки электронной почты To: $to From: $from Date: $date Subject: В очередь загрузки SABnzbd добавлены задания: $amount X-priority: 5 X-MS-priority: 5 ## Теперь следует тело сообщения. Пустая строка является обязательной! Привет. В очередь загрузки SABnzbd были добавлены задания: $amount. Они были получены из RSS-ленты «$feed». $job До свидания ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4512365 SABnzbd-4.3.2/email/rss-pl.tmpl0000644000000000000000000000107414625637243015432 0ustar00runnerstaff#encoding UTF-8 ## ## Szablon wiadomości RSS dla SABnzbd ## To jest szablon Cheetah ## Dokumentacja: http://sabnzbd.wikidot.com/email-templates ## ## Znak nowego wiersza i spacji ma znaczenie! ## ## To są nagłowki maila To: $to From: $from Date: $date Subject: SABnzbd dodał $amount zadań/zadania do kolejki X-priority: 5 X-MS-priority: 5 ## Następnie treść maila, wymagana jest pusta linia! Cześć, SABnzbd dodał $amount zadanie/zadań do kolejki. Pochodzą one z wiadomości RSS "$feed". $job Nara ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4513059 SABnzbd-4.3.2/email/email-da.tmpl0000644000000000000000000000210314625637243015655 0ustar00runnerstaff#encoding UTF-8 ## ## Standard E-mail-skabelon til SABnzbd ## Dette er en Cheetah-skabelon ## Dokumentation: http://sabnzbd.wikidot.com/email-templates ## ## Linjeskift og blanktegn har betydning! ## ## Dette er e-mail-headerne To: $to From: $from Date: $date Subject: SABnzbd har job $name X-priority: 5 X-MS-priority: 5 ## Herefter kommer kroppen, den tomme linje skal være der! Hej, SABnzbd har hentet "$name" SABnzbd kunne ikke hente "$name" Færdig kl. $end_time Hentet $size Resultat af job: Etape $stage $result Output fra brugerscriptet "$script" (Afslutningskode = $script_ret): $script_output Hav det godt! Beklager! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4513721 SABnzbd-4.3.2/email/rss-de.tmpl0000644000000000000000000000111214625637243015400 0ustar00runnerstaff#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hallo, SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt. Sie stammen vom RSS-Feed "$feed". $job ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.451438 SABnzbd-4.3.2/email/rss-zh_CN.tmpl0000644000000000000000000000102314625637243016012 0ustar00runnerstaff#encoding UTF-8 ## ## SABnzbd RSS 电子邮件模板 ## 这是一款 Cheetah 模板 ## 文档: http://sabnzbd.wikidot.com/email-templates ## ## 新行及空格均有重要意义! ## ## 这些是电子邮件头 To: $to From: $from Date: $date Subject: SABnzbd 已将 $amount 项任务加入队列 X-priority: 5 X-MS-priority: 5 ## 到主体部分时,必须要有空行! Hi, SABnzbd 已将 $amount 项任务加入队列。 它们出自 RSS feed "$feed"。 $job Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4515057 SABnzbd-4.3.2/email/email-sv.tmpl0000644000000000000000000000220014625637243015717 0ustar00runnerstaff#encoding UTF-8 ## Translation by Andreas Lindberg andypandyswe@gmail.com ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has job $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hej, SABnzbd har laddat ned "$name" SABnzbd misslyckades med att ladda ned "$name" Färdig $end_time Nedladdat $size Resultat: Stage $stage $result Utmatning från användarskript "$script" (Exit code = $script_ret): $script_output Lycka till! Beklagar! ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1716993699.45157 SABnzbd-4.3.2/email/rss-sr.tmpl0000644000000000000000000000136714625637243015450 0ustar00runnerstaff#encoding UTF-8 ## ## РСС шаблон ел. поште за САБнзбд ## Ово је Гепард шаблон ## Документација: http://sabnzbd.wikidot.com/email-templates ## ## Нови редови и размаци су важни! ## ## Ово су заглавља ел. поште To: $to From: $from Date: $date Subject САБнзбд је додао $amount посла у ред X-priority: 5 X-MS-priority: 5 ## После тога долази разрада, празни редови су потребни! Здраво, САБнзбд је додао $amount посао(ла) у ред. Долазе са РСС довода „$feed“. $job Поздрав ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4516327 SABnzbd-4.3.2/email/rss-it.tmpl0000644000000000000000000000105214625637243015427 0ustar00runnerstaff#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has added $amount jobs to the queue X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has added $amount job(s) to the queue. They are from RSS feed "$feed". $job Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4516962 SABnzbd-4.3.2/email/email-es.tmpl0000644000000000000000000000224214625637243015704 0ustar00runnerstaff#encoding UTF-8 ## ## Plantilla de correo predeterminada para SABnzbd ## This a Cheetah template ## Documentación: http://sabnzbd.wikidot.com/email-templates ## ## !Los saltos de línea y espacios en blanco son significativos¡ ## ## Cabeceras de correo electrónico To: $to From: $from Date: $date Subject: SABnzbd job $name X-priority: 5 X-MS-priority: 5 ## !Después de esto viene el cuerpo del mensaje, la línea en blanco es necesaria! Hola, SABnzbd he bajado "$name" SABnzbd fallo en bajar "$name" Terminado a las $end_time $size bajado Resultado de la transferencia: Etapa $stage $result Producción desde el script de usuario "$script" (Exit code = $script_ret): $script_output Que lo disfrutes! Perdon! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4517598 SABnzbd-4.3.2/email/badfetch-nl.tmpl0000644000000000000000000000100314625637243016351 0ustar00runnerstaff#encoding UTF-8 ## ## Ongeldige URL Ophaal Email sjabloon voor SABnzbd ## Dit is een Cheetah sjabloon ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Lege regels en spaties zijn belangrijk! ## ## Dit zijn de email koppen To: $to From: $from Date: $date Subject: Ophalen van NZB door SABnzbd is mislukt X-priority: 5 X-MS-priority: 5 ## Hierna komt het bericht, de lege regel is noodzakelijk! Hi, Het is SABnzbd niet gelukt om een NZB bestand op te halen van $url. De foutmelding was $msg Sorry ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4518332 SABnzbd-4.3.2/email/email-nb.tmpl0000644000000000000000000000213414625637243015674 0ustar00runnerstaff#encoding UTF-8 ## Translation by ProtX ## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd har jobb $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hei, SABnzbd har lastet ned "$name" SABnzbd mislyktes med å laste ned "$name" Ferdig $end_time Nedlastet $size Resultat av jobben: Steg $stage $result Utskrift fra brukerskript "$script" (Exit code = $script_ret): $script_output Gratulerer! Synd! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4518971 SABnzbd-4.3.2/email/rss-en.tmpl0000644000000000000000000000103214625637243015413 0ustar00runnerstaff## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has added $amount jobs to the queue X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has added $amount job(s) to the queue. They are from RSS feed "$feed". $job Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4519649 SABnzbd-4.3.2/email/badfetch-pt_BR.tmpl0000644000000000000000000000101314625637243016747 0ustar00runnerstaff#encoding UTF-8 ## ## Template de e-mail de busca em URL ruim para SABnzbd ## Este é um template Cheetah ## Documentação: http://sabnzbd.wikidot.com/email-templates ## ## Novas linhas e espaços em branco são significativos! ## ## Estes são os cabeçalhos de e-mail To: $to From: $from Date: $date Subject: SABnzbd falhou ao buscar um NZB X-priority: 5 X-MS-priority: 5 ## Depois daqui vem o corpo. A linha vazia é necessária! Olá, SABnzbd não conseguiu obter o NZB de $url. A mensagem de erro foi: $msg Tchau! ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.452029 SABnzbd-4.3.2/email/badfetch-fi.tmpl0000644000000000000000000000103014625637243016336 0ustar00runnerstaff#encoding UTF-8 ## ## Virheellisen URL-noudon sähköpostin pohja SABnzbd ohjelmalle ## Tämä on Cheetah pohja ## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates ## ## Rivinvaihdot ja välilyönnit ovat merkitseviä! ## ## Tässä on sähköpostin otsikkotiedot To: $to From: $from Date: $date Subject: SABnzbd ei voinut hakea NZB tiedostoa X-priority: 5 X-MS-priority: 5 ## Tämän jälkeen tulee viestin sisältö, tyhjä rivi on pakollinen! Hei, SABnzbd ei voinut hakea NZB tiedostoa osoitteesta $url. Virheviesti: $msg ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.452093 SABnzbd-4.3.2/email/badfetch-de.tmpl0000644000000000000000000000104414625637243016335 0ustar00runnerstaff#encoding UTF-8 ## Translation by Thomas Lucke (Lucky) ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd konnte eine NZB-Datei nicht herunterladen X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hallo, SABnzbd konnte die NZB-Datei von $url nicht herrunterladen. Die Fehlermeldung war: $msg ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4521573 SABnzbd-4.3.2/email/email-fr.tmpl0000644000000000000000000000223114625637243015702 0ustar00runnerstaff#encoding UTF-8 ## ## Template Email pour SABnzbd ## Ceci est un template Cheetah ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Les retours à la ligne et les espaces sont importants ! ## ## Entêtes de l'email To: $to From: $from Date: $date Subject: SABnzbd SuccèsEchec du téléchargement $name X-priority: 5 X-MS-priority: 5 ## Après cela vient le contenu, la ligne vide est nécessaire! Bonjour, SABnzbd a téléchargé avec succès "$name" SABnzbd a téléchargé sans succès "$name" Terminé à $end_time Téléchargé $size Résultat du téléchargement : Etape $stage $result Sortie du script utilisateur "$script" (Code Retour = $script_ret): $script_output A bientôt ! Désolé ! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4522252 SABnzbd-4.3.2/email/badfetch-ru.tmpl0000644000000000000000000000150614625637243016376 0ustar00runnerstaff#encoding UTF-8 ## ## Шаблон электронной почты для излечения неверного URL-адреса ## Это шаблон Cheetah ## Документация: http://sabnzbd.wikidot.com/email-templates ## ## Новые строки и пробелы имеют значение! ## ## Это заголовки электронной почты To: $to From: $from Date: $date Subject: Службе SABnzbd не удалось загрузить NZB-файл X-priority: 5 X-MS-priority: 5 ## Теперь следует тело сообщения. Пустая строка является обязательной! Привет. Службе SABnzbd не удалось загрузить NZB-файл по адресу $url. Сообщение об ошибке: $msg Конец сообщения ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.452294 SABnzbd-4.3.2/email/badfetch-pl.tmpl0000644000000000000000000000102414625637243016356 0ustar00runnerstaff#encoding UTF-8 ## ## Szablon wiadomości błędnego pobierania URL SABnzbd ## To jest szablon Cheetah ## Dokumentacja: http://sabnzbd.wikidot.com/email-templates ## ## Znaki nowego wiersza i białe znaki mają znaczenie! ## ## To są nagłówki wiadomości To: $to From: $from Date: $date Subject: SABnzbd nie udało się pobrać pliku NZB X-priority: 5 X-MS-priority: 5 ## Po tym następuje treść. Pusty wiersz jest wymagany! Cześć, SABnzbd nie udało się pobrać pliku NZB z $url. Komunikat błędu: $msg Do usłyszenia. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4523952 SABnzbd-4.3.2/email/badfetch-it.tmpl0000644000000000000000000000074214625637243016365 0ustar00runnerstaff#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd failed to fetch an NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has failed to retrieve the NZB from $url. The error message was: $msg Bye ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.452515 SABnzbd-4.3.2/email/badfetch-sr.tmpl0000644000000000000000000000133014625637243016367 0ustar00runnerstaff#encoding UTF-8 ## ## Шаблон ел. поште лошег набављања адресе за САБнзбд ## Ово је Гепард шаблон ## Документација: http://sabnzbd.wikidot.com/email-templates ## ## Нови редови и размаци су важни! ## ## Ово су заглавља ел. поште To: $to From: $from Date: $date Subject: САБнзбд није успео да преузме НЗБ X-priority: 5 X-MS-priority: 5 ## После тога долази разрада, празни редови су потребни! Здраво, САБнзбд није успео да преузме НЗБ са „$url“. Порука грешке је: $msg Поздрав ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4525995 SABnzbd-4.3.2/email/email-ro.tmpl0000644000000000000000000000220714625637243015716 0ustar00runnerstaff#encoding UTF-8 ## ## Șablon Email Original pentru SABnzbd ## Acesta este un Șablon Cheetah ## Documentație: http://sabnzbd.wikidot.com/email-templates ## ##Rândurile noi și caracterele spațiu sunt importante! ## ## Acestea sunt antetele email To: $to From: $from Date: $date Subject: SABnzbd sarcina $name X-priority: 5 X-MS-priority: 5 ## După acesta urmează conţinutul, este necesar o linie goală! Salut, SABnzbd a descărcat "$name" SABnzbd nu a reuşit să descarce "$name" Terminat la $end_time Mărime $size Rezultatele sarcinii: Stagiu $stage $result Rezultatul script-ului utilizatorului "$script" (Exit code = $script_ret): $script_output Bucuraţi-vă! Ne pare rau! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4526868 SABnzbd-4.3.2/email/badfetch-en.tmpl0000644000000000000000000000072214625637243016351 0ustar00runnerstaff## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd failed to fetch an NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has failed to retrieve the NZB from $url. The error message was: $msg Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4527738 SABnzbd-4.3.2/email/rss-nl.tmpl0000644000000000000000000000110314625637243015421 0ustar00runnerstaff#encoding UTF-8 ## ## RSS Email sjabloon voor SABnzbd ## Dit is een Cheetah sjabloon ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Lege regels en spaties zijn belangrijk! ## ## Dit zijn de email koppen To: $to From: $from Date: $date Subject: SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd X-priority: 5 X-MS-priority: 5 ## Hierna komt de inhoud, de lege regel is benodigd! Hallo, SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd. Ze komen van de RSS bron "$feed". $job ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.452854 SABnzbd-4.3.2/email/email-he.tmpl0000644000000000000000000000226014625637243015671 0ustar00runnerstaff#encoding UTF-8 ## ## SABnzbd תבנית דוא״ל ברירת מחדל עבור ## זאת תבנית ברדלס ## http://sabnzbd.wikidot.com/email-templates :תיעוד ## ## !שורות חדשות ורווחים לבנים הם משמעותיים ## ## אלו כותרות הדוא״ל $to :אל $from :מאת תאריך: $date $name יש עבודה אשר SABnzbd-נושא: ל ## !אחרי זה בא הגוף, השורה הריקה דרושה ,היי SABnzbd הוריד את "$name" SABnzbd נכשל להוריד את "$name" הסתיים ב-$end_time הורדו $size :תוצאות העבודה שלב $stage $result :(קוד יציאה = $script_ret) "$script" פלט מתסריט משתמש $script_output !תהנה !סליחה ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4529335 SABnzbd-4.3.2/email/email-de.tmpl0000644000000000000000000000232614625637243015670 0ustar00runnerstaff#encoding UTF-8 ## Translation by Severin Heiniger ## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd Auftrag $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd hat "$name" heruntergeladen SABnzbd konnte "$name" nicht herunterladen Fertiggestellt: $end_time Heruntergeladen: $size Ergebnis des Auftrages: Stufe $stage $result Ausgabe des Benutzerskripts "$script" (beendet mit Code $script_ret): $script_output Viel Spass! Entschuldigung! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4530141 SABnzbd-4.3.2/email/rss-da.tmpl0000644000000000000000000000105514625637243015402 0ustar00runnerstaff#encoding UTF-8 ## ## RSS E-mail-skabelon til SABnzbd ## Dette er en Cheetah-skabelon ## Dokumentation: http://sabnzbd.wikidot.com/email-templates ## ## Linjeskift og blanktegn har betydning! ## ## Dette er e-mai-headere To: $to From: $from Date: $date Subject: SABnzbd har tilføjet $antal jobs til køen X-priority: 5 X-MS-priority: 5 ## Herefter kommer kroppen, den tomme linje skal være der! Hej, SABnzbd har tilføjet $antal job(s) til køen. De er fra RSS-feedet "$feed". $job Farvel ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4531057 SABnzbd-4.3.2/email/badfetch-fr.tmpl0000644000000000000000000000074214625637243016360 0ustar00runnerstaff#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd failed to fetch an NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has failed to retrieve the NZB from $url. The error message was: $msg Bye ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.453283 SABnzbd-4.3.2/email/email-ru.tmpl0000644000000000000000000000303414625637243015723 0ustar00runnerstaff#encoding UTF-8 ## ## Стандартный шаблон сообщения электронной почты ## Это шаблон Cheetah ## Документация: http://sabnzbd.wikidot.com/email-templates ## ## Новые строки и пробелы имеют значение! ## ## Это заголовки электронной почты To: $to From: $from Date: $date Subject: SABnzbd: задание $name X-priority: 5 X-MS-priority: 5 ## Теперь следует тело сообщения. Пустая строка является обязательной! Привет. Системой SABnzbd загружено задание «$name» Системе SABnzbd не удалось загрузить «$name» Время окончания загрузки: $end_time Загруженный размер: $size Результаты задания: Stage $stage $result Результат выполнения сценария «$script» (Exit code = $script_ret): $script_output Удачи! Сожалеем. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4534101 SABnzbd-4.3.2/email/email-pl.tmpl0000644000000000000000000000210514625637243015706 0ustar00runnerstaff#encoding UTF-8 ## ## Domyślny szablon maila w SABnzbd ## To jest szablon Cheetah ## Dokumentacja: http://sabnzbd.wikidot.com/email-templates ## ## Znak nowego wiersza i spacji ma znaczenie! ## ## To są nagłowki maila To: $to From: $from Date: $date Subject: SABnzbd zadanie $name X-priority: 5 X-MS-priority: 5 ## Następnie treść maila, wymagana jest pusta linia! Cześć, SABnzbd pobrał "$name" SABnzbd nie pobrał "$name" Zakończono o $end_time Pobrano $size Rezultat zadania: Etap $stage $result Odpowiedź od skryptu "$script" (kod wyjścia = $script_ret): $script_output Baw się dobrze! Przykro mi! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4534888 SABnzbd-4.3.2/email/email-fi.tmpl0000644000000000000000000000224114625637243015672 0ustar00runnerstaff#encoding UTF-8 ## ## Oletus sähköpostipohja SABnzbd:lle ## Tämä on Cheetah pohja ## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates ## ## Rivinvaihdot ja välilyönnit ovat merkitseviä! ## ## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa! To: $to From: $from Date: $date Subject: SABnzbd on työssä $name X-priority: 5 X-MS-priority: 5 ## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on pakollinen! Hei, SABnzbd on ladannut "$name" SABnzbd on epäonnistunut "$name" latauksessa Valmistui $end_time Ladattu $size Työn lopputulos: Tila $stage $result Käyttäjän skriptin tuloste "$script" (Exit code = $script_ret): $script_output Nauti! Pahoittelut! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4535587 SABnzbd-4.3.2/email/rss-cs.tmpl0000644000000000000000000000105214625637243015420 0ustar00runnerstaff#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has added $amount jobs to the queue X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has added $amount job(s) to the queue. They are from RSS feed "$feed". $job Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4536276 SABnzbd-4.3.2/email/badfetch-zh_CN.tmpl0000644000000000000000000000066114625637243016752 0ustar00runnerstaff#encoding UTF-8 ## ## SABnzbd 装取 URL 错误电子邮件模板 ## 这是一款 Cheetah 模板 ## 文档: http://sabnzbd.wikidot.com/email-templates ## ## 新行与空格均有重要意义! ## ## 这些是电子邮件头 To: $to From: $from Date: $date Subject: SABnzbd 装取 NZB 失败 X-priority: 5 X-MS-priority: 5 ## 到主体部分时必须要有空行! Hi, SABnzbd 从 $url 检索 NZB 失败。 错误信息为: $msg Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4536939 SABnzbd-4.3.2/email/badfetch-he.tmpl0000644000000000000000000000106214625637243016341 0ustar00runnerstaff#encoding UTF-8 ## ## SABnzbd רעה עבור URL תבנית דוא״ל של משיכת ## זאת תבנית ברדלס ## http://sabnzbd.wikidot.com/email-templates :תיעוד ## ## !שורות חדשות ורווחים לבנים הם משמעותיים ## ## אלו כותרות הדוא״ל $to :אל $from :מאת תאריך: $date NZB נכשל במשיכת SABnzbd :נושא ## !אחרי זה בא הגוף, השורה הריקה דרושה ,היי .$url מתוך NZB-נכשל לאחזר את ה SABnzbd הודעת השגיאה הייתה: $msg ביי ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4537585 SABnzbd-4.3.2/email/email-en.tmpl0000644000000000000000000000205714625637243015703 0ustar00runnerstaff## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has job $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has downloaded "$name" SABnzbd has failed to download "$name" Finished at $end_time Downloaded $size Results of the job: Stage $stage $result Output from user script "$script" (Exit code = $script_ret): $script_output Enjoy! Sorry! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4538226 SABnzbd-4.3.2/email/rss-nb.tmpl0000644000000000000000000000106014625637243015411 0ustar00runnerstaff#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd har lagt $amount jobber til køen X-priority: 5 X-MS-priority: 5 ## Etter dette kommer meldingen, den tomme linjen er nødvendig! Hei, SABnzbd har lagt $amount jobb(er) til køen. Disse er fra RSS feeden "$feed". $job Hade ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4539618 SABnzbd-4.3.2/email/badfetch-ro.tmpl0000644000000000000000000000104514625637243016366 0ustar00runnerstaff#encoding UTF-8 ## ## Adresă URL Greşită şablon Email pentru SABnybd ## Acesta este un şablon Cheetah ## Documentaţie : http://sabnzbd.wikidot.com/email-templates ## ## Liniile noi şi spaţiile sunt importante! ## ## Acestea sunt headerele email Către: $to De la: $from Dată: $date Subiect: SABnzbd nu a reuşit să descarce un NZB X-priority: 5 X-MS-priority: 5 ## După aceasta urmează corpul email, linia goală e necesară ! Salut, SABnzbd nu a putut descărca NZB-ul de la adresa $url. Mesajul de eroare a fost: $msg La revedere! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4540284 SABnzbd-4.3.2/email/rss-es.tmpl0000644000000000000000000000117414625637243015427 0ustar00runnerstaff#encoding UTF-8 ## ## Plantilla de correo RSS para SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## !Los saltos de línea y espacios en blanco son significativos¡ ## ## Cabeceras de correo electrónico To: $to From: $from Date: $date Subject: SABnzbd he añadido $amount transferencia(s) a la cola X-priority: 5 X-MS-priority: 5 ## !Después de esto viene el cuerpo del mensaje, la línea en blanco es necesaria! Hola, SABnzbd he añadido $amount transferencia(s) a la cola. Originaron desde el RSS "$feed". $job Adios ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4540944 SABnzbd-4.3.2/email/email-it.tmpl0000644000000000000000000000207714625637243015717 0ustar00runnerstaff#encoding UTF-8 ## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has job $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has downloaded "$name" SABnzbd has failed to download "$name" Finished at $end_time Downloaded $size Results of the job: Stage $stage $result Output from user script "$script" (Exit code = $script_ret): $script_output Enjoy! Sorry! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4541595 SABnzbd-4.3.2/email/email-sr.tmpl0000644000000000000000000000256314625637243015727 0ustar00runnerstaff#encoding UTF-8 ## ## Основни шаблон ел. поште за САБнзбд ## Ово је Гепард шаблон ## Документација: http://sabnzbd.wikidot.com/email-templates ## ## Нови редови и размаци су важни! ## ## Ово су заглавља ел. поште To: $to From: $from Date: $date Subject: САБнзбд је посао „$name“ X-priority: 5 X-MS-priority: 5 ## После тога долази разрада, празни редови су потребни! Здраво, САБнзбд је преузео „$name“ САБнзбд није успео да преузме „$name“ Завршено је у $end_time Преузето је $size \n Резултат рада: Фаза $stage $result Излаз корисничке скрипте „$script“ (Шифра излаза = $script_ret): $script_output Уживајте! Жао ми је! ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.454227 SABnzbd-4.3.2/email/rss-sv.tmpl0000644000000000000000000000105314625637243015444 0ustar00runnerstaff#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd har lagt till $amount jobb i kön X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hej, SABnzbd har lagt till $amount jobb i kön. De kommer från RSS feed "$feed". $job Hej då ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4542935 SABnzbd-4.3.2/email/rss-fr.tmpl0000644000000000000000000000114614625637243015426 0ustar00runnerstaff#encoding UTF-8 ## ## Template Email pour SABnzbd ## Ceci est un template Cheetah ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Les retours à la ligne et les espaces sont importants ! ## ## Entêtes de l'email To: $to From: $from Date: $date Subject: SABnzbd a ajouté $amount fichier(s) à la file d'attente X-priority: 5 X-MS-priority: 5 ## Après cela vient le contenu, la ligne vide est nécessaire! Bonjour, SABnzbd a ajouté $amount fichier(s) à la file d'attente. Ils proviennent du Flux RSS "$feed". $job Au Revoir ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4543614 SABnzbd-4.3.2/email/badfetch-da.tmpl0000644000000000000000000000074514625637243016340 0ustar00runnerstaff#encoding UTF-8 ## ## Dårlig URL-hentning af E-mail-skabelon til SABnzbd ## Dette er en Cheetah-skabelon ## Dokumentation: http://sabnzbd.wikidot.com/email-templates ## ## Linjeskift og blanktegn har betydning! ## ## Dette er e-mail-headere To: $to From: $from Date: $date Subject: SABnzbd kunne ikke hente en NZB X-priority: 5 X-MS-priority: 5 ## Herefter kommer kroppen, den tomme linje skal være der! Hej, SABnzbd kunne ikke hente NZB fra $url. Fejlmeddelelsen er: $msg Farvel ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4544265 SABnzbd-4.3.2/email/rss-pt_BR.tmpl0000644000000000000000000000125314625637243016024 0ustar00runnerstaff#encoding UTF-8 ## ## Template de e-mail RSS para SABnzbd ## Este é um template Cheetah ## Documentação: http://sabnzbd.wikidot.com/email-templates ## ## Novas linhas e espaços em branco são significativos! ## ## Estes são os cabeçalhos de e-mail To: $to From: $from Date: $date Subject: SABnzbd adicionou $amount à fila X-priority: 5 X-MS-priority: 5 ## Depois daqui vem o corpo. A linha vazia é necessária! Olá, SABnzbd adicionou $amount à fila. Elas são do feed RSS "$feed". $job Tchau! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4544928 SABnzbd-4.3.2/email/badfetch-cs.tmpl0000644000000000000000000000074214625637243016356 0ustar00runnerstaff#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd failed to fetch an NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has failed to retrieve the NZB from $url. The error message was: $msg Bye ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4545808 SABnzbd-4.3.2/email/rss-he.tmpl0000644000000000000000000000114414625637243015411 0ustar00runnerstaff#encoding UTF-8 ## ## SABnzbd עבור RSS תבנית דוא״ל ## זאת תבנית ברדלס ## http://sabnzbd.wikidot.com/email-templates :תיעוד ## ## !שורות חדשות ורווחים לבנים הם משמעותיים ## ## אלו כותרות הדוא״ל $to :אל $from :מאת תאריך: $date הוסיף $amount עבודות לתור SABnzbd :נושא ## !אחרי זה בא הגוף, השורה הריקה דרושה ,היי .הוסיף $amount עבודות לתור SABnzbd ."$feed" בשם RSS הם מהזנת $job ביי ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4546454 SABnzbd-4.3.2/email/email-pt_BR.tmpl0000644000000000000000000000216314625637243016305 0ustar00runnerstaff#encoding UTF-8 ## ## Template padrão de e-mail para SABnzbd ## Este é um template Cheetah ## Documentação: http://sabnzbd.wikidot.com/email-templates ## ## Novas linhas e espaços em branco são significativos! ## ## Estes são os cabeçalhos de e-mail To: $to From: $from Date: $date Subject: SABnzbd a tarefa $name X-priority: 5 X-MS-priority: 5 ## Depois daqui vem o corpo. A linha vazia é necessária! Olá, SABnzbd baixou "$name" SABnzbd falhou no download de "$name" Completado em $end_time Baixados $size Resultados da tarefa: Etapa $stage $result Retorno do script de usuário "$script" (Código de retorno = $script_ret): $script_output Aproveite! Lamento! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4547114 SABnzbd-4.3.2/email/email-nl.tmpl0000644000000000000000000000216714625637243015714 0ustar00runnerstaff#encoding UTF-8 ## ## Standaard Email sjabloon voor SABnzbd ## Dit is een Cheetah sjabloon ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Lege regels en witruimte zijn belangrijk! ## ## Dit zijn de email koppen To: $to From: $from Date: $date Subject: SABnzbd: opdracht $name is X-priority: 5 X-MS-priority: 5 ## Hier onder volgt de hoofdtekst, de lege regel is noodzakelijk! Hallo, SABnzbd heeft "$name" gedownload SABnzbd is niet geslaagd in het downloaden van "$name" Klaar om $end_time Hoeveelheid gedownload $size Resultaat van de opdracht: Fase $stage $result Bericht van het script "$script" (Exit code = $script_ret): $script_output Veel plezier! Sorry! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4547777 SABnzbd-4.3.2/email/badfetch-nb.tmpl0000644000000000000000000000075114625637243016350 0ustar00runnerstaff#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd ikke klarte å hente en NZB fil X-priority: 5 X-MS-priority: 5 ## Etter dette kommer meldingen, den tomme linjen er nødvendig! Hei, SABnzbd klarte ikke å hente NZB fra $url. Feilmeldingen var: $msg Hade ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4548452 SABnzbd-4.3.2/email/badfetch-es.tmpl0000644000000000000000000000104514625637243016355 0ustar00runnerstaff#encoding UTF-8 ## ## Plantilla de correo para URLs incorrectas de SABnzbd ## Esta es una plantilla Cheetah ## Documentación: http://sabnzbd.wikidot.com/email-templates ## ## Líneas nuevas y espacios en blanco IMPORTAN! ## ## Estas son las cabeceras del email To: $to From: $from Date: $date Subject: SABnzbd ha encontrado un error al recuperar un NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hola, SABnzbd ha encontrado un error al descargar un NZB desde $url. El error ha sido: $msg Un saludo ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4549115 SABnzbd-4.3.2/email/rss-ro.tmpl0000644000000000000000000000113614625637243015436 0ustar00runnerstaff#encoding UTF-8 ## Şablon Email RSS pentru SABnzbd ## Acesta este un şablon Cheetah ## Documentaţie: http://sabnzbd.wikidot.com/email-templates ## ## Rândurile noi și caracterele spațiu sunt importante! ## ## Acestea sunt antetele email To: $to From: $from Date: $date Subject: SABnzbd a adăugat $amount sarcini în coadă X-priority: 5 X-MS-priority: 5 ## După acesta urmează conţinutul, este necesar o linie goală! Salut, SABnzbd a adăugat $amount sarcină(e) în coadă. Ele sunt din fluxuri RSS "$feed". $job La revedere ! ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4549768 SABnzbd-4.3.2/email/badfetch-sv.tmpl0000644000000000000000000000100314625637243016370 0ustar00runnerstaff#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd misslyckades med att hämta en NZB -fil X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hej, SABnzbd har misslyckats med att hämta NZB -filen från $url. Felmeddelandet lyder: $msg Hej då ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4550536 SABnzbd-4.3.2/interfaces/Glitter/licenses/LICENSE-Apache.txt0000644000000000000000000002646214625637243022601 0ustar00runnerstaff License for: Bootstrap -------------------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------------------------------------------././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4551442 SABnzbd-4.3.2/interfaces/Glitter/licenses/LICENSE-CC.txt0000644000000000000000000004126314625637243021701 0ustar00runnerstaffhttp://creativecommons.org/licenses/by/3.0/ http://creativecommons.org/licenses/by/3.0/legalcode License THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 1. Definitions 1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("syncing") will be considered an Adaptation for the purpose of this License. 2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. 3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. 4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. 5. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. 6. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. 7. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. 8. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. 9. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: 1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; 2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; 3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, 4. to Distribute and Publicly Perform Adaptations. 5. For the avoidance of doubt: 1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; 2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, 3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: 1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested. 2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. 3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. 5. Representations, Warranties and Disclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. Termination 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 8. Miscellaneous 1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. 6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4552252 SABnzbd-4.3.2/interfaces/Glitter/licenses/LICENSE-MIT.txt0000644000000000000000000000247014625637243022042 0ustar00runnerstaff License for: jQuery jQuery UI jQuery Peity Knockout JavaScript library Knockout sortable Knockout filedrop Knockout slider Knockout Persist DateJS MomentJS -------------------------------------------------------------------------------------------- The MIT License Copyright (c) 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.././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4552975 SABnzbd-4.3.2/interfaces/Glitter/templates/include_history.tmpl0000644000000000000000000002620314625637243024063 0ustar00runnerstaff

$T('menu-history') ($T('archive'))

$T('empty')
$T('button-retry')
$T('name')
$T('post-Completed')
$T('status')
$T('size')
$T('category')
$T('srv-password')
$T('msg-path')
0
B $T('Glitter-today') B $T('Glitter-thisMonth') B $T('Glitter-total')
././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.455384 SABnzbd-4.3.2/interfaces/Glitter/templates/include_menu.tmpl0000644000000000000000000002041414625637243023324 0ustar00runnerstaff
#include $webdir + "/../../Config/templates/staticcfg/images/logo-small.svg"#
  • $T('Glitter-pause5m')
  • $T('Glitter-pause15m')
  • $T('Glitter-pause30m')
  • $T('Glitter-pause1h')
  • $T('Glitter-pause3h')
  • $T('Glitter-pause6h')
  • $T('Glitter-custom')
0:00
  • $T('Glitter-setMaxLinespeed')
    • $T('menu-help')
    • $T('menu-donate')
    • $T('logout')
    • $T('link-resetQuota')
    • $T('button-rssNow')
    • $T('sch-scan_folder')
    • $T('sch-resume_post')
    • $T('shutdownSab')
    • $T('Glitter-restartSab')
    • $T('Glitter-onFinish'):
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4554734 SABnzbd-4.3.2/interfaces/Glitter/templates/include_messages.tmpl0000644000000000000000000000451114625637243024167 0ustar00runnerstaff
$T('none')
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4555569 SABnzbd-4.3.2/interfaces/Glitter/templates/include_queue.tmpl0000644000000000000000000003701314625637243023507 0ustar00runnerstaff

$T('menu-queue')

$T('Glitter-left')
B / B $T('quota-left')
B $T('Glitter-free') ($T('Glitter-freeTemp'))
B $T('Glitter-free')
  • $T('Glitter-sortRemaining')
  • $T('Glitter-sortAgeAsc')
  • $T('Glitter-sortAgeDesc')
  • $T('Glitter-sortNameAsc')
  • $T('Glitter-sortNameDesc')
  • $T('Glitter-sortSizeAsc')
  • $T('Glitter-sortSizeDesc')
$T('Glitter-addNZB')
0
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4556494 SABnzbd-4.3.2/interfaces/Glitter/templates/include_overlays.tmpl0000644000000000000000000015720414625637243024234 0ustar00runnerstaff
$T('Glitter-notification-uploading')
$T('Glitter-repairQueue')
$T('Glitter-notification-disconnect')
$T('button-rssNow')
$T('sch-scan_folder')
$T('cmenu-sorting')
$T('Glitter-notification-shutdown')
$T('Glitter-notification-removing1')
$T('Glitter-backToQueue')
$T('Glitter-notification-removing') ()
...
$T('Glitter-lostConnection')
$T('Glitter-afterRestart')

Feedback ×

If anything is not working as expected, or could be improved, let us know!

If you encounter an error, please include the log file (click on ) when contacting us.

SABnzbd Forum
SABnzbd on Github
Translations of SABnzbd

$T('Glitter-statusInterfaceOptions')

  • $T('menu-cons')
  • $T('connections')
  • $T('Glitter-orphanedJobs')
  • $T('Glitter-interfaceOptions')
$T('opt-socks5_proxy_url')  
$T('Glitter-loading')...
$T('dashboard-localIP4')  
$T('Glitter-loading')...
$T('dashboard-publicIP4')  
$T('Glitter-loading')...
$T('dashboard-IP6')  
$T('Glitter-loading')...
$T('dashboard-NameserverDNS')  
$T('Glitter-loading')...

$T('cache')  
( $T('Glitter-articles'))
$T('dashboard-loadavg')  
$T('dashboard-delayed')  
$T('dashboard-delayed-disk') (x)
$T('dashboard-systemPerformance')  
$cpumodel $cpusimd
$T('Glitter-loading')...
$T('dashboard-downloadDirSpeed')  
MB/s
$T('Glitter-loading')...
$T('dashboard-completeDirSpeed')  
MB/s
$T('Glitter-loading')...
$T('dashboard-internetBandwidth')  
MB/s Mbps
$T('Glitter-loading')...
$T('dashboard-testDownload')  
100 MB 1 GB 10 GB

$T('link-forceDisc')
$T('Glitter-repairQueue')
$T('link-showLog')
$T('swtag-server')
$T('optional').capitalize()
$T('priority')
$T('srv-ssl')
# $T('connections')
/

$T('Glitter-speed')
B/s
$T('Glitter-unblockServer')
$T('article-id') $T('nzo-filename') $T('file-set')

$T('none')

$T('Glitter-purgeOrphaned') $T('Glitter-retryAllOrphaned')

$T('Glitter-addNZB')

$T('Glitter-addFromURL')
$T('Glitter-addFromFile')

$T('Glitter-loading')

100%
( - MB)

$T('removeNZB-Files')

$T('confirm-delete')

$T('nzo-delete')

$T('confirm-delete')

$T('Glitter-retryJob')

$T('opt-extra-NZB')
$T('srv-password')
$T('Glitter-retryNoChecks')

$T('Glitter-scriptLog')

$T('menu-help')

#include $webdir + "/../../Config/templates/staticcfg/images/logo-full.svg"#

SABnzbd $('version'): $version


$T('menu-wiki'): https://sabnzbd.org/wiki/
$T('menu-forums'): https://forums.sabnzbd.org/
GitHub: https://github.com/sabnzbd/sabnzbd/
$T('menu-live-chat'): https://sabnzbd.org/live-chat

Copyright © 2007-2024 by The SABnzbd-Team (sabnzbd.org)
$T('yourRights')

$T('Glitter-clearHistory')



$T('Glitter-pauseFor')

././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.455734 SABnzbd-4.3.2/interfaces/Glitter/templates/main.tmpl0000644000000000000000000002373614625637243021613 0ustar00runnerstaff dir="rtl" id="sabnzbd" data-bind="filedrop: { overlaySelector: '.main-filedrop', onFileDrop: addNZBFromFile }"> SABnzbd
  • $T('menu-queue')
  • $T('menu-history')
  • $T('warnings')
././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.455848 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/bootstrap.min.css0000644000000000000000000045433014625637243027374 0ustar00runnerstaff/*! * Bootstrap v3.3.5 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * * SABnzbd EDIT: We use the Glyphicons of v3.0.2 because the new ones are not sharp on Firefox and Chrome on Windows (Sep 2015). * For example compare the icons in the config (that uses the new ones), with the Glitter icons. * *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}} @font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAFr8ABEAAAAAoRQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABgAAAABwAAAAcaPfj5EdERUYAAAGcAAAAHgAAACABCAAET1MvMgAAAbwAAABDAAAAYGenS4RjbWFwAAACAAAAARcAAAJq4khMF2N2dCAAAAMYAAAACAAAAAgAKAOHZnBnbQAAAyAAAAGxAAACZVO0L6dnYXNwAAAE1AAAAAgAAAAIAAAAEGdseWYAAATcAABN8wAAiRgqz6OJaGVhZAAAUtAAAAA0AAAANgEEa5xoaGVhAABTBAAAABwAAAAkCjIED2htdHgAAFMgAAABFAAAAvTBvxGPbG9jYQAAVDQAAAGrAAABuDKVVHptYXhwAABV4AAAACAAAAAgAgQBoG5hbWUAAFYAAAABgwAAA3zUvpnzcG9zdAAAV4QAAAM+AAAIhMxBkFZwcmVwAABaxAAAAC4AAAAusPIrFHdlYmYAAFr0AAAABgAAAAZh/lI3AAAAAQAAAADMPaLPAAAAAM5dLpcAAAAAzl0SfXjaY2BkYGDgA2IJBhBgYmAEwltAzALmMQAADagBDQAAeNpjYGZpZJzAwMrAwszDdIGBgSEKQjMuYTBi2gHkA6Wwg1DvcD8GBwbeRwzMB/4LANVJMNQAhRmRlCgwMAIAC2EJ1gB42s2RPUsDQRCGZ5Nc5ERjCAoeiDNYGKKFadOdjSaFErC6KkEkGLAIVqZLmy6NBDt/gKV/Jld485rCykptbNY1BxZXWVj4wnwtM8/ALBHlKbUtMs6TuXCVWdQF03TxlELyqOSyVRLap3tZlgPpyMNOZddU/eqa5tXXQGva0JZG2tW+DnWsU/gIUEMDR2ghQh9DjHGLu2ey9nvTgrfneJThkXpaVtG6htp2vHMd6EgnMChDUEeIJtroYoARJpgueMZ+2LmNbU+XknnymFw+5eONWWnmSyCbUpEVKQrxJ7/zG7/yC4Nv+JqvuMdd7nDEZ3zCx3zI4Xac3uEvZYr0AzU553LZhvQLUhU8+tcqZh/WfzP1BXUjZUgAAAAAjwAoAvh42l1Ru05bQRDdDQ8DgcTYIDnaFLOZkMZ7oQUJxNWNYmQ7heUIaTdykYtxAR9AgUQN2q8ZoKGkSJsGIRdIfEI+IRIza4iiNDs7s3POmTNLypGqd+lrz1PnJJDC3QbNNv1OSLWzAPek6+uNjLSDB1psZvTKdfv+Cwab0ZQ7agDlPW8pDxlNO4FatKf+0fwKhvv8H/M7GLQ00/TUOgnpIQTmm3FLg+8ZzbrLD/qC1eFiMDCkmKbiLj+mUv63NOdqy7C1kdG8gzMR+ck0QFNrbQSa/tQh1fNxFEuQy6axNpiYsv4kE8GFyXRVU7XM+NrBXbKz6GCDKs2BB9jDVnkMHg4PJhTStyTKLA0R9mKrxAgRkxwKOeXcyf6kQPlIEsa8SUo744a1BsaR18CgNk+z/zybTW1vHcL4WRzBd78ZSzr4yIbaGBFiO2IpgAlEQkZV+YYaz70sBuRS+89AlIDl8Y9/nQi07thEPJe1dQ4xVgh6ftvc8suKu1a5zotCd2+qaqjSKc37Xs6+xwOeHgvDQWPBm8/7/kqB+jwsrjRoDgRDejd6/6K16oirvBc+sifTv7FaAAAAAAEAAf//AA942r29B4Ab5ZUAPN/MSKMujaTRSNqVVmUlbZW80mrl9RYbV9yNDS50g4CAKabEGDAGTAskhgWCCTEJDhzgUEeyCUnO3CUkcEpR2hmHcBeONI6Ecgn4Sox3/L/3fdKuthjC3f//XkuaJs1773vf+14fjufaOI58RohwAidx6RLhMoNlSeTfy5aMhn8dLAs8bHIlAQ8b8HBZMgpHB8sEj+fkqJzIyfE2Mkd/+89/FiJH32zjf8YRrsgVxWXiMk7lWjmNy2j2nEaqmjVLNH9G8xzSDFnNXdWkbClAOrkZPZ58NFVQ5ZxcUKWoElWllByXpVShSIQXdr5QgRcR9NH65uFJB/RRehmgwcE/el8rt4QrWziuE28u0ZsbsmXCWTr3zSGCuZNotoxmOaTxWc1c1cRs2WzBU2bJ3Fm2mHHTwpk7S3YKXYBE5fofGSFdZETfrB8c39I3kxGKs0H8gvgsV+C2cFo2o7VVy21Z/Km2tJnCEaVwtGQ1Q0ZrzmnGqhbMakpGs1bLihUvVFwI2cyMVqCQxaqlUEsWPl2lbtKpubJauqo5s6V+0lmKFWS3JvVr3XLZGsn29/cjFQu53kK8kOsr9OWyqk+N96b5eMzBS1EpalTgLSzmssN8PmeUjPFYKk1SxeLlhteLtyeWfnb/B5sHjc/nli0J+/vnz/aQ64r6QSPZBe/mGf3zckpoybLcsy0bNz1Rvbp1ro0cLmbyxSdO3fniBRcV1s8IeLtOHS6m+4pLrprb6QzOWJd/+qLPfjX91FYOx6RCRsRl/AHgLzflBaFKNDFTMrCRB6JWhFuObkNy4vCRYx+QLvEl8QTOx7VwmpDRnFXNAl9RMyU/fKVkEWR3yebu75/RI3h9uWi2L9+bjMekNInHjIpXdRDH5Sv597c++eTWdFfX85d+6TV+7ink/VVXPH3t1mccG6/+5YMBm2MTJ8K9iqIGvCIC31s4O8fliVogCdlsgFGuANQfrSJd+kF+Pb8eRruriAf1zRW6d3j0Mf403Ua6RvfC7wjHPjz2ofii+CLHc0bOxXFSAtiZwKvQ15shyZhkJ8v/7dRD/PmH1h46125/0NnqtG/+t5PYgdPtKceDdjtX49/6v546P2uixpm5HFc2Ij9LVU2AaWTJaKZDQMqyYELOEQzAuCYBN01GYFwrJa4cJTJMp3xUFjUE9uibQFpt9PXR14tFPom/7+BMMF+e4yIclwyTwjDJywk5KTmIWtvrTUoGB1HgmFFs/dzKE4AYc5asXOeW71i5cI3DMuqyOGD/85e2B5WzO/gzd4/+t0sNXtFXaA+oJxWEyy1W4buCxzK6UvYHOKCOeuxd8fvig5yHa+I2cGUHYuTOaGpVa2KM0ZzRyCFNqWqKC2WDZoA5AOweUGT3PoF3uVvVfs0gA+dzJbcDpoC5X1NlzdWvNbn3EU4ywPkZPW4XIKR4JeLzOokxliLA7rzLF+lzJSMqaQZWa15BuiTpEpPXpB+8+q7KzS8R93e/q79P3sNz+u8rd12tH4STl0gS6VrBX6z/+aXvwhWUP2GerxefE+dzAU7hiBbMaNwhzVGF/6UmxtK9w3yYqPDGK16HIKXF4sxTr776mq4Z12397Pq+edfcsnd4+IlbrpknuOZsWdMtLp6/4ESxe82WOf3X3HhD+ZRTyjfceA3Q6tg3uUXi/TD2Fs4GLBb15DxR4jETj1A4kfzbvfy95DV9xz36jfqOe7/ICxEqiv6kzyYe/T3yj/BJ+bLxN3ycn9PsIH6pGBKzY1MKJlLjr3tUqaCmCvGUNPU+876/+DvfW/Ldd5avmOaO/FV3/fYLO//whX/+Z66Rdz3Ay3mSjyWHSG9f1hciXmNcIQoZSczW/kebnSAjdxNSvD9X2aZp2yq5+4v6sbs5nI/0+8voumTlnPA7KnBNCxfnUlwnl4EZoXFlDjlIrJb8ERCUUkaL5TRTVWvNataMlsxptqrWltWcGa0jp7mqWldW82S0dE7zVrUZWcQ/nM0hOYjWS8dRrO4z2VzeVjWriS4UUfvMdlnBXX9Va4Z3xpWhrBap7mtt65qBpyKuUhSuTLR39+CuUC3lUVDZrCCogk39/ZpTLjWHUGD10PUyH89PeqEUhFkaJdOcE7WP9hfH/oH4Gd1LXwfGD4rLGi9BWQrC6ui2sSOUlGNroxNomOFmc3O5sh2p15UDtJFkoYw2SEnTC7wxh9LDRddHP7y7ShFAHIjWXtVmZksnUL4B+dAHEtinyDCm0VgyQCbuk084HwIuUEIhRd+M7+Pb/Prjnck2HOYvadgZffF4ZziQnpNxX8mdxV3G3cDdDWs1pUJp8OIc0qHUW8wiJUrLtuWQFqX5V8F+d6Z0+hdgv7VaOvmWLFBnBKlTciHTmYH52rKUQjNAUs1ZBdv91dKJ6/HTVTobjm2+EbYvrJa2fi6bLd1DKYdzYYCw2dBJYkk5//H7JP//7fUhpYIEO84bGfm/nc+O7ZHHpts8+p//1wtg3a3Li8YxXlvj8UHK4710+i/Lac1VbT6OqnY6jql2Mozo2RNGVD3OiJY2Tj96Xh/s9sHhJOwalcnncTSQ76nsizLqf9z+J1ObP4A7o/PxffrtRpqPf/tTUBRleIiLiR+IHZyB42BxSJFUiDwqZA+Ofu0n5BX9dKEXtn6K113EXSQuFBeCnMbrCmaimolkJheRoP7WQRIkwYP6W/QNPoYn7h/Ea2CtmqAbpLgXJmgHoBbEc1qoqkWz5eYQqjnNSdB4Qs24GWoB/bqmP7Q16A9JEFjhrJaoapFsOZHESxNx+FYygZvJZvhWYkzLaIeRToKWUeZ9ILL7tYSsufu1AGgdqivYoHWobtA6XP2lEGgf+ziD4sdzTXLZGyD9/Z+gewggz3NKTokr8fzH6iELixUQ9Z+gjegb8CKU7nXafZnSroU7YzrNKjJVs4rWNKvnUbNqDn2MbvU86lbN4U/UrgRYxqZitnXnOGaoNZD3a4jtvEZ/VfLBVSbSuZwi9hJxvQSIUV2RU8UHQX9ogtV+AYeGI5oBXXRdkqpliRpzEhhzmuQq2QAjT7Vs8+BBG9hRaDKVbBIMkupvjgPgVDNzFxTQZr0ALBgNqbzPDRoaH0vzhE1g1HfpBFZ/8cQF246Qc45su+CJX5y2+9V3X919Gvl1SCni7CjiAvUCaRt+vFDZWjpypLS1Unh8WH/thS1wFVxMbONrFqy7RY6AXCqN6TEzuLKIK47JlssRzZXRRMQHkQAqgDGoWRk6zmpJptKmABY2AeO4/lcE46SrAkNfIWigkMO6DS1vUBRWId2CXJO4S9zFLeJO4s7hkAlWVbWlGa0PqLeaUu/Eqnaiq7Qc7gEL2hqg04kcqCrWIWD75fI+p5LrR1ZodZcCGTAsS6uA5UsSKDDaUnmfEE0twLN97lLnCcjwHm8L72shkk8tqD7YzGVn832zidpXSBX6YDPfm+GTGVJIpqRUEjbjMSdvdJKUUVIlI2waUClUvMZYMmh8gHf4hVXdg7caunsMybZYUyZpTGcMt82csUrwO8mXDIYvEZcqrOoavM3QPcPIrjBkuwy3DqRXCQE7/4CRXLC9vB3+8xui7UljT5fhtoH0SUIQThkMD/D2oHBS19Bthq4e/HJzd9KY6zDcNitzkhBwsJ93BISTMrNuM2TSxuSMwPrt29dv2L4dZKHEFY8dEzWDF/T+cQ20wN3BlaM411rB2p/Rm4WlIpUpd2T7cqAuNFVBxUSlwtEFxzMZWFmoeR88hKtOq6uUwHmY1dpQMy0n2qiE4oCh21woj7QZoKW6Sj2w1Z3VequaPVvu7cGLej1wUa8L9UwQiugQoE4UXETGVpKG5cQDaifbQlbywAvVTU9tu+i0EM9AO+lqHyAei9Nh/egtq6Mo3DLQPjq/faBIZQzyGZM2IslanMX2gYF2+F7W6nAcvRSZr31wsJ0/MDqfPwCW8kf72Sazl+DPoIi/Bhukiyubqb4OfA/6ufkQ6uomqmcjlYDpSwYTCB5CJ6uZxOtOF36Ev6WiH8Q/fgN/y+i20b0oR/j1yO8oAN8GOeHgZC7GlcFY6iTI9SDtjNWykSDBjCaQCB42m6hOOkYRIpOiw0r+hYw4rEeftTr49aQrIG63OnTb6BmAnuBG3FHGipwoPi0+DXPYAzywg0Mb3FnVvChky6oXb6MqMC4eHHJqGAIEdhg1V8kLCI5fFICLVBdObpj3aDSWvHaQUxbB4YGZVZJV2DGLTrR1uZLXCXsSZ3fhKQ+eMhLZVhPE7taI6HbxYqTVXRPAHpQQiriHuMl84t6zR39fP6C/7/uQrP3wQ/3JRSAyvtF4Ys8e/iz9yQ/x9KgOJD1IbQX+2EMcZ/ACTVFepWtWlpRDjMGicmao48FJHQ/EjCyMcqwmreIkJ8AfiQpxwZMT4kXy3M+VR7w/I8+NvtX+QVvPm01Piho6VD5aRdeCw8zvw9d0dHbPJVzZivdkdwMThGTHRWVZlPDWIsdEvx3oaKGysiSJIKl4M0gquwzylXrF0AuCfkqAiNpe5E/6Gyg/9Tdg6zfPPUf9eCBC0Y9XKcI4A7+Cff8cQKFyYe7cmgbpoXPZAAPbQgdWrmoyW0hBmWx2lRTYAsUxgkuqLLv320W3SnWDZlkL92uKe7/N4PGF6JiqHlhzicnMBWsrau8wnw3zdCki9ZEUqLAXyFl73jj8xp6z2MfpH5CTP/hAf3rVrsquI6ThBHzwvP70B3hep9MVmHYizwa5jXWerbFoUwOLIiZg4/rH+LIZMQG+3I986UVM/LKm9GtwBJnTRzHxOBETo8RRPWh6lhSaYCLH5ePx5MojR3Ydnyv1cxgulEn4MZ+CjfNy7TUPr71aMsggX2Ei8oCUkin50Py2W4AXiBOXqLzsibpztQnvyanRQk6IVoTIPxEQdjusjkolS7qylY2jjwTIv6Do0hMw88lbsM4exls20lHh/NzChrmPdAxQOgKv2saoFwTqyTYgjmi2CD7/2FSmxPKpU4jlqekkEZjdhuOR6kMyi7RPJhXZD6P+9FNw/k5yTwW4t643NXNrOHQ1w/jKGS0AcIYonAC301WyMH4NA5wWhMsgerxqAIfZLJcUH677Mo4+4cxeBQ8HZI0C7Q3z6ESOe42RpAsdzVJUlmBVdxC1pijtOqJ/FbSiz116Lxm55yuvgFbE/+RdphptAXUJtKqT8My1p+3mmJ7HUXhdXJS7livLOKYwx3zVsq8F57kvCPPcjnOvbDfgATuHbvIYc1BUNRdj3mC1FAdkXKjKyO5+BPgFyWC1gH4SRfiD7pLZhGj5WmCJiVIRYcbrDOhIZ247wKYgRwtJ9CQLclQCZaYvn4N5GY+lELstr3zlHn3zfZtvLx1ZTEbo5y52mF+Pyt+1eHbVkRIuT/hJj3Gw8hVrfDudL2sVp5kymj+HYi6YxcBEcw4HLZRFiRfJoaiJUvZuzaH+nshSM8d0qGxzeVHhsFbLDrcPtlBpAImHqxsu+QkwNlINLw8s+kMkqiTy7MX8RsItR9+sO4pQDo6/0POErnmmArD/o3uLY7sNMht1IpDZKo5dhOk5rTBih2BUyoYgDpoBpXXQhcud5gCAm/CgA/QYVIK4UgRXNtFhCNKZgX6lgXGjOdfgUQIFh6nooIBsWU26Vm+hysjRbaC9gCSntmuRX98+UFm9ZcvqCigxe+E8/4ddVBuv6QvUFyTAXFbZ2kY0H+UmASx/RkKQvZ5hEuaHSUF2kLRglADtwdu3brviomJ723W3jNx+1alepB8ZGZxhjzYZVp5EDp+0wNLWZllwEpMZTFY9AFzdw53AXcCVM0id4ZyWrGp9dJxDQKa5NXsGV7IY0KazqnW6SlnYGqhqA66Si6oOpXnA2tlOoJHNGmqm0iSZgdkpuTxeAbnbBusdlXXymCUzTCJhoozvp/mYg1c8MnNNIEHRNZGYtO+wglK38/fE+PuddPPcR994+41Hz63YTHtMNvrGrx/fJh4QlFbSdcPPr7ji5zfoB9neVfAF+N5Vo6+SH+OFei++N2zXZHlFXC+8zRlAb+PkqEE2REkBYyYqWAYpMHWZ5Oe1nTsX1f+TERDbFf2phkP13xI2099ycm6OqgqOQyjf5FogBH89UQA7Q0qBmB377QMLLrto3lr2q/3525/7+q19l955b338vi2eI/w3/c0QN0hjV+gpDtd+G/1DHiZ4WmB0PGYYHZdPZUs84VCJc3gYPwdINCEnyNj9wVJSwHhWC2gdEQYNuZfCcqZ03dXSSca7RozkHoDr6JsV8gMA7MlbC5feeU/V9MB3X9xlmmsq/+6tsmnMR66BVJGBmwMAZ5TaJbO5eWD/LeVWEsI4vDRjPhgk7mq5vWcByoxgppzqXMaMlHKiezkei2VKvBGOxEEpzwKaJceJsBetlnoXo89zFRouJUMY/aPVkoCRyRDzkNnRvMlVtTy8u0ppa6fWQd0uc7LlNPW1pGPmzjKxOvEuCVepAN+ZfyJsD1RLySX46SotA0rOzWorq+X+oYUoy06Ci2aEYGXyKv5A72xUfwsJ2V1ua5+J4c5SrAko7PHOpLZqXC6LswbQbxN2zzEbfIG+wuDQnHmU+D1ROZ5Hl0suH0WHOhOOBF4CCEUBVcI8qIfUK4MXsaMgAKK4y64WQFwSFKHwIofR9iYjxaJuo5oWGuMoPLuYVc789LBdGd2LH3gJla01GdsFQgPjigfwHeUpfwB/iV5UrMBWUXgbmbOC4ngzXoQCWrgFhO985ss3j4371PVkM7OAyqK3GUcXlCMllM3SY1R7baWBQ+ZlQNliy6JqizohmClWlDVom/hhC6zXJub1j1dRSJdcGNCQjP39pSaQ1jSkgTEANCOBPCmgmIorDXwq8JmvfeI+RbsytopUKsLbH62CLeHto/7KaadN+0nnNRnjbw/qe1LNq4VKl5cqMzDFFVw/3BKwBme0Uh+ch5p4ZsJ5VV+20NebSsYkAlbu6/wBsOpeC4XXhEP4BkPwLxYnqHs24Xcnh8LhEL7RuQ8SxfDr2n0DIL/ZndUcu7nmzdbtOzOL+tH774f7+wKU56aDIJFDDyoPApLB8Ut2P3jjrUU8kiUvIURWxySINNyHkzT2yOhhgRles8qY1muly4ilqlkmmNMWDj2akonOGAl3iGigNMrJBdDbQMeJysXnhK8UR91F/n2RPHfUD+xXpOTH2D1dK0twPw6gl3uTsAYblQp5ibwUUo6+qYTIAX2BuN0bDnsb1jy04VTQbDZw5QTCCBaShdqMFqGeWqFJ2bJgmWBBtlEUgDP5LDKniflGJOaaNVlx7XOmYsyTB8yFWjxM7KjigS0hTRAySSgME9QZWoiPqgsVUAWA3Y6+mW/jVw2fybss+rDFxc9N8h4LOWzx8Eneahnda8EBgPk6v1Lhf7VtGzkV17GPbvqSxeGw4FstfsbyBUJcgusGnriMZieAmGvPaN2gomVgIhFM/AAsWqrlFuqfbMkAdi2uUoou7aUcoNICw6AF+kudKUAp2pqI0AWjux32WmJxtAi1qFxK94Aw87j3WwPBzAymFNWyHaiPMi3CYu3gnTTpgUMXmtcY472+bF9vMoaK30C78DYqRrtEZ66wpqPSvnpW2mrbBVpScaQyMlIxDq8fHl5PgDp4FSpMpqYF+U7YUbwD7WAKwzUjJIIXDZ9Jdb08HdvnwCaOwYtxnz2nhatl3oaSnWjxTKm1poHmwZKdTaIqDIMSzSdTaQLrXByMHwdxEuJRPXlySftwq+d0cvtqV2eefC3W5g4bjfoNZ+iX+5ttHU4n2VROXzXX19f1pze6182dSzo8aYddeOuoe0aTLShJ5J/ID76gfw94Dv0/36M5DO0wKudx5QhCFq2yT0LHp6Oq9WSYpQscRkdJPATX4EIVhSUL02tAs44ckoFZ6Sgl0jBKPhiY9ihsNPdrHTLsaj3o/AcE8zQ5Ii2k8hjO9OJIhEX4JPFUjmakdMJywVJTQD/lzb7WFvLLrd9WozGrDQjd27nl8ZWVr2248fozH/78sov37t4g5dqEgWY1ZHdKC7UvFM4otJkkwZY7YcvCk+9ZXtl48qk3Fa9bvnojm5PCZVTnjtRGgdAQLYgAB0a8UTTVUhEQzIKnD8kPgKoOwUkEo09VKsuvND1jaVtkNBvI1/norFjAYLjRMmNRvzQvI5w0s9VDBNLfb4qnEjbb0X/qHTT2c/yx52s+ITPw/3au3MTstDJv8OFCYwOOt1GOdwHHW4AbklRAMs0WrU2YKbD2h6ifoeynQRx/EIM4fhrEaYKv+dma5KzifClZQKaWDNRma2li8QibrIlA/hTM/IIal3OSR85FYQdGopPIKrBaQQZTVFCWLl16/fXwOrKLP7Ar61LS0VilqG8uVmLRjFcGde+JJ46++YRwLi6voZRi5o8+my0Ws8Jq3qykQnTtiR77hng3yD7E9w4O1C3Al69S07QRXQvA7WToWg59eiRDoNPs401mggqOy49WEIgxKhJ4E+DPgbjWWmSQ20Eqt2cTQFKVQO4Jx0E9+gTDrshQ92bGUU8rrtz1jDLCT8dQH92CqPN31lGv5Qo0xlK5mvDBCCddAj7tfkgRl6EF9tF+fBci+I7rB2y/Tbf9NHq5nkYv94LKgksKjbZUPnbrb4FVnrTv+YTzE2Ed364cN9Q6Bg45PLapb57u6DTwJmseRtArujMYGAhlMAljKKP1VjEPo5ZrMUQmxog9+U+334hJsZHslcbxqEwYBBbuAuD5i8c29benO/rxeDGMGHafhJf8qWPl04/W8bbHkSJzPmETUTJNm1eAuSOra/gto7kF82n+zOk0f+ZkmltwMc0tKGYR4205jN9cBWLiRtQPyq7IjCzNNCj722aitXPT/yorZLqsj/8bLesBzo9/Qz/LhDn8idufgupHRz7NCBmP7a6NjxG01CDXwc3ilsDKiNZ6kma6pYHqSzNoYDKznK4gGIoHKUpjYJ9etE1I9jjvB48/jmYNzhyc5zhzYM534bZ+cHz+67Y61CgKwBxEOazbxGUfvfW3Cjv4Z0SbyKA08OM8wFflynOoH2tpRptzSJtXpejO6Cn8H3HDsLNHpalo5NPhJ0SK0Scqlb9Vjn/0FjrT+OT1S4tLa74hTXibenO6adYiTDG0+jxUvQarywtrp5mjuRhcSbTXnL7oapmYYgZWS1cL/35LV1fLqLulS7gFzHQPfyfd3wLvpMiSeIWGea4CZTfUZjcs9/UwLs2hmOBzDlXRBVIL/WA2RSgAEMn9miKXPG6quABkZZdHQddEk6x5+6cmzc0mhhTxyFF3TYsPusX1nkDA89Fed7D436RjCUm8e9R/8YrNK1Zs7hIOu4NB91EbvL/3jZsfIsP6m+Sw/hM8twLo9sVjH4rN4oucFzT0oRoGIQZ7C4Wd5X+gE9bEglVNCpDOLiKsIYRV4vzMhu4FSyobJl6qsafFVBJ5iZoXxi9e8/Nrr/vZNYsX/31/vyV27hlXds5+6YGLNj3wwKFd/B+3/fKm7a/+1/1X/NfcuebYpsv2LP38LnrmAWbP12NrCrd4PLLmZZE1X0NkzcOIqqJnTa6BiKEJA0b1Sl4PKEoYQZs2fpaTYxPDZss/0rTJ0TKz/tUjwlqA6bOcKPybwcn5QM/jAG2hEDaiRi+l+UKYqIU0n0r2zSYO8tn5l1x5ZVhZvHLd8tmJFdu/vPKK79243XHaaS7Jl7Y4ebP59ALZdeY3v/aVl89edPeWq6/87G0LNjxYHBCNZ75ww+qLg+cYfUvaFu/szV26a8xWfln8DNfMRWGtXMeVg0gNZxWjAThgKTpgLKqE1PBVS21IDRvGgENhNBs1n1xqiSFBTBgmVkIs1CHK+yKxeKLmegRuE1VpgqJTUBjrJQokZQYUM+Sdx8ilLd/Wf4DGIDncPlB55zH94GPvkP1fIw9doW8if738cuV0dLA/9o7R9G0wEG145fWV3zz2zjsXZclDl8M1/3P55ac0j8dy74e51MyluRNrmMG0iWW0VFUzs9ns0oyAZYZiaa+iI5ErxVzAgkqoFViwZA7CXEr0l0QjfCbHprZqlOLjuOTrqJBhoYUoZqLEHAZAxsDfeso9k5F5InzBBWeFQ+Qz+oOS/8R5a+f1M4xWRdbXMXowDwiRaLLXYybk52Q+GX6Nd6i5eZeM4/UE9QHEcf1vquFlZiPWWsNlPORP/WY0ui+FW9B3gRlVURgvMyC6zwf2PhuvUiTaILyOM1pmPkVSgFvX4Lyy/uhk5NaSJr7vc/rq+xhOaqmO0oLK1xGnnfrv+cId+kn3sdxslpOkcgu4shux8FHrEewbMyvS8R7ShCziZqJFOiWXFyahkco0H+YD2VWYj7xc4mw06kAUWCPMJA4fZpKHDzPmMivoBQWBm/oe9YJWvqf/Ct4r/Gmk7RV25BX9Nf3gKxXqRH1lzOck3AI09gCVWTTQmqPuPkZbgEcZS+RgkQsCf0wBqjD15LBuoxtZpuXqS8m/f7SfvK0vqec11mU9Svqygv5xuxOzsfz0LnIda64eiqrfZfxOtRvRzIEpN9MDtRv6x25KuM+N6SneWi0H5sFIGfR0Yb4L+/XP8b34m3yST47/SoMvbhlyIVCXFs3gVZQvK1xRuIWuly0cV5iUzDY5ua0yfeLurum1t9q9i+Iy+vtcYdwNxZyBjV/ahQt6w/eQzm11nKmvwtCIM/CNDAs0Ocz3jv5YXIYIY3UKeXvKGNEYBkj2XJ05xSwKjcDYz5BJcaw8HoPhGVdaUdXCO8Dr+XGTk3wDBwnuhxkGwtt1vqOwOhjfuWk1lrVa47vodPfqarwTvc+Ee7C4I+g0YhvVadw1nQYVGhQVyM6TdfMomWCmictGXz8ypoUTJ98LNPoWJwl/Fb9O83Mx7Tb1LX7Vn/WHycY/8+tGtT+TjbCFuLmO/UJcLV6F1kzCTApElRQ4SDbqD/+FH1TIqPYSvXT0ZR8hoyUm6wSOF58Rn6G+3Lk048FRxXI1hNo/NeMhUMt42IcZD9R/oWCKLOY7TM12yIGcQKUyrsSFPcQDctazZ4/+nn5Af++OCv1H0xzqB9/ds4espocnwOUEHWI8JwnhcjXAZWdwYV6QfQJcNswMkThYYkQn5ogY+yeDF81Hp4CFRRfTADWVVlkKU01f9Y85wRiFJILVay4UoyKCYVem3FwtqIVUISWlJHUyEGte3bnz1bvugveDO6fA0l4/A+8MJqEGkzwRJncDTJ4xmBzjMDmnwAScJaUmQ7OJeMnu5949fwIk7wEkt+jvkN3Pvns+i6OO06YPbLOLKSSFqjaL6gJRql73stEboHMtXNXCzCUL8A0CfGFcb6K9sN6k5f1msY2G/LhSalZtGLWorHVglnLZ5kyjot0rl4xkCg65LHrHhw2zaD6B1yg5RDU3LOZ70wIoFB5gx8kIVkZEp2TkDbxZdIgeweMzqQZnKuQnFYO7O9Yc75nf03ThbXdMZVY+yBttFskg8MTr8tlcRFRbhpKCpT27Pptb1uY3bh79S3EibTB6O1DnZoUuxm6auOOrYn6ROO7WLbmVOv/6UDOeimohilFOTDSfDqv3yAgLNk6F+04whooVON+YaxXkergLubIPJSJIw2gVk+q5TNnVFM/R4qmyI5Gh/v8sQHuoLIU70behVMvmSDv6NtCdrvhgBrYmZvSwTCjY09T+Eoe+9ZZ+jcjlSEcntTvkfA408HxOCfMqIOAgkhLPp0kqB6o4HO0rxPM52IWDcCqnvOTsWLBpcaVvyyb3j34UeGFD5QufC5/tv2xp5f7eH1QC5y+uLL3U/3NyuDK4YU3BXql4V928oHL+3ujLLzc9cP3iS/w/+cmMr1aWbFJ//CP/phMrk3O9PLDyLJyUMxdpyJmrST40/DBXiuZ6eYMTE+NoPsBxEuMash2Ol/K1+PbbL6n/P37q5r80XMVNzVWdjENwKg5NE3DwT8Ih8DE4AAbkeNBv2rnux3fpjx8/uy++c131Lv2JKTA31WD20SkgjhWGMskeYDDTwtB6jp3TS2GWfTWYHU3T5NipBFO7PDStqzc1Bephfmbxqqc+rG7c/NSHA1Pz7K4s8oXhD0c/GPjwqc0buZp+cy71UxhhlmCuHYZia9pNiTcAc3NUOaZZzFhIPLqXj5OXaSbzP0/5fi2/pP79MV8V1p+DlsS+T9NVu/QBfQ7pZjD8GObpEpinRtSTDNQLJNHcK7GKP1QSDQ0p1QjIj8lL5IB+iJU2j+7FekL8nc/AILxV/x1j/XfI+O/AMqEZ+2tF26CefIa0ASwd+uz679Rp8k9Ub8OKapjKCLpDMC68498fwqvO0v5uR+WWV5+5wEScDAu+df5nG+WNEb4p1/OyHJmSs6bjqQT+PPCSo+pNJHmX/vpN79xFkjfpm28iI7UDghmPwC78XoyLi3eJd9Hf48DQjcpg67JfiZEUXqT/iuy9iaTu0n91kwZH9M079F/xefyx1E79VzuwrobmUj5I9eo4t5JqbZGqFqf+7FCmnlFBGp1CZmb1BVyYVWmzi9E4k3lxkNVmXK5CMtCzf7LfgnjCBNV0jNehmo6iu55RyT7I2lli3NvnjYuzRL/yU69/Bkjw346fhw9+of4LbyjkJWl4H30Z5LhhjK5JroObwfXCKpPjyimU5j05DIyi5B7MaD20K0Mv7cowBPD39oDEtnrys1jEXc4pUZoTA2ANkmSGYL29E2YabOKkchIH8Sq0ktUTw/oPmmRTCGMC+AguKZfxfMw6lIqE/sPn9ijvR0OpIUuc5y8rYhZ4UYi53Yf+BTbv/qHBEXHzQoTZh0Vi8ZqeTs2QR+w+v23EnU6WTF4Lof0CDp89I/OPuKVvFm552da+rp/Z6Mf+JD5H64ay4/l9OdA2MPW11Eu5SckX0pjbN2woeHmHmObjUp+v0JcYxgSCVDLG4tSi9JrZJCgz05kLz/vyHW9/pmvJZy6/eet1p69xnutOzSuQmQs3bjqt3SeaJG9Ujn9laEi/e4Pv7u/mB288Z8fA4Cm57nB/+EX9xz/bfUrObPQ4CzfY18zdm5x91o0nZ71mQyiQuzISefnHOGcu42zifPHfuROBy4i2mHLUgqq2wEUVoCXwGlwA7DOrj6bcuL0qrIY+BmyYAKygy4QJ4iMW+viUT/Wlkqk0XwANJyw4RMmI2+Qyg3nhwpa5s2a2OSMO78q1sqHFZzE7BcHkCLT6++dvmjfHmXzs73xKapHTvXKNIWfvuGBJ2snbRBMhVlfQnZylSo7e2eRbc8Mzb+hWLInhofDc91Kr9haji7s83ohTNVmJaPQ2D827dN7TZM0lXac8bOCl6G2/ut/Ucv4lT6yxDTT1NrWpAZdoSS9fG0lfijXq3+OuF98Tc1yUm80t4uZxuDy1U/0Q00hPzGiDh0BfLC0GIhQGZfccizkQNLW35YdpfhdXMoMe+AInt6bzw3MXUaEPdDFmw4YWIIsxljakCmFDFiiTFlOs0CjfWzCqPrWASQlDQWPzwpVXbrlv5L4tV65c2GwMTj6wW5rXfdrJ19549eoNXSdaSSE0qz/co/2Plj7/1p4LL0ws83j59W2WtnUnn70ok1l09snr2jALdOK+5eyhM2d2tuVOH/iMgyxOLJgVWLIBy91PWbzuym3zLvSf3dqK0xRowQEtNM5HsxlO4L7GlZ11S3RuBrNAtb7gt4f+4z9+zSmdFs2Zdmi27xhKDvJXh2b/juZ07bM6bZ7OfS76HqDvQfreSt8T+F6Gs5E7I3fGjWCg9WuBfi3Yr7X2a4l+zdrPvWC12V2BYGsiXftH5ljgkMM54WA6rc0JEo7RGtOmcySOBC64kaw1As8mNO0DrigkYRB4HBBxjOAnDg0mvqi/8sXE6sevuDBl2f2LFxKb7qZEzajhWU4HaUv6ujOxGZ4M2diZmndT2h4MSolTz7tvnNzyXR+tuls574JrZjrb9Lf6drqfuJRRNLOueXVTcPSJe5zJbHK2fw5/w4x7++6e421rs/VuOud82hvhqyAc3eJToG+4MQc9Sd0aKQBZQksaVGhFbiL5+GVNCYMj0aSMbvfO9I5u/0/yInlRfwIDPvPnL4qIkagx8tGhIv/Po91FFGXYKaTeJ0KhcrcdZjUmjSI3d2S0BJWzPuyGU/bR7Eif39xZTvjq9amlTuB0XwKmeyiMNpk5DJu+BHXK53v7Cuh9oP6oMEFfQSohU59BhsQlI/ZYKMgGY7Loc5JN67etJ5ucPr+sP1gMes5840xPsKg/KPuJsd3b4yALyJrh9euH9Wf0v3f0eNu9dttf9b+e5sM2NCtWmF3KHN9pRPqrDVfjep63eVIHhgKsJmO5ptwabt1Y9D2PJWYsDwYzgMDQx8h7Yzb6p9xmvpCP9ovLQsouTJjcpYSKH/uPxp749+sXhpSjS+qp67Di/E1bzE8vGLaKz3IWzgW69AlUT/PTyKKHJt2YaGsJITtuoBFag+CDpd4q75Psblo/4QJLzYGDOESwzwN6SYHLwNSPkoLK9onAr/8LLnsPj+7VnyLCtTuf15/iH9957cN48C+VCr/+FfSgvowq27V37R+9/67r2IFGf5kbdElW/+sCYzI30cs0MTxG5HgsWc8UG31a/1kRs+gxGYzlzSM3D3Asx4qOfwK4uZs7myu34O+bwcSjJRpmzOFTspgD05FDs74TqJGmvtQkNsTAJhyCq+QmNDNYxXLHUga4XEAVFySPWy6FW4BcKibGsX5QihcECCjqw8ZULxYteB0GEOX1VkxgpxrlU1L5xEB7i2wFMxv2/anl533lO185b3nKb8TWTKSLX185cnnk9IDV6m2Ot3Wl/bLpSKVj9faLLl+Vy626/KLtq8lalsCLFX7Ye+i33DfFzwhvoNYkqOgoC/+OnE02/nb0H8ju36G77Hf8PKT1Qu518cciV6+LN5OF/Hx+7m/1h/U9Qmj0RX7e79AJx2rpZnFFwxbQ8U0wj9o41KlrThiJqtbogRElpqKzDQcuYbT6UQUVCl7oWJdfIZ2k60fkpl8efZN88ZfketzvrPAHSJP+B9qWCGvaNut/IE2ozgOMbhizJ2HMsgBtOYbjFchpXUB7l5ZkWcEYfBGryCYom0BFasXMRUxXbGbRC1CWSmozgNRNRyVZAN4BnQN9n+j5FBx8J6ErKh0h+hnH5RUvi8aSKbfB6QgINyYNTfKZOBn7fsCbwu6WUEdIPwhvWZpGo84YvT3SbRCe8rs9j8gKHD86W7T76OzNsvewVwlVOnxcQw0Y1m84GzPgRNTGNXuW4jJWjYgdV0g+V2P6qIJF0pVasethLFwVbmHFrFw939jwa/rbLhirsd920txBA/ttOYOM3GCf5UgUDIvxe0QJtlnSDzbc6agfy8rqUwsdDYSkgcd2UJkaZXWxtKsT9cxh/ybmlhPNVOMjOcYEOfjaK6+QDtLxyiv6IeRwlkRe41/4nwF7cgf8ZjOtKkJ71JKh7aDG08louCaKEieqjP8EfNIf1X/58ssNOWAaUJnVFSxmmeVakDqAQrQ0yUC5x1ul5VhNdd9dC7WCyi20kVoLNlLDyixzi1yb3pNTfpoIy9pVPRg0AmEYr8uko/72gZanDa1efo8nYXhav7vIEuzpkMEbOYX/nS/VrY62Uo8WXdd31/J0rSCtcmD11Hv7GKuakTWFSNMOPaWkEf2ePkpgAZh2NlHSoprvzYNZNkASciLu8TmAodHFn+JpL5ua4Iwlz8sGAqIjFvRViGgzV/hHR89IZniLzWkQ1nhD4kzhjyEFWRdbBWT9Wbv9CC8pvugpR3jBbnUajxx9tqK/a7OSZoWcpP9WWE29/M/Wco54bgnQ/nygfQpW2TxX7kS6Z6paIqOFcyhP1Ww5QXOpEzGshZuRwSpxrpTIAEZt3Sx+3zdACh6wCVJJGqxwgr4A5nPd98nHqA1nCKPJaYwtafLKW2Y7r13jNrq9Z3rhfc21ztlbZG9T0O1bPXrkL7NmuYPkCdvMhTOtMy4mZyqhZ8ii5du9EU9Q8SQ8NyzXv/UMYNwmmZvT7YpXav/XnqGhHiPypAJ60EPiQ6hj0dZS+JdCD3dBQid3SpVU5Y8r3uzevbv7zRV/2r//T/XtP+4jL9KPffT0Q12/WfHH/fv/uOI3XQ+xdblYq4GIcWlY82gsue0QxsmxKMXXBuzmrVcoEO8AwSgYWNcs2WUsx8XJg14izyY5RYoqQjyFAcvi0HWuI+nE+6GhlP7N5qFUtmmG4+x7vMVdRTCWXzpy6HPYhunDpcV+sr6ls9h10hZpV9dJbc2vfD+Y0O8gVx989bnfXK/fUWysA1tWg3MzV27G0UxQLy+Xw+J/WCklLHHG5haWsZg4DDOsmSKtv9DijHNZhS72BpAZlsm47C6b2rrQ7c3qc9vdWiesJGkU2x3Ue5STC3LvAEEuUD21STeWMpbhk4UWmHapaF6IS3GYXZ+EexHF2Oje68kIEEDfO5kAFHlyNZ2LsOYVDYp4CsX9BO4aDt2nrbQlSTvNyPYi2uUeWhffQ8s6506LezdLqO2mWbTdgyBRsCCuG5Dfb5ObvLOpIdjUCijHgQKy5u8veXuAMurgCdSrXJApEWCKJ2AStxBafhWtr2KEtkZQox66tNGk7WgHjzkvebB2UwZTpdjscJCLHFbZdonDegpJn7LpkpM37ZCanPpT0uOg9yduNjY5f+Ryu116gVhFsyCJIm+w3LdWf4Z27FrK2+WExfyW0bbZ4XU7rlk2skJ/xpd6pGkDWaO0hRVviBBeMAg2k8P+wpp3a3LsPPE5cS0X5mZyg0g7fz07FNbomVhPoc3KlmdSMTCzH2k3RJcPrD2gTQ9auljtATIOENrrwkYR2mC1NIyM04Llg7ZmsZ3SLtRKkyy0Flnj+kvCTKwUSXVR2vG9fWqUkQLLfQ1hvp65lBLisVQO5Xa0ICckLGqTHIYOgoplTj7vYiSU1XGJ3WV1kEskT/Qpk/6ks8l480UnW97AT5K4SH9y3T0WAzEAwcyileitwtsVft7IMnKNy6XYL7cZ3xLtKXn0A/vX2hSyptju1Z/ZQP7rvTXftDqtZgEDLES3IYXZXNuIeqrBAVYKxpoWceUCzrWZLLakHNIK2L+s3K4gedpnAXlycMCFuij270NfSzsGV9x9/f0lR4bmcoEAaSJhvh7zTiXymAKlyKmk0UmM2PSkMGwYxGqAPpxUPtUgS1GsF9tIQeft9kfaFP2ZFSPLrnEmHJt9p615wRdgkGeziNQG3Wzi1/M/1e83eloel8haRqJLN52i/+JkG7Ff6rOuvddtZzQSbIRU0IH2Q1eTcYf+OtgqlVrcgnAW4T2Dn/q9+rBjTo5l2hZoxVeOYU67Rbb3IWNQzLEDib1amomYo35gCQHmdjA+0RUAq4ixBZaN2UTAypIhkmAtITHu7ySCJ6rKBgc1QpN5eRBWk1TSSVB3J07fZnvSeQ1ZPrKCrPG2P2If/RD437L7PfLfG/SnvW3ZrCAZ/b5v3guIL27xXWonVsT24ktPvghnElkrPd7scOo7YMj113cYm50/9LndPlKxSi6TYHffy19eoT2CDFS2PsU5YJWZVdNPnFSy1vLJOOr0w6LektOGDli5n2bncazyu2Ty9I/VftfCBHwiKplBQTKctefX1z7SEB4jKdCWyL36pfoh/pRrf73nrD36u7WIp+eEl0iSdLxc10+fAphcsOLNrFlinioCY6jWsxcsLHWh5ME+S27M4ypbOLmfVaOjC0umEGEHSQpSAXQ1+AOIrmm8cQWsnLR+kEFDwWXQPKa//tIPXm6gD8IyPAZLPc/Fw6r+WP8MjE570HB1IIm8csmAGT4Wd8nONCTPRIgStD0FoUS6hoJUJ1KlUpkWpINolE2CaXkNpnHiAFisBLEBLHUCWO4aWB6aiwQEBNK5+8eHcRxEM208MQ2ItFSzMg2Mm9FspMq00ADnndyXudtqkIIBdVJGu4nBu5vCy2TrqQzehzDhi2Ojeqo8x+EweKLx1uFl66697fbPP4COAIv7BXusLTt0+oVbqeg9qUt2v+DLzhw+ccm6DXjBTfIcs4XznnrV7Zvv20WbcrnLV2+9djoUPUaf5PVJWXQHq2G+4DPCu+p1EJRKfAFmJPzHFsBG0AIxjNqXJrhd6CvAdWHSApo4nCkMC4VkAePjhbSQ6kvhlIcrU8aUA+Yp9oOV4EYOnP8FXxbevHDDND+Fsn81NRljxObzm7zrfcP9IVNasClxj5EYztvaEmkVHBmbY6FsHoqkXVmXSIztIm8KBFWPx2pyGNuajLY2h8MjignRYJH8PqPL1OJWzZb2+Gyb1dJSsFmN6dVOj9vZGRw2OYcd3tmC4CFCDxGEoGCRrW7JJRPj3PYp40o2xLY0mxcGrB7REjFlwqJ7qVdpahKNHouNvzzcOtxiJpLkshLeao2rfIa3mwRf0h0KhJrDLiMhJrMnYTYJixW10+Lo8AbMbo9gtqopJSK1C3bBILbGfTZBsLmNFiIYjcaU06pKsSsutyUki00W3T0pkZhszEfDw5p+K+fluEFSIED5PtWgFnwwJsQYyxAnvz664uy/u0sfvecj+99dt2P0aWen87K7O138uvN+0Hf6eXe+vf250xdmRp92uS7laM/Ds4FHn67lgjN/3CoOewv0VlHwG2jrvBlVXAuUKuqXM6u4FCaqNOaTP1Tq6R/vYVnOU4stjxYbdkLEOND/okKDYHMp2mBqoiF3vG2wPA/rNlYnXal8f9y4+9Z0m/qD6PzjDxTHezmgDYBVWqxGqxZGZR2SmS3NlThTzVjH5ckA+okkF4W3jy4RbtEfqYjLiljMrR8c6/dSty3QNk9wZ1OvDaFVrKEcagr+GFays4rPZEZzHtJitMugM4YEBNUEwKCNu+OsByEWg8VpMRh2HeSzWPrFlRwWmv5AXYJKY4fUsbIO6qmjrmjaCbZOO9I10F5pH0DfAhCO/qPGMBlpH2CEwhJOWnPOTbDlMRbqBQ2hno3nzmFkHSPpLMSK2QiE5h+hVxJ7oQgFDJxKN1XuqmCklX3wv6rtVTCMWsEXHBAi9OPog+wk/xa7hqv15twr7qV5Li1cOzcPJP8vav17YL0OZ7SlOS1Q1RZmsQy4n/Yg6M2W2yjN2k4wd9Zb7axoSAOAVb1WpB61dmJXjaSr1AHHhqvasKs0H7YWV/cVFs83dWo91NooVLXFYxkPK1EJxh4CFgdtoVEa7oBVpnsQ9J8CmA7Pm50eMTNAJXSY9eCyyawPzr6O7sFh3GxjyTdaXC5lBlA6+8l0HX18tQ538VgfdSHglgq2CE89ZWw/JbErkglWBQBbx2sCdElLOhJRfcvhFYn41JM6Wq4lZrbjsoOh05rIkZZIugXORUj5OM2Cbmfnf98VjaQj3470GLYTh8OHO5Z7fKHWXG61L4L34cix17gB8dvAOytBw8Ich1QVrTiQJn0ZbUkV+0JgrwaulMI8g9n9WkTeb3UGmzDTR1PcpWyOGhGwMJFcFhelvgLBGGsKo8YSAX6r9auXsJEkHK5dgs14wrDugKLZQvAbqF7GYxJ8pyk4I75l4eyZ0TntqTaZ3Bn3O5tO9ZrT82L6NmkBucbrUZuSTlfr6K97FxdONRucM1qTfi85vXdoU19APWuLSTrt6Ki0gDfMmym7zl+5YM2mU9sW6Rw59A8r+uc0u3o6OrvwV8/JrJP5WEy/SppHPutzqa0p/MW5s+PDc1pbFfy9Ql6Ud59z3ml/PcZJg+TYvP1nrLutNVrww48xP85Krk/8nrieawaNfB6Hjqg09d9IWaqXg/LASkg6mfKAaniIlYdrnfI+QXKyTByhF44ZmFcHyEL9UFihgH0U03wqLeKCDFatCgbuME/74TsptYwrX7l55JwL7trxUnzdvEUvny27Oq9YOHdWfk0i/NTQ8BzfGRtXX26bM2/47FmLZ225Ird44FzBdfPLN9308s3pUy9etPAfb1bVWTctPGFW/qyhVcmmtScM+0697PTLbMML1zcv2rjmqWdXncvw7D/2gXi1+A+cH2wPzuMFUGCsCW1+n5KwEz6Mt2TEVpGFFAEZ41Oxu3wvTR2Ace+fu3PuGWfNIU1z5+60SRce1K/777Pc6VBh7sG5Oz0XHiS34m5LKF5g1+l/mEs2ngnbc+Eb34avGPAr/3OWu3tmYS4Rz5i7U6ZfOtudzofiF3WegZfqf5jDZHul1i8QO6aEMP+dRlgD1LJ2U9vByLq8wOjAvptVX9COGVTcZGi7lyY3KJ5Gg489eqEgs1SOumVciMpRd60avzJ4/kNPfrk4i4VUimisfn9o7dDQ2qLwLSWbDofTWeXoIpDaf+EPHP0Vnhia0D/dP54NE8hgYzEU1QTjRqlkb6EvqxKfV0LlgYCcJpmf/gK0W2vc6XR0OEgT/WjV/3jwZ2Tbzw4StRV2nU79LSd+xPX/1A/+4qecQFKcG+zv34AOMcCdwN3DaZ0ZrY3WNQ5my50iSuHODpDC/XQBdFXLrn485pJrLhvbIVzvQM8gtGUlSOGy6MLCRjQ63aFBuuVCxwM6voJYZx9gTY1mYFYRj6GPTthI9Wv98jc4WyAxc/gEFjXTPP3o/waFUwZGz/eC9onZgaIaB4Egq1h1b8QcQSxy93jDAvCW7CAe2uCVpD5vWLekKT13RSa6fsfKYnLB6sFO4WFT35I5scFVhbby7uKXTmkL7HXJHd5mSRxa/Kcn168mpeXnOslKyRHI9K8vnH77PGnFStHTNfvCuScutetVh+TpGjxv+PNPWpevkNe1beLDoS6/YpTAnnebBkY73bfOWRRg8d/zhS+Kz3Ancjs5lJWZKqomcRo5jNJO1NZq2UMf/OFxIB0X05DQMO01354t+2mXQz92LJao30viWPW4k3krMCvEjw1u+aFFJyKtnPLz1tZEpm8m7jjcWg9QNdMHi1p2GBYpTi71sIat+RzSCuhI5Ui8lz45QzIq3rARUy59sC0Nk1wfzmEVe58laTZMatiA+SbFx/1ei1nIdG98/KYfPjh/VWviZG+7wWg3eU0q/8HLJkVpnxU/R4l8IbZsMNu+MtWh/iKbWqv6C0bFIttk8wxbK7++2FMIDqw9s219+erepc0hpavf2qRE3AlHm1jM7ggN9FkdJBa+L6AKc0UxaLPeIzqMdqtsKdy9iMobsLLFZ2v6TEu956eD8qG1igQqWcHa10xjjUTjspnHd57GTirk3tonjf7RUgoaBjm6TbgFo3p8TUYY6XMTsOPF47UeMMYcCGq2aaIJld5qiROBve00P55658ohGhUNqdjyDPsq4YjytEEGy6fDhwtgSp1dhS9aao95sdBKwlITtiB3gdoayGb3uV2KiXoPPCibsLtGPQ1PM8mwInAlr4nWQGp2WZNxcJlZHqV9pjHAwxofCTJrglQANZJ/pYKxo5Eirbo5t3guOryLBFv0ICFoo1c8y1oaHcaGRJXKBJo4aH1hjNvD8gRLkgU7DVG/JOBqovEykJwu6uhtpiLVN5UAEiDjVABZ4GUZCeBw0bhXKMKI4gHi7AtarCam5WWw0VYjASRGgFgLVhmIBqwyKDW74JwfPTywhI5To4a9MJkqDdRAGhTHSHLuODUYBfgD41Q5ug1LcSgPLqvxiBu4ZFO9Z2mm5u4BQlCmKNsdtG0hFZZqRpMxW3CfxyWb6ONcJPp4JA/NH8QOTFaKPX3WDXa92c/xgpF2h3BglatBpHO45tqgiAkY4JDR2qpxN/IyjBkb0zqDg5YOiAhvg6GDD4eocB+Hg0ShdyMmZTftqe3Gth5YJEYfxaNZ0Ye1z0NHx07xlCgOFoaDTFmY4uCZiINvMg4JCj1j0FQjDrTtcPHcRhyKFHj8o1yJSyTly5ptYwHORCxWczUErPXaEFdtqlLYnYfKktWDSxIwKbaZpJ1sfRYzvoMkZnBbTShaBSOrXqkTnPYBq79ySl2c0Dow2s4WkxYbiE5bdY+9/nfwWgFeJ4XXgY9CKlvommFxI7wW3yfAm1OEBpjH4K0wIGsNeI8P7liPR1Zv3jFes9s8tSRaHSuE5qYWYk+uG8NCxkfef+9RLF6ssFJGVrHI6hfZiXdOqJc5DrTXY2l1WGLo0ZwETXwqNCgyVBALtMSSKzV7cDM2Xan4ZAg93eT9RxAWrLB89L0JQFbIcn0fQvroe6z+shFS3XbkyHjs738Nb2wc3ujfAq/ahGW8YxBNgLd45AiD9v1HJkNbBESW//9O26iAsNbHeSKs5PARxgSICPDI7AbSbgZYKU8avLSuMMgNcmPLMXX9YMWAm3U3tqEzGZNZQJRK1ISqZ21osqwJLLceEyE8+THg8nWo2ePdKnW4yAjCg3BV9Ef0R/BRYBMKcKnO/hpHhEPiV4CCGI+O0FbvXlYh4g3SmhdUSIAUYLu18GgipZJStM9d6MuAEgZqFicZX7P4SHq3wWA2m+12Pug0m/wwP7/M8yaT2WUWX9T/c5nMSx59iVexmoiL3wJU50XynE22mJyGV/V/Xu+pz1tKIz9AM5srCzUambDuGkuKgjR3A0Sgd2waW9nkLQWFWvah5pK1ZtZVFIavkI9isSP1UGFmJ20QQemHY5nJs3pjcthROeOMx97BVYgKGCCc81uMVt8SJZ5/h8YCGBUb8v5DXCt3cg1OJ11AgwBYosEOszLPTRLVOzC/nvcHwi2RVtR2QReIYzQAK1ZM5nAsTo8GZepdGyukTkk1Lxsr6i2kMCcxQSsDajNnxbX1qumHtiwpPvYO+TPZeD85fL/+JBv+cxZf98U6M1674p3HzGTt/brtfv3hKfUrp9ZrbproQzg8jVUsrPIG20aA1RkY80jVH3T2gmi2OJxuD6tWVJvgCDFKNrtL5o5bh8PXmkccrxJHvWLPFVfsOX4hjhtPX9Egs9D36QI9L13r2S/XujTQhzgqtFDPBLoBjSe60WHsq/kQ6/PezNPW/bCiO6yi3+o66icvkpcwWxE7YWLjWKdFf0+IYKdhZJPRLVlumvt3Trr/33ZzliZonnD3LixE1+eRM8fvzh+gUanDH7014d43wL2xp2Ydd7YaG1jTSdDebFm8vUxvL+PtlSm4g+k54eY9/Mlf1hfu4m9tuPl39Z/yJ+/WFz4wOis79nwuxBt9tP4xzJUqxsUMrM+4j2Luo7f24a2DkzFXCykhKmP1aCMAGw9u3MwfOHL/wfvJTxqo/6/nvLrx6G/4v/8POKHbsw3PCRuHI30cODzZvwEUjyqpBVUWxkHZdvCcVwW83/+c20CL4sGNB8k7AN8XYVBwOPBZgcdov0EDZ8I6DpHaeGZa2WSsYkc5VjSPNT1moooP6gn9hyv5PaNnk4cF10c/IC79arKnKjw5OrOuxxQpXlhpuZzDVcIIg2ikg4jP03Bky0aZPixChD1Ttv5sP5A9Rip+nNQNREvlnEbZXTb7VOb9YeIEnzGg0opw1GVjSSR/SDkC3F4Je3eNzt+FuWDF4i7hbW+YCsCjz2IBvr45JFxQobw3TPvreWi+3RwO9UCA0EkhdILxUDY6J4AXri/IRtqBmCsZQfyVrSpr4NIAlAKSj4KUKGD5kzAOmP7u1u36bQjZguu2ko3X6YnfNEL4uv7e1hsAwBKcPPs6vVV4slKfJ0aDg8KqcnH6HMTWBmASDZ0TGFWkFBmjiaeh7LEGxgVP6of0F2oEKj755A31/+Og6B/SiyixPnqVnrzx6/g+oe+om9LuYg59AUA7B6WdA00XowtV6yCWG5dEU3aMfE6gMDcetKGLo9OFvIyuWVuWOvuC2ILEg6XjDlgYkcDskGUinfFhm5TMTPkWaNY6o/Nm3UbRY5HnSgONwV4ArJ6igoi2Ba5UuGlwOm0anKbDZgL8jcBrIVmzAwpY9FG22gKYbAAL5GQUagPFwvtmMo5CBah/KcWBBvj1g404XFqhY1PDAp+UWsehQnPfzJRTJtcGME0QzBLWn+2jVaJW609HRo7Q3OBkkXalGHXTH8Q40vnwe8/WbCfW8fomjEqUfMEcti8pqc30QZAlqzOHj4Is2Vw16kj19rhW6j5Db4OPrsCUSFYLWk8GZqRiUsE+UXC6avEet1eRWUdGVtIJ6kaJeIF+JuadxHRa+KPuBfqiOhHuDmBWP9Mjae/nkVozaLoJhtgr/Ldp9A7zbg+9QmN5Yz3qme83g3ktXir7ZtQeUYnOE9WKy9I+s0s1YV9njMuYqWZusVLnYA8Tj3LtqcrsTRrrV5HwYjXOeG949pTXYjZb+08bgtBGgFYL3W4N6u8GEvwB2vYaa1zq75t/pJ9Ae1z8YzGUj/qNBv1K2m9vdYtH/qxrQUu9FoblQOYwI4ZGHm05LVct81YH2rVtmbK/OYHV5Cl8BgJm7LJnaLblsMA9QhsWR/MIOX1uj4L9ZYU8TegD9qFBUlx2cDssoPbuJEDhpQFyOLCUjNBE3WwgoG9eGtBtgaX65vqRmbYkuVPfkrTNnEkMZsUhbPUFCD8TDutbyJ1jh49+Dg/X4pjMRvJzzVwE7OE0l+XK/pqW4EN9uuympTxuL7p7MhnW2MjtoiwVaKYanDzFGirkEtiLecxWj6pKAtBJRUk+obAsctBMD6JxNFK5EPSYdUX9jmK9eAErLFMX0mOoTLGrmeEyOr9yjn6oOGbWj1TOOadSHF346K2Pwri4OJf4VfFhLspx7rCghoXcbNKHFZ1AwGQqmSoME8wSdhIXaRm+9/wLfv7AdS0tj7qMnu94el1X371t+3lbZKPj845u9yPC7zvvuPvg+RfcOxQlj8gZx+ccorzlgm3b79oi93hf8hjlRxpy93F9y9T6J+EzWjM0R++ETGkufXJqE9qRGZhgbfK+ZHt2DiUapiEUSL53WMgi8yq1+ieageD1zSbDZIj0RVTFi92fQdtPi/GYQ3QSxUEu4X3J1ZtXJ32EkEscSthLm0J6f+gN7STDO+mGMVjc9vr20x//bHF2l9mcPejNOUgmK9ojAcXb1GyxZPWfO3JebHfHP6UExKgYU+71++9VYrAZUCqmwAk97Uq0rS1qtYzNX8z5DYzF2snEzrxRJRFNYc9WhXWnpy9ZpU/lOCZ843r6mA3WTb6y6wh9+jT+0zcXa76F+j3MtGNNay2a7s1RaWdpzO5iCwF7MshYY796C5vc2FYR0wpoBRD9KNZ2mNldT9fgDzCuouYlPieq1jMPeyVgVdiJNb+Ba8zm6WrwG8jMb4DP5pNdtLd/JN7WwboN0P1gJNnWzoo4J7XJw5CaB52EOdat35BDxyGoE9hfXtvGH8B6ytH52zTaGYkyPPaaArrVnmBGDuMVug3esRpjLxNi1MtdZI67/5dwCnw6nOiSwdiAfDxOtQcIHBejCnXs0acSjGEkTsCnCbS1+VOwaZ2KTaKGzT6v0hwaw2WfN9gc+5jRAQaG0SG1z+OOCnWiVJjpNREDCjmFn4qKCbD7YC5NhT04FfamcdhV/zjsiq/Wx2Ja2A2yp5tMC3FNyk4EVX9kFx7etWsqz6iUa04dh9RL4z/xLLZgTNBH+NRgb2uA3TuW3Y+1V9EqtiVvJfXnMdQwY8/3mRZ++mRpjDd3EhGXdVDipsEGabyjva8/uYN4+tp37EhOMy0w3nHyjrVrd5yMLbEmz4c4rWedPAodU0ehs2GOR1tTE+ZDLNn2t87xOI3hxD9uht9TxChB5WNnOPq5OeMEXFhVU4pbNgWbtqnYtNewecGrBJvDLbHEGD4veP3BpnCkNfnxGMWxllX9BHyK5+HEPg4yIzTXewwZ1Icn4BOiuWqd3O5xfMKZUqwdtKoWyn7UXEBuTFImTGWnk2ZhLBbI1hiQlQHuC6jNJlr3FcTniCE/xsb6uWPCVXtVa3fRBKwMRvnHBSJXamqhXk/NizUZ05NHhbGuxeOARFEascCQ0LQkOrd47j/ROVmZIv8qdKxxgaRCkoaKJveVCWEdBfPLhagHNEBDkzU6hCc9shExHvPOUVPKC/xrcXgE+iA/TZafNztFt9pEmSEYwooKu4vz1h6XpvRrPvc+o00mx2+fky9Eqe0QPZ7jLjSu5B3/yY10QWC+G1HcW8M1AjrBnjq20QxoBpik2JRpEECJSQhH4Hy2HKHlOJEwWJjs0fZaIIuVJ2oWn1kqjzthI16aPkcdldiEy4cPjd1ndrpFSpBYtEaQcO0Zyaq/Ba1OpYEojRlzY0QBnqAKET6TB1fH45AmgPMbdaLi8UnzZTRY2D+sxf3g2EPiS+IJXBDmyuU0m41qSZoDM1JMrIo71mBm4QRgFbESc/5gIaOIz1Hx+fEx0aWWZlBVPVHYsuLTClwRjIPgQ0z3cdYQxdshl10+5pIRqGAGycZqjGISzbxQvKqDEBapdly+8g0ycuPWJ5/cmu7qev7SL73Gzz2FzKIWN3l/1RXIB09fu/UZx8arf/lgwObYpN9fe9bjOG7o7w+z6EMY88tYY+IwwCwHDcxhRQExE0zBmggGS5IAKEzkq+S+M6+ZCAZzXlA4vqpfEnyoeM1UQHDNILW83EvAvuCAwSVQdKMkR7ApKMmhYUbOBLNM/+BJ/A9fws/K7u7u3dR7sFzfV69nvQZ+pyDuhjWH83h9KgCJSSky/KBca+JEcUjVMPApmPN2TX9GvHDJzC68S7pvyYXm7MB1G4L3nXnVo7zDvORC/kB+veLyLbkwrP+ku5tkwxcu8bdEzh869WbjhssfvUp0CfyF3P8DkKeJqAB42mNgZGBgYGRw1FsVMSWe3+YrgzzLBqAIw7lYoVoY/d/q/xzWu6wSQC4HAxNIFABKQAvLeNpjYGRgYJX43wImrf5dZr3LABRBAfMBiTsGS3jaY9zBoMGygYEBCafA2Ew9DAysEgiacRMQuzEwMNyE4sVAPguQ9oDQIDmo/hMsG/5/gpjz/zPjF7jZfEAsDlHzfwcEo9gNw7JAnAVVK47QwyAFpRmhNAvQjDlQPYwQPpjNgqYPxV9YMEgvE8LtcHFTJP9sBdKK2PX/nw01AyY2BcovxaIeZn4HlH0C1U5GHaidO4FsASDNjAPD/MmC5G8QPgPEGUh8JWg4wPj5QPcehuL5WMIFFDePgLQbkLYC0kKIMGLUQ/OzFxCLIunlgIonQv3PChVnRcIMLEcg9jCAwf8bDP4MlgwngOlHHSjGhAIR4AaYZEESEWdABSlgEwUgrP9zUCFI5/9P/z8B5SoBYR2ue3jaY2Bg0ILCNIYl+CCjAaMHYw3jIsZjjOcY/zGZMc1gOsP0jlmH2Yf5C0sRawobH5sSmwvbI3Yf9g3sLzimcBpwJnBO4eLicuHq4HrHHcY9ifsFjwPPJl453greNXw2fEl8PXz3+G8J+Al0CVwT5BNUE5wiJCKUIHRDWES4R4RLJEFkh6iK6ASxBLEb4l7iLeLPJMwkGiT2SGpJTpP8JeUhVSW1ReqK1CNpIWk9aR/pFukt0vekP8nwyETILJJ5I2sgu0+OR65D7pW8i/w8+X3yDxRYFDQUXBRyFPoUPihmKB5SclA6plyjvEZFSGWCyhNVIdU21VmqG1TfqEWotantUXumzqOeoX5Kw0AjRmODpp7mGa00rSfacdortN/pWOj06G7TvacXp9el90nfyEDAYJ2hkmGF4RkjJqM1xlHGXSYiJnNM/pkmmO4wEzALM1tnzmIeZb7M/I2Fg8USSw5LD8s2yyNWHFY+ViVWR6ylrJOsz9jo2YTZnLI1sp1m+8/OzG6V3R17OfsO+w8Ofg6LHAUcyxzvORU4PXMuc37iouXi59IDAEV6iBwAAAEAAADbAJsAEQAAAAAAAgABAAIAFgAAAQABAQAAAAB42q2SzU7CQBSFTwsaiUaNJKy7cOHGhn9BVsaF+E8kii4FoVQKbSxSSXwKn8GNGxcufQJ9D5/ChfHMMCJBFsbYZu58c+feM3duC2ABz9AgniiWaEPQwhHOl1wNWMMKbhXrmMe94hD28KQ4jBw+FE/hRssqnkZWe1Q8g5j2pjhCflc8i2V9UfEcOa04Sj5V/IKY/lXDK+L6XRAEpuX0vaZdczu+WXPb2IQLD31cwYaFJrow8MCRRBwJpEhV7hrYwTk6nHcZ3yOL+BZMejbg8DVGFHy5qnOuc+7RXjByizc/QwlFbPPUQxygzLgitRw0OGzqW8w5YryFa3rEKQlmxmUtBRzz9ArzChO1fiqtjmn9tgJjLO9E3sPnvit7MFpTSWoMVt/eJiO7qMn43jDDxBptAW2qtqgpYhr0ipOr7LiJjBw59j2J/B9vOflLTfYG8jWZ7fAre6zbVlX79Apq/1tMhVVWWbnwdoc92Vc9LXPXk96stBmsc6RpU+za8H/8BJBMiJoAeNpt1VXXlGUARuHZgGCB3d2tc7/z1tgo89nd3QKKgCgqdnd3d3dhd3fHgT/Cn6CfzObMObnXzHrnep6DPWs6YzoLXv/M7xSd/3v91ekwhrGdsZ2JnUmMYxHGM4FFWYzFWYIlmcgklmJplmHZzt8sx/KswIqsxMqswqqsxuqswZqsxdqsw7qsx/pswIZsxMZswqZsxuZswZZsRZdQ0KOkoqahpc/WbMO2bMf27MCOTGYndmYKA0bYhV3Zjd3Zgz3Zi73Zh33Zj/05gAM5iIM5hEM5jMM5giM5iqM5hmM5juM5gRM5iZOZyjSmcwqnMoPTmMksZnM6cziDM5nLWZzNOczjXM7jfC7gQi7iYi7hUi7jcq7gSq7iaq7hWq7jem7gRm7iZm7hVm7jdu7gTu7ibu7hXu7jfh7gQR7iYR7hUR7jcZ7gSZ7iaZ7hWZ7jeV7gRV7iZV7hVV7jdebzBm/yFm/zDu/yHu/zAR/yER/zCZ/yGZ/zBV/yFV/zDd/yHd/zAz/yEz/zC7/yG7/zB3+Onzpj3uxpmTB35vRutztluJO7/20x+oEbt3B7bulWbu02buv23cnDLUaGW42MG8ydM2vBm9pDGh9uugseGniJgZcYeImBlxh4+MDDBx4+8PCBhw+60YlOdKKT0tWLXvSiF71Cr9Ar9Aq9Qq/QK/QKvUKv0Ovp9fR6ej29nl5Pr6fX0+vp9fRKvVKv1Cv1Sr1Sr9Qr9Uq9Uq/Sq/QqvUqv0qv0Kr1Kr9Kr9Gq9WqfWqXVqnVqn1ql1ap1Gp/FejV6j1+g1eo1eo9foNXqtXqvX6rV6rV6r1+q1eq1eq9fX6+v19fp6fb2+Xl+vP/Ri97H72H2GP77RrdzaXfi91h3eI/Yf+4/9x/5j/7H/2H/sP/Yf+4/9x/5j/7H/2H/sP/Yf+4/9x/5j/7H/2H/sP/Yf+4/9x/5j/7H/2H/sP/Yf+4/9x/5j/7H72H3sPnYfu4/dx+5j97H72H3sPnYfu0+tZ/+x/9h/7D/2H/uP/cf+Y/+x/9h/7D/2H/uP/cf+Y/+x/9h/7D/2H/uP/cf+Y/+x/9h/7D/2H/uP/cf+Y/+x/yzsvq/THzqj/x7/AibTMyUAALgB/4WwAY0AS7AIUFixAQGOWbFGBitYIbAQWUuwFFJYIbCAWR2wBitcWFmwFCsAAAABUjdh/QAA) format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}.glyphicon:empty{width:1em;} .glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4559433 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/bootstrap.min.js0000644000000000000000000010772014625637243027042 0ustar00runnerstaff/*! * Bootstrap v3.3.5 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under the MIT license */ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'

'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.171099 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/fonts/glyphicons-halflings-regular.eot0000644000000000000000000004750214625637207032717 0ustar00runnerstaffBOMLPX.(GLYPHICONS HalflingsRegularxVersion 1.001;PS 001.001;hotconv 1.0.70;makeotf.lib2.5.583298GLYPHICONS Halflings RegularBSGPv5O5U-R`WhKqJx"U:r,/4\ liʚELFMƀV(gW6V`m_fZ}~Hi%[Dd"wz, ߘbAi*+2 8,媳BIPfI͡Iއ+ͱw3-鵫bb ˋ\.f0g-}P1'=n}@@ر rU +(,Ugc1wL9n`Gv!(\SJTs3d&ruN]}Lq45Weo@7@`m`ʆ6P p\qf3h<@AU&Q*]X%i,g!RBa/22!y3tM E zE2Ѡ˜p¨E`2);BhP*Ю}.]jE+I*(L=sVsXN:eOo[P6R6t/lgx(y{aD"Z 1(dWNrG|MEXqە:Ä"59Q)3eB`\YG>X)I '_\jЋX+ozTy7*au(B @ha@8H{/.ُ ʾ0fe3x1Q'pk^,[QӀalf@.]JYo4 _]ă98B xb95"uH0S? q+ T'(a;:<mHLdeM̤ўo2SQF2c(:Bl:(=bYDoV9hd, яijmTeX2W^qj>!*acz8Y"'r=φS*!\!v4IQaʇmiR3N%Jx">722M~ʽ2fG%!)qA 8( bv^*[p\ 6t wCsҐ, lf CӹiScD'3M%fa K(q*MB$H\gp˛2ԂXAX8p(өjĩoBfC #L%cftnpe{\듇7 ,XıP%"7X^P5,M vɓuU:AI1\r8iExX;dS4fIüIORH4 (FFrxb7UЈ@)y~c8  8=o-+n3D2 5Lf!7Yd>Ny }6+9Tk)$EԍJdZٟbYQt90l?,G )yaGA;;EtG5v!rϨ&HAtHQI6_[՛ąO͂Dk3QX,)+lUb'v/4/h8PnAH) Oc[ ;$0f󨡭YnK0s~kR_gAc 1xG )`BY|\P80f
i?6!<Vrv2yĭ(c Ծhp--0RUBoFI)OŦij2jD!Y|` j," ec)1d:n*F]|r=q l&#nv[gLiZ,IPv*]/ &_A.P@m5*WfS]*`g5˺r3̝݁]Bo hr/ODXk!K 9e%#{7Ap Fpt;3̔=$)@Paw&ql=աrJʆB]n u&ǸJA{)mPFl/0,&wpӄJܵcHKm ^rdpJa a&[zA†'~(/'[hvoX`e@0&fkpddhF eT]%Q*%RBYXz'R2s\8f=hszGqntU"=f]B`|xZŴ,('{$$LYSŔom" P:P#/JDÊd-,:N"Aۜ{m"ej J݂%C(v3Mx:yAI35/!o_ȕ~gŅu{}Y&IrwH٥ Ѳڞ"@ڳv4aF, !WEe$w2hD$!…BK)V" zuзL^{<7+7EF! Uv!!4=־.}$bボ&c8,<ܣ @Ù7t}Җ!G8sa} d^IGt&(")\<c8%vv fPn./ !×d@ Fh0kYt#_KgS:0s(__34 X* |B4v}aD*WwwK)p6zB 5|R)SPڭԃ&>;$\0$d2'ЍZ ]d};et_d^$kz, +ɭȄc8Ѕ0!ODPd-l8 @M%хx\)WYl(|V lNNoB@S:~eɎ B.abېdmuYH'#'vc=lN$BU>cjM)RRP ,!?*go$3@d6<2?ѭ/ϪX%,NPJo< smt(3 X@Y3/3d8]Iډ79Y`L$ZVԃB:kb[5@PZ!e"-6F.$[+}YAB`2|e5z52,"b[/J.+WՠQ(4F 132њTc0ńEM: GnBۤe65Y-`0ρ$N HXPZajL` ^DXJ !d HX9E}\ư/4 " {w 1)PBV"?={jQTB""֍\k Iqyp$A;$~L\ʔwdU@ym};uf"A )>'Ё+!œd-i1!ghg\g"[ ̳]b1B#AĆ$]vxh\mȴϑ"i(0/ś4\P3;r673<F=G2S͕|++@~Jx"9Hkxcs1ܘ"Cy2oK`8fA-DGcOa\EX ;ԁl2?Ȁ:}Ij,,1ɑE2 USW)C0ළ( v>0Ǻnp[LP3@4]{T~A?񁁀X4gY) 3<2^.+[Ja LcE;DUI`$H#`2r-@*EEŰOc U/㪽%]ϤBVeݖF(n!gN/<9B< uT Ո>W/d(ᨦ:9RN+h| $#g@q!(=~5$?xԚ[!em18% ,E!l[/)^ʥY qN)槪ߎO~Np?ai =0($S!wf`-l.j98Lwi;"͑\\+?_lQ"ZݭNqU. YTX3LH'N'c7ሡPq8s_NCR.1! sX$M,|8<@ >}ENtlX{t Fʊ1!7j4E"^ˍ p.̖ ꘩3@h[0zdT"qmh &ΠKlJLO7l Q!%t eV=C@R$M%G*1@^PQRZL-,1# eAmE4r͘}cJ$QS*RSx! ͞aX7;@"oYka1O+~4JQ~ה\Vp&B! w='l=Ď.D-͇$KlYD U4M5 gDGh<<'<_`r <`PgmXP`ѧw ^`#z-\#>J- B/W3]@Lo u /^ra@-TAYZ*,Hf1ZDFZL!<<R :.JU-J-dn8%3j x0¸T䡋hA 6񖐈"jI{u#yVY,ҺCdY|N:B(XNP|E3wQi6Ҹ a3N*nt^s k+Hh v20d &j B8NLŴ^8*'h]:s旇Ǫ$5q_.k~aDEs}#/iǤn&"587di2 TqYPLF=4Y"?F[Y^9 ZNJ7gHiji!ɕ-Z'2pPp,`:TO M6T_&tΒ *o7;Gm*g?4d tPIF&(wWv[(O$K@F-{ dCnA%$[A7,LdG:2g4̵3̕x T^ZFKp K+XϸkT@Dv12=G4haYpJJsC'fHcوM-PH)ot/5o!@=8pc 7cBTh|q$ _qP1Fq&2OV4h: bKn Kk9:]`=hCr@ys8r-dzde\J授| S: %&Ҕ`"όbȯy% Z"xō6)U` dK,Pi1%Y8)djCi#Y rdDY|)ʡP[߻Pqj;,EVcL!4o>ZFέWy~#hO1h|m>6& g&Ki_q$mrǫ9gVFi5).`)s&˴ m%!0<:I씜KJfMTMjN_CLG!cM*51n~0qw!sdλ?;Lje^ԇ-04GBTN^*L)x]#t:BKk 4BW>$R߸S2E*Ƽ>:\|PU X{;| fk ddQ$ʲ>tfΑ6,N\tDnEƤ,nf E&iqiy4ɡJ? 'ͧF#/hG C'8JfnfaS#Ӏo0QDAg/ťy.d Cp&Qx'މQ?YVGW!t&H cTZuh7gC`^(_ ǎ،Gu lPV@@zJPe/"We8J-s H7a[:|Rǁp ac U'?81>y .OvJ&mpZxmQR`xGL΄xF ~Ư٤ng4qV[4\lmǜ#Skg@Nr⎶NQSh8ێKg)^F^AԱUKxTv#I>lc߻f8ExҖ+-s! Bsec.SƏ8/V*1o)vp--Ӿ]JQ 947ŎKƾEz= l=k}j&9S9APIWYjnaL= D -c1c@a] Qg`}Iq(AL'4LJL%>;Uwn&Ґ9J[θiCjE7Ok.ZQkE/]ׯ%\2])Didx}6<= V?yMFp8X*>C;UV!Uo|%Px2Ű$`UlBjީ \xq 촙( Fl Ik݊!&jhS> K?!δH X{/uv8D&}@'^A8϶`Zs9-:muRD+FhZZR kGנI}x6GK:^{C0bP"#4DyZ!^9jYN%aSw;T)k$ hqHO>/҅FP+:` K^uJ>xx)GSO݃K,xU9QFSx%JO<8Nj7f^Қ͊_S qqBGS'ALط 1#p*D߻<`FoÁUMg5 WpE ėTxyiYm,%hTM6Q U 5& .KdQp&=/34vn;r*CD \Yl q4 p'z܈G}[c,^{ڌA_5xZ0y$mnPX7Fj/M mqP![$f6Zq[]ϗY1>ؠj˕>Z4_aƼ`[EyO{-m =J;anBF$ˀtXnta>D.5MqC q[%v*Ȋ#G`cq,sl|z[|אBrӦrϠF_c[$ BCJ -ΝH jG)RDYDŽCmP%~_zB["?vh`:AQx

e*:7G9܍M:{gzySspL92X_ۍ )>a^y"2ŻK^Uo}SKޥ*tvL~#:b-hvN y?D)'J8}$5jFbay)qگ GqTclHo_ T=nn:J[ :` #5aĩp I-Iw#^im|@Z DD+ 3mG@qo³N#+2s 8XA%aǃ8YbnZx{/M=D&BtL#iYN, `~u#UtD?؄vg0EG3dHp,,Tpm׀&3Ư9InVRiYiaxɧ;)b>7tVN0y#)6[kIVrT93>0Lurp"Mx>mceT㓸X{AdAZ?'Rl% L2-4CM8,6cP>BǶ$_7oFN2],:(^ O@^圾 B4zJ3Qv 0/^+9aG\D G0<s28u e@eHI=AIf4<ӢGMJ.=-xQ`5ĻȄb{lg?h[*>2i2D٠cKpi ̀iF=/>+7>]=x -^ yM+ɐ[ؘ :؞f3&I Xs8hK<{Z}nlyMCCܴ:ܚJ{b &KNlº& _dwOH?u'qRNkv_ D\wѾmβ =bSF4?,N{Ti3IĖm]|-;멟IqOX~4N+)G(Ӊ2"tAM P 財lR!h-Z1V;EP8;`88s׵4Qr!cBՆY*+2Y<[/LZ\ ~6m4q$dұ&N}F; e)8ڰG8.۝\[~e:j#][`<$$e'#e C(.$O6 ¹p\F,.L1KŠ(vIm*|@YI 6̜p@mCp:Q%ȯ衧rHhvQP"ي`{\vRU 2 R0#ѓ$p _4IhHt(w9z;!L{yYǚ`t=(hl-\[ )eC슉E24bxxKFI̓ R>(DN.Qmǔ [K1(r\EMZ3xㆤh!4mI]V}b^jƤZH%:4NȤ_󓜩bDžquS,RZ G#d }>R)(_iPyJg1/E-LI01/ltPʑJ5tT)MU*f,=MɀCmCd ;&Gg^\Db=u1xpF;38(A}(`8`' VmmBN`]["nL`1npK ctEz9E*ȴw 띞A2j-b5RLV#e m1A[g9EM8 ͘Ac6F9=fSaԓ@64LeMj] xN^qzhQ#l/p-H؜m d-%6E F#SK.t͹q :%=ŐFtjl:[K2rF oZikEݼρƊP?"#k $m . W FszQ$9 hcS` .}IV)59>ƜS~"CR]-!&E}7 *ࠓAoKE G֭d&ڒ}e48<0?xi!&/nhi/pG@]q[ФJ-BudggȯTy-^%?v2t1BAȰke*M|CnGTk5{Al4@"JHXJ1yRv6) ̾byƴ5. IkUh;!m09jgrMWaz&P+_WE@(xٱ`AH*jn Lb0i[Pj DzZR" 'Lw~I H3P46BKB TbtJ,`ș>9W94VNVl1JC3ҤXh+TRfIlvZ%̎)- /á;rÝz󵞖-A*iL9VHWxSHXe%&, ltS)XTM̀)l% h]ZPWqcExrhuP4rã#ZI)\my !߯/'yɬiLH1D)xWW^Qͭg6%sNszm,YEe2͗V @ʔ, Ij=wOb46r !"o2~}d#)?!/ 5W K#~8M>elK\C߫W LƝv:R Wq]?$9>WzH^b7bY8k.H"þz_̱<īK01`_Вm˴6.vI2!-43R_ G3ʛa墳eo.! J1Z MTK9#QO [ |Jd H`Q}F6]ޱ!v&m4K1 7О'D+L~ @rIcEpjHFeBbr-8$pmbETZuiZypX8(F%V΍&0W`њH}I{_O\}`)P !"ϴtm' Jy7xFʑEԈc!xy^B405DgF/]O6zqLl~G `ٟ(oWƀLj'â]N'>aEKqB ʈڣ_1)?H#|~E5Z$%/n+>W0) |J (+$Z8=fbG\v{"`{څB}d 嵻cj6 ɘ(Q`:JܖzцQ33⡙/,tmM@! "`S~ʈW%蕥o\aҾk{ӟB')ֲ8zgI290GYNR҅uiKnb 螅4 # 50 A̲kee #ے_ad #fP%~p*'ҞUq;n.2T~;P7 PEx4o'|9̀^>! \,zlt >ʼn[\Z= L *4U"3duM}=U&{ t|hٯkJpjm F~3=v]( cҵȇ|QQh+J8|#&@vNҾBm4Gy^$+ӔNg VpU dП9N虲(40ٓY 9ͭO JqC'HiCl'R r«!"BI˲A!YؽǕrmR#Er{#M@^ \&]2dG@\@ Sn|XSKapʷ&yqH[PJt!zUbwa_mvЦ .V8y ѳ-$u"1YaL8Y XhMbdYcI-31jh Av qMɧ.m M ,8(Ą[gi@%Ѱ7̓!(2uШFV;vdz_"[Br%Eȸ`'lIi)>YKzz?7zӐہњ)'<{a[,á_au7IU#/JyEk-Xiѹ7Qf"du!fF1N4l9 2mD8hu*8;\ZYgc}\L"vYX^|"cՉh-T!۲2:)7"? 9r ugL}"3H@B(%0(%a.m;6+D#1>C炏3lVB yHwgLnFc0&a9zf'n-ʊ hF rDCDH2CW18^7æ`vGM};E.aѬEu'xF'{ʐTG?1Ͽ sGzD:"9R6šo^^Z53#"'.'ddqd%Kup<3LJ9D?{dd 09C3JL3akw$B d/5dZgj7X0,Z>d.6dJtB+0W5ju.xL//+01!!|,,A/Ͱ /+  99013!2654&#".#"qOxx.,,nBUPrzxawי kdL 57% P,XX,dpX[ ,%'7'7764/&" MZfVc $ pQfV\ ' 1 3+Ͱ2 /ְͲ +@ + +@ + +01!!!5! ,,dd&L &7>5%&7>54&&$OAXX@JOWOFS  @JOn)`*^r67)Q7q  OY+/Ͱ//ְͰ+ͱ+$99 99$901 "'#" 6& N,mwȃȎwm,NldXD/ְͰͱ+014>>.d8Zwwy,0{xuX6Cy>>yC@vS-IDEH-Sv@9yUUyG !3! 7Hߒ p??G  /3Ͱ2/+01!3! 77'7#'HߒCIJMN p??t⌍155"&=462#%??%d3||3d L #'+/3+ͱ 22/"3Ͱ$2 /&3 Ͱ(2/*3Ͱ,2/.3Ͱ02/2334/ְͳ $2+ $2Ͱ2+2 ͳ$(,0$2 !+%)-1$2ͱ5+ 9999011!%35#535#535#535#535#!!5!!35#535#535#535#535#ddddddddddXXddddddddddLdddddddddd|d|dddddddddLL/?B +,3Ͱ$2/<3Ͱ42@/ְ2 Ͱ2  +02)Ͱ82A+015463!2#!"&463!2#!"&463!2#!"&463!2#!"&ppXpp2pmppmp LL/?O_ov +'+/Ͱ/#3Ͱ!2 +@& + +@ +/(/ְͰ&+2%Ͱ 2%& +@%# +&% +@& +%+ͱ)+&999%9$999$999901 "'#" 6& 53533##5N,mwȃFdddȎwm,NlYdddd]+/Ͱ/ /ְͰ+ͱ!+$99 99$901 "'#" 6& !5!N,mxȃFpȍym+MlY+E/ ,/ְͲ +@ + +Ͳ  +@  +-+ #$90147 654&'5".;2654&+"ҧg|b|g[՛[ddX(>7xx7>طv՛[[ d 0+ 33/ְͰ+ Ͱ  +ͱ+0173#33333d,dd,  PGQb/PͰK/6R/ְHͰHM+$ͱS+H =99M39$9$/99P99K!'E$96+A9901732?6?67'76?654/&/7&''&/&#"'462"&P-<-1&("/&./80PP,<-0&("/&2,;.P g~~~~Y!)&1,;.Q  Q,=,1&("-&3*:/QQ/:/.&0X~~XY~~d#'+/37!+$Ͳ(04222'/*26333Ͱ/ͱ,22// 8/ְ$Ͱ$%+2(Ͱ,2%( +@% +()+0Ͱ01+-24Ͱ 241 +@4 +45+ͱ9+015463!5463!2!2#!"&!#!"&73#3#!5!3#3#d ;),);  d;)D);ddddd,dddd2 d);;)d 2 n )<<)D,dD , +3 / ְͰ+ͱ +901 #!!!Y|pXd" +/ְͲ +@ ++017463!!#!"&d  X,~  ] ,  /Ͱ/Ͳ +@ +//ְ Ͱ +Ͳ +@ ++ͱ+  $9 $9 $9 $901$  $ 6& 33DVGdD_Vd .+3 / Ͱ/Ͳ +@ +2/+01#333!#3#d)(1,Pp,L J + Ͱ/ Ͱ2/ְͲ +@ + + ͱ+ 99  99011!3!3!%35#,ᯯ, pdc +Ͱ//ְͰ+Ͱ+ ͱ + $99 $9 $9014>2". 6& 333_ޠ__ޠ\TPȖޠ__ޠ__Td, a /Ͱ//ְ Ͱ +Ͱ+ͱ+  $99 $9$901$  $ 6& ##DVOD_Vb,, ) + ͱ22//+ 99015!3#!"&3!73!  2,2aD%  F /Ͱ//ְ Ͱ +ͱ+  $9$901$  $ 654& DV:)DS/ Ͱ//ְͰ + ͱ+ $9 99  $99012>5# &632!&#"[՛[nv՛՛[[vbQz[!z+/Ͳ +@ + /Ͳ  +@ +"/ְͰ+ͱ#+99 !$9 99!9  999014>327!7&#"!32653#"'[vƝppIp[vƝXv՛[zpPPv՛[z d #'P/3 Ͱ2 /3 Ͱ2/ 3Ͱ!2/$3Ͱ%2(/ֲ 222 Ͳ222)+013!!!%53'53'53'53!5!=!%5!%5!dLddddddddd   |dddddddddddddddddL#J+ / $/ְͲ +@ ++Ͳ +@ +%+ $901546;5463!232#!"&!54&+";)dvR,Rvd);;)|);,dX);RvvR;));;dLL+/ְͱ+0133>>7.ddd3&Ͱ62 /B/ְͰ"++Ͱ+2+;Ͱ;+ͱC+2+ $9&/$9 9901;2654> ;2654."46;2+"&%46;2+"& 2  2 cޣc   X     ,rr  ,tޣcct 4  4 X!!7'77',,GGG GGGp/ְ ͱ+01!!%7'654,,EojCV 956nb<//ְ Ͱ +ͱ+ $9 $901!%%7'65477654/,,EojCV^{wQ57nB !/3?CGKO+0D33Ͳ)1E222/'+L333Ͳ%-M222"/33#Ͱ2/H33!ͱ4I22P/ֱ22ͱ220+ ,223Ͱ523. +*2%Ͱ@2.% +@." + 222%7+DH22;ͱ&J22;L+B2OͲ9=F222Q+04?$97%()8999"89$9#:;999@ 67<=@C$9011!#5##535!535#!!!5335#5!3##5#5355333!5#53!!5!5353dddd d,,dddd,,ddddddd,,,ddddddddd,,,ddd ddddd dddp,ddddDdd  #p +333 ͱ22 +$/ְ Ͱ + 2ͰͰ +Ͱ +Ͱ +#ͱ%+ 99990153#5!'353'3535353'3ddd,ddddddPdd[[[[[[)+//ְ ͱ+ 99901463! 2764'&"  SS D TT1+3/Ͱ2/ְ ͱ+ $901463! 2764'&"%3 '  TT d 2 D TTD 2d ?+/ /ְ Ͱ +ͱ + 9999990137!!!dddddL 3 4&#!"E~ 'Y%+Ͱ /Ͳ  +@ +2 +@ +2(/ְ Ͱ2 +2ͱ)+  '"$90153!73#5!!7.#!"7>3!2#!"&dXd5(P>^ > B&  & dD||Z   dL%-1o/%Ͱ)/-Ͱ!/2/ְͲ +@/ +'++ͱ3+9+'!$% $9-)"#$9!.199 /0$90153!2654&+.+"#"462"264&"%53;));;)37S*)R:. );dȐ>X>>XXd);;)X);E5+);;;)pȐȐ X>>X>^dd5"+ 3Ͳ 222#/$+013!5".?!#!5&'./#5m)>$\R+5"(]q *k.tB6,-WBB*. 0 Ɍd )1e +!Ͳ +Ͱ)/*Ͱ1/ Ͱ  2/ְ!Ͱ*2!.+Ͱ% ͱ3+%.9)!9*9190135>54.'5!2#'32654&+532654&#d); $x!" E4+vOȡY}^LlY3(; F7]7( 3AvFTMaTZd{MRao +Ͱ2 /3 /+0135>76&'.'5!Ms (G !:" 0G9C/Q8$99#'% 4<9 %~+/333 Ͳ +@ + 2&/ְͰ +%Ͱ%+Ͳ +@ + +@ ++ͱ'+ 99 9 901'3#7#33!3#4.+!57#"KKK}}KK}2.!"dpd"!/ c,' 2dd2R '! %+Ͱ/3 Ͳ +@ +2&/ ְ%Ͱ%+Ͳ +@ + +@ ++ͱ'+% $9$99999901?!55!3!3#4.+!57#"! d2/!"dpd"!.3}KK}}KK,' v2dd2 'L/?53!26=4&#!"53!26=4&#!"53!26=4&#!"53!26=4&#!"L X2ddddL/?53!26=4&#!"3!26=4&#!"3!26=4&#!"3!26=4&#!"LLDD2ddpddL/?& +Ͱ-/$Ͱ/Ͱ=/4@/A+01=463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&Ld X2ddlddddlddL/?& +Ͱ/Ͱ-/$Ͱ=/4@/A+01=463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&LLLL2dd@dd@dd@ddL/?O_oR +L3ͰD2/\3ͰT2-/l3$Ͱd2=/|34Ͱt2/ֲ 0222 Ͳ(8222+01=46;2+"&546;2+"&546;2+"&546;2+"&5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&dddddddd,    2dd@dd@dd@dddd@dd@dd@ddL *:J /&3Ͱ.2K/L+90153553#3!26=4&#!"53!26=4&#!"53!26=4&#!"5;26=4&+"eɦddX, dddK}}K LddddL/?CJ@+K/@ְCͱL+0173!26=4&#!"53!26=4&#!"53!26=4&#!"5;26=4&+"3535#5X, dd d!2ddddL&}KdK- /Ͱ/ְ ͱ+ 9 9901463!2#!"& ,,,,,,,v,,d,LY +/Ͱ/ /ְͰ+Ͱ+ ͱ!+999 9999015463!2#!"&?'!462"Xd*J%lNpNNp, >pNNpN= +//ְͰ+ͱ + 99 999014>32.'&73264&"yz{yII99 "c]s+?—jk֖|ׁ~rBB "koKk֖I +Ͱ//ְͰ+ ͱ+ 99  99 $9014>2".3"_ޠ__ޠMޠ__ޠ__ Vu%4>7.77.'&6?uDmssIOWM?%N~OrÀ~[[.  \7^`GvwsuEYd;^RlbJ(I43nh!&W+Ͱ/'/ְ Ͱ +ͱ(+  $9"99!$9 "#%$901463!"3!26=7#!"&%7' 7/n);;));ԥrkqq\,;) );;)}j2qkqqUL.H+Ͱ"/'Ͱ /Ͱ//ְ ͱ0+"$999 %9&901463!#"3!2657#!"&> "U);;));ԥgg_hHCVC9,P X;) );;)5!&4 D>3CmL#R+Ͱ /$/ְ Ͱ +ͱ%+ "$9!9 "#$9 !9901463!2!"3!26=7#!"& '',:323>54.#"35#DȐ '-"#1D1iD젠  =& )2X23L(pd ; / Ͱ/3Ͱ/Ͱ//+999901$  $7!5#!3#35#DddddD젠d,dd1i+/!Ͱ2/#333Ͳ%/2222/ֲ+222Ͳ )2223+$%01$99!9 *+9990153>7533##5.'35367#53.'#53*EkI6vkYȌ`oKȕ4fIKn8dtap;Dsd7>;pac//+901!!XX#c//+901! XX,,;@-J+/ְͱ+901 !!XXXh+/ְͱ+901!!!h(,*?XXL 5>7 FX_Ȅխg;@-$Du +/+011!&ځ&p&ځ &"# 7'!' "''ف'p5'ق#O / Ͱ#/Ͱ/$/ְͰ+ ͱ%+ !#$9# 9999014>2".;2676&+"35#[՛[[՛V:#6#:0՛[[՛[[F.d&*04;3'+13*Ͱ227>7.#676%>7>'&" 8./ieh,Jhqx{\Sc'C78Fak[)!#==Y57>'>7>76''&'.7.7o FFB:8( OV $9DkC@&'GOS3 *gJ.  &:4?B8- %>=B'Pd!I,  =CnCSm,U!ٕfmS ;4( .MV .n}3!?GC/)Ͱ:/ H/<ְ7ͱI+7<@ )(5>@C$9 :$.5>BG$9017>2".'72>7.'"&5477./=FOsvvsOFFOsvvsOFC-[TzwRY,H 7:91.f1ii%LX( (WT`G//G`TW( (( (WT`G//G`TW( ( `=^8+(3\;hI%E:JY||UIWs|Ci`$$ )A+3B/C+6=+ .    + + + +$ +% + #999$9%9 9 $%........@ $%..........@017>3273#7.'77.547?./7>7&'7=FOsvH=<%Ɣ%Rri' ҷ%k.f1i/:(&-/"0/a+'C. %ZeX( (WT`G/Pegy8(6nUIWs|C/WR&2&?@06@(( 4kbf &3!26'.7 !5#5#o%%~8~ddDDG  ! d-dd,dd)H/ */%ְ2Ͱ 2% +@ +% +@%# +++%99 %99015467462'%/#&=47&dkX|Xkd^^d)1ES>XX>1) [@ NN @[ L #'+/37;?CGKOSW53!265!5!54&+5#!5##"53'53'5353'53'5353'53'5353'53'5353'53'53Ld ddddddddddddddddddddddddddddddd2dddddJddddddpddddddpddddddpddddddpddddddx A/3Ͱ2 /3Ͱ2/+99  $99901=!35 5# !7'!735 5#X,ԟzz,XXz{L+/ 3/+01463!2#!#"&;));;)d);X);;));,;dL%)-`+ Ͳ  +@  +2&/*3'Ͱ+2./ְ&2Ͱ(2+*2Ͱ,2/+$9999015!32>'4=!".!!!d,U'5%;) ,'MeeM',,Xq \ #(,.*R~jqP33Pqj~RV,,h 7`aaCF ' FDBCa:dv(//ְͱ+9901 #!!!# #+,}++pX,pX2F"+3,Ͱ,&ͱ22//Ͱ/ 3/$ְͰ+ͱ4+-901&763!7>;2++"&=!"&=#"&5463!7!"&'&^6**20 -*? 2222*L +Ͱ/Ͱ 2 /+011!53463!2!P;),); d);;)dL(+Ͱ/ Ͱ2 /+9013! 3463!2!!,P;),);DX);;). ! + /ְͱ + 99013# #3.**,X,/ / / +9901!5 5!,X,X*!I +Ͱ2/ 3Ͱ/"/ְͰ+ Ͳ +@ +#+ 901=463!2#!"&>3!235#35#;));;));$%dddddd);;)d);;U'-$ddddL %3&4/ְͰ&+.ͱ5+& 9901546?.5454>;%%##"+"&'4632#"&e2" ]&/ S8X22 !U  QRJf'/5++/Ͱ%/3Ͱ2% +@%" +0/1+%/(-990146;7>7'&6;232"&/.267"Jv?zS^Sz?vR:: 8F8 0l^GM~ %M( .))1==1777'7'7'7'''N--N괴N--N-N鳳N-,N鴴N,d".//(ְͱ0+(90153#;;276=4&#!6=4&+"?3!#',d={.%='='20`dd22ֈXKd9X+d,Qv,Q(%wկ}dL".p+%Ͱ/3(Ͱ./Ͱ2,/ //ְͰ+#Ͱ#&+Ͱ)+ͱ0+&#(,9999)+9.*901374;6;2#!+"&/&735'!5##dd={.%='='20`dd22ֈdX}Kd9+d,Qv,Q(%կ}wddU"Ay /$Ͱ/)Ͱ1/Ͱ21 +@1 +B/ְͰ+#Ͱ#-+Ͳ- +@-< +C+-# ?$9$#9)91;2654&#!*.'&54?'dj  m U.UkmTkdd%7   VXK %  pyLN'YS(  SeV8<y/$Ͱ/Ͱ8/Ͱ:28 +@89 +=/ְͲ +@, +&+Ͱ9+<ͱ>+& )$9$&998',9990146!'&54?632#!"&'#"'32!7%*#!3elU.U m  m!jT %jW   $CLy q  ' (Sd)YS   XaL6:G7+8;/ְ72)Ͳ) +@): +32)/+ͱ<+)699/9013!2654&'%54&"'&77><546!5!a ' (NLy%p[S22(SY XVjTnkUT  n V   dp 26E3/47/ְ32)Ͳ) +@)6 +2)%+ ͱ8+) 99 % 901?26=%>54&#!"!&5<.'&5!p &yMNS) % Y(22XIn  UTlnTjVSdڂ  q: +Ͱ//ְͱ+  999999014>32 $%! !_z',nUzݠ_A&*8+Ͱ//ְ ͱ+9 9999014>32 $75!5!5_yzݠ_.Uzݠ__z>+/ְͰ+ ͱ+9999  99014>32 $%333_zyݠ_'Uzݠ__z,M+//ְͰ+ ͱ+9999  99 999014>32 $% ##_zyݠ_',,Uzݠ__zp,+,ͰQ///ְͰZ+ ͱ+9Z@!#$>LWz$9  "(2=\ix$9Q,28>HJWY$9@ Ztp$9wxz999014>32 $277>7.'.'"'&65.'6.'&76746'&67>7&72267.'6'?6.''&%>72>7._zyݠ_" X>9. #ex $/ F = .2) ( (%  )#? 7 .R+>>?1  B)Uzݠ__zY"v F  /K q$>   #/ & % I+ *  ' ) $#   ' "rq % 1' <7&6767'"/X!N` {+o+We6\e~\F/n`/37;P /4Ͱ7/Ͱ/0Ͱ3/Ͱ,/8Ͱ;/%Ͱ>D+Iͳ7ID+1Ͱ1/7ͰI+ͱO+& $9>*-<9971 /;$9 $9*-<>$9(99#/;9901$  $ 654& 462#"64632#"46?&54632#"'#"&%462#"&DVm. M  Q*z   73$%3 .  D.  ,! . 1~! . $33R . ;O:/'Ͱ /Ͱ6/JP/Q+'?9  1$9239901327>767>'&'&#"67632#"&'&>767>32>'.'&#"0#vF?8!@)'(#Z .C"|Ey&$4I7Z 0$&\4=k6_v[EC8fOESkZ(G־N9@1*+,#b/W""tCu$'$4B?#>@$$\475be[<C]W$!7GO6X6C4/.3Ͱ27/ְͰ++ ͱ8+9+$949014632632'.'.76?>54&#"'&#"Oƃbg#WCG`+rFB:5S%=>@]aRq @C>`:I:vr3I;cŁŃ.ZlGF:FA:5_=P&VA>Zo\o >FXGaSPc9w232764/&''7'&'7'7>54/&#"9BB]_@BB i{_.7BBi_.#7BB]_@Ba^BBBBB i{_-87B]Bi`.5#j+]BBB@E+Ͱ/Ͱ//ְͰ+ Ͱ Ͱ/+9990174>2#!"&7!!264&"+%Ͱ ͱC+09+'99 %8>A$99013'.54>753#.'#5&'.654&''WJ.BN/!XOd&ER<+6J@" MNW(k,;+@GdfH6//Ͱ/#3Ͱ!2/ Ͳ +@ +I/ְ>2Ͱ)2 +@# + +@ ++ͱJ+=GH$9 $%/68$919/62>991A990153&'.>7632#4.#"3#>36327#"&'>7>'d /-aʙDP$%T) ):#b "L<2)O'*2'V7   0 $Xd17;V^(Xw4K,9  %(d2;6 "B   7G  +/ ְ ͱ+ 901 ## ##****,,|X,| "+3 Ͳ+Ͱ/ͱ22 /Ͱ/Ͳ +@ +2"/Ͱ2#/ְͰ+ 22 ͱ22 + 22ͱ 22+Ͱ/ͱ$+999 901333!5335!##535!#5#735#d,cdc,dddd,|dddddd, dd"+ 33 /Ͱ"/Ͱ/ͰͰ/Ͱ/Ͱ2#/ְͰ+22ͱ22 + 22 ͱ22 +Ͱ/ͱ$+99"$99901333!!#5#5335!##53535#,dddd,cdccdd,| dddddddd|L k + /Ͱ/Ͱ /Ͳ  +@  +/ְͳ+Ͱ/ 3Ͱ + 2 ͱ+ $9 9901 ##!#553#35#**X,dddd,,| dd |L k +/Ͱ/Ͳ +@ +// ְ ͳ + Ͱ /3Ͱ  +2ͱ+ $99901 ##%53#!#5'35#**Xdd,dcdd,,|dd  dd R/Ͱ / Ͱ/Ͱ//ֲ 222ͰͲ +@ +@ ++ $901 ##5!5!5!53** p,,,|,,, R/Ͱ / Ͱ/Ͱ// ֲ222Ͱ Ͳ +@  +@  ++ $901 ##535!5!5!**,p,,|,,,LL* +Ͱ/ /ְͰ+ ͱ!+01463!2#!"&73!2654&#!",ԥ;));;) );,ԥA);;));;)LL"> +Ͱ/#/ְͰ+ ͱ$+ !99 "9901463!2#!"&73!2654&#!"-,ԣ;));;) );M,ԥA);;));;) LL"> +Ͱ/#/ְͰ+ ͱ$+ "99 !9901463!2#!"&73!2654&#!",ԥ;));;) );d,ԥA);;));;)dMLL"> +Ͱ/#/ְͰ+ ͱ$+ !99 "9901463!2#!"&73!2654&#!"!,ԥ;));;) );d,Ԣ?);;));;)pML<+Ͱ/Ͱ// ְͱ+99901!5 55!2654&#!5!2#,p);;) ,p;));ԥ /ְͱ!+9013!276'&!676/#" .    LJ v  XL?+ͰͰ/Ͱ/Ͱ /ְ ͱ!+999013!275!"&5463!5./"!5 5,/5 );;)]]X,p;));,$T+Ͱ/%/ְͰ +ͱ&+  $$9#9 "#$$99013!26='#!"&546;7'#"%'!',Nz;) );;)vJdabI{);;));zN V  Z /Ͱ/Ͱ//ְ Ͱ +Ͱ+ͱ+ $9 $901$  $ 6& 462"DVrrrD_VrrrL . +Ͱ/Ͱ 2/ְͲ +@ ++011463!2 !!35#  dd   pv2L + +Ͱ//ְͲ +@ ++011463!2!!! 35#  ,,'C^dd  ,2L . +Ͱ//ְ 2Ͳ +@ ++011463!2 ''35#  1TFdd  TF:2L + +Ͱ//ְͲ +@ ++011463!27'!'35#  aapԕdd  baԕ 2L . +Ͱ//ְ2Ͳ +@ ++011463!27'735#  |bԕcdd  daԔ2+ /ְͱ +01  %O`w8dLM/Ͳ +@ +2 +@ +2/ְͰͰ+ ͱ+ 99901546;!3+!#"&35#dDXdd,pg>@/Ͳ +@ + +@ +2/ְͰͱ+ 99901546;!3'!#"&%735#dx~E{xa{%dd,xp{x`{$#$/ְͰͱ%+01546;!3'!#"&35#7'77'dgXddd,gpgժl/Ͳ +@ + Ͱ/ͱ22/ְͲ +@ +Ͱ+Ͱ 2+9 99 901546;!3!!#"&% ##53dp X,,d,p,,[/Ͳ +@ +/ͱ22/ְͰͰ+ͱ+9 9 999 901546;!3'!#"&%333 53dnXd,np,,L 53!265!5!54&#!"5!LPd&df /33ͱ22/ 33ͱ 22/ְ Ͱ  +Ͱ+ͱ+ $9$9$9999901!!5335335!5 553;5#,pdddd,ddddd* d/:+0/ְͰ +ͳ +Ͱ/ Ͱ +ͱ1+0173737+"&5%;2654&d22d22d22dX $%dd,dd,ddpAd5!sRuEdL38+ 33Ͳ 222(/%333'Ͱ24/5+(3 99013!5"&5!#!5".546?5!2!4635!2dKK"2pK Kp"28 &v& 88 x88 &v& 88 LL *.2+Ͱ/Ͳ +@ +//0+$9013!2654&#!"!73%!!5!5!!%35!'!5%;),);;));di'Wdd,,'iWd,);;));;)Dbd,,bbdF!3?6&/&&'&'7>/.>fgї{4w|~ev-+fg=!/vg|~v1L@/+ Ͱ(/8A/B+  /99(&)2@$901=46754>2#!"&?>=6 6=.#"m&RpR&m>d|~\ud?, 23/2  23!""!A1)!((! dL+/+0135!%!'57##5##5##5#dL}dddddddddȖdpddL $ +3/ ְͰ+ͱ+013!4&+"46;2346;2d,;)d);;)d);d;)d););;)p);;));;)DL'+H +Ͱ/,/ְͰ+ ͱ-+ #(*$9 &()$901463!2#!"&7!!!#535!3#353#5#3d|||D||d,dddd,|| |,ddddd,dp,L'+H +Ͱ/,/ְͰ+ ͱ-+ #(*$9 &()$901463!2#!"&7!!3533##5#353#5#3d|||D||ddddddddddd,|| | d,dp,L#D +Ͱ/$/ְͰ+ ͱ%+$9"$901463!2#!"&7!!!5#35!!5#35!d|||D||d,,,|| |d,d d,dLD +Ͱ//ְͰ+ ͱ+$9$901463!2#!"&7!!-d|||D||d,d,,|| |,ԖL'Z +Ͱ/Ͱ#2/%3Ͱ/(/ְͰ+Ͱ+!Ͱ!$+Ͱ+ ͱ)+01463!2#!"&7!!!%3264&+;#"d|||D||d)69&6)&,|| | dTVVT,L#)H +Ͱ/*/ְͰ+ ͱ++ !$'$9 "&($901463!2#!"&7!!!#535!3#35#33#d|||D||d,ddcdd,|| |,ddddd,pL!'L +Ͱ/(/ְͰ+ ͱ)+"%$9 $&$901463!2#!"&7!!!#5#5335#33#d|||D||d,dedddcdd,|| |dpdd,pL!%+ +Ͱ/")33Ͱ#2/Ͱ/&3Ͱ'2/,/ְͰ+2!Ͱ!+ͳ+Ͱ/Ͱ"+%Ͱ%*+)Ͱ)&Ͱ&/)+ ͱ-+9901463!2#!"&7!!5!##53553!5353#d|||D||d,cdcd,dd,|| |dddpddddd  y /Ͱ/Ͱ/Ͱ//ְ Ͱ +Ͱ+ͱ+ $9 $9 $99 $901$  $ 6& 57!!!!DVd,,D_Vddd  $ /Ͱ!/3"Ͱ/Ͱ/%/ְ Ͱ + Ͱ2  +@  + !+2$Ͱ2$+ͱ&+  $9!9$ $9"! $9999 $901$  $ 6& !#5#3#353DV,dddD_VddddddddA!q/Ͱ Ͱ2"/ְͰ+Ͱ+ ͱ#+999!99  99 $999901;!32654&#".#"333qOxx.,,nBU:Pr,Ԭzxawי k,A /ְͱ!+99901; >54&#".#" ##qO^yx.,,nBU:,,Prmdyawי k,,dLm7!!'5!33 33dK^KԪț--,,My7)327!'32654'>54&'.#"&#"y9/iJ8,K^K.6Ji 2;{Y^t Ji5XJi--2iJ f=ZYqtiA.X_<]}]}::(dFHFddjdddddd5d!u,dh"oddF:.JadO9'ddddddy****f0H|6,Lrd"DL 0 ` D V @  x <bN&` `$`J6*Hz.L X0 D  ( D l !h!"@"#|#$$$%%%%%&X&&&' 'h'(0(\().)*f*+^++,8,--.^../2001"1x1223Z34445`566V677Z778@899H99::L:t:;;b;<.6>>???@N@AAvABpBCvCD*DND j (|  L 8 x6 6   $ $4 $X | 0www.glyphicons.comCopyright 2013 by Jan Kovarik. All rights reserved.GLYPHICONS HalflingsRegular1.001;UKWN;GLYPHICONSHalflings-RegularGLYPHICONS Halflings RegularVersion 1.001;PS 001.001;hotconv 1.0.70;makeotf.lib2.5.58329GLYPHICONSHalflings-RegularJan KovarikJan Kovarikwww.glyphicons.comwww.glyphicons.comwww.glyphicons.comWebfont 1.0Mon Sep 16 15:54:37 20132       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~glyph1uni000Duni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni2601uni2709uni270FuniE000uniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200KPXYF+X!YKRX!Y+\XY+R7a././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1713922 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/fonts/glyphicons-halflings-regular.svg0000644000000000000000000017260214625637207032727 0ustar00runnerstaff ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4560242 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/glitter.js0000644000000000000000000000367414625637243025620 0ustar00runnerstaff/****** Glitter V1 By Safihre (2015) - safihre@sabnzbd.org Code extended from Shiny-template Code examples used from Knockstrap-template The setup is hierarchical, 1 main ViewModel that contains: - ViewModel - QueueListModel - paginationModel - QueueModel (item 1) - QueueModel (item 2) - ... - QueueModel (item n+1) - HistoryListModel - paginationModel - HistoryModel (item 1) - HistoryModel (item 2) - ... - HistoryModel (item n+1) - Fileslisting - FileslistingModel (file 1) - FileslistingModel (file 2) - ... - FileslistingModel (file n+1) ViewModel also contains all the code executed on document ready and functions responsible for the status information, adding NZB, etc. The QueueModel/HistoryModel's get added to the list-models when jobs are added or on switching of pages (using paginationModel). Once added only the properties that changed during a refresh get updated. In the history all the detailed information is only updated when created and when the user clicks on a detail. The Fileslisting is only populated and updated when it is opened for one of the QueueModel's. ******/ #include raw $webdir + "/static/javascripts/glitter.basic.js"# /** GLITTER CODE **/ \$(function() { 'use strict'; #include raw $webdir + "/static/javascripts/glitter.main.js"# #include raw $webdir + "/static/javascripts/glitter.queue.js"# #include raw $webdir + "/static/javascripts/glitter.history.js"# #include raw $webdir + "/static/javascripts/glitter.filelist.pagination.js"# // GO!!! ko.applyBindings(new ViewModel(), document.getElementById("sabnzbd")); });././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4561076 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/jquery-ui.min.js0000644000000000000000000013437214625637243026662 0ustar00runnerstaff/*! jQuery UI - v1.12.1 - 2016-09-16 * http://jqueryui.com * Includes: widget.js, data.js, keycode.js, scroll-parent.js, widgets/sortable.js, widgets/mouse.js, widgets/slider.js * Copyright jQuery Foundation and other contributors; Licensed MIT */ (function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"

",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,l=r+t.height,h=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+h>r&&l>s+h,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&l>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],l=[],h=this._connectWith();if(h&&e)for(s=h.length-1;s>=0;s--)for(o=t(h[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&l.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(l.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=l.length-1;s>=0;s--)l[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,l,h,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,h=r.length;h>s;s++)l=t(r[s]),l.data(this.widgetName+"-item",a),c.push({item:l,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t(" ",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,l,h,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(l=this.items[s].item.offset()[a],h=!1,e[u]-l>this.items[s][r]/2&&(h=!0),n>Math.abs(e[u]-l)&&(n=Math.abs(e[u]-l),o=this.items[s],this.direction=h?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s} },_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():l?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():l?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.slider",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e).attr("tabIndex",0)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("
").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,l,h,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),l=o.offset(),h=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=h?{left:0,top:0}:{left:e.pageX-l.left-o.width()/2,top:e.pageY-l.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,l=this,h=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((l.values(s)-l._valueMin())/(l._valueMax()-l._valueMin())),c["horizontal"===l.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[h?"animate":"css"](c,r.animate),l.options.range===!0&&("horizontal"===l.orientation?(0===s&&l.range.stop(1,1)[h?"animate":"css"]({left:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&l.range.stop(1,1)[h?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[h?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}})});././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.456187 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/glitter.filelist.pagination.js0000644000000000000000000003124714625637243031557 0ustar00runnerstaff// For the file-list function Fileslisting(parent) { var self = this; self.parent = parent; self.fileItems = ko.observableArray([]); // Prevent flash of unstyled content when deleting items self.fileItems.extend({ rateLimit: 50 }) // Need to reserve these names to be overwritten self.filelist_name = ko.observable(); self.filelist_password = ko.observable(); // Load the function and reset everything self.loadFiles = function(queue_item) { // Update self.currentItem = queue_item; self.fileItems.removeAll() self.triggerUpdate() // Update name/password self.filelist_name(self.currentItem.name()) self.filelist_password(self.currentItem.password()) // Hide ok button and reset $('#modal-item-filelist .glyphicon-floppy-saved').hide() $('#modal-item-filelist .glyphicon-lock').show() // Set state of the check-all setCheckAllState('#modal-item-files .multioperations-selector input[type="checkbox"]', '#modal-item-files .files-sortable input') // Show $('#modal-item-files').modal('show'); // Stop updating on closing of the modal $('#modal-item-files').on('hidden.bs.modal', function () { self.removeUpdate(); }) } // Trigger update self.triggerUpdate = function() { // Call API callAPI({ mode: 'get_files', value: self.currentItem.id }).then(function(response) { // When there's no files left we close the modal and the update will be stopped // For example when the job has finished downloading if(response.files.length === 0) { $('#modal-item-files').modal('hide'); return; } // Go over them all var newItems = []; $.each(response.files, function(index, slot) { // Existing or updating? var existingItem = ko.utils.arrayFirst(self.fileItems(), function(i) { return i.nzf_id() === slot.nzf_id; }); if(existingItem) { // Update the rest existingItem.updateFromData(slot); } else { // Add files item newItems.push(new FileslistingModel(self, slot)); } }) // Add new ones in 1 time instead of every single push if(newItems.length > 0) { ko.utils.arrayPushAll(self.fileItems, newItems); self.fileItems.valueHasMutated(); } // Check if we show/hide completed if(localStorageGetItem('showCompletedFiles') === 'No') { $('.item-files-table tr.files-done').hide(); $('#filelist-showcompleted').removeClass('hover-button') } // Refresh with same as rest self.setUpdate() }) } // Set update self.setUpdate = function() { self.updateTimeout = setTimeout(function() { self.triggerUpdate() }, parent.refreshRate() * 1000) } // Remove the update self.removeUpdate = function() { clearTimeout(self.updateTimeout) } // Move in sortable self.move = function(event) { // How much did we move? var nrMoves = event.sourceIndex - event.targetIndex; var direction = (nrMoves > 0 ? 'up' : 'down') callAPI({ mode: 'move_nzf_bulk', name: direction, value: self.currentItem.id, nzf_ids: event.item.nzf_id(), size: Math.abs(nrMoves) }).then(function() { // Refresh all the files self.loadFiles(self.currentItem) }) }; // Move to top and bottom buttons self.moveButton = function (item, event) { // Up or down? var direction = "bottom" if ($(event.currentTarget).is(".buttonMoveToTop")) { // we are moving to the top direction = "top" } callAPI({ mode: 'move_nzf_bulk', name: direction, value: self.currentItem.id, nzf_ids: item.nzf_id() }).then(function() { // Refresh all the files self.loadFiles(self.currentItem) }) }; // Remove selected files self.removeSelectedFiles = function() { // Get all selected ones var nzfIds = [] $('.item-files-table input:checked:not(:disabled)').each(function() { // Add this item nzfIds.push($(this).prop('name')) }) callAPI({ mode: 'queue', name: 'delete_nzf', value: self.currentItem.id, value2: nzfIds.join() }).then(function() { // Refresh all the files self.loadFiles(self.currentItem) }) } // For changing the passwords self.setNzbPassword = function() { // Have to also send the current name for it to work callAPI({ mode: 'queue', name: 'rename', value: self.currentItem.id, value2: self.currentItem.name(), value3: $('#nzb_password').val() }).then(function() { // Refresh, reset and close parent.refresh() $('#modal-item-filelist .glyphicon-floppy-saved').show() $('#modal-item-filelist .glyphicon-lock').hide() $('#modal-item-files').modal('hide') }) return false; } // Check all self.checkAllFiles = function(item, event) { // Get which ones we care about var allChecks = $('#modal-item-files .files-sortable input').filter(':not(:disabled):visible'); // We need to re-evaltuate the state of this check-all // Otherwise the 'inderterminate' will be overwritten by the click event! setCheckAllState('#modal-item-files .multioperations-selector input[type="checkbox"]', '#modal-item-files .files-sortable input') // Now we can check what happend if(event.target.indeterminate) { allChecks.filter(":checked").prop('checked', false) } else { // Toggle their state by a click allChecks.prop('checked', !event.target.checked) event.target.checked = !event.target.checked; event.target.indeterminate = false; } // Set state of all the check-all's setCheckAllState('#modal-item-files .multioperations-selector input[type="checkbox"]', '#modal-item-files .files-sortable input') return true; } // For selecting range and the check-all button self.checkSelectRange = function(data, event) { if(event.shiftKey) { checkShiftRange('#modal-item-files .files-sortable input:not(:disabled)') } // Set state of the check-all setCheckAllState('#modal-item-files .multioperations-selector input[type="checkbox"]', '#modal-item-files .files-sortable input') return true; } } // Indiviual file models function FileslistingModel(parent, data) { var self = this; // Define veriables self.filename = ko.observable(data.filename); self.nzf_id = ko.observable(data.nzf_id); self.file_age = ko.observable(data.age); self.mb = ko.observable(data.mb); self.canselect = ko.observable(data.status !== "finished" && data.status !== "queued"); self.isdone = ko.observable(data.status === "finished"); self.percentage = ko.observable(self.isdone() ? fixPercentages(100) : fixPercentages((100 - (data.mbleft / data.mb * 100)).toFixed(0))); // Update internally self.updateFromData = function(data) { self.filename(data.filename) self.nzf_id(data.nzf_id) self.file_age(data.age) self.mb(data.mb) self.canselect(data.status !== "finished" && data.status !== "queued") self.isdone(data.status === "finished") // Data is given in MB, would always show 0% for small files even if completed self.percentage(self.isdone() ? fixPercentages(100) : fixPercentages((100 - (data.mbleft / data.mb * 100)).toFixed(0))) } } // Model for pagination, since we use it multiple times function paginationModel(parent) { var self = this; // Var's self.nrPages = ko.observable(0); self.currentPage = ko.observable(1); self.currentStart = ko.observable(0); self.allpages = ko.observableArray([]).extend({ rateLimit: 50 }); // Has pagination self.hasPagination = ko.pureComputed(function() { return self.nrPages() > 1; }) // Subscribe to number of items parent.totalItems.subscribe(function() { // Update self.updatePages(); }) // Subscribe to changes of pagination limit parent.paginationLimit.subscribe(function(newValue) { self.updatePages(); self.moveToPage(self.currentPage()); }) // Easy handler for adding a page-link self.addPaginationPageLink = function(pageNr) { // Return object for adding return { page: pageNr, isCurrent: pageNr === self.currentPage(), isDots: false, onclick: function(data) { self.moveToPage(data.page); } } } // Easy handler to add dots self.addDots = function() { return { page: '...', isCurrent: false, isDots: true, onclick: function() {} } } self.updatePages = function() { // Empty it self.allpages.removeAll(); // How many pages do we need? if(parent.totalItems() <= parent.paginationLimit()) { // Empty it self.nrPages(1) self.currentStart(0); // Are we on next page? Bad! if(self.currentPage() > 1) { // Force full update parent.parent.refresh(true); } // Move to current page self.currentPage(1); } else { // Calculate number of pages needed var newNrPages = Math.ceil(parent.totalItems() / parent.paginationLimit()) // Make sure the current page still exists if(self.currentPage() > newNrPages) { self.moveToPage(newNrPages); return; } // All the cases if(newNrPages > 7) { // Do we show the first ones if(self.currentPage() < 5) { // Just add the first 4 $.each(new Array(5), function(index) { self.allpages.push(self.addPaginationPageLink(index + 1)) }) // Dots self.allpages.push(self.addDots()) // Last one self.allpages.push(self.addPaginationPageLink(newNrPages)) } else { // Always add the first self.allpages.push(self.addPaginationPageLink(1)) // Dots self.allpages.push(self.addDots()) // Are we near the end? if((newNrPages - self.currentPage()) < 4) { // We add the last ones $.each(new Array(5), function(index) { self.allpages.push(self.addPaginationPageLink((index - 4) + (newNrPages))) }) } else { // We are in the center so display the center 3 $.each(new Array(3), function(index) { self.allpages.push(self.addPaginationPageLink(self.currentPage() + (index - 1))) }) // Dots self.allpages.push(self.addDots()) // Last one self.allpages.push(self.addPaginationPageLink(newNrPages)) } } } else { // Just add them $.each(new Array(newNrPages), function(index) { self.allpages.push(self.addPaginationPageLink(index + 1)) }) } // Change of number of pages? if(newNrPages !== self.nrPages()) { // Update self.nrPages(newNrPages); } } } // Update on click self.moveToPage = function(page) { // Update page and start self.currentPage(page) self.currentStart((page - 1) * parent.paginationLimit()) // Re-paginate self.updatePages(); // Force full update parent.parent.refresh(true); } }././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4562712 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/glitter.main.js0000644000000000000000000013735414625637243026546 0ustar00runnerstaff/** Define main view model **/ function ViewModel() { // Initialize models var self = this; self.queue = new QueueListModel(this); self.history = new HistoryListModel(this); self.filelist = new Fileslisting(this); // Set status varibales self.isRestarting = ko.observable(false); self.useGlobalOptions = ko.observable(true).extend({ persist: 'useGlobalOptions' }); self.refreshRate = ko.observable(1).extend({ persist: 'pageRefreshRate' }); self.dateFormat = ko.observable('fromNow').extend({ persist: 'pageDateFormat' }); self.displayTabbed = ko.observable().extend({ persist: 'displayTabbed' }); self.displayCompact = ko.observable(false).extend({ persist: 'displayCompact' }); self.displayFullWidth = ko.observable(false).extend({ persist: 'displayFullWidth' }); self.confirmDeleteQueue = ko.observable(true).extend({ persist: 'confirmDeleteQueue' }); self.confirmDeleteHistory = ko.observable(true).extend({ persist: 'confirmDeleteHistory' }); self.keyboardShortcuts = ko.observable(true).extend({ persist: 'keyboardShortcuts' }); self.extraQueueColumns = ko.observableArray([]).extend({ persist: 'extraColumns' }); self.extraHistoryColumns = ko.observableArray([]).extend({ persist: 'extraHistoryColumns' }); self.showActiveConnections = ko.observable(false).extend({ persist: 'showActiveConnections' }); self.speedMetrics = { '': "B/s", K: "KB/s", M: "MB/s", G: "GB/s" }; // Set information varibales self.title = ko.observable(); self.speed = ko.observable(0); self.speedMetric = ko.observable(); self.bandwithLimit = ko.observable(false); self.pauseCustom = ko.observable('').extend({ rateLimit: { timeout: 200, method: "notifyWhenChangesStop" } }); self.speedLimit = ko.observable(100).extend({ rateLimit: { timeout: 200, method: "notifyWhenChangesStop" } }); self.speedLimitInt = ko.observable(false); // We need the 'internal' counter so we don't trigger the API all the time self.downloadsPaused = ko.observable(false); self.timeLeft = ko.observable("0:00"); self.diskSpaceLeft1 = ko.observable(); self.diskSpaceLeft2 = ko.observable(); self.queueDataLeft = ko.observable(); self.diskSpaceExceeded1 = ko.observable(false); self.diskSpaceExceeded2 = ko.observable(false); self.quotaLimit = ko.observable(); self.quotaLimitLeft = ko.observable(); self.systemLoad = ko.observable(); self.cacheSize = ko.observable(); self.cacheArticles = ko.observable(); self.loglevel = ko.observable(); self.nrWarnings = ko.observable(0); self.allWarnings = ko.observableArray([]); self.allMessages = ko.observableArray([]); self.finishaction = ko.observable(); self.speedHistory = []; // Statusinfo container self.hasStatusInfo = ko.observable(false); self.hasPerformanceInfo = ko.observable(false); self.statusInfo = {}; self.statusInfo.folders = ko.observableArray([]); self.statusInfo.servers = ko.observableArray([]); self.statusInfo.active_socks5_proxy = ko.observable(); self.statusInfo.localipv4 = ko.observable(); self.statusInfo.publicipv4 = ko.observable(); self.statusInfo.ipv6 = ko.observable(); self.statusInfo.dnslookup = ko.observable(); self.statusInfo.delayed_assembler = ko.observable(); self.statusInfo.loadavg = ko.observable(); self.statusInfo.pystone = ko.observable(); self.statusInfo.downloaddir = ko.observable(); self.statusInfo.downloaddirspeed = ko.observable(); self.statusInfo.completedir = ko.observable(); self.statusInfo.completedirspeed = ko.observable(); self.statusInfo.internetbandwidth = ko.observable(); /*** Dynamic functions ***/ // Make the speedlimit tekst self.speedLimitText = ko.pureComputed(function() { // Set? if (!self.bandwithLimit()) return; // The text var bandwithLimitText = self.bandwithLimit().replace(/[^a-zA-Z]+/g, ''); // Only the number var speedLimitNumberFull = (parseFloat(self.bandwithLimit()) * (self.speedLimit() / 100)); // Trick to only get decimal-point when needed var speedLimitNumber = Math.round(speedLimitNumberFull * 10) / 10; // Fix it for lower than 1MB/s if (bandwithLimitText === 'M' && speedLimitNumber < 1) { bandwithLimitText = 'K'; speedLimitNumber = Math.round(speedLimitNumberFull * 1024); } // Show text return self.speedLimit() + '% (' + speedLimitNumber + ' ' + self.speedMetrics[bandwithLimitText] + ')'; }); // Dynamic speed text function self.speedText = ko.pureComputed(function() { return self.speed() + ' ' + (self.speedMetrics[self.speedMetric()] ? self.speedMetrics[self.speedMetric()] : "B/s"); }); // Dynamic icon self.SABIcon = ko.pureComputed(function() { if (self.downloadsPaused()) { return './staticcfg/ico/faviconpaused.ico?v=1.1.0'; } else { return './staticcfg/ico/favicon.ico?v=1.1.0'; } }) // Dynamic queue length check self.hasQueue = ko.pureComputed(function() { return (self.queue.queueItems().length > 0 || self.queue.searchTerm() || self.queue.isLoading()) }) // Dynamic history length check self.hasHistory = ko.pureComputed(function() { return (self.history.historyItems().length > 0 || self.history.searchTerm() || self.history.isLoading()) }) self.hasWarnings = ko.pureComputed(function() { return (self.allWarnings().length > 0) }) // Check for any warnings/messages self.hasMessages = ko.pureComputed(function() { return parseInt(self.nrWarnings()) + self.allMessages().length; }) // Update main queue self.updateQueue = function(response) { // Block in case off dragging if (!self.queue.shouldUpdate()) return; // Make sure we are displaying the interface if (self.isRestarting() >= 1) { // Decrease the counter by 1 // In case of restart (which takes time to fire) we count down // In case of re-connect after failure it counts from 1 so emmediate continuation self.isRestarting(self.isRestarting() - 1); return; } /*** Possible login failure? ***/ if (response.hasOwnProperty('error') && response.error === 'Missing authentication') { // Restart document.location = document.location; } /*** Basic information ***/ // Queue left self.queueDataLeft(response.queue.mbleft > 0 ? response.queue.sizeleft : '') // Paused? self.downloadsPaused(response.queue.paused); // Finish action. Replace null with empty self.finishaction(response.queue.finishaction ? response.queue.finishaction : ''); // Disk sizes self.diskSpaceLeft1(response.queue.diskspace1_norm) // Same sizes? Then it's all 1 disk! if (response.queue.diskspace1 !== response.queue.diskspace2) { self.diskSpaceLeft2(response.queue.diskspace2_norm) } else { self.diskSpaceLeft2('') } // Did we exceed the space? self.diskSpaceExceeded1(parseInt(response.queue.mbleft) / 1024 > parseFloat(response.queue.diskspace1)) self.diskSpaceExceeded2(parseInt(response.queue.mbleft) / 1024 > parseFloat(response.queue.diskspace2)) // Quota self.quotaLimit(response.queue.quota) self.quotaLimitLeft(response.queue.left_quota) // Cache self.cacheSize(response.queue.cache_size) self.cacheArticles(response.queue.cache_art) // Warnings (new warnings will trigger an update of allMessages) self.nrWarnings(response.queue.have_warnings) /*** Spark line ***/ // Break the speed if empty queue if (response.queue.sizeleft === '0 B') { response.queue.kbpersec = 0; response.queue.speed = '0'; } // Re-format the speed var speedSplit = response.queue.speed.split(/\s/); self.speed(parseFloat(speedSplit[0])); self.speedMetric(speedSplit[1]); // Update sparkline data if (self.speedHistory.length >= 275) { // Remove first one self.speedHistory.shift(); } // Add self.speedHistory.push(parseInt(response.queue.kbpersec)); // Is sparkline visible? Not on small mobile devices.. if ($('.sparkline-container').css('display') !== 'none') { // Make sparkline if (self.speedHistory.length === 1) { // We only use speedhistory from SAB if we use global settings // Otherwise SAB doesn't know the refresh rate if (!self.useGlobalOptions()) { sabSpeedHistory = []; } else { // Update internally self.speedHistory = sabSpeedHistory; } // Create $('.sparkline').peity("line", { width: 275, height: 32, fill: '#9DDB72', stroke: '#AAFFAA', values: sabSpeedHistory }) // Add option to open the server details tab $('.sparkline-container').click(function() { $('a[href="#modal-options"]').trigger('click') $('a[href="#options_connections"]').trigger('click') }) } else { // Update $('.sparkline').text(self.speedHistory.join(",")).change() } } /*** Speedlimit ***/ // Nothing or 0 means 100% if(response.queue.speedlimit === '' || response.queue.speedlimit === '0') { self.speedLimitInt(100) } else { self.speedLimitInt(parseInt(response.queue.speedlimit)); } // Only update from external source when user isn't doing input if (!$('.speedlimit-dropdown .btn-group .btn-group').is('.open')) { self.speedLimit(self.speedLimitInt()) } /*** Download timing and pausing ***/ var timeString = response.queue.timeleft; if (timeString === '') { timeString = '0:00'; } else { timeString = rewriteTime(response.queue.timeleft) } // Paused main queue if (self.downloadsPaused()) { if (response.queue.pause_int === '0') { timeString = glitterTranslate.paused; } else { var pauseSplit = response.queue.pause_int.split(/:/); var seconds = parseInt(pauseSplit[0]) * 60 + parseInt(pauseSplit[1]); var hours = Math.floor(seconds / 3600); var minutes = Math.floor((seconds -= hours * 3600) / 60); seconds -= minutes * 60; // Add leading zeros if (minutes < 10) minutes = '0' + minutes; if (seconds < 10) seconds = '0' + seconds; // Final formating timeString = glitterTranslate.paused + ' (' + rewriteTime(hours + ":" + minutes + ":" + seconds) + ')'; } // Add info about amount of download (if actually downloading) if (response.queue.noofslots > 0 && parseInt(self.queueDataLeft()) > 0) { self.title(timeString + ' - ' + self.queueDataLeft() + ' ' + glitterTranslate.left + ' - SABnzbd') } else { // Set title with pause information self.title(timeString + ' - SABnzbd') } } else if (response.queue.noofslots > 0 && parseInt(self.queueDataLeft()) > 0) { // Set title only if we are actually downloading something.. self.title(self.speedText() + ' - ' + self.queueDataLeft() + ' ' + glitterTranslate.left + ' - SABnzbd') } else { // Empty title self.title('SABnzbd') } // Save for timing box self.timeLeft(timeString); // Update queue rows self.queue.updateFromData(response.queue); } // Update history items self.updateHistory = function(response) { if (!response) return; self.history.updateFromData(response.history); } // Set new update timer self.setNextUpdate = function() { self.interval = setTimeout(self.refresh, parseInt(self.refreshRate()) * 1000); } // Refresh function self.refresh = function(forceFullHistory) { // Clear previous timeout to prevent double-calls clearTimeout(self.interval); // Do requests for full information // Catch the fail to display message var api_call = { mode: "queue", start: self.queue.pagination.currentStart(), limit: parseInt(self.queue.paginationLimit()) } if (self.queue.searchTerm()) { parseSearchQuery(api_call, self.queue.searchTerm(), ["cat", "category", "priority", "status"]) } var queueApi = callAPI(api_call) .done(self.updateQueue) .fail(function(response) { // Catch the failure of authorization error if (response.status === 401) { // Stop refresh and reload clearInterval(self.interval) location.reload(); } // Show screen self.isRestarting(1) }).always(self.setNextUpdate); // Force full history update? if (forceFullHistory) { self.history.lastUpdate = 0 } // Build history request and parse search var history_call = { mode: "history", failed_only: self.history.showFailed() * 1, start: self.history.pagination.currentStart(), limit: parseInt(self.history.paginationLimit()), archive: self.history.showArchive() * 1, last_history_update: self.history.lastUpdate } if (self.history.searchTerm()) { parseSearchQuery(history_call, self.history.searchTerm(), ["cat", "category", "status"]) } // History callAPI(history_call).done(self.updateHistory); // We are now done with any loading // But we wait a few ms so Knockout has time to update setTimeout(function() { self.queue.isLoading(false); self.history.isLoading(false); }, 100) // Return for .then() functionality return queueApi; }; function parseSearchQuery(api_request, search, keywords) { var parsed_query = search_query_parse(search, { keywords: keywords }) api_request["search"] = parsed_query.text for (const keyword of keywords) { if (Array.isArray(parsed_query[keyword])) { api_request[keyword] = parsed_query[keyword].join(",") } else { api_request[keyword] = parsed_query[keyword] } // Special case for priority, dirty replace of string by numeric value if (keyword === "priority" && api_request["priority"]) { for (const prio_name in self.queue.priorityName) { api_request["priority"] = api_request["priority"].replace(prio_name, self.queue.priorityName[prio_name]) } } } } // Set pause action on click of toggle self.pauseToggle = function() { callAPI({ mode: (self.downloadsPaused() ? "resume" : "pause") }).then(self.refresh); self.downloadsPaused(!self.downloadsPaused()); } // Set pause timer self.pauseTime = function(item, event) { callAPI({ mode: 'config', name: 'set_pause', value: $(event.currentTarget).data('time') }).then(self.refresh); self.downloadsPaused(true); }; // Open modal self.openCustomPauseTime = function() { // Was it loaded already? if (!Date.i18n) { jQuery.getScript('./static/javascripts/date.min.js').then(function() { // After loading we start again self.openCustomPauseTime() }) return; } // Show modal $('#modal-custom-pause').modal('show') } $('#modal-custom-pause').on('shown.bs.modal', function() { // Focus on the input field when opening the modal $('#customPauseInput').focus() }).on('hide.bs.modal', function() { // Reset on modal close self.pauseCustom(''); }) // Update on changes self.pauseCustom.subscribe(function(newValue) { // Is it plain numbers? if (newValue.match(/^\s*\d+\s*$/)) { // Treat it as a number of minutes newValue += "minutes"; } // At least 3 charaters if (newValue.length < 3) { $('#customPauseOutput').text('').data('time', 0) $('#modal-custom-pause .btn-default').addClass('disabled') return; } // Fix DateJS bug it has some strange problem with the current day-of-month + 1 // Removing the space makes DateJS work properly newValue = newValue.replace(/\s*h|\s*m|\s*d/g, function(match) { return match.trim() }); // Parse var pauseParsed = Date.parse(newValue); // Did we get it? if (pauseParsed) { // Is it just now? if (pauseParsed <= Date.parse('now')) { // Try again with the '+' in front, the parser doesn't get 100min pauseParsed = Date.parse('+' + newValue); } // Calculate difference in minutes and save var pauseDuration = Math.round((pauseParsed - Date.parse('now')) / 1000 / 60); $('#customPauseOutput').html(' ' + glitterTranslate.pauseFor + ' ' + pauseDuration + ' ' + glitterTranslate.minutes) $('#customPauseOutput').data('time', pauseDuration) $('#modal-custom-pause .btn-default').removeClass('disabled') } else if (newValue) { // No.. $('#customPauseOutput').text(glitterTranslate.pausePromptFail) $('#modal-custom-pause .btn-default').addClass('disabled') } }) // Save custom pause self.saveCustomPause = function() { // Get duration var pauseDuration = $('#customPauseOutput').data('time'); // If in the future if (pauseDuration > 0) { callAPI({ mode: 'config', name: 'set_pause', value: pauseDuration }).then(function() { // Refresh and close the modal self.refresh() self.downloadsPaused(true); $('#modal-custom-pause').modal('hide') }); } } // Update the warnings self.nrWarnings.subscribe(function(newValue) { // Really any change? if (newValue === self.allWarnings().length) return; // Get all warnings callAPI({ mode: 'warnings' }).then(function(response) { // Reset it all self.allWarnings.removeAll(); if (response) { // Newest first response.warnings.reverse() // Go over all warnings and add $.each(response.warnings, function(index, warning) { // Reformat CSS label and date // Replaces spaces by non-breakable spaces and newlines with br's var warningData = { index: index, type: glitterTranslate.status[warning.type].slice(0, -1), text: convertHTMLtoText(warning.text).replace(/ /g, '\u00A0').replace(/(?:\r\n|\r|\n)/g, '
'), timestamp: warning.time, css: (warning.type === "ERROR" ? "danger" : warning.type === "WARNING" ? "warning" : "info"), clear: self.clearWarnings }; self.allWarnings.push(warningData) }) } }); }) // Clear warnings self.clearWarnings = function() { callAPI({ mode: "warnings", name: "clear" }).done(self.refresh) } // Clear messages self.clearMessages = function(whatToRemove) { // Remove specifc type of messages self.allMessages.remove(function(item) { return item.index === whatToRemove }); // Now so we don't show again today localStorageSetItem(whatToRemove, Date.now()) } // Update on speed-limit change self.speedLimit.subscribe(function(newValue) { // Only on new load if (!self.speedLimitInt()) return; // Update if (self.speedLimitInt() !== newValue) { callAPI({ mode: "config", name: "speedlimit", value: newValue }) } }); // Clear speedlimit self.clearSpeedLimit = function() { // Send call to override speedlimit callAPI({ mode: "config", name: "speedlimit", value: 100 }) self.speedLimitInt(100.0) self.speedLimit(100.0) } // Shutdown options self.setOnQueueFinish = function(model, event) { // Something changes callAPI({ mode: 'queue', name: 'change_complete_action', value: $(event.target).val() }) } // Use global settings or device-specific? self.useGlobalOptions.subscribe(function(newValue) { // Reload in case of enabling global options if (newValue) document.location = document.location; }) // Update refreshrate self.refreshRate.subscribe(function(newValue) { // Refresh now self.refresh(); // Save in config if global-settings if (self.useGlobalOptions()) { callAPI({ mode: "set_config", section: "misc", keyword: "refresh_rate", value: newValue }) } }) /*** Add NZB's ***/ // Updating the label self.updateBrowseLabel = function(data, event) { // Get filename var fileName = $(event.target).val().replace(/\\/g, '/').replace(/.*\//, ''); // Set label if (fileName) $('.btn-file em').text(fileName) } // Add NZB form self.addNZB = function(form) { // Anything? if (!$(form.nzbFile)[0].files[0] && !$(form.nzbURL).val()) { $('.btn-file, input[name="nzbURL"]').attr('style', 'border-color: red !important') setTimeout(function() { $('.btn-file, input[name="nzbURL"]').css('border-color', '') }, 2000) return false; } // Disable the buttons to prevent multiple uploads let submit_buttons = $(form).find("input[type='submit']") submit_buttons.attr("disabled", true) // Upload file using the method we also use for drag-and-drop if ($(form.nzbFile)[0].files[0]) { self.addNZBFromFile($(form.nzbFile)[0].files); // Hide modal, upload will reset the form $("#modal-add-nzb").modal("hide"); // Re-enable the buttons submit_buttons.attr("disabled", false) } else if ($(form.nzbURL).val()) { // Or add URL var theCall = { mode: "addurl", name: $(form.nzbURL).val(), nzbname: $('#nzbname').val(), password: $('#password').val(), cat: $('#modal-add-nzb select[name="Category"]').val(), priority: $('#modal-add-nzb select[name="Priority"]').val(), pp: $('#modal-add-nzb select[name="Processing"]').val(), script: $('#modal-add-nzb select[name="Post-processing"]').val(), } // Add callAPI(theCall).then(function(r) { // Hide and reset/refresh self.refresh() $("#modal-add-nzb").modal("hide"); form.reset() $('#nzbname').val('') submit_buttons.attr("disabled", false) }); } } // default to url input when modal is shown $('#modal-add-nzb').on('shown.bs.modal', function() { $('input[name="nzbURL"]').focus(); }) // From the upload or filedrop self.addNZBFromFile = function(files, fileindex) { // First file if (fileindex === undefined) { fileindex = 0 } var file = files[fileindex] fileindex++ // Check if it's maybe a folder, we can't handle those if (!file.type && file.size % 4096 === 0) return; // Add notification showNotification('.main-notification-box-uploading', 0, fileindex) // Adding a file happens through this special function var data = new FormData(); data.append("name", file); data.append("mode", "addfile"); data.append("nzbname", $('#nzbname').val()); data.append("password", $('#password').val()); data.append("cat", $('#modal-add-nzb select[name="Category"]').val()) data.append("priority", $('#modal-add-nzb select[name="Priority"]').val()) data.append("pp", $('#modal-add-nzb select[name="Processing"]').val()) data.append("script", $('#modal-add-nzb select[name="Post-processing"]').val()) data.append("apikey", apiKey); // Add this one $.ajax({ url: "./api", type: "POST", cache: false, processData: false, contentType: false, data: data }).then(function(r) { // Are we done? if (fileindex < files.length) { // Do the next one self.addNZBFromFile(files, fileindex) } else { // Refresh self.refresh(); // Hide notification hideNotification() // Reset the form $('#modal-add-nzb form').trigger('reset'); $('#nzbname').val('') $('.btn-file em').html(glitterTranslate.chooseFile + '…') } }); } // Load status info self.loadStatusInfo = function(item, event) { // Full refresh? Only on click and for the status-screen var statusFullRefresh = (event !== undefined) && $('#options-status').hasClass('active'); // Measure performance? Takes a while var statusPerformance = (event !== undefined) && $(event.currentTarget).hasClass('diskspeed-button'); // Make it spin if the user requested it otherwise we don't, // because browsers use a lot of CPU for the animation if (statusFullRefresh) { self.hasStatusInfo(false) } // Show loading text for performance measures if (statusPerformance) { self.hasPerformanceInfo(false) } // Load the custom status info, allowing for longer timeouts callAPI({ mode: 'status', skip_dashboard: (!statusFullRefresh) * 1, calculate_performance: statusPerformance * 1, }, 30000).then(function(data) { // Update basic self.statusInfo.folders(data.status.folders) self.statusInfo.loadavg(data.status.loadavg) self.statusInfo.delayed_assembler(data.status.delayed_assembler) // Update the full set if the data is available if ("dnslookup" in data.status) { self.statusInfo.pystone(data.status.pystone) self.statusInfo.downloaddir(data.status.downloaddir) self.statusInfo.downloaddirspeed(data.status.downloaddirspeed) self.statusInfo.completedir(data.status.completedir) self.statusInfo.completedirspeed(data.status.completedirspeed) self.statusInfo.internetbandwidth(data.status.internetbandwidth) self.statusInfo.dnslookup(data.status.dnslookup) self.statusInfo.active_socks5_proxy(data.status.active_socks5_proxy) self.statusInfo.localipv4(data.status.localipv4) self.statusInfo.publicipv4(data.status.publicipv4) self.statusInfo.ipv6(data.status.ipv6 || glitterTranslate.noneText) } // Update the servers ko.mapping.fromJS(data.status.servers, {}, self.statusInfo.servers) // Add tooltips to possible new items if (!isMobile) $('#modal-options [data-tooltip="true"]').tooltip({ trigger: 'hover', container: 'body' }) // Stop it spin self.hasStatusInfo(true) self.hasPerformanceInfo(true) }); } // Download a test-NZB self.testDownload = function(data, event) { var nzbSize = $(event.target).data('size') // Maybe it was a click on the icon? if (nzbSize === undefined) { nzbSize = $(event.target.parentElement).data('size') } // Build request var theCall = { mode: "addurl", name: "https://sabnzbd.org/tests/test_download_" + nzbSize + ".nzb", priority: self.queue.priorityName["Force"] } // Add callAPI(theCall).then(function(r) { // Hide and reset/refresh self.refresh() $("#modal-options").modal("hide"); }); } // Unblock server self.unblockServer = function(servername) { callAPI({ mode: "status", name: "unblock_server", value: servername }).then(function() { $("#modal-options").modal("hide"); }) } // Refresh connections page var connectionRefresh $('.nav-tabs a[href="#options_connections"]').on('shown.bs.tab', function() { // Check size on open checkSize() // Set the interval connectionRefresh = setInterval(function() { // Start small checkSize() // Check if still visible if (!$('#options_connections').is(':visible') && connectionRefresh) { // Stop refreshing clearInterval(connectionRefresh) return } // Update the server stats (speed/connections) self.loadStatusInfo() }, self.refreshRate() * 1000) }) // On close of the tab $('.nav-tabs a[href="#options_connections"]').on('hidden.bs.tab', function() { checkSize() }) // Function that handles the actual sizing of connections tab function checkSize() { // Any connections? if (self.showActiveConnections() && $('#options_connections').is(':visible') && $('.table-server-connections').height() > 1) { var mainWidth = $('.main-content').width() $('#modal-options .modal-dialog').width(mainWidth * 0.85 > 650 ? mainWidth * 0.85 : '') } else { // Small again $('#modal-options .modal-dialog').width('') } } // Make sure Connections get refreshed also after open->close->open $('#modal-options').on('show.bs.modal', function() { // Trigger $('.nav-tabs a[href="#options_connections"]').trigger('shown.bs.tab') }) // Orphaned folder processing self.folderProcess = function(folder, htmlElement) { // Hide tooltips (otherwise they stay forever..) $('#options-orphans [data-tooltip="true"]').tooltip('hide') // Show notification on delete if ($(htmlElement.currentTarget).data('action') === 'delete_orphan') { showNotification('.main-notification-box-removing', 1000) } else { // Adding back to queue showNotification('.main-notification-box-sendback', 2000) } // Activate callAPI({ mode: "status", name: $(htmlElement.currentTarget).data('action'), value: $("
").html(folder).text() }).then(function() { // Refresh self.loadStatusInfo(true, true) // Hide notification hideNotification() }) } // Orphaned folder deletion of all self.removeAllOrphaned = function() { if (!self.confirmDeleteHistory() || confirm(glitterTranslate.clearWarn)) { // Show notification showNotification('.main-notification-box-removing-multiple', 0, self.statusInfo.folders().length) // Delete them all callAPI({ mode: "status", name: "delete_all_orphan" }).then(function() { // Remove notifcation and update screen hideNotification() self.loadStatusInfo(true, true) }) } } // Orphaned folder adding of all self.addAllOrphaned = function() { if (!self.confirmDeleteHistory() || confirm(glitterTranslate.clearWarn)) { // Show notification showNotification('.main-notification-box-sendback') // Delete them all callAPI({ mode: "status", name: "add_all_orphan" }).then(function() { // Remove notifcation and update screen hideNotification() self.loadStatusInfo(true, true) }) } } // Toggle Glitter's compact layout dynamically self.displayCompact.subscribe(function() { $('body').toggleClass('container-compact') }) // Toggle full width self.displayFullWidth.subscribe(function() { $('body').toggleClass('container-full-width') }) // Toggle Glitter's tabbed modus self.displayTabbed.subscribe(function() { $('body').toggleClass('container-tabbed') }) // Change hash for page-reload $('.history-queue-swicher .nav-tabs a').on('shown.bs.tab', function(e) { window.location.hash = e.target.hash; }) /** SABnzb options **/ // Shutdown self.shutdownSAB = function() { if (confirm(glitterTranslate.shutdown)) { // Show notification and return true to follow the URL showNotification('.main-notification-box-shutdown') return true } } // Restart self.restartSAB = function() { if (!confirm(glitterTranslate.restart)) return; // Call restart function callAPI({ mode: "restart" }) // Set counter, we need at least 15 seconds self.isRestarting(Math.max(1, Math.floor(15 / self.refreshRate()))); // Force refresh in case of very long refresh-times if (self.refreshRate() > 30) { setTimeout(self.refresh, 30 * 1000) } } // Queue actions self.doQueueAction = function(data, event) { // Event var theAction = $(event.target).data('mode'); // Show notification if available if (['rss_now', 'watched_now'].indexOf(theAction) > -1) { showNotification('.main-notification-box-' + theAction, 2000) } // Send to the API callAPI({ mode: theAction }) } // Repair queue self.repairQueue = function() { if (!confirm(glitterTranslate.repair)) return; // Hide the modal and show the notifucation $("#modal-options").modal("hide"); showNotification('.main-notification-box-queue-repair', 5000) // Call the API callAPI({ mode: "restart_repair" }) } // Force disconnect self.forceDisconnect = function() { // Show notification showNotification('.main-notification-box-disconnect', 3000) // Call API callAPI({ mode: "disconnect" }).then(function() { $("#modal-options").modal("hide"); }) } /*** Retrieve config information and do startup functions ***/ // Force compact mode as fast as possible if (localStorageGetItem('displayCompact') === 'true') { // Add extra class $('body').addClass('container-compact') } if (localStorageGetItem('displayFullWidth') === 'true') { // Add extra class $('body').addClass('container-full-width') } // Tabbed layout? if (localStorageGetItem('displayTabbed') === 'true') { $('body').addClass('container-tabbed') var tab_from_hash = location.hash.replace(/^#/, ''); if (tab_from_hash) { $('.history-queue-swicher .nav-tabs a[href="#' + tab_from_hash + '"]').tab('show'); } } self.globalInterfaceSettings = [ 'dateFormat', 'extraQueueColumns', 'extraHistoryColumns', 'displayCompact', 'displayFullWidth', 'displayTabbed', 'confirmDeleteQueue', 'confirmDeleteHistory', 'keyboardShortcuts' ] // Save the rest in config if global-settings var saveInterfaceSettings = function(newValue) { var interfaceSettings = {} for (const setting of self.globalInterfaceSettings) { interfaceSettings[setting] = self[setting] } callAPI({ mode: "set_config", section: "misc", keyword: "interface_settings", value: ko.toJSON(interfaceSettings) }) } // Get the speed-limit, refresh rate and server names callAPI({ mode: 'get_config' }).then(function(response) { // Do we use global, or local settings? if (self.useGlobalOptions()) { // Set refreshrate (defaults to 1/s) if (!response.config.misc.refresh_rate) response.config.misc.refresh_rate = 1; self.refreshRate(response.config.misc.refresh_rate.toString()); // Set history and queue limit self.history.paginationLimit(response.config.misc.history_limit.toString()) self.queue.paginationLimit(response.config.misc.queue_limit.toString()) // Import the rest of the settings if (response.config.misc.interface_settings) { var interfaceSettings = JSON.parse(response.config.misc.interface_settings); for (const setting of self.globalInterfaceSettings) { if (setting in interfaceSettings) { self[setting](interfaceSettings[setting]); } } } // Only subscribe now to prevent collisions between localStorage and config settings updates for (const setting of self.globalInterfaceSettings) { self[setting].subscribe(saveInterfaceSettings); } } // Set bandwidth limit if (!response.config.misc.bandwidth_max) response.config.misc.bandwidth_max = false; self.bandwithLimit(response.config.misc.bandwidth_max); // Reformat and set categories self.queue.categoriesList($.map(response.config.categories, function(cat) { // Default? if(cat.name === '*') return { catValue: '*', catText: glitterTranslate.defaultText }; return { catValue: cat.name, catText: cat.name }; })) // Get the scripts, if there are any if(response.config.misc.script_dir) { callAPI({ mode: 'get_scripts' }).then(function(script_response) { // Reformat script-list self.queue.scriptsList($.map(script_response.scripts, function(script) { // None? if(script === 'None') return { scriptValue: 'None', scriptText: glitterTranslate.noneText }; return { scriptValue: script, scriptText: script }; })) }) } // Already set if we are using a proxy if (response.config.misc.socks5_proxy_url) self.statusInfo.active_socks5_proxy(true) // Set logging and only then subscribe to changes self.loglevel(response.config.logging.log_level); self.loglevel.subscribe(function(newValue) { callAPI({ mode: "set_config", section: "logging", keyword: "log_level", value: newValue }); }) // Update message if (newRelease) { self.allMessages.push({ index: 'UpdateMsg', type: glitterTranslate.status['INFO'], text: ('' + glitterTranslate.updateAvailable + ' ' + newRelease + ' '), css: 'info' }); } // Message about cache - Not for 5 days if user ignored it if (!response.config.misc.cache_limit && localStorageGetItem('CacheMsg') * 1 + (1000 * 3600 * 24 * 5) < Date.now()) { self.allMessages.push({ index: 'CacheMsg', type: glitterTranslate.status['INFO'], text: ('' + glitterTranslate.useCache.replace(/
/g, " ") + '
'), css: 'info', clear: function() { self.clearMessages('CacheMsg') } }); } // Message about tips and tricks, only once if (response.config.misc.notified_new_skin < 2) { self.allMessages.push({ index: 'TipsMsgV110', type: glitterTranslate.status['INFO'], text: glitterTranslate.glitterTips + ' Glitter Tips and Tricks ', css: 'info', clear: function() { // Update the config to not show again callAPI({ mode: 'set_config', section: 'misc', keyword: 'notified_new_skin', value: 2 }) // Remove the actual message self.clearMessages('TipsMsgV110') } }); } }) // Orphaned folder check - Not for 5 days if user ignored it var orphanMsg = localStorageGetItem('OrphanedMsg') * 1 + (1000 * 3600 * 24 * 5) < Date.now(); // Delay the check if (orphanMsg) { setTimeout(self.loadStatusInfo, 200); } // On any status load we check Orphaned folders self.hasStatusInfo.subscribe(function(finishedLoading) { // Loaded or just starting? if (!finishedLoading) return; // Orphaned folders? If user clicked away we check again in 5 days if (self.statusInfo.folders().length >= 3 && orphanMsg) { // Check if not already there if (!ko.utils.arrayFirst(self.allMessages(), function(item) { return item.index === 'OrphanedMsg' })) { self.allMessages.push({ index: 'OrphanedMsg', type: glitterTranslate.status['INFO'], text: glitterTranslate.orphanedJobsMsg + ' ', css: 'info', clear: function() { self.clearMessages('OrphanedMsg') } }); } } else { // Remove any message, if it was there self.allMessages.remove(function(item) { return item.index === 'OrphanedMsg'; }) } }) // Message about localStorage not being enabled every 20 days if (!hasLocalStorage && localStorageGetItem('LocalStorageMsg') * 1 + (1000 * 3600 * 24 * 20) < Date.now()) { self.allMessages.push({ index: 'LocalStorageMsg', type: glitterTranslate.status['WARNING'].replace(':', ''), text: glitterTranslate.noLocalStorage, css: 'warning', clear: function() { self.clearMessages('LocalStorageMsg') } }); } if (self.keyboardShortcuts()) { $(document).bind('keydown', 'p', function(e) { self.pauseToggle(); }); $(document).bind('keydown', 'a', function(e) { // avoid modal clashes if (!$('.modal-dialog').is(':visible')) { $('#modal-add-nzb').modal('show'); } }); $(document).bind('keydown', 'c', function(e) { window.location.href = './config/'; }); $(document).bind('keydown', 's', function(e) { // Update the data self.loadStatusInfo(true, true) // avoid modal clashes if (!$('.modal-dialog').is(':visible')) { $('#modal-options').modal('show'); } }); $(document).bind('keydown', 'shift+left', function(e) { if($("body").hasClass("container-tabbed")) { $('#history-tab.active > ul.pagination li.active').prev().click(); $('#queue-tab.active > ul.pagination li.active').prev().click(); } else { $('#history-tab > ul.pagination li.active').prev().click(); $('#queue-tab > ul.pagination li.active').prev().click(); } e.preventDefault(); }); $(document).bind('keydown', 'shift+right', function(e) { if($("body").hasClass("container-tabbed")) { $('#history-tab.active > ul.pagination li.active').next().click(); $('#queue-tab.active > ul.pagination li.active').next().click(); } else { $('#history-tab > ul.pagination li.active').next().click(); $('#queue-tab > ul.pagination li.active').next().click(); } e.preventDefault(); }); $(document).bind('keydown', 'shift+up', function(e) { if($("body").hasClass("container-tabbed")) { $('#history-tab.active > ul.pagination li').first().click(); $('#queue-tab.active > ul.pagination li').first().click(); } else { $('#history-tab > ul.pagination li').first().click(); $('#queue-tab > ul.pagination li').first().click(); } e.preventDefault(); }); $(document).bind('keydown', 'shift+down', function(e) { if($("body").hasClass("container-tabbed")) { $('#history-tab.active > ul.pagination li').last().click(); $('#queue-tab.active > ul.pagination li').last().click(); } else { $('#history-tab > ul.pagination li').last().click(); $('#queue-tab > ul.pagination li').last().click(); } e.preventDefault(); }); } /*** Date-stuff ***/ moment.locale(displayLang); // Fill the basic info for date-formats with current date-time $('[name="general-date-format"] option').each(function() { $(this).text(displayDateTime('', $(this).val()), '') }) // Update the date every minute setInterval(function() { $('[data-timestamp]').each(function() { $(this).text(displayDateTime($(this).data('timestamp'), self.dateFormat(), 'X')) }) }, 60 * 1000) /*** End of main functions, start of the fun! ***/ // Trigger first refresh self.interval = setTimeout(self.refresh, parseInt(self.refreshRate()) * 1000); // And refresh now! self.refresh() // Special options for (non) mobile if (isMobile) { // Disable accept parameter on file inputs, as it doesn't work on mobile Safari $("input[accept!=''][accept]").attr("accept","") } else { // Activate tooltips $('[data-tooltip="true"]').tooltip({ trigger: 'hover', container: 'body' }) } } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4563572 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/date.min.js0000644000000000000000000014735314625637243025650 0ustar00runnerstaff/** * @overview datejs * @version 1.0.0-rc3 * @author Gregory Wild-Smith * @copyright 2015 Gregory Wild-Smith * @license MIT * @homepage https://github.com/abritinthebay/datejs */ /* 2015 Gregory Wild-Smith @license MIT @homepage https://github.com/abritinthebay/datejs */ (function(){var h=Date,f=Date.CultureStrings?Date.CultureStrings.lang:null,d={},c={getFromKey:function(a,b){var e;e=Date.CultureStrings&&Date.CultureStrings[b]&&Date.CultureStrings[b][a]?Date.CultureStrings[b][a]:c.buildFromDefault(a);"/"===a.charAt(0)&&(e=c.buildFromRegex(a,b));return e},getFromObjectValues:function(a,b){var e,g={};for(e in a)a.hasOwnProperty(e)&&(g[e]=c.getFromKey(a[e],b));return g},getFromObjectKeys:function(a,b){var e,g={};for(e in a)a.hasOwnProperty(e)&&(g[c.getFromKey(e,b)]= a[e]);return g},getFromArray:function(a,b){for(var e=[],g=0;gb?1:0;throw new TypeError(a+" - "+b);};h.equals= function(a,b){return 0===a.compareTo(b)};h.getDayName=function(a){return Date.CultureInfo.dayNames[a]};h.getDayNumberFromName=function(a){var b=Date.CultureInfo.dayNames,e=Date.CultureInfo.abbreviatedDayNames,g=Date.CultureInfo.shortestDayNames;a=a.toLowerCase();for(var m=0;me?!1:!0};h.validateMillisecond=function(a){return c(a,0,999,"millisecond")};h.validateSecond=function(a){return c(a,0,59,"second")};h.validateMinute=function(a){return c(a,0, 59,"minute")};h.validateHour=function(a){return c(a,0,23,"hour")};h.validateDay=function(a,b,e){return void 0===b||null===b||void 0===e||null===e?!1:c(a,1,h.getDaysInMonth(b,e),"day")};h.validateWeek=function(a){return c(a,0,53,"week")};h.validateMonth=function(a){return c(a,0,11,"month")};h.validateYear=function(a){return c(a,-271822,275760,"year")};h.validateTimezone=function(a){return 1==={ACDT:1,ACST:1,ACT:1,ADT:1,AEDT:1,AEST:1,AFT:1,AKDT:1,AKST:1,AMST:1,AMT:1,ART:1,AST:1,AWDT:1,AWST:1,AZOST:1, AZT:1,BDT:1,BIOT:1,BIT:1,BOT:1,BRT:1,BST:1,BTT:1,CAT:1,CCT:1,CDT:1,CEDT:1,CEST:1,CET:1,CHADT:1,CHAST:1,CHOT:1,ChST:1,CHUT:1,CIST:1,CIT:1,CKT:1,CLST:1,CLT:1,COST:1,COT:1,CST:1,CT:1,CVT:1,CWST:1,CXT:1,DAVT:1,DDUT:1,DFT:1,EASST:1,EAST:1,EAT:1,ECT:1,EDT:1,EEDT:1,EEST:1,EET:1,EGST:1,EGT:1,EIT:1,EST:1,FET:1,FJT:1,FKST:1,FKT:1,FNT:1,GALT:1,GAMT:1,GET:1,GFT:1,GILT:1,GIT:1,GMT:1,GST:1,GYT:1,HADT:1,HAEC:1,HAST:1,HKT:1,HMT:1,HOVT:1,HST:1,ICT:1,IDT:1,IOT:1,IRDT:1,IRKT:1,IRST:1,IST:1,JST:1,KGT:1,KOST:1,KRAT:1, KST:1,LHST:1,LINT:1,MAGT:1,MART:1,MAWT:1,MDT:1,MET:1,MEST:1,MHT:1,MIST:1,MIT:1,MMT:1,MSK:1,MST:1,MUT:1,MVT:1,MYT:1,NCT:1,NDT:1,NFT:1,NPT:1,NST:1,NT:1,NUT:1,NZDT:1,NZST:1,OMST:1,ORAT:1,PDT:1,PET:1,PETT:1,PGT:1,PHOT:1,PHT:1,PKT:1,PMDT:1,PMST:1,PONT:1,PST:1,PYST:1,PYT:1,RET:1,ROTT:1,SAKT:1,SAMT:1,SAST:1,SBT:1,SCT:1,SGT:1,SLST:1,SRT:1,SST:1,SYOT:1,TAHT:1,THA:1,TFT:1,TJT:1,TKT:1,TLT:1,TMT:1,TOT:1,TVT:1,UCT:1,ULAT:1,UTC:1,UYST:1,UYT:1,UZT:1,VET:1,VLAT:1,VOLT:1,VOST:1,VUT:1,WAKT:1,WAST:1,WAT:1,WEDT:1,WEST:1, WET:1,WST:1,YAKT:1,YEKT:1,Z:1}[a]};h.validateTimezoneOffset=function(a){return-841a}})(); (function(){var h=Date,f=h.prototype,d=function(a,b){b||(b=2);return("000"+a).slice(-1*b)},c=function(a){var b={},e=this,g,c;c=function(b,g,c){if("day"===b){b=void 0!==a.month?a.month:e.getMonth();var d=void 0!==a.year?a.year:e.getFullYear();return h[g](c,d,b)}return h[g](c)};for(g in a)if(Object.prototype.hasOwnProperty.call(a,g)){var d="validate"+g.charAt(0).toUpperCase()+g.slice(1);h[d]&&null!==a[g]&&c(g,d,a[g])&&(b[g]=a[g])}return b};f.clearTime=function(){this.setHours(0);this.setMinutes(0); this.setSeconds(0);this.setMilliseconds(0);return this};f.setTimeToNow=function(){var a=new Date;this.setHours(a.getHours());this.setMinutes(a.getMinutes());this.setSeconds(a.getSeconds());this.setMilliseconds(a.getMilliseconds());return this};f.clone=function(){return new Date(this.getTime())};f.compareTo=function(a){return Date.compare(this,a)};f.equals=function(a){return Date.equals(this,void 0!==a?a:new Date)};f.between=function(a,b){return this.getTime()>=a.getTime()&&this.getTime()<=b.getTime()}; f.isAfter=function(a){return 1===this.compareTo(a||new Date)};f.isBefore=function(a){return-1===this.compareTo(a||new Date)};f.isToday=f.isSameDay=function(a){return this.clone().clearTime().equals((a||new Date).clone().clearTime())};f.addMilliseconds=function(a){if(!a)return this;this.setTime(this.getTime()+1*a);return this};f.addSeconds=function(a){return a?this.addMilliseconds(1E3*a):this};f.addMinutes=function(a){return a?this.addMilliseconds(6E4*a):this};f.addHours=function(a){return a?this.addMilliseconds(36E5* a):this};f.addDays=function(a){if(!a)return this;this.setDate(this.getDate()+1*a);return this};f.addWeekdays=function(a){if(!a)return this;var b=this.getDay(),e=Math.ceil(Math.abs(a)/7);(0===b||6===b)&&0a){for(;0>a;)this.addDays(-1),b=this.getDay(),0!==b&&6!==b&&a++;return this}if(5 b)this.moveToLastDayOfMonth(),this.is().weekday()&&(b+=1);else return this;return this.addWeekdays(b)}var e=0;if(0a)return a=(a-1E4).toString(),a.charAt(0)+a.substr(2);a=(a+1E4).toString();return"+"+a.substr(1)};f.getElapsed=function(a){return(a||new Date)-this};f.set=function(a){a=c.call(this, a);for(var b in a)if(Object.prototype.hasOwnProperty.call(a,b)){var e=b.charAt(0).toUpperCase()+b.slice(1),g,d;"week"!==b&&"month"!==b&&"timezone"!==b&&"timezoneOffset"!==b&&(e+="s");g="add"+e;d="get"+e;"month"===b?g+="s":"year"===b&&(d="getFullYear");if("day"!==b&&"timezone"!==b&&"timezoneOffset"!==b&&"week"!==b&&"hour"!==b)this[g](a[b]-this[d]());else if("timezone"===b||"timezoneOffset"===b||"week"===b||"hour"===b)this["set"+e](a[b])}a.day&&this.addDays(a.day-this.getDate());return this};f.moveToFirstDayOfMonth= function(){return this.set({day:1})};f.moveToLastDayOfMonth=function(){return this.set({day:h.getDaysInMonth(this.getFullYear(),this.getMonth())})};var b=function(a){switch(1*a){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th"}},e=function(a){var b=Date.CultureInfo.formatPatterns;switch(a){case "d":return this.toString(b.shortDate);case "D":return this.toString(b.longDate);case "F":return this.toString(b.fullDateTime);case "m":return this.toString(b.monthDay); case "r":case "R":return a=this.clone().addMinutes(this.getTimezoneOffset()),a.toString(b.rfc1123)+" GMT";case "s":return this.toString(b.sortableDateTime);case "t":return this.toString(b.shortTime);case "T":return this.toString(b.longTime);case "u":return a=this.clone().addMinutes(this.getTimezoneOffset()),a.toString(b.universalSortableDateTime);case "y":return this.toString(b.yearMonth);default:return!1}},g=function(a){return function(e){if("\\"===e.charAt(0))return e.replace("\\","");switch(e){case "hh":return d(13> a.getHours()?0===a.getHours()?12:a.getHours():a.getHours()-12);case "h":return 13>a.getHours()?0===a.getHours()?12:a.getHours():a.getHours()-12;case "HH":return d(a.getHours());case "H":return a.getHours();case "mm":return d(a.getMinutes());case "m":return a.getMinutes();case "ss":return d(a.getSeconds());case "s":return a.getSeconds();case "yyyy":return d(a.getFullYear(),4);case "yy":return d(a.getFullYear());case "y":return a.getFullYear();case "E":case "dddd":return Date.CultureInfo.dayNames[a.getDay()]; case "ddd":return Date.CultureInfo.abbreviatedDayNames[a.getDay()];case "dd":return d(a.getDate());case "d":return a.getDate();case "MMMM":return Date.CultureInfo.monthNames[a.getMonth()];case "MMM":return Date.CultureInfo.abbreviatedMonthNames[a.getMonth()];case "MM":return d(a.getMonth()+1);case "M":return a.getMonth()+1;case "t":return 12>a.getHours()?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case "tt":return 12>a.getHours()?Date.CultureInfo.amDesignator: Date.CultureInfo.pmDesignator;case "S":return b(a.getDate());case "W":return a.getWeek();case "WW":return a.getISOWeek();case "Q":return"Q"+a.getQuarter();case "q":return String(a.getQuarter());case "z":return a.getTimezone();case "Z":case "X":return Date.getTimezoneOffset(a.getTimezone());case "ZZ":return-60*a.getTimezoneOffset();case "u":return a.getDay();case "L":return h.isLeapYear(a.getFullYear())?1:0;case "B":return"@"+(a.getUTCSeconds()+60*a.getUTCMinutes()+3600*(a.getUTCHours()+1))/86.4;default:return e}}}; f.toString=function(a,b){if(!b&&a&&1===a.length&&(output=e.call(this,a)))return output;var c=g(this);return a?a.replace(/((\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S|q|Q|WW?W?W?)(?![^\[]*\]))/g,c).replace(/\[|\]/g,""):this._toString()}})(); (function(){var h=Date,f=h.prototype,d=Number.prototype;f._orient=1;f._nth=null;f._is=!1;f._same=!1;f._isSecond=!1;d._dateElement="days";f.next=function(){this._move=!0;this._orient=1;return this};h.next=function(){return h.today().next()};f.last=f.prev=f.previous=function(){this._move=!0;this._orient=-1;return this};h.last=h.prev=h.previous=function(){return h.today().last()};f.is=function(){this._is=!0;return this};f.same=function(){this._same=!0;this._isSecond=!1;return this};f.today=function(){return this.same().day()}; f.weekday=function(){return this._nth?m("Weekday").call(this):this._move?this.addWeekdays(this._orient):this._is?(this._is=!1,!this.is().sat()&&!this.is().sun()):!1};f.weekend=function(){return this._is?(this._is=!1,this.is().sat()||this.is().sun()):!1};f.at=function(a){return"string"===typeof a?h.parse(this.toString("d")+" "+a):this.set(a)};d.fromNow=d.after=function(a){var b={};b[this._dateElement]=this;return(a?a.clone():new Date).add(b)};d.ago=d.before=function(a){var b={};b["s"!==this._dateElement[this._dateElement.length- 1]?this._dateElement+"s":this._dateElement]=-1*this;return(a?a.clone():new Date).add(b)};var c="sunday monday tuesday wednesday thursday friday saturday".split(/\s/),a="january february march april may june july august september october november december".split(/\s/),b="Millisecond Second Minute Hour Day Week Month Year Quarter Weekday".split(/\s/),e="Milliseconds Seconds Minutes Hours Date Week Month FullYear Quarter".split(/\s/),g="final first second third fourth fifth".split(/\s/);f.toObject=function(){for(var a= {},g=0;ge)throw new RangeError(h.getDayName(a)+ " does not occur "+b+" times in the month of "+h.getMonthName(e.getMonth())+" "+e.getFullYear()+".");return this}return this.moveToDayOfWeek(a,this._orient)}},k=function(a,b,e){for(var g=0;ga.length&&0>a.indexOf(".")&&0>a.indexOf("/"))return e.year= a,h.processTimeObject(e);a=a.match(this.regex);if(!a||!a.length)return null;for(b=0;bp;p++){var q=c.shift();q&&(delete e[q],g--)}try{f=e[l]=e[l]||a.call(this,l)}catch(s){f=e[l]=s}g++;c.push(l);if(f instanceof h.Exception)throw f;return f}},any:function(){var a=arguments;return function(e){for(var g=null,c=0;cthis.hour&&Date.Config.strict24hr)throw"Invalid hour and meridian combination";"p"===this.meridian&&12>this.hour?this.hour+=12:"a"===this.meridian&&12===this.hour&&(this.hour= 0)}};h.Translator={hour:function(c){return function(){this.hour=Number(c)}},minute:function(c){return function(){this.minute=Number(c)}},second:function(c){return function(){this.second=Number(c)}},secondAndMillisecond:function(c){return function(){var a=c.match(/^([0-5][0-9])\.([0-9]{1,3})/);this.second=Number(a[1]);this.millisecond=Number(a[2])}},meridian:function(c){return function(){this.meridian=c.slice(0,1).toLowerCase()}},timezone:function(c){return function(){var a=c.replace(/[^\d\+\-]/g, "");a.length?this.timezoneOffset=Number(a):this.timezone=c.toLowerCase()}},day:function(c){var a=c[0];return function(){this.day=Number(a.match(/\d+/)[0]);if(1>this.day)throw"invalid day";}},month:function(c){return function(){this.month=3===c.length?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(c)/4:Number(c)-1;if(0>this.month)throw"invalid month";}},year:function(c){return function(){var a=Number(c);this.year=2h.getDaysInMonth(this.year,this.month))throw new RangeError(this.day+" is not a valid value for days.");c=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.millisecond);100>this.year&&c.setFullYear(this.year);this.timezone?c.set({timezone:this.timezone}):this.timezoneOffset&&c.set({timezoneOffset:this.timezoneOffset});return c},finish:function(c){var a,b,e;c=c instanceof Array?f(c):[c];if(0===c.length)return null; for(a=0;ac?-1:1,k=Math.abs(c);this.setDays(Math.floor(k/864E5)*h);k%=864E5;this.setHours(Math.floor(k/36E5)*h);k%=36E5;this.setMinutes(Math.floor(k/6E4)*h);k%=6E4;this.setSeconds(Math.floor(k/1E3)*h);this.setMilliseconds(k%1E3*h)}else this.set(c,a,b,e,f);this.getTotalMilliseconds=function(){return 864E5*this.getDays()+ 36E5*this.getHours()+6E4*this.getMinutes()+1E3*this.getSeconds()};this.compareTo=function(a){var b=new Date(1970,1,1,this.getHours(),this.getMinutes(),this.getSeconds());a=null===a?new Date(1970,1,1,0,0,0):new Date(1970,1,1,a.getHours(),a.getMinutes(),a.getSeconds());return ba?1:0};this.equals=function(a){return 0===this.compareTo(a)};this.add=function(a){return null===a?this:this.addSeconds(a.getTotalMilliseconds()/1E3)};this.subtract=function(a){return null===a?this:this.addSeconds(-a.getTotalMilliseconds()/ 1E3)};this.addDays=function(a){return new d(this.getTotalMilliseconds()+864E5*a)};this.addHours=function(a){return new d(this.getTotalMilliseconds()+36E5*a)};this.addMinutes=function(a){return new d(this.getTotalMilliseconds()+6E4*a)};this.addSeconds=function(a){return new d(this.getTotalMilliseconds()+1E3*a)};this.addMilliseconds=function(a){return new d(this.getTotalMilliseconds()+a)};this.get12HourHour=function(){return 12this.getHours()?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator};this.toString=function(a){this._toString=function(){return null!==this.getDays()&&0a.toString().length?"0"+a:a};var b=this;return a?a.replace(/dd?|HH?|hh?|mm?|ss?|tt?/g, function(a){switch(a){case "d":return b.getDays();case "dd":return b.p(b.getDays());case "H":return b.getHours();case "HH":return b.p(b.getHours());case "h":return b.get12HourHour();case "hh":return b.p(b.get12HourHour());case "m":return b.getMinutes();case "mm":return b.p(b.getMinutes());case "s":return b.getSeconds();case "ss":return b.p(b.getSeconds());case "t":return(12>b.getHours()?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator).substring(0,1);case "tt":return 12>b.getHours()?Date.CultureInfo.amDesignator: Date.CultureInfo.pmDesignator}}):this._toString()};return this};(function(c,a){for(var b=0;bc;)f();else for(;bp?1:-1;this.dates={start:arguments[0].clone(),end:arguments[1].clone()};d(q,l,p,this);var s=!1===(l.isDaylightSavingTime()===p.isDaylightSavingTime());s&&1===q?l.addHours(-1):s&&l.addHours(1);l=p-l;0!==l&&(l=new TimeSpan(l),this.set(this.years,this.months,l.getDays(),l.getHours(),l.getMinutes(),l.getSeconds(),l.getMilliseconds()))}return this};(function(a,b){for(var c=0;c 1) { // ... concatenate both arrays. exclusion[key] = exclusion[key].concat(values); } else { // ... append the current single value. exclusion[key].push(value); } } // We saw that keyword only once before else { // Put both the current value and the new // value in an array exclusion[key] = [exclusion[key]]; exclusion[key].push(value); } } // First time we see that keyword else { // ...and got several values this time... if (values.length > 1) { // ...add all values seen. exclusion[key] = values; } // Got only a single value this time else { // Record its value as a string if (options.alwaysArray) { // ...but we always return an array if option alwaysArray is true exclusion[key] = [value]; } else { // Record its value as a string exclusion[key] = value; } } } } else { // If we already have seen that keyword... if (query[key]) { // ...many times... if (query[key] instanceof Array) { // ...and got several values this time... if (values.length > 1) { // ... concatenate both arrays. query[key] = query[key].concat(values); } else { // ... append the current single value. query[key].push(value); } } // We saw that keyword only once before else { // Put both the current value and the new // value in an array query[key] = [query[key]]; query[key].push(value); } } // First time we see that keyword else { // ...and got several values this time... if (values.length > 1) { // ...add all values seen. query[key] = values; } // Got only a single value this time else { if (options.alwaysArray) { // ...but we always return an array if option alwaysArray is true query[key] = [value]; } else { // Record its value as a string query[key] = value; } } } } } } // The key allows a range else if (isRange) { // When offsets is true, push a new offset if (options.offsets) { query.offsets.push(term); } var value = term.value; // Range are separated with a dash var rangeValues = value.split('-'); // When both end of the range are specified // keyword:XXXX-YYYY query[key] = {}; if (2 === rangeValues.length) { query[key].from = rangeValues[0]; query[key].to = rangeValues[1]; } // When pairs of ranges are specified // keyword:XXXX-YYYY,AAAA-BBBB else if (!rangeValues.length % 2) { } // When only getting a single value, // or an odd number of values else { query[key].from = value; } } else { // We add it as pure text var text = term.keyword + ':' + term.value; query.text.push(text); // When offsets is true, push a new offset if (options.offsets) { query.offsets.push({ text: text, offsetStart: term.offsetStart, offsetEnd: term.offsetEnd }); } } } } // Concatenate all text terms if any if (query.text.length) { if (!options.tokenize) { query.text = query.text.join(' ').trim(); } } // Just remove the attribute text when it's empty else { delete query.text; } // Return forged query object query.exclude = exclusion; return query; } } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4565127 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/jquery.hotkeys.min.js0000644000000000000000000000434214625637243027725 0ustar00runnerstaff/* * jQuery Hotkeys Plugin * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * * Based upon the plugin by Tzury Bar Yochay: * https://github.com/tzuryby/jquery.hotkeys * * Original idea by: * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ */ !function(c){function e(e){var o,f;"string"==typeof e.data&&(e.data={keys:e.data}),e.data&&e.data.keys&&"string"==typeof e.data.keys&&(o=e.handler,f=e.data.keys.toLowerCase().split(" "),e.handler=function(a){if(this===a.target||!(/textarea|select/i.test(a.target.nodeName)||c.hotkeys.options.filterTextInputs&&-1","/":"?","\\":"|"},textAcceptingInputTypes:["text","password","number","email","url","range","date","month","week","time","datetime","datetime-local","search","color","tel"],options:{filterTextInputs:!0}},c.each(["keydown","keyup","keypress"],function(){c.event.special[this]={add:e}})}(jQuery||this.jQuery||window.jQuery);././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4566085 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/knockout-3.5.1.min.js0000644000000000000000000020523014625637243027217 0ustar00runnerstaff/*! * Knockout JavaScript library v3.5.1 * (c) The Knockout.js team - http://knockoutjs.com/ * License: MIT (http://www.opensource.org/licenses/mit-license.php) */ (function() {(function(n){var A=this||(0,eval)("this"),w=A.document,R=A.navigator,v=A.jQuery,H=A.JSON;v||"undefined"===typeof jQuery||(v=jQuery);(function(n){"function"===typeof define&&define.amd?define(["exports","require"],n):"object"===typeof exports&&"object"===typeof module?n(module.exports||exports):n(A.ko={})})(function(S,T){function K(a,c){return null===a||typeof a in W?a===c:!1}function X(b,c){var d;return function(){d||(d=a.a.setTimeout(function(){d=n;b()},c))}}function Y(b,c){var d;return function(){clearTimeout(d); d=a.a.setTimeout(b,c)}}function Z(a,c){c&&"change"!==c?"beforeChange"===c?this.pc(a):this.gb(a,c):this.qc(a)}function aa(a,c){null!==c&&c.s&&c.s()}function ba(a,c){var d=this.qd,e=d[r];e.ra||(this.Qb&&this.mb[c]?(d.uc(c,a,this.mb[c]),this.mb[c]=null,--this.Qb):e.I[c]||d.uc(c,a,e.J?{da:a}:d.$c(a)),a.Ja&&a.gd())}var a="undefined"!==typeof S?S:{};a.b=function(b,c){for(var d=b.split("."),e=a,f=0;fa.a.A(c,b)&&c.push(b)});return c},Mb:function(a, b,c){var d=[];if(a)for(var e=0,l=a.length;ee?d&&b.push(c):d||b.splice(e,1)},Ba:g,extend:c,setPrototypeOf:d,Ab:g?d:c,P:b,Ga:function(a,b,c){if(!a)return a;var d={},e;for(e in a)f.call(a,e)&&(d[e]= b.call(c,a[e],e,a));return d},Tb:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},Yb:function(b){b=a.a.la(b);for(var c=(b[0]&&b[0].ownerDocument||w).createElement("div"),d=0,e=b.length;dp?a.setAttribute("selected",b):a.selected=b},Db:function(a){return null===a||a===n?"":a.trim? a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},Ud:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},vd:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(1!==a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;return!!a},Sb:function(b){return a.a.vd(b,b.ownerDocument.documentElement)},kd:function(b){return!!a.a.Lb(b,a.a.Sb)},R:function(a){return a&& a.tagName&&a.tagName.toLowerCase()},Ac:function(b){return a.onError?function(){try{return b.apply(this,arguments)}catch(c){throw a.onError&&a.onError(c),c;}}:b},setTimeout:function(b,c){return setTimeout(a.a.Ac(b),c)},Gc:function(b){setTimeout(function(){a.onError&&a.onError(b);throw b;},0)},B:function(b,c,d){var e=a.a.Ac(d);d=l[c];if(a.options.useOnlyNativeEvents||d||!v)if(d||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var k=function(a){e.call(b,a)},f="on"+c;b.attachEvent(f, k);a.a.K.za(b,function(){b.detachEvent(f,k)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,e,!1);else t||(t="function"==typeof v(b).on?"on":"bind"),v(b)[t](c,e)},Fb:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===a.a.R(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==d||"radio"==d):d=!1;if(a.options.useOnlyNativeEvents||!v||d)if("function"==typeof w.createEvent)if("function"== typeof b.dispatchEvent)d=w.createEvent(k[c]||"HTMLEvents"),d.initEvent(c,!0,!0,A,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");else v(b).trigger(c)},f:function(b){return a.O(b)?b():b},bc:function(b){return a.O(b)?b.v():b},Eb:function(b,c,d){var l;c&&("object"===typeof b.classList? (l=b.classList[d?"add":"remove"],a.a.D(c.match(q),function(a){l.call(b.classList,a)})):"string"===typeof b.className.baseVal?e(b.className,"baseVal",c,d):e(b,"className",c,d))},Bb:function(b,c){var d=a.a.f(c);if(null===d||d===n)d="";var e=a.h.firstChild(b);!e||3!=e.nodeType||a.h.nextSibling(e)?a.h.va(b,[b.ownerDocument.createTextNode(d)]):e.data=d;a.a.Ad(b)},Yc:function(a,b){a.name=b;if(7>=p)try{var c=a.name.replace(/[&<>'"]/g,function(a){return"&#"+a.charCodeAt(0)+";"});a.mergeAttributes(w.createElement(""),!1)}catch(d){}},Ad:function(a){9<=p&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},wd:function(a){if(p){var b=a.style.width;a.style.width=0;a.style.width=b}},Pd:function(b,c){b=a.a.f(b);c=a.a.f(c);for(var d=[],e=b;e<=c;e++)d.push(e);return d},la:function(a){for(var b=[],c=0,d=a.length;c",""],d=[3,"","
"],e=[1,""],f={thead:c,tbody:c,tfoot:c,tr:[2,"","
"],td:d,th:d,option:e,optgroup:e},g=8>=a.a.W;a.a.ua=function(c,d){var e;if(v)if(v.parseHTML)e=v.parseHTML(c,d)||[];else{if((e=v.clean([c],d))&&e[0]){for(var l=e[0];l.parentNode&&11!==l.parentNode.nodeType;)l=l.parentNode; l.parentNode&&l.parentNode.removeChild(l)}}else{(e=d)||(e=w);var l=e.parentWindow||e.defaultView||A,p=a.a.Db(c).toLowerCase(),q=e.createElement("div"),t;t=(p=p.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&f[p[1]]||b;p=t[0];t="ignored
"+t[1]+c+t[2]+"
";"function"==typeof l.innerShiv?q.appendChild(l.innerShiv(t)):(g&&e.body.appendChild(q),q.innerHTML=t,g&&q.parentNode.removeChild(q));for(;p--;)q=q.lastChild;e=a.a.la(q.lastChild.childNodes)}return e};a.a.Md=function(b,c){var d=a.a.ua(b, c);return d.length&&d[0].parentElement||a.a.Yb(d)};a.a.fc=function(b,c){a.a.Tb(b);c=a.a.f(c);if(null!==c&&c!==n)if("string"!=typeof c&&(c=c.toString()),v)v(b).html(c);else for(var d=a.a.ua(c,b.ownerDocument),e=0;eb){if(5E3<= ++c){h=f;a.a.Gc(Error("'Too much recursion' after processing "+c+" task groups."));break}b=f}try{d()}catch(p){a.a.Gc(p)}}}function c(){b();h=f=e.length=0}var d,e=[],f=0,g=1,h=0;A.MutationObserver?d=function(a){var b=w.createElement("div");(new MutationObserver(a)).observe(b,{attributes:!0});return function(){b.classList.toggle("foo")}}(c):d=w&&"onreadystatechange"in w.createElement("script")?function(a){var b=w.createElement("script");b.onreadystatechange=function(){b.onreadystatechange=null;w.documentElement.removeChild(b); b=null;a()};w.documentElement.appendChild(b)}:function(a){setTimeout(a,0)};return{scheduler:d,zb:function(b){f||a.na.scheduler(c);e[f++]=b;return g++},cancel:function(a){a=a-(g-f);a>=h&&ad[0]?p+d[0]: d[0]),p);for(var p=1===g?p:Math.min(c+(d[1]||0),p),g=c+g-2,h=Math.max(p,g),U=[],L=[],n=2;cc;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.ad(b);return a.a.hc(b,c,d)};d.prototype={constructor:d,save:function(b,c){var d=a.a.A(this.keys, b);0<=d?this.values[d]=c:(this.keys.push(b),this.values.push(c))},get:function(b){b=a.a.A(this.keys,b);return 0<=b?this.values[b]:n}}})();a.b("toJS",a.ad);a.b("toJSON",a.toJSON);a.Wd=function(b,c,d){function e(c){var e=a.xb(b,d).extend({ma:"always"}),h=e.subscribe(function(a){a&&(h.s(),c(a))});e.notifySubscribers(e.v());return h}return"function"!==typeof Promise||c?e(c.bind(d)):new Promise(e)};a.b("when",a.Wd);(function(){a.w={M:function(b){switch(a.a.R(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__? a.a.g.get(b,a.c.options.$b):7>=a.a.W?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.w.M(b.options[b.selectedIndex]):n;default:return b.value}},cb:function(b,c,d){switch(a.a.R(b)){case "option":"string"===typeof c?(a.a.g.set(b,a.c.options.$b,n),"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__,b.value=c):(a.a.g.set(b,a.c.options.$b,c),b.__ko__hasDomDataOptionValue__=!0,b.value="number"=== typeof c?c:"");break;case "select":if(""===c||null===c)c=n;for(var e=-1,f=0,g=b.options.length,h;f=h){c.push(p&&q.length?{key:p,value:q.join("")}:{unknown:p||q.join("")});p=h=0;q=[];continue}}else if(58===u){if(!h&&!p&&1===q.length){p=q.pop();continue}}else if(47===u&&1arguments.length){if(b=w.body,!b)throw Error("ko.applyBindings: could not find document.body; has the document been loaded?"); }else if(!b||1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");k(q(a,c),b)};a.Dc=function(b){return!b||1!==b.nodeType&&8!==b.nodeType?n:a.Td(b)};a.Ec=function(b){return(b=a.Dc(b))?b.$data:n};a.b("bindingHandlers",a.c);a.b("bindingEvent",a.i);a.b("bindingEvent.subscribe",a.i.subscribe);a.b("bindingEvent.startPossiblyAsyncContentBinding",a.i.Cb);a.b("applyBindings",a.vc);a.b("applyBindingsToDescendants",a.Oa); a.b("applyBindingAccessorsToNode",a.ib);a.b("applyBindingsToNode",a.ld);a.b("contextFor",a.Dc);a.b("dataFor",a.Ec)})();(function(b){function c(c,e){var k=Object.prototype.hasOwnProperty.call(f,c)?f[c]:b,l;k?k.subscribe(e):(k=f[c]=new a.T,k.subscribe(e),d(c,function(b,d){var e=!(!d||!d.synchronous);g[c]={definition:b,Gd:e};delete f[c];l||e?k.notifySubscribers(b):a.na.zb(function(){k.notifySubscribers(b)})}),l=!0)}function d(a,b){e("getConfig",[a],function(c){c?e("loadComponent",[a,c],function(a){b(a, c)}):b(null,null)})}function e(c,d,f,l){l||(l=a.j.loaders.slice(0));var g=l.shift();if(g){var q=g[c];if(q){var t=!1;if(q.apply(g,d.concat(function(a){t?f(null):null!==a?f(a):e(c,d,f,l)}))!==b&&(t=!0,!g.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.");}else e(c,d,f,l)}else f(null)}var f={},g={};a.j={get:function(d,e){var f=Object.prototype.hasOwnProperty.call(g,d)?g[d]:b;f?f.Gd?a.u.G(function(){e(f.definition)}): a.na.zb(function(){e(f.definition)}):c(d,e)},Bc:function(a){delete g[a]},oc:e};a.j.loaders=[];a.b("components",a.j);a.b("components.get",a.j.get);a.b("components.clearCachedDefinition",a.j.Bc)})();(function(){function b(b,c,d,e){function g(){0===--B&&e(h)}var h={},B=2,u=d.template;d=d.viewModel;u?f(c,u,function(c){a.j.oc("loadTemplate",[b,c],function(a){h.template=a;g()})}):g();d?f(c,d,function(c){a.j.oc("loadViewModel",[b,c],function(a){h[m]=a;g()})}):g()}function c(a,b,d){if("function"===typeof b)d(function(a){return new b(a)}); else if("function"===typeof b[m])d(b[m]);else if("instance"in b){var e=b.instance;d(function(){return e})}else"viewModel"in b?c(a,b.viewModel,d):a("Unknown viewModel value: "+b)}function d(b){switch(a.a.R(b)){case "script":return a.a.ua(b.text);case "textarea":return a.a.ua(b.value);case "template":if(e(b.content))return a.a.Ca(b.content.childNodes)}return a.a.Ca(b.childNodes)}function e(a){return A.DocumentFragment?a instanceof DocumentFragment:a&&11===a.nodeType}function f(a,b,c){"string"===typeof b.require? T||A.require?(T||A.require)([b.require],function(a){a&&"object"===typeof a&&a.Xd&&a["default"]&&(a=a["default"]);c(a)}):a("Uses require, but no AMD loader is present"):c(b)}function g(a){return function(b){throw Error("Component '"+a+"': "+b);}}var h={};a.j.register=function(b,c){if(!c)throw Error("Invalid configuration for "+b);if(a.j.tb(b))throw Error("Component "+b+" is already registered");h[b]=c};a.j.tb=function(a){return Object.prototype.hasOwnProperty.call(h,a)};a.j.unregister=function(b){delete h[b]; a.j.Bc(b)};a.j.Fc={getConfig:function(b,c){c(a.j.tb(b)?h[b]:null)},loadComponent:function(a,c,d){var e=g(a);f(e,c,function(c){b(a,e,c,d)})},loadTemplate:function(b,c,f){b=g(b);if("string"===typeof c)f(a.a.ua(c));else if(c instanceof Array)f(c);else if(e(c))f(a.a.la(c.childNodes));else if(c.element)if(c=c.element,A.HTMLElement?c instanceof HTMLElement:c&&c.tagName&&1===c.nodeType)f(d(c));else if("string"===typeof c){var h=w.getElementById(c);h?f(d(h)):b("Cannot find element with ID "+c)}else b("Unknown element type: "+ c);else b("Unknown template value: "+c)},loadViewModel:function(a,b,d){c(g(a),b,d)}};var m="createViewModel";a.b("components.register",a.j.register);a.b("components.isRegistered",a.j.tb);a.b("components.unregister",a.j.unregister);a.b("components.defaultLoader",a.j.Fc);a.j.loaders.push(a.j.Fc);a.j.dd=h})();(function(){function b(b,e){var f=b.getAttribute("params");if(f){var f=c.parseBindingsString(f,e,b,{valueAccessors:!0,bindingParams:!0}),f=a.a.Ga(f,function(c){return a.o(c,null,{l:b})}),g=a.a.Ga(f, function(c){var e=c.v();return c.ja()?a.o({read:function(){return a.a.f(c())},write:a.Za(e)&&function(a){c()(a)},l:b}):e});Object.prototype.hasOwnProperty.call(g,"$raw")||(g.$raw=f);return g}return{$raw:{}}}a.j.getComponentNameForNode=function(b){var c=a.a.R(b);if(a.j.tb(c)&&(-1!=c.indexOf("-")||"[object HTMLUnknownElement]"==""+b||8>=a.a.W&&b.tagName===c))return c};a.j.tc=function(c,e,f,g){if(1===e.nodeType){var h=a.j.getComponentNameForNode(e);if(h){c=c||{};if(c.component)throw Error('Cannot use the "component" binding on a custom element matching a component'); var m={name:h,params:b(e,f)};c.component=g?function(){return m}:m}}return c};var c=new a.ga;9>a.a.W&&(a.j.register=function(a){return function(b){return a.apply(this,arguments)}}(a.j.register),w.createDocumentFragment=function(b){return function(){var c=b(),f=a.j.dd,g;for(g in f);return c}}(w.createDocumentFragment))})();(function(){function b(b,c,d){c=c.template;if(!c)throw Error("Component '"+b+"' has no template");b=a.a.Ca(c);a.h.va(d,b)}function c(a,b,c){var d=a.createViewModel;return d?d.call(a, b,c):b}var d=0;a.c.component={init:function(e,f,g,h,m){function k(){var a=l&&l.dispose;"function"===typeof a&&a.call(l);q&&q.s();p=l=q=null}var l,p,q,t=a.a.la(a.h.childNodes(e));a.h.Ea(e);a.a.K.za(e,k);a.o(function(){var g=a.a.f(f()),h,u;"string"===typeof g?h=g:(h=a.a.f(g.name),u=a.a.f(g.params));if(!h)throw Error("No component name specified");var n=a.i.Cb(e,m),z=p=++d;a.j.get(h,function(d){if(p===z){k();if(!d)throw Error("Unknown component '"+h+"'");b(h,d,e);var f=c(d,u,{element:e,templateNodes:t}); d=n.createChildContext(f,{extend:function(a){a.$component=f;a.$componentTemplateNodes=t}});f&&f.koDescendantsComplete&&(q=a.i.subscribe(e,a.i.pa,f.koDescendantsComplete,f));l=f;a.Oa(d,e)}})},null,{l:e});return{controlsDescendantBindings:!0}}};a.h.ea.component=!0})();var V={"class":"className","for":"htmlFor"};a.c.attr={update:function(b,c){var d=a.a.f(c())||{};a.a.P(d,function(c,d){d=a.a.f(d);var g=c.indexOf(":"),g="lookupNamespaceURI"in b&&0=a.a.W&&c in V?(c=V[c],h?b.removeAttribute(c):b[c]=d):h||(g?b.setAttributeNS(g,c,d):b.setAttribute(c,d));"name"===c&&a.a.Yc(b,h?"":d)})}};(function(){a.c.checked={after:["value","attr"],init:function(b,c,d){function e(){var e=b.checked,f=g();if(!a.S.Ya()&&(e||!m&&!a.S.qa())){var k=a.u.G(c);if(l){var q=p?k.v():k,z=t;t=f;z!==f?e&&(a.a.Na(q,f,!0),a.a.Na(q,z,!1)):a.a.Na(q,f,e);p&&a.Za(k)&&k(q)}else h&&(f===n?f=e:e||(f=n)),a.m.eb(k, d,"checked",f,!0)}}function f(){var d=a.a.f(c()),e=g();l?(b.checked=0<=a.a.A(d,e),t=e):b.checked=h&&e===n?!!d:g()===d}var g=a.xb(function(){if(d.has("checkedValue"))return a.a.f(d.get("checkedValue"));if(q)return d.has("value")?a.a.f(d.get("value")):b.value}),h="checkbox"==b.type,m="radio"==b.type;if(h||m){var k=c(),l=h&&a.a.f(k)instanceof Array,p=!(l&&k.push&&k.splice),q=m||l,t=l?g():n;m&&!b.name&&a.c.uniqueName.init(b,function(){return!0});a.o(e,null,{l:b});a.a.B(b,"click",e);a.o(f,null,{l:b}); k=n}}};a.m.wa.checked=!0;a.c.checkedValue={update:function(b,c){b.value=a.a.f(c())}}})();a.c["class"]={update:function(b,c){var d=a.a.Db(a.a.f(c()));a.a.Eb(b,b.__ko__cssValue,!1);b.__ko__cssValue=d;a.a.Eb(b,d,!0)}};a.c.css={update:function(b,c){var d=a.a.f(c());null!==d&&"object"==typeof d?a.a.P(d,function(c,d){d=a.a.f(d);a.a.Eb(b,c,d)}):a.c["class"].update(b,c)}};a.c.enable={update:function(b,c){var d=a.a.f(c());d&&b.disabled?b.removeAttribute("disabled"):d||b.disabled||(b.disabled=!0)}};a.c.disable= {update:function(b,c){a.c.enable.update(b,function(){return!a.a.f(c())})}};a.c.event={init:function(b,c,d,e,f){var g=c()||{};a.a.P(g,function(g){"string"==typeof g&&a.a.B(b,g,function(b){var k,l=c()[g];if(l){try{var p=a.a.la(arguments);e=f.$data;p.unshift(e);k=l.apply(e,p)}finally{!0!==k&&(b.preventDefault?b.preventDefault():b.returnValue=!1)}!1===d.get(g+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.c.foreach={Rc:function(b){return function(){var c=b(),d=a.a.bc(c); if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.ba.Ma};a.a.f(c);return{foreach:d.data,as:d.as,noChildContext:d.noChildContext,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.ba.Ma}}},init:function(b,c){return a.c.template.init(b,a.c.foreach.Rc(c))},update:function(b,c,d,e,f){return a.c.template.update(b,a.c.foreach.Rc(c),d,e,f)}};a.m.Ra.foreach=!1;a.h.ea.foreach= !0;a.c.hasfocus={init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var f=b.ownerDocument;if("activeElement"in f){var g;try{g=f.activeElement}catch(l){g=f.body}e=g===b}f=c();a.m.eb(f,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var f=e.bind(null,!0),g=e.bind(null,!1);a.a.B(b,"focus",f);a.a.B(b,"focusin",f);a.a.B(b,"blur",g);a.a.B(b,"focusout",g);b.__ko_hasfocusLastValue=!1},update:function(b,c){var d=!!a.a.f(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue=== d||(d?b.focus():b.blur(),!d&&b.__ko_hasfocusLastValue&&b.ownerDocument.body.focus(),a.u.G(a.a.Fb,null,[b,d?"focusin":"focusout"]))}};a.m.wa.hasfocus=!0;a.c.hasFocus=a.c.hasfocus;a.m.wa.hasFocus="hasfocus";a.c.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.fc(b,c())}};(function(){function b(b,d,e){a.c[b]={init:function(b,c,h,m,k){var l,p,q={},t,x,n;if(d){m=h.get("as");var u=h.get("noChildContext");n=!(m&&u);q={as:m,noChildContext:u,exportDependencies:n}}x=(t= "render"==h.get("completeOn"))||h.has(a.i.pa);a.o(function(){var h=a.a.f(c()),m=!e!==!h,u=!p,r;if(n||m!==l){x&&(k=a.i.Cb(b,k));if(m){if(!d||n)q.dataDependency=a.S.o();r=d?k.createChildContext("function"==typeof h?h:c,q):a.S.qa()?k.extend(null,q):k}u&&a.S.qa()&&(p=a.a.Ca(a.h.childNodes(b),!0));m?(u||a.h.va(b,a.a.Ca(p)),a.Oa(r,b)):(a.h.Ea(b),t||a.i.ma(b,a.i.H));l=m}},null,{l:b});return{controlsDescendantBindings:!0}}};a.m.Ra[b]=!1;a.h.ea[b]=!0}b("if");b("ifnot",!1,!0);b("with",!0)})();a.c.let={init:function(b, c,d,e,f){c=f.extend(c);a.Oa(c,b);return{controlsDescendantBindings:!0}}};a.h.ea.let=!0;var Q={};a.c.options={init:function(b){if("select"!==a.a.R(b))throw Error("options binding applies only to SELECT elements");for(;0g)var m=a.a.g.Z(),k=a.a.g.Z(),l=function(b){var c=this.activeElement;(c=c&&a.a.g.get(c,k))&&c(b)},p=function(b,c){var d=b.ownerDocument;a.a.g.get(d,m)||(a.a.g.set(d,m,!0),a.a.B(d,"selectionchange",l));a.a.g.set(b,k,c)};a.c.textInput={init:function(b,c,k){function l(c,d){a.a.B(b,c,d)}function m(){var d=a.a.f(c());if(null===d||d===n)d="";L!==n&&d===L?a.a.setTimeout(m,4):b.value!==d&&(y=!0,b.value=d,y=!1,v=b.value)}function r(){w||(L=b.value,w=a.a.setTimeout(z, 4))}function z(){clearTimeout(w);L=w=n;var d=b.value;v!==d&&(v=d,a.m.eb(c(),k,"textInput",d))}var v=b.value,w,L,A=9==a.a.W?r:z,y=!1;g&&l("keypress",z);11>g&&l("propertychange",function(a){y||"value"!==a.propertyName||A(a)});8==g&&(l("keyup",z),l("keydown",z));p&&(p(b,A),l("dragend",r));(!g||9<=g)&&l("input",A);5>e&&"textarea"===a.a.R(b)?(l("keydown",r),l("paste",r),l("cut",r)):11>d?l("keydown",r):4>f?(l("DOMAutoComplete",z),l("dragdrop",z),l("drop",z)):h&&"number"===b.type&&l("keydown",r);l("change", z);l("blur",z);a.o(m,null,{l:b})}};a.m.wa.textInput=!0;a.c.textinput={preprocess:function(a,b,c){c("textInput",a)}}})();a.c.uniqueName={init:function(b,c){if(c()){var d="ko_unique_"+ ++a.c.uniqueName.rd;a.a.Yc(b,d)}}};a.c.uniqueName.rd=0;a.c.using={init:function(b,c,d,e,f){var g;d.has("as")&&(g={as:d.get("as"),noChildContext:d.get("noChildContext")});c=f.createChildContext(c,g);a.Oa(c,b);return{controlsDescendantBindings:!0}}};a.h.ea.using=!0;a.c.value={init:function(b,c,d){var e=a.a.R(b),f="input"== e;if(!f||"checkbox"!=b.type&&"radio"!=b.type){var g=[],h=d.get("valueUpdate"),m=!1,k=null;h&&("string"==typeof h?g=[h]:g=a.a.wc(h),a.a.Pa(g,"change"));var l=function(){k=null;m=!1;var e=c(),f=a.w.M(b);a.m.eb(e,d,"value",f)};!a.a.W||!f||"text"!=b.type||"off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.A(g,"propertychange")||(a.a.B(b,"propertychange",function(){m=!0}),a.a.B(b,"focus",function(){m=!1}),a.a.B(b,"blur",function(){m&&l()}));a.a.D(g,function(c){var d=l;a.a.Ud(c,"after")&& (d=function(){k=a.w.M(b);a.a.setTimeout(l,0)},c=c.substring(5));a.a.B(b,c,d)});var p;p=f&&"file"==b.type?function(){var d=a.a.f(c());null===d||d===n||""===d?b.value="":a.u.G(l)}:function(){var f=a.a.f(c()),g=a.w.M(b);if(null!==k&&f===k)a.a.setTimeout(p,0);else if(f!==g||g===n)"select"===e?(g=d.get("valueAllowUnset"),a.w.cb(b,f,g),g||f===a.w.M(b)||a.u.G(l)):a.w.cb(b,f)};if("select"===e){var q;a.i.subscribe(b,a.i.H,function(){q?d.get("valueAllowUnset")?p():l():(a.a.B(b,"change",l),q=a.o(p,null,{l:b}))}, null,{notifyImmediately:!0})}else a.a.B(b,"change",l),a.o(p,null,{l:b})}else a.ib(b,{checkedValue:c})},update:function(){}};a.m.wa.value=!0;a.c.visible={update:function(b,c){var d=a.a.f(c()),e="none"!=b.style.display;d&&!e?b.style.display="":!d&&e&&(b.style.display="none")}};a.c.hidden={update:function(b,c){a.c.visible.update(b,function(){return!a.a.f(c())})}};(function(b){a.c[b]={init:function(c,d,e,f,g){return a.c.event.init.call(this,c,function(){var a={};a[b]=d();return a},e,f,g)}}})("click"); a.ca=function(){};a.ca.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource");};a.ca.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.ca.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){c=c||w;var d=c.getElementById(b);if(!d)throw Error("Cannot find template with ID "+b);return new a.C.F(d)}if(1==b.nodeType||8==b.nodeType)return new a.C.ia(b);throw Error("Unknown template type: "+b);};a.ca.prototype.renderTemplate= function(a,c,d,e){a=this.makeTemplateSource(a,e);return this.renderTemplateSource(a,c,d,e)};a.ca.prototype.isTemplateRewritten=function(a,c){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,c).data("isRewritten")};a.ca.prototype.rewriteTemplate=function(a,c,d){a=this.makeTemplateSource(a,d);c=c(a.text());a.text(c);a.data("isRewritten",!0)};a.b("templateEngine",a.ca);a.kc=function(){function b(b,c,d,h){b=a.m.ac(b);for(var m=a.m.Ra,k=0;k]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi, d=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{xd:function(b,c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.kc.Ld(b,c)},d)},Ld:function(a,f){return a.replace(c,function(a,c,d,e,l){return b(l,c,d,f)}).replace(d,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",f)})},md:function(b,c){return a.aa.Xb(function(d,h){var m=d.nextSibling;m&&m.nodeName.toLowerCase()===c&&a.ib(m,b,h)})}}}();a.b("__tr_ambtns",a.kc.md);(function(){a.C={};a.C.F=function(b){if(this.F=b){var c= a.a.R(b);this.ab="script"===c?1:"textarea"===c?2:"template"==c&&b.content&&11===b.content.nodeType?3:4}};a.C.F.prototype.text=function(){var b=1===this.ab?"text":2===this.ab?"value":"innerHTML";if(0==arguments.length)return this.F[b];var c=arguments[0];"innerHTML"===b?a.a.fc(this.F,c):this.F[b]=c};var b=a.a.g.Z()+"_";a.C.F.prototype.data=function(c){if(1===arguments.length)return a.a.g.get(this.F,b+c);a.a.g.set(this.F,b+c,arguments[1])};var c=a.a.g.Z();a.C.F.prototype.nodes=function(){var b=this.F; if(0==arguments.length){var e=a.a.g.get(b,c)||{},f=e.lb||(3===this.ab?b.content:4===this.ab?b:n);if(!f||e.jd){var g=this.text();g&&g!==e.bb&&(f=a.a.Md(g,b.ownerDocument),a.a.g.set(b,c,{lb:f,bb:g,jd:!0}))}return f}e=arguments[0];this.ab!==n&&this.text("");a.a.g.set(b,c,{lb:e})};a.C.ia=function(a){this.F=a};a.C.ia.prototype=new a.C.F;a.C.ia.prototype.constructor=a.C.ia;a.C.ia.prototype.text=function(){if(0==arguments.length){var b=a.a.g.get(this.F,c)||{};b.bb===n&&b.lb&&(b.bb=b.lb.innerHTML);return b.bb}a.a.g.set(this.F, c,{bb:arguments[0]})};a.b("templateSources",a.C);a.b("templateSources.domElement",a.C.F);a.b("templateSources.anonymousTemplate",a.C.ia)})();(function(){function b(b,c,d){var e;for(c=a.h.nextSibling(c);b&&(e=b)!==c;)b=a.h.nextSibling(e),d(e,b)}function c(c,d){if(c.length){var e=c[0],f=c[c.length-1],g=e.parentNode,h=a.ga.instance,m=h.preprocessNode;if(m){b(e,f,function(a,b){var c=a.previousSibling,d=m.call(h,a);d&&(a===e&&(e=d[0]||b),a===f&&(f=d[d.length-1]||c))});c.length=0;if(!e)return;e===f?c.push(e): (c.push(e,f),a.a.Ua(c,g))}b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.vc(d,b)});b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.aa.cd(b,[d])});a.a.Ua(c,g)}}function d(a){return a.nodeType?a:0a.a.W?0:b.nodes)?b.nodes():null)return a.a.la(c.cloneNode(!0).childNodes);b=b.text();return a.a.ua(b,e)};a.ba.Ma=new a.ba;a.gc(a.ba.Ma);a.b("nativeTemplateEngine",a.ba);(function(){a.$a=function(){var a=this.Hd=function(){if(!v||!v.tmpl)return 0;try{if(0<=v.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}(); this.renderTemplateSource=function(b,e,f,g){g=g||w;f=f||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=v.template(null,"{{ko_with $item.koBindingContext}}"+h+"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=v.extend({koBindingContext:e},f.templateOptions);e=v.tmpl(h,b,e);e.appendTo(g.createElement("div"));v.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+ a+" })()) }}"};this.addTemplate=function(a,b){w.write(" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4596348 SABnzbd-4.3.2/interfaces/Config/templates/_inc_header_uc.tmpl0000644000000000000000000002265714625637243023372 0ustar00runnerstaff#if $pane == "Config"# #set global $root = '../'# #else# #set global $root = '../../'# #end if# SABnzbd $T('menu-config') #if $pane != "Config" then "-" else ""# #if $pane == "General" then $T('cmenu-general') else ""# #if $pane == "Folders" then $T('cmenu-folders') else ""# #if $pane == "Switches" then $T('cmenu-switches') else ""# #if $pane == "Servers" then $T('cmenu-servers') else ""# #if $pane == "Scheduling" then $T('cmenu-scheduling') else ""# #if $pane == "Email" then $T('cmenu-notif') else ""# #if $pane == "Categories" then $T('cmenu-cat') else ""# #if $pane == "Sorting" then $T('cmenu-sorting') else ""# #if $pane == "Special" then $T('cmenu-special') else ""# #if $pane == "RSS" then $T('cmenu-rss') else ""#
#include $webdir + "/staticcfg/images/logo-small.svg"#
  • $T('cmenu-general')
  • $T('cmenu-folders')
  • $T('cmenu-servers')
  • $T('cmenu-cat')
  • $T('cmenu-switches')
  • $T('cmenu-sorting')
  • $T('cmenu-notif')
  • $T('cmenu-scheduling')
  • $T('cmenu-rss')
  • $T('cmenu-special')
  • $T('menu-help')
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4597223 SABnzbd-4.3.2/interfaces/Config/templates/config_switches.tmpl0000644000000000000000000007447214625637243023643 0ustar00runnerstaff

$T('swtag-server')

$T('explain-max_art_tries')
0 then 'checked="checked"' else ""#--> /> $T('explain-auto_disconnect')

$T('swtag-queue')

$T('explain-pre_script')
$T('explain-end_queue_script')
$T('minutes') $T('explain-propagation_delay')
0 then 'checked="checked"' else ""#--> /> $T('explain-top_only')
0 then 'checked="checked"' else ""#--> /> $T('explain-pre_check')
0 then 'checked="checked"' else ""#--> /> $T('explain-fail_hopeless_jobs')
$T('explain-no_dupes')
https://sabnzbd.org/wiki/duplicate-detection
$T('explain-no_smart_dupes')
https://sabnzbd.org/wiki/duplicate-detection
0 then 'checked="checked"' else ""#--> /> $T('explain-dupes_propercheck')
$T('explain-pause_on_pwrar')
$T('explain-unwanted_extensions')
$T('explain-action_on_unwanted_extensions')
$T('explain-auto_sort') $T('explain-auto_sort_remaining')
0 then 'checked="checked"' else ""#--> /> $T('explain-direct_unpack').replace('. ', '.
')

$T('swtag-pp')

0 then 'checked="checked"' else ""#--> /> $T('explain-pause_on_post_processing')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_all_par').replace('. ', '.
')
"> /> $T('readwiki')
"> /> $T('readwiki')
$T('readwiki')
$T('readwiki')
0 then 'checked="checked"' else ""#--> /> $T('explain-sfv_check')
0 then 'checked="checked"' else ""#--> /> $T('explain-safe_postproc')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_recursive')
0 then 'checked="checked"' else ""#--> /> $T('explain-flat_unpack')
0 then 'checked="checked"' else ""#--> /> $T('explain-script_can_fail')
0 then 'checked="checked"' else ""#--> /> $T('explain-ignore_samples') $T('igsam-del').
0 then 'checked="checked"' else ""#--> /> $T('explain-deobfuscate_final_filenames') $T('explain-deobfuscate_final_filenames-ext')
$T('explain-cleanup_list')

$T('swtag-naming')

0 then 'checked="checked"' else ""#--> /> $T('explain-folder_rename').replace('. ', '.
')
0 then 'checked="checked"' else ""#--> /> $T('explain-replace_spaces')
0 then 'checked="checked"' else ""#--> /> $T('explain-replace_underscores')
0 then 'checked="checked"' else ""#--> /> $T('explain-replace_dots')
0 then 'checked="checked"' else ""#--> /> $T('explain-sanitize_safe')

$T('swtag-quota')

$T('explain-quota_size')
$T('explain-quota_period')
$T('explain-quota_day')
0 then 'checked="checked"' else ""#--> /> $T('explain-quota_resume')
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4598165 SABnzbd-4.3.2/interfaces/Config/templates/config_rss.tmpl0000644000000000000000000011525214625637243022611 0ustar00runnerstaff

$T('explain-RSS')

  $T('name') $T('feed') URLs  
"> ">
rel="$feed_item_html" /> $feed_item_html
$uri

  $T('rss-nextscan'): $rss_next $T('explain-rss_rate')

$T('cmenu-rss') » $active_feed

$error
  $T('rss-order') $T('rss-type') $T('rss-filter') $T('category') $T('priority') $T('mode') $T('script')  
">
/>   $T('Incorrect filter')

  • $T('rss-matched')
  • $T('rss-notMatched')
  • $T('rss-done')
$T('link-download') $T('rss-filter') $T('size') $T('sort-title') $T('category') $T('nzo-age') $T('source')
$job['rule'] $job['skip'] $job['size_units'] $job['title'] $job['cat'] $job['age']
$T('none')
$T('link-download') $T('rss-filter') $T('size') $T('sort-title') $T('category') $T('nzo-age') $T('source')
$job['rule'] $job['skip'] $job['size_units'] $job['title'] $job['cat'] $job['age']
$T('none')
$T('rss-added') $T('rss-filter') $T('size') $T('sort-title') $T('category') $T('nzo-age') $T('source')
$job['time_downloaded'] $job['rule'] $job['skip'] $job['size_units'] $job['title'] $job['cat'] $job['age']
$T('none')

$T('Edit')

$T('addMultipleFeeds')
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4598963 SABnzbd-4.3.2/interfaces/Config/templates/config_cat.tmpl0000644000000000000000000002001614625637243022542 0ustar00runnerstaff

$T('explain-catTags2')
$T('explain-catTags')


$T('explain-relFolder'): $defdir
class="sorting-row">
$T('category') $T('priority') $T('mode') $T('script') $T('catFolderPath') $T('catTags')

././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.460055 SABnzbd-4.3.2/interfaces/Config/templates/config_special.tmpl0000644000000000000000000000645014625637243023421 0ustar00runnerstaff

$T('explain-special')

$T('sptag-boolean')

0 then 'checked="checked"' else ""#--> />

$T('sptag-entries')

././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4601526 SABnzbd-4.3.2/interfaces/Config/templates/config_folders.tmpl0000644000000000000000000002205114625637243023432 0ustar00runnerstaff

$T('userFolders')

$T('explain-folderConfig')

$T('base-folder'): $my_home
$T('explain-download_dir')
$T('explain-download_free')
$T('cmenu-sorting') $T('explain-complete_dir')
$T('explain-complete_dir-sorting')
$T('explain-download_free')
$T('explain-complete_free')
0 then 'checked="checked"' else ""#--> /> $T('explain-fulldisk_autoresume')
$T('explain-permissions')
$T('explain-dirscan_dir').replace(".nzb", $file_exts)
$T('explain-dirscan_speed')
$T('explain-script_dir')
$T('explain-email_dir')
$T('explain-password_file')
      

$T('systemFolders')

$T('explain-folderConfig')

$T('base-folder'): $my_lcldata
$T('explain-admin_dir1') $T('explain-admin_dir2')
$T('explain-backup_dir')
$T('purge_log_files') $T('explain-log_dir')
$T('explain-nzb_backup_dir')
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4602525 SABnzbd-4.3.2/interfaces/Config/templates/config_server.tmpl0000644000000000000000000010441414625637243023306 0ustar00runnerstaff
×
-

$T('addServer')

$T('srv-enable')
$T('explain-ssl')
$T('explain-svrprio')
$T('days')
$T('seconds')
$T('explain-ssl_verify').replace('. ', '.
')
$T('explain-ssl_ciphers')
$T('readwiki') https://sabnzbd.org/wiki/advanced/ssl-ciphers
$T('explain-required')
$T('explain-optional')
$T('srv-explain-expire_date')
$T('srv-explain-quota')
">
">

$server['displayname']

$server['priority'] $T('srv-priority'):
/>
/> $T('explain-ssl')
$T('explain-svrprio')
$T('days')
$T('seconds')
$T('explain-ssl_verify').replace('. ', '.
')
$T('explain-ssl_ciphers')
$T('readwiki') https://sabnzbd.org/wiki/advanced/ssl-ciphers
/> $T('explain-required')
/> $T('explain-optional')
$T('srv-explain-expire_date')
$T('srv-explain-quota')

$T('srv-bandwidth'):
$T('total'): $(server['amounts'][0])B
$T('today'): $(server['amounts'][3])B
$T('thisWeek'): $(server['amounts'][2])B
$T('thisMonth'): $(server['amounts'][1])B
$T('selectedDates'):

$T('srv-article-availability'):
$T('selectedDates'):
https://sabnzbd.org/not-complete

$T('srv-expire_date'): $(server['expire_date'])

$T('quota-left'): $(server['quota_left'])B

././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4603395 SABnzbd-4.3.2/interfaces/Config/templates/config_scheduling.tmpl0000644000000000000000000001717114625637243024130 0ustar00runnerstaff <% import time t = time.localtime() hour = t[3] if hour != 23: hour += 1 else: hour = 0 %>

$T('addSchedule')

 : 






$T('currentSchedules')

"> 0 then 'checked="checked"' else ""#-->>
$taskinfo[$schednum][1]:$taskinfo[$schednum][2]$taskinfo[$schednum][3] $taskinfo[$schednum][4]
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4604225 SABnzbd-4.3.2/interfaces/Config/templates/_inc_footer_uc.tmpl0000644000000000000000000000331114625637243023422 0ustar00runnerstaff

$T('restarting-sab')
...
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4605205 SABnzbd-4.3.2/interfaces/Config/templates/config_sorting.tmpl0000644000000000000000000007552014625637243023472 0ustar00runnerstaff
$T('explain-sorting')
style="display: none;">
class="sorting-row">

$T('add-sorter')

$slot.name

/>
style="display: none;">
$T('button-Series'):
$T('guessit-type-movie'):
$T('cmenu-general'):

$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('sort-title'): %sn $T('movie-sp-name') / $T('show-sp-name') ($T('case-adjusted'))
  %s.n $T('movie-dot-name') / $T('show-dot-name') ($T('case-adjusted'))
  %s_n $T('movie-us-name') / $T('show-us-name') ($T('case-adjusted'))
$T('sort-title'): %title   %t   %sN   $T('movie-sp-name') / $T('show-sp-name')
  %.title   %.t   %s.N   $T('movie-dot-name') / $T('show-dot-name')
  %_title   %_t   %s_N   $T('movie-us-name') / $T('show-us-name')
$T('Resolution'): %r 1080p
$T('year'): %y 2021
$T('decade'): %decade 20
  %0decade 2020
$T('month'): %m 1
  %0m 01
$T('day-of-month'): %d 2
  %0d 02
$T('show-seasonNum'): %s 1
  %0s 01
$T('show-epNum'): %e 5
  %0e 05
$T('ep-name'): %en $T('ep-sp-name')
  %e.n $T('ep-dot-name')
  %e_n $T('ep-us-name')
$T('extension'): %ext avi
$T('orgFilename'): %fn $T('sort-File')
$T('orgJobname'): %dn $T('orgJobname')
$T('lowercase'): {$T('TEXT')} $T('text')
$T('multiPartLabel') $T('sort-pattern') $T('sort-result')
$T('partNumber'): %1 1
GuessIt $T('sort-pattern') $T('sort-result')
$T('sort-guessitMeaning'): %GI<$T('sort-guessitProperty')> $T('guessit-sp-property')
%G.I<$T('sort-guessitProperty')> $T('guessit-dot-property')
%G_I<$T('sort-guessitProperty')> $T('guessit-us-property')
$T('Example') %GI<audio_codec> DTS
$T('Valid properties') $prop

$T('sort-quick-add'):

././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4606137 SABnzbd-4.3.2/interfaces/Config/templates/config_general.tmpl0000644000000000000000000005562214625637243023423 0ustar00runnerstaff

$T('webServer')

$T('restartRequired')

$T('explain-host')
$T('explain-port')
0 then 'checked="checked" data-original="1"' else ""#-->/> $T('explain-enable_https') $T('warning').upper() $T('explain-enable_https_warning')
$T('explain-web_dir')  $caller_url
$T('explain-language')
$T('explain-ask-language') https://sabnzbd.org/wiki/translate
$T('base-folder'): $my_lcldata
$T('explain-https_port')
$T('explain-https_cert')
$T('explain-https_key')
$T('explain-https_chain')

$T('security')

$T('restartRequired')

$T('explain-web_username')
$T('explain-web_password')
$T('explain-inet_exposure')
$T('explain-apikey')
$T('explain-nzbkey')

$T('cmenu-switches')

0 then 'checked="checked"' else ""#--> /> $T('explain-auto_browser')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_https_verification')
$T('explain-socks5_proxy_url')
$T('readwiki')

$T('tuning')

$T('explain-bandwidth_perc')
$T('explain-cache_limitstr').replace("64M", "256M").replace("128M", "512M")

$T('backup')

$T('explain-create_backup')
$T('restartRequired')
././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4607127 SABnzbd-4.3.2/interfaces/Config/templates/main.tmpl0000644000000000000000000000027514625637243021377 0ustar00runnerstaff/* This file was intentionally left blank and is only needed for 'skin' detection routine */ /* https://github.com/thezoggy/sabnzbd-uni_Config */ /* Updated Nov 2015 by Safihre for 1.0.x */././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.460865 SABnzbd-4.3.2/interfaces/Config/templates/config.tmpl0000644000000000000000000001101114625637243021706 0ustar00runnerstaff
$T('version'): $version [$build]
$T('uptime'): $uptime
$T('confgFile'): $configfn
$T('parameters'): $cmdline
$T('pythonVersion'): $sys.version [$CODEPAGE]
OpenSSL: $ssl_version
Par2cmdline-turbo: $T('notAvailable') $T('explain-getpar2turbo')
https://sabnzbd.org/wiki/installation/par2cmdline-turbo
$T('opt-enable_7zip'): $T('notAvailable')
$T('homePage') https://sabnzbd.org/
$T('menu-wiki') https://sabnzbd.org/wiki/
$T('menu-forums') https://forums.sabnzbd.org/
$T('source') https://github.com/sabnzbd/sabnzbd
$T('menu-live-chat') https://sabnzbd.org/live-chat/ (IRC & Discord)
$T('menu-issues') https://sabnzbd.org/wiki/introduction/known-issues
$T('menu-donate') https://sabnzbd.org/donate
Copyright © 2007-2024 by The SABnzbd-Team (sabnzbd.org)

$T('yourRights')

././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4610052 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/bootstrap/css/bootstrap.min.css0000644000000000000000000045165614625637243027657 0ustar00runnerstaff/*! * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}} @font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAFuAAA8AAAAAsVwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABWAAAABwAAAAcbSqX3EdERUYAAAF0AAAAHwAAACABRAAET1MvMgAAAZQAAABFAAAAYGe5a4ljbWFwAAAB3AAAAsAAAAZy2q3jgWN2dCAAAAScAAAABAAAAAQAKAL4Z2FzcAAABKAAAAAIAAAACP//AANnbHlmAAAEqAAATRcAAJSkfV3Cb2hlYWQAAFHAAAAANAAAADYFTS/YaGhlYQAAUfQAAAAcAAAAJApEBBFobXR4AABSEAAAAU8AAAN00scgYGxvY2EAAFNgAAACJwAAAjBv+5XObWF4cAAAVYgAAAAgAAAAIAFqANhuYW1lAABVqAAAAZ4AAAOisyygm3Bvc3QAAFdIAAAELQAACtG6o+U1d2ViZgAAW3gAAAAGAAAABsMYVFAAAAABAAAAAMw9os8AAAAA0HaBdQAAAADQdnOXeNpjYGRgYOADYgkGEGBiYGRgZBQDkixgHgMABUgASgB42mNgZulmnMDAysDCzMN0gYGBIQpCMy5hMGLaAeQDpRCACYkd6h3ux+DAoPD/P/OB/wJAdSIM1UBhRiQlCgyMADGWCwwAAAB42u2UP2hTQRzHf5ekaVPExv6JjW3fvTQ0sa3QLA5xylBLgyBx0gzSWEUaXbIoBBQyCQGHLqXUqYNdtIIgIg5FHJxEtwqtpbnfaV1E1KFaSvX5vVwGEbW6OPngk8/vvXfv7pt3v4SImojIDw6BViKxRgIVBaZwVdSv+xvXA+Iuzqcog2cOkkvDNE8Lbqs74k64i+5Sf3u8Z2AnIRLbyVCyTflVSEXVoEqrrMqrgiqqsqqqWQ5xlAc5zWOc5TwXucxVnuE5HdQhHdFRHdNJndZZndeFLc/zsKJLQ/WV6BcrCdWkwspVKZVROaw0qUqqoqZZcJhdTnGGxznHBS5xhad5VhNWCuturBTXKZ3RObuS98pb9c57k6ql9rp2v1as5deb1r6s9q1GV2IrHSt73T631424YXzjgPwqt+Rn+VG+lRvyirwsS/KCPCfPytPypDwhj8mjctRZd9acF86y89x55jxxHjkPnXstXfbt/pNjj/nwXW+cHa6/SYvZ7yEwbDYazDcIgoUGzY3h2HtqgUcs1AFPWKgTXrRQF7xkoQhRf7uF9hPFeyzUTTSwY6EoUUJY6AC8bSGMS4Ys1Au3WaiPSGGsMtkdGH2rzJgYHAaYjxIwQqtB1CnYkEZ9BM6ALOpROAfyqI/DBQudgidBETXuqRIooz4DV0AV9UV4GsyivkTEyMMmw1UYGdhkuAYjA5sMGMvIwCbDDRgZeAz1TXgcmDy3YeRhk+cOjCxsMjyAkYFNhscwMrDJ8BQ2886gXoaRhedQvyTSkDZ7uA6HLLQBI5vGntAbGHugTc53cMxC7+E4SKL+ACOzNpk3YWTWJid+iRo5NXIKM3fBItAPW55FdJLY3FeHBDr90606JCIU9Jk+Ms3/Y/8L8jUq3y79bJ/0/+ROoP4v9v/4/mj+i7HBXUd0/elU6IHfHt8Aj9EPGAAoAvgAAAAB//8AAnjaxb0JfBvVtTA+dxaN1hltI1m2ZVuSJVneLVlSHCdy9oTEWchqtrBEJRAgCYEsQNhC2EsbWmpI2dqkQBoSYgKlpaQthVL0yusrpW77aEubfq/ly+ujvJampSTW5Dvnzmi1E+jr//3+Xmbu3Llz77nnbuece865DMu0MAy5jGtiOEZkOp8lTNeUwyLP/DH+rEH41ZTDHAtB5lkOowWMPiwayNiUwwTjE46AI5xwhFrINPXYn/7ENY0dbWHfZAiTZbL8ID/InAd5xz2NpIH4STpDGonHIJNE3OP1KG4ISaSNeBuITAyRLgIxoiEUhFAnmUpEiXSRSGqAQEw0kuyFUIb0k2gnGSApyBFi0il2SI5YLGb5MdFjXCey4mNHzQ7WwLGEdZiPPgYR64we8THZHAt+wnT84D/x8YTpGPgheKH4CMEDVF9xBOIeP3EbQgGH29BGgpGkIxCMTCW9qUTA0Zsir+QUP1mt+P2KusevwIO6Bx/Iaj8/OD5O0VNrZW2EsqZBWbO1skRiEKE0DdlKKaSVO5VAuRpqk8VQJAqY7ydxaK44YJvrO2EWjOoDBoFYzQbDNkON+UbiKoRkywMWWf1j4bEY2iIY1AeMgvmEz/kVo9v4FSc/aMZMrFbjl4zWLL0+Y5FlyzNlEVYDudJohg8gPUP7kcB/mn+G6cd+5PV4Q72dXCgocWJADBgUuDTwiXiGSyZo14HOEQ2lE6k0XDIEusexDzZOMXwt1Dutz+tqmxTvlskNWXXUQIbhaurum9GrePqm9Yaeabjkiqf+bUvzDOvb2Y1E+EX2DnemcTP/zLcuu7xjQXdAtjR0Lo5n4/Hs/GtntMlysHt+29NXbH6se//WbFcyu+r28H0MwzI30DYeYTLMXIA2EG8QlHpAsyS0EfEToR0a3utIxFPJ3kiIHCCrZ66b0e2xEmL1dM9YN/MwS5p01N5jMX/BLKt/1R83l0LyC29M6+iYxo/UNg/EF7c2WyyW5tYl8WnhWg2/hyySbD5UhnDyS7OcU0dnrFw+DfGdI7v4QfYIIzOMq9hFtY55gmvC7jZ2FK7sEdrn6IXBuucYhjsGdQ8z0yEbWkkczjjsE5hNAIZrPx2zOLZDmKNXcXtg7EMqidAEEWg+SJCBBNwxvxJfc/bZa+KKf+xoKZybnq5vaqpPTye7CiF+ZFjxZ8/7Qij0hfOG/cowPA1rT1l4ymWnrKmxxqfErTVrpgwPlz1kC+Oy8NMDz6c+IO38K/x0xkPnLW8Kx6qGAoQdL+TD9V9rb+/ctn//trxz8dUrZrD/zk/ferF0cNt1BzctmX2FZPXt/jnFCQNz4Ah/iKllGiCMs1w5Lkg0kiEwj6VTXCDKsX9rMpnvIj9pcDecXAIXMnqn2dTUbN6w0XQ9ue6FV/nnXCH7S3lPWGltVcLsH75ub3ab7A8M28caNrIeOr3o5Q0yFsYL80xaa0EY/UEczV7icUMY5pnelAkmUAXmHYjvFWFGxuqlSaow3OM+/iYY7/l/hVELF4EjRqNR/bvRbOY+DUGzGR/Oh3EqmE/ugIQQguGt/eMYz/+L0cimjeZfQDI3phXMbMQsqH+CjwVz/hf4idHovgVmB8gLvjbicDcC/NypP536E/9N/puMibExdohBmNwyiaZdJGoigos7GpF222xrfnZhML/7Z+ylaqP63Hr+m7bdUkQ6/2cXqdfmvwixY+s2ksXFeXcE+iX0Z+Iow76DBNgjJ7TOdUK18iPsPflfQD+DPsZG2Aj9VmKMMJ4fYRrhIaxhTDR0Elh2vA6h/AE6xUb29mj3sjmL72petXjejPy+oel60M99tFduCI59N3221xe7apOvxs6aHs7vab1IqY2tv7q2xsHeHGml/cV06u/8S/xTjJ+JYc0bWEX0ukW6YmIbGkJRMdjJ9mYIH5QIdJF4hvRGyK7cC7ctImQRcUET99fGXOoft35GYLMQu+g2smnkgZUrH8AL/9Si217IssJ916nv14ZrJrvdxLkQvrvtBcjgPC0NXOicO8Qf4mcxPqh3hgUw3DDfdvLJXngg7N3dN2zbPJSaed3OfZnMU7dvmznp3C3bruO+Nmue0LFsy7S+6265+fCKFYdvvuW6vmlblnUI8xCXp37CrOZv4B9gauDBlYp7adcUXB5DNCwYImlXOJJKkAdvExXxVvKEYnCo+3eIskP9qrrfIYs71CccBjfXRC52udTHHdaP1A1ui/VvH1otbrLrpNXBsGX5B89QghDyimlvNB2KfkxZ5C9/em3+d1+d//IfFp2+2Oxn/s+9n/79p39S3s8idN6g0yZObwJOgKUpNB3GyU0Ls0PbRzIRq4lcarLKOJBkLRzJQD4j2090XrbA7DW8K3jNF5hlGS5e4V2D17zgss4T20egOJte5iD0bReM9yjTxnQxCRj3c5kFzGJmGbNKmwGw39IJDJcXJZGMkaAB4jyJAKw0jt5IAuIE+A+U3cVAZZrq9zhDyBrU8oosuxcGNTzCKJfla7JjNVmuSb/+tuzN2H+X4vlB+PpdfMXXmuVsNiub1T34SFbjYw5itEvVi0K0Nt9pNJUMI7SLGRhf2xipfCYf8z5OdlGKayOucFeVPeS/dbo3lBrbSMmwUiQN5/ed7g0Ds1s17IuZC5kNzM3MZ6EWCa0DtekdJfAxz+R/OX28sND7yRMTBcf++s8mQCQWHya4qBv/ufeMoWyslPA9DtMxUknxkH/yfTnm2CMYzs+Cq3r7PxY/MXomrvTEsRpfEGHa+WN8E1AHjElb7d06ddA7oK/+5Mdsv9EtPms0jv0Z5kf1FqPxWdFtfFr0kHfgDX0Y+5PRSG7RUj0tQr7rmfX8DH4G5W28kKeJLtmQsQkuwMP1pk16EV4sl7vrMJATfyUWo/GwEco4rh4XFQgaiUX9qxZHrMQqKnz/c2d8b9TysYrAuXpP/Rf/Gr8b1qwwc5a+euLa6S6sneNXToG2XrEJi4R5SGs8Sq2S3d97bsfCRaTdaLwKClRHt37mkudvXbjwVrLhuYeGhh56bvfQkHpk2CwvwClqgWwuBfndC3c8dwmstj81KkagcUgbfPY8Zje0W/82VPWJHmSq6pP8hPWpotc/EexDOK3qU+wngPhOCiO9MJRm8TJefjelrzoKnG2Bn+1NCUmPE4gHFmBN9jrTigRIpsACrc9Gstg58ULkp9467+Gf/eFnD5/31lNrt2967dhrm7bzI+VT5m+fzKhvf2MzpICEm79Bopkn07lt1762adNr127LwVqQLdJ5+lpQDcvHPQtVY5knhYrK6q8/JsiP6EuhGZdFdaNszjvpqvc+PI0CdjN0AXsFOC3ZfALDJwr4q2Xq+GF+GNbsxUg5NLLIEXi8otcDQcUts0D8eQ1iVDRAMBTsYiNdRIxE09EIBJO9A2xqgERTaW86BUFn0OD2xFO97FAgFhF6OoQ7prYt4XwSeUgQHiJyDbeke9IdQntciLQ1FlJMaYcUNvZBg+FB1ubjlnRNvl3o6IEU2w7fdNPhm/hh+FLysUu6++DLHkOkrSHYEjH0tEPe7WdD3uyDgvAgK/m4szFFR7ch0toUgBTdWHr7EpaWru6+6dmbbnqWEbV2EtxAsXiZAPTtGPSbHsotI2leoM8TePEqgSQprs7AGFf8kuOkPdZPXGb55POAW1d/jLST9v5YflasP6v/CO7+GNAPC2BMZWmsOjp2NNbfHwMCJD+LPVL+D/OYlWEEI/9jpPddOFkB5d1GSuKZYggmCCd7JUxD7EXAzxyirYnNDLdDZoFdx14kivkvGc3579Jm36reTTvDgBnaO6vzyQ6chQmlsMoIkIQ2+bBDWBud1Va4pcCn8CPqxlh/fgtG8IPaPH8C5wk6/nZDv69jurV5QhtwE0x2iqOsj9Mx8B9/0EaUdiPfOYYDCi/q9jhWRuupMDEU0+CtX0sDFxv07T/K5niBPqN9+tQjgEc31NGCXFeMcCEuQBIc/BK4CO78u7EPYvl3yaEfK3vcb6qP1R2tI7vUjVDDUdKubsSrNjYKY1qBEa2P50SJoaXiksIoLiCwnxS6EBuBde87botNfdEWwYvF/R0/u5yCqhGeEOR2ynSeyXjt6ka7neyye8kryBSWE52y+RBgogrXPZ8E1yIHoHIFUM+AbJhE7lbMtt8ApL+xmZW7PwbjAO0fAVoXQOuiSP/ksIVdFZ0aulsamKUzwPZ/NYDMJRBPCxsBqLzqHyneXF6Ej9HlIFo7+pg+jUb3unRmGpstGkm6etOuDBGA5wCMefp1gTHcdZlvPBXlOslvYTp1cd8UjYLVd/J5awNrIOKLnIt9MD9qdrKrWCvA6ALm3QV9VrsPm60Q7+RHJHP+2hqfugo/MvI2H/mqr4b9tFnKSRY1Y5Ek80Nm/WIhr1ikKnxGz9TWXrokf9xwujfvcOTtNTWnxd0F37Y2W79tteBqZ4G5qLCuomw+nSr28QESCRVLTyYKILGJOPfcnaIFOsewhRdvv+rWa/Wih0vlbX6Zb75T5C0qNKVFvH1QL/vazSWgC2s6oWXXIuUxQelKiJbowuJDQViatLmLijg9CQBMg8WiPgiw3LEeYRmm5f+XdnvkDnxLLjMLxtvX74C3OlwPQqx4xwIdpPx38LrlDphiyWUWHWKAzzxurS/xTo+P5wGFak62ap1PVFFN4v/y+xuR39WnIO7lsWfwgVsK17wxrs9K8ltIKuhkw7f/6dhK6gQokFKhWX3urrjk/rnI0pgfpGMeuQIUaEM7+GF5q2iMkCaMQwxxOzcvU0eXbsnS9XknXvP7Gtw5dwPXlFu2ecvSHEZgNDsU6x/GdXBYXyOQjzZReSedeEPY6nEv9gJR4oBQJtFO6Kd0fwC6BO4LNHDeBujB6dSNcUQC9zIv2LnAzGk99bUDrdFY+9yGFQtEo0GQPNv6vS2drj4+1jHbv3aJSMUWP+QTZrmbNTjU8wyG/iXNNpskybLcJ3CiTF5Ir+JYzmJwE0mSVhlxbtbmvweB3ulB6Til5UuUZydpgiFVeobhU0WaBqpJ198d+/XeNRTZ9/1OPfG7+2hwzd5W3D+hmyjsRcUg/+Cavb++Vh2ls3L7zT/etOnHNxeerv313vzLVqPai4nJv+K1FC6040/4udw7sAb3laSg0XCkAAs0npBO6VJabS4Elk/U+D4gTXW+j0wnrMlqNamq4tMIYB87tE10i0FR3LZNhJsb7/R561btmes8YBCRkhYNByRtKd55mqTas9FYhJnbRGHuOh3M4QTdgQSqmgRxuzGdSvZGcbMxNQGk5C3ebLjoXIOFM4l+WKHmLTJwRv9E8GWJ6dYvf/FmEyEGr+gyrr1p5zrgkz0Cw2j94Hv8Jdx7dIVegBSNtgsqGsRQEYiIBoXwD0LNvQ5d7s5Z00QzwNhqZA0b+tMG1tQq5nd84uq8R0zPvX35G8uRaze4jcOHzz0w1+Q2BIRvf6J6Kgatnrbiem+CFvAxfkrndzD9MFPP1GWTUHclpASUkCNAQkpCCcCgDSUDAhDZ+CuEkgn8J7i9nMA7pA4lISappxILKfAeSAbIcSDuN2bJcfZILqeO5rLs0MnngSHYRdrHjmaz7JEsEPw51ZqDJDmUIOZIe34WaQeegNsJn1qz8AIpT3yCjyEih/xELkuJ0lEMYTLVCiWpo5oYMleMH6USyYJcD+uOe+kWKpn1Qns34iyYDjkSLvgnZXcgVQNeqINXr48m3iS7cjm8tedyY0f1QvTnHHdsrKby/+SSbPY8/NH6vpl/Esq3Ae4ZU1HC44KFiI9o7CEgab/RqHbj7s5KAg06s39ZP/zxI/mVuF/TbTSy+3Fb8If9/cv7+wt91yy8RfP1QXtW5RzQn7qIiZyuFM5QfJ5E9uVnqT85TanFx0lkP3ukBAMprvsRyi/C8NAJL1xbIIirSvnSj4O5netb4JxmNANHPssHAcHMHsFRgEug816gDBeMbdfiuRcghqYcm0+Xxx/5IAEtN3fqFF3LzAXqwoT0PN0OVTNqxo8sxMkd5Ig6k79Zk7VxxX6gMLOZFQgvpW2RrMW1D0BDihaXQ9wVRoBxPLfpknmkeMtoB/qM9cRc9IqmMD2XUmdZ7GSRKPUZvChf8BoykriM2MnKYbOHX8R7cLdNCxSFFVQqoYswnlWtlFS2mNkhswVpZiQW1J/UKFfipHGlUkM6UKBhMz1istELIHJLMSctu3ugzfaVSOjKvUgc/THK4Sdg2Wscz69leKIkkrwuuWiOe9yGYKQXRumkC3qbRcMwrvhjNXgdZk3RxAUEhuSPvn3nnd++U/3vlVOmrJzCD8JLxV1OHRjrZifbcFDOuRNTGqdgQm1tSNJ2OcQ04YiEXuxtII1ECSQRoQGYioEsgCfchB4ghAtw7FfJre4WZ9hkVi9MtjuWqtdNDlpMrfEG9fOT6q21okg+e4As38MfGquNt7oUws6Ysarj1/efE+yst86YUVNvDdts3Pv5c8m/aP0C+f8/Qb+IMnGq09BgwN01oIOAnAdagI8mBSrqk1gxTDUBOtk2ousEtBH2z4Ir2d3f6k8PXXVlt2qN9RODxRuoJT/v27wm09jRYVc/e++iyx2tyzJb/n3J0htXP87eSsQaf2Ly0s6Zmxela88REy1cf4273mI3iXNJ7KxrZibOm9xm6rl4fqy/t27smU8tOfdW2ucBzg2UfmOIVyLIl3kpYlwphDISTXJXsctmiDtN7fNV6zelgxwnWxsVr83Aj/S5ki1jL/a0GC6+2L6Um+aoddlNFuj+bJ8mH/iaLh8I0/U51NspIEfq0dohwyFXKgm4NggwQ4rRhCOUFtxxo8XnitT4cnGfT93IS8FaT85XE3H5LMY4zIEPL1hw443wz+1UmhTJyJGxZzw+wsKkKZgUiVtKOKMEb2AKHTv61FNc01PQFwKnvsZ/9pPA4RKTASWahmh+8MxwzHxKy74IRn5LGRjsPUUwTu64UYNY38caqd7HKucZ/tHnODtENw/2UfHRMaq1UUPDJQ0OKkWCeet5fYOhII1VRz8+/Elg5j4Gxur3J8o2PJ4rg+2d08T/fwEzSVbyZ9XPro95T477lRKqUSRXQnauHNsISAl27oWi6Fv9z48JMv8r/aMMj8onCP/DuDZOuN+GPPr/+p7bx+7JlbYdppcNhzKU/1Px5aiaGDn/s1iGMaBcleKUo/v9rcxkZj7DBEKOfrayytXNLYiUdBY+pleQXdnscKlQcpzuWluxsieeyuXIK6SdxozitWyGOV3vOHHjguyCQ6fpIYy2JwvrQEF/Qa9Pdf/QqOSqCiE/EE1/XIVKTc2tzWbHnimrEd+Vyz311Ml3P0GVTj7PD5aDnsvCvH36alEaPMePcMegXs7x8igTu4B9v7G9vTHvhCu/kzIdx+BxC0ay9zRSvoS0F2lIxI+X7klU63I40gLQ3w5ep5na+SFnba3z5D64zv+QtM4n4ffG3tq4aNHGRfxgrXPMim+5487abL7xhdseIRn1KDl+7aINixdv0OD+JSPwKf5+xoP6aiTeQIDVlIhMcL1H5R9PYXvprs3fv2bO7MOplCmweuiq2JRZ1zz+9a/v2PH1Hfz9236w+ZrPXvWfAxlj4NLLHpq3c/PQ3uvmvbrjG7fe+o2y/cLdtE6VUlXi0ASb1VLUBVSUWSU4HdvAraTyS8xzM8NxvxFkXV6pUVRiJwcgC5zEeht4rwcp7ki0k41G0qlQhG1Vzlq8alEmnFi58caB5Q9vn988MLhqyVlHvLEWjtQFeupdiocF/tkkOGPW2ibWaBTkeZ/dvPWazXfOnnvL6jkRXpi85sFzZt+55ZptW3bl1cCCHZPD06MhySha7UFzjcjbp8fOecFCirzAG/yVjBX6OFIaadSjQq1nNhyIe8tVbaaSdHlXIWKacMeuZA1uxS95zILhyrxAdsXTL6m7kNQlx2P9uZf2qhufePFFbpI6/OU0WcP99RrCsrwseVot5mtytpf6Y0gm9sdeyKnPQ7onyK4nXlR/rg7H95M1upzu89DH6pgUcikoiihJ6NJKmRxV1x+MJiOA3YwhDRQrWU0u/0rvq0VYXnyCwsLeTJYBq3dAtJDavuzyoVpzZ99Z0+a0uoiFH/xcqgDR7rUFeOrUn6Cywb8ZeNMbhLV5ugP9l0zv9UN5b5mFkjzxUcpPJCn3V402pRxtJd2GrnLdhtVk9ZSZh9W91fCSH5B7ofxPiWL+j3D/uwhBRdyAyozeZwvQzs79soi+BKSnafLviZCcfrpBpLyimfLfTyJtbyruIQKD01tUwJyKEo/ybaxkSNFUMdMkhQoJyRBQFhnUkDQSXhTM+3NmY0EDM7ffLIjqWEGt8lCO6mLia3PukFnghosJD5p5SIho/VDkzQfLE+IrYoJXkD19pdP7OwG/voIUtagiWiZ4PAFTHHlTVhRZ7dYmPar+NJ+8JhmR6DFK5DV1foHoLNO/pHrvZfmWZ15RQlwvoVDKhCWNK3CCch9lfFBuAqUgpFSShmNaPj+i5++WZfKeViJfW5HnUakVL4UCNVkA4+ETfIqx4B5xSaP2L1yn0zn2ltPn4+OqZGmwwEVCaCSqG53ldtL1oLGAhdMLd09MpCCF6tD6ZnAZBY9hDaYsP0jzZ0j5ZjKsF4i1UmLuhbJMCnYJPt5VwFNvmZawXjEvLJqIH8STonZjq7BZ8gKgR20C9MDFqJAX1H64QW2NEup6qgzLP8cvppL/NNTOBTCJABOHeWoXzLhw4Wuy7gaBtjKr9kgKq8ZlRYBS32Lpxc8vIhpNDTfyNXWybMJbn2RyQ5EmWc2QF9wmSZ0KYCE+cPuYO6b15Uotj2Kd4MItLS7gtFbkTdrFND6pvEZqv5Yv7jXAus7Pg7avo7KDot50NX3CPkP+Kps8J9/3mGQIteY/LGPC+L7872SPR2br5fy8MtKBMHedGuM28/MZmPJMrGgi3Gb1S+Si1/L/zrZwO9XH1ce/z7ZQ1WSoY/+pMb5FT4ua0Wm+Jf/298nFmChEQ+Ti71est4mq9VYI6RsymoRJKYidElT2FGnDTZvqtfhGAFTbeqEw68GqtfmbVa/1IFO1/jdWr/8BDRRtQh9XNjubEm4aWVpVonpTGR7PVGc+KJNoBIWF7kYi4gUV3r1U6723i6TxUl3n3/tM27aZfKb7THiHW9VzFSwHJ05VfK6Ar7kaB0XgPPE0BSkSFKsBUpaLihEWoA9wBt8qirh2VSOkZwXEwyrxZ5jyt2rJmSo9gX7cg6jsEUGJU9z9xJPOEM3uQQxKgkh35DNATnVyrmJ3mbCNyIB/yox4wH1bg2DwN7q9kov4pFqny8oSm3RQbGgJ1QQTs6ZMLilOVYJ9v6Wha3HcJ9jddsXp9YhGUXLXt/qMDnvLpPNTXfNa60z5/yjXQOMq+lNmwh5egpYrdfZQZV9rI47xlRkuyTjpzsmCBSWNkAXVoK8sgYWqQJWbo1RLo6QH0YW6pxqfCnRgkd+RiFjUQUQ7poIaYoakgXxwFd9BuuI38H1xBxXSFb/pBDIKQFn7YB3dB36l7sG1FLaKiBdp1KxLvfswap/30lnVESgNnvjbUoT6w9N+Xoio0qcYOIM+heg940YimsucQVvli9NEcft2UZwGQwLuilj1fFr1i3NP94X+PE7Hpvtj6lBJfJ4R6NvWiaL6MgzWHxiN66DExa+dAdAbMYX6HVF8A+7rjEZIXAVbDe7PVI9rmN69JOLV1DOSvRPxWNPZBZf/Nf+Ny65BhYxxxV+77XJ2wfQ389/IQPgajXbwMsuAz/0IaQcXJavKbRqR2IqyZruXjVC2+hdee/5vdnYOedpmVtR3NGXldxSzDSIiBVpkGb9by89UpEPKrSLZmyFDzMab/wXl2CNe7s/qCtTvWgG5kpBmCBlSzDS/r8N4uwBwohRW63JTS1y32f0TQsPfXVGEHQrV8/NCfiOUVirYcBbIeA2+iF68rQIo3B/S628vYESr79ehzS7Q9LEL9UXmik9XVHb1yBO3Ngvt5935+k1efkV51mzzrM0LL3/20avnwMeKuWyOUZg2TasSqZ+KcZQiOn1Iu2Vh497ALUVZiCKt/gh6IvTIj1ZLRjWAkpHKOKovNwp00eqPROiAbiNEKieXwMLcXhVJ1/uzmLP4tfxaHR59cBdJVG1kTAgl9ze9QKUEQ946Hkb+okJ5JRDyf54Axur1D+WS49cLr0tTPEu7UmXrxcSr3XNvumv4yXzInXKH4F7Tc7p17Zt+t/qW2+93k063X7VW6lALxTY7i1nBXMxcxmzQbabxz+tJo+wijYaIGMNS8AoSMgAPt84DdHOoMPfjXhF+kuH1tZvuFQrRCN07xGcXRX9MYxYchDe5BcHj+Z4i+42WyPc8Xofi7bbZJN5nJLJ5qr6IqRtzqNlM17SpFsnkEyTWoABEjz4JXOQvzWYuwdnV5LNGOwTM5v9r4RpQ8ZXsYodks3o31JBlzbYtNotisnm22MxiwGFXam5oN1n0TA/hRvshvTSDwHff4nNzRo9Dum6PaJbMXzDz+x+Fkj4L4bFNBb1asqsgH7Dyh4DvbkPtf5yMDKzEwyoaESMSNS9P9gJVA3/RTlwoMwZvxECFWxIPNw9gi01nOHjP32esZTtmXHnxvZd8ZtakqQ7ekajbXetpNa6ocTVxJtY+uSe69OLz77zh5bDR3xjZMzUz6fxrz1nqrZGcHQHfPVefN+fiK86LeXj+Sc5lPKy+k/vCUI/DaLFYCWHr6nbXuILTIsb5imNKY/rCm28fSMxPhkN1XbNMNZGuqwOBhtTSxWuTk6bw0ZaG86b1hKddePOKuBvmiguYBn4T/yOqOyGRBt7bKUI1GjioBC8aUKwF7Q319UgcmtFGIzCJGBqwQij0ynDsfdFGc3TS3BlNfJ25xmzniMkpXXTPvCaD3ZaZvyzjmZdudBostmhb0ORZNN2sJBeed1HXkrUsywueQH+L0eCPxmsa5ZpgRJSDZ11yDv+jmbd86vxZfc1WcZJ3UkMq1BOOOVtvu/+pB+en186d3GTwWAw2jheaJs09/+LNfZft37DALyrNj1wABMuUKbODyTVnT/KYbJ3Tpq8IrNh92dkxOj5P/YpZx4/ycyiVcDYdn4JbEoKdQi9054iBKsygLW46FRGxAb0NPNCm8BSNCPjoKcj6EAus4SuP3rB+cV99/eTF6294dA8+TK6v74MHVpYNRt/I30e8QGTOOdfGWzzxcy+87a7bLjw37rHw1nPzp0KyyRSeZO+QQhInt3dYgvycjrPOv+T8s1rptaP84VeywdWX2T4ysr0/7TLIs6+x9zib56ye1dM9e/XsZmePY3NDs9zlnNVt4+WgHJbbz3Livg4P9WWgviOMm4kCRT6I8vw0NbUUEnFvOuFKoxQW1gTsvFirsF5pb7qTUCx4i7VmtToveaDxvK9uOaedVvPRpVOnNz0Q6bry7uiSdQ8t7Vy4JQKVS+XPplV2ts4bvCwZu+KzgITtxepaPRzWdpv74muvv6RO0SorX6cu/dqKn/XWnrtp/Zragz13DUCl5myiFW2Ycvb0PtsXnU+tx8pvLFbUspLX68mdegwmOif/NPDONajTGoUh6tU56HBJCTBASVvNUB5VIiKpc9kd7kludodSFz7xQbiOmMk5dOYk56gzL6uaf7N8a6MQOHm0ae6snZpFDfuT3/jdYzjzwkXXIVHoXNuCfQslQZqBZjTsoHMqrkE4jaYdgkGz2ATOgB3cPkSukD01DnV3ttb1wx+6arPqbkcNAHoFPzKUUQ+qL0k97pjbZv1I/egC9zTFbrrlFpNdmea+gIgfWW3wqkcis8ky5FAcRd1If5nNZrl2FFpungc8wpoCl1BpQV/ScS+zjlASyUTVv/AJ46gkJI4bHX4lTnloctxPZE1ckS3+jG2fKIjkQFyzuo8jvYQG1OrGvJPSTu/nSp9PHNTl4z5hK/8gtXVKF6gEKiglgcKiRlCESsQCV5QIlKWKpr34lt/wkSx/JCmP5/cBKQfl/5gd+rOS/+p91/+YCg5CXK2W4M9fu+/6xxX+vnelVuldIDCG0VQTpU9Dw4pRfei+6zWx0MLie0gPbyrkmRU7OwT16JGeyXLHqOLqAfVN1GPlBzWtFNzj0TRTCjogtP1NjIvu5habN5Aoa1k66wGpqriVetJgiGdwDZtKhnN0y4n9sXYnsqGmZfDSR15+5NLBlhoDaedEm7sxmpqRija6ZEEg2EAnTiAC8IrmFbGz1q08P9PSkjl/5bqzYqT9hMmptEXDgTqP3Wiye+sD4Wir4jCeoHbbp5hRfpB7BakUIppIlPCD30dR1GtslDz8OsqbXmejFC/v8wu5X2myq7SJ8Avzv9DFUJySf5uNvq4+Ti7W9D/OZrLChdwxmPNiBRqVjnpK/aGxRCDspVYKAW9AN1JANoo8wP4BJUlGqdgw6m1qPQ2QW3+OfU5/ieLS/NuKpDU3uf8bcAXyBal5jMR2NEAbPAZt0K3hvxHBEDlUxfIGcD+N2gNSNx36nfqlAYow0puatNpRz0e4W2oahKzQHsjf2c16ad/3t2KTtPobnX6D8C8pd0MDP+Kx7wnXqGGlLQcvikMErm6TmfsuxJXbSAxqNjOogJLQBLiKEHAE+JGTS3JoEhTrz8/CB+5YlupJ58aOat8Kv4JvregxwcU5Cp8GFAFm1FyOfto6GS2m1NGTS6CPNKkbsTdCBlnN9onMho55BX8IJZtEQ35lk+htwN5A0V3RCPoD/yXAcv6pAtbZczRUA64JmcUf4q7Q89ZHLeJVZ5D1Ps/t+0iCT3AHVtZC7JDCXfR7OSb/Xja5H3zQbZL1B+ULX1BMTEk3AseSpmnKEK4T9ekMIidUCRQFfcbj7z8gNLvzF7mbhQN8h6ZbRset+nQWdS/ZX3k7WpS8P9sfo0iGS64wV516pOhjI6TZ2dApgI5+LhxywYoWxKUrykKJsIoDsR4mSrCTg0egMPnLW/3Q5Nn8BZEuzqEI7HK3n0+zFmuO3TtWQ5WJoG9YqCD6Gc32SxnbnVPfsxvrFXK2dILl7bLthDp6glhcsfp4bYvbSmj/mQ94uBTw0E73x2jbNRCvC6VL6GCFDwU7eWQDcC5FY5s0slieRDwtAbRsbLXbaXAuu14e2OJw1dc6jQ3ZdY8v7rv2/BWZLqvFWVvvcmwZkK9f5jS4muO9yR5res4kfkRxhV03L1RfPOiPtYi8pd7jNEsOpyTwxpaY/yCZu/Amd5Or9uS3DYaeqVOhH7gZN/8I/wi1fEuLXvyNivibjuKvN+1Nc01HF/3h+ef/sOhox8MPd5SFucPjorQwXT+ytA8EmA5mamHNFDVhBI5pjZbQpugBNkO8MvRub8KVDKST1Wag7D3xlin1ZF7LFP/79nbvCXFOY+PUjrT7/otsPXXZ4exdPzuhZuL5LUXVAn7k7PbhG89uz3b41X01gbjP1xwlu5rrvvf9+pbs6E/Vu7Nk642/PYRaAiUBdrmO6CDTBLPQFA1ur0uXoBR1INDMkypKpoTqnSMx5GiEdTEaSHLs0Alvu/19/5QW9Rv1U1ridT22i+53pzumbs+XFFXYC++CGsTj5JUT/GCgRt3n78i2n71FHG4/u6X++9+raya7os3ZbDmgWfXun44e+u2NZKuGZ0HiF8M4TlMPR+EU6rPKRJ8wOU2RFUFLex3egEsz3YqEAq0cqhAAW19dBZIlVzR61tuIdTnpXH7l+uXrbjPUyep+8cl6aXKWhPHpDcXl9KiTWDNr4mBQc8Tq+NzK/OKSbsfl79o9G20R+brBXYvUg0rLHhtrc4TN81TTOWSZ0gL1ZVlOYH2ery/7XVUjFMbzYpg7UswcqJPQwBd0LKLabJ8IaCr2otcjSkIrGwootKECaUd4XH1+SdazRrfddkBU98t1htvWrbjqSqjaCguxrffM/5zDCpBALUycmajhd+R6ww4SWafuZ5eU+tPid4lgd3gt+b/Y9rQoZNmiXYPXyRHbRs8zX/f4WIFjWZJtUdSD55AP3xtXH+ZipC0EqdBGDA4CoYEU6gRLGPU11QhkLTBiEYPiqOeQgwTCl9aok1Qr5pFf71qEeNxjy/8F0GoqYPv75Yh9j3x4DuJ+uEzHRpAq2lMqb+qfTdiq6kGtzfOWsv0c7lSeMXDHBDe1MT+LUgx0Pg/p87u2UicdIvqQi8DkxhcUwUXCedMpb4NQjwY3npTmgsURJavLwCRyEcN2HfWsDVGfv/u9ZUWUx+PYFueUKwaNvbtu+Xps3eVWbN1GcgVrdMnWJ7WmJz9SD66EBidag0NF1Ukep0t5A7sFCWdhzvYwHv6L/BehXuHqfaBwBEU7hfVLcXvS4VQv+T/vaSIl7cbeMc7ekv9i8S3e1L5xxpvMGcu1EYPbKyCiijjGXcDKckm43PqU2qNWlXusZMiqF82cuVzolUHN9NNR0HZPxFPV9V0wLtvq+k4DqOwVWDlzuQLVdqFiP08cRX7aRlBVfR8cb55bWe5LExnlcsDp1vAP8Q9BucPMk1Ulh4GnN0SAdxcNHv3q9ohx1Ati4S/tkWjIDe3hQdkUGrGRaFBiUdiTSkI41UkMuuQHP+EaSQYlPQTFWJF03BNPpTu5KFAdkWgDukzsZKMG0Q1TAQQglScOaP/dsZ8+fP75D/9Uu5Gs3FY/2SxPld0DHOciXI9gqjcEidXjE+3BLosy0OcX3T7O5g65ROGyzQ2BZs7WbZVnO5ydLe32hMwTQ4wnnKXW6XW5LAa7oaXOIHoUl0FgLQLH2by8wSTWeAx2Y5PDazK3BqZbeJZwXGPaYhX87ZNszoDdaRxotXO1nNlpdvAPFWHDm8PqEE0sZxDEqGzxisFNnuCWetPcGrObN0p23tTZwMuRVodSV8+LTrOV3eRvzjQZiSjaLYS1WEJe0kNsJlZu9LFun7++wW4gRDRbaxw2nrOGm+xOj9cmtbp9ZqeTM1m8UXfQQCSTVSQox6pvtjot/FpHvIUjJovFEoYvHYV9C5Y/xN9OfcalvII37UEhTbTg/AQIaPb4Vz6j5u8/aViycMod/fkDcpu8QZbZoeBi/vbzP3XPsZvOubMtaPHkD9jt6+U2O7vqU/9C9SMvgrXpQNG/E0oJxun+CiElUa0IKQSUwERxOntKSV7ekcuh9VBZBBo3VUcB58ofKBHCwLyf9qFosz9Ibf8dGqwaBMjRig4SGOZ2UkWI7UiO9OfUPdxOYFApUZyfpY7mgEc5rtNGGk2H1lPhAk1Hp/VAMqQEHEUfEYkkUQq1JMdzsX7kklRrTrUi1wMcDjmu1YYfATj7Y+pGpPEBXuoQIj8rR9mgCl4C9yqmF7xnVWxGVniNqtpVmXBvQ6iwni5YQ8a1jYrXtc2J13HvgkvqWxuva1sbr+P2S5ceKGyBwDv2DbrToe1u6BkAJV7xnVLUaq0sJB8pFqcUIPi3yuwxi4JuLr+P30f3OkPQ72aO0xYo3/EsmO3QO5qEF8S0qQH0UsKXv0brnl9+8M7jF174+DsfvPOl1au/RL5/9DsbNnwHL2pHR1NTRxMZhJtHktOOxLxErPF6YlLvpC9YP73x+4ofw+3xVdrHcDE0dQQCmCRgvt9b35xINDf1CDcRSfJ+pYl+Sf8YcurfmXP5F/kj6J82jNsrkWiEuhVlgFfyNkB3S5MUzLhoNiwSCYcxQ7Ui4J0Xh7fmqRbaPa1tzujxkBRlsEHy0/OM4pYLPb7g9O6BQJN6l9zQ0OGyCaZz0vMTbHOzXfQ7a2tsterTcqxeInODoemdktw+1SbVhKwtW9ffe8VKadK0OVuC3bWzyKm5LeddsWTeorWyY9IMtUFutdu5g+Rn533qkocdvLs2HmhU75br/MmWtD8zA3OP2t1ea636jEzqYxJZGAwFiDEd61oTsrRuW3/3pYNi3bS+Rd+GjOfVpAPNd6y64Gsz1GaZleWIPoYL/v9mTeQBENVEguiF1aC4YeXxFETw6QyPfn0m9g8IrMFAvKM1EI11DARnbqibHk/Iojy5rSdgCyZi06y8sS024PeuO4MfwQ5Y9yKRZCqyYaF30vzeHlmUprR21tR0t0yz8KZY66zWuGvxVQB/36kP+K38t2Hu6NQ9SFJfw0AdpqPEK2qTMpf2VCqJwqPoJezTL824b8akoL+x03nhh+oNo5e77psxg9Q5LzebIKD+fsY34f2MtB9fk9v5b8PT6tYrgv4kRPwd0q9z3gdJSJ0653KjCYPwCaR5aUY63eW48O/kdo33yxX9wCiMv2QTrk8eGSI6Ag6moG9t2P/F7GRNlDjl0gw7pJ5aOXXqyqn8SENnXBmbSwUYLyqJjv3UmY1nKr4t80no0faXsaIEiF/BRaIBnItSce4OUif7W6Vm9T9H1X9Vj71BEm+RdmIJQST/ZfVdudUvh9S/qqNvqT98g9SQ3lHibZY0mRVHooyDN/FHmTgzjdozKw28NwQ0hwN6BCoPKaEk3YtKwNhwRLXuk076CGoZNXDQcRwZvreTZY9EZi+d0s4+ztv8iei04JQl6ZbDD2eHV7X4uHuFVfPrOmcs6m6Kr7hssr+1VZFcEZ/PdJkn1hOs8SXS/NFFgqt94PIZzZ3tdaL6Q5vo6piSzdy737pwsX1VyxUrF15iJ4uNkq+rbyg1Z+O8VsNC1UmcvORPRfxtPrfRwL2p/oA1eZp6Z/aGffoewaXcA/xBlKlQLfhQL/oPgBGP3qsA7IQS8qDVNswHKRSheDUvA3Q7MZoRcJMxlEygujn1QdyzfPfq3dEp/bXh5e5YXW2Ngfvza0ZF6UgFL/E0fTq4LBlvTE2qb/KuuzYSXVnjTfM1osvqMHVbm9950quIZlbqaL6YP7jk3kUtA0GnX2nvq53f3WoSsvEdDRnULgo2fN7lNZJgI8/VWi33c3bBZnGY05+dm+3qc7fNmj4YGKLj2nfqFP+g7jdDlxEV5XsJQZP6hYrS1l0VQr4c69Xueixp90gnZPmE5OF22j+SYEWHlZ0K/Hgsh/Ztsbh6h2DNRlvv6jJh9XaJaHCZDiUDKNTMkvb8vsqCyf3ZNdSmO0fa0Y4baJTtpbKzuVzeeSI7fCKr2Z0WypapnXJ4gnoWy3PoUIlIQ1TXdqhQJIXp9Wx5fYdpeWh2TY5D+YVyKd0jw3iumwi/BC3cEy4o83QlZnW79MrCgCjbhWXBlRZVVZZv4rIKpXC01HFlHdHLoeWVl6UVc/J5uGm6CViW5mulYMk+HqNYr0AyUPivLg2oMs2MPqtuhHyRyiwvNJej1Br+fcLyoAyu8D9B7bgmzUqfFobF5nKnK4+t8MPJkI/xHUNWk117jugWF+xazTAALQn6+UE9lhoI5ApGA/iuJOsrlNP28SVVuBVajXmircLel46w2bJS1Q0Ft0KDuikDFL/3pYrid1Q4FvofwRIo4R9h2ftSwc6jHAMqLcCql8YPHtlzGoByNXYN6v8hXnRaOhUvx0sVLCexwupGDR4NOYC7PePa5keIPACnuAdD7dEadRuTIiS6Lb7uskb381My5yjzF8lGCjBRqdwrWJCagfB3yCy7XT1i92hbcZ5Ci1FJkgYMDf6n+jspIsHFjJrTOdzSMuOa9DbDcj/nH9N9bIoGVgzHPWIQuFuYtaMRaq8eCKI0gEF6lPOZjBz3EEvaaxwSUT9U/8JbJZPJJLBLolH1La/RbF9AbC8JJjv/mMnssKjLRBJyqj9QXxNko0Ux/X79epfiXkm6fmKwF/en1HLc6LxloXWKvGa5rVCVL83VuiPcDEX/K5pTXOxHfx6HHB0t2FI0qI2rCZFTrvPWU67zVuS/kTsLnc7IKhFg30e4FOkqNSfH5PtkmUy6Cpiv/36k2sbqCeCFNa+URpoY0sZoYmCgCr3qgZz6s8I0gP1bYiR+D79H56NOz0EVWCTy2/fffvSCCx59W7uRV9995eqrX8GLesOXNm360iZ+T/El3uZqL+FyzSZ8XxpTiI/G0nkT4zznFZ0t4ipMz5v4q9ssqbdKUZt6u82knPCrt6PZwsnn0XySVnyPR1ZXAn72yx48bWJsu7apnI3Hy8bygUK5Js32qcytapqgmn95uexccj205vGgJ+euOeG2SORmKZr/qKzcx9SFctMJdwMUFZDJITs7dnOp1EKZCxg304Cevyfya+vlKqv6aXK1qIj3imL+L6hL+yvUlFfE0VKZ7E8gBY3M/8VoJCFgizH1W6VyC76nH6b7jiibYVxUmVIEspry/LgZIlCeP11Z4zs/AwvVwtGFEut5S1JY4lfyT0N/evOLo+rUEgjcqc9IkGpQbv3iW7Co5b+KgjvpzYdH85PLcc4X21ouwEGl/S4qnUAvoSlXUUhR1eKr2VWFTB+GMl6FsiQsVD1R3urlAAIoSn7JQkmiVVCHSpCwDH/qPepXQ0Db77CJOAImohB+RPWr31ev5g/kE+zTa4lbvZo8xdWPffQu9yJTPCNB66s+zXoJt/0L6hSoCuBIoK8fnBGG87OoRckJpLqyWe4YbpGi50g0+3I3UD85Oa0fzubfoXxPLbW3FDWzigmyJeM0tQkax7PqTy80+UxfUHPlBZIRVNQ+v0xRm8REKPoLmNr0+Uo48v9GFbXPKylqQ2IKm00QddgyWGMROCTxdLB9nCY8P7j2DjlsV/+mfr0C0r/NkeXbbpPlOTBBwT0mVz1zx9S/wJecBF9Wgv3p032iP2v4VSgfgW2G+HUEdEXU6iq4CtpLJfIN9XQG8dwa1VoO8XC2SrPDDyCOQptXgbcPvlAgBfxBoGwftQKeKFrNTASPt3pGGqDt/QRasn2kri+H6L80MJRsmVYJrAKyDItpJUy3/15WYIJqcJ9Q5N/LFJ4c3dc1URpWl9hW6mu50MUIelg4ucTPf15zs5DFo1c0VSp1tKB9jkwIyuM45kb+IP8gHed+6jO3v0KbIknzLy636E8KPTdCuUpB0wLo9JKnAO6pv0vS31EtBha/fJemkgLVVnd8KCk4qBTpQ5m7FbifBKrPJcq0pZAFVG/XbOFz+Tcq2MLrcmV28Nmi/OHskh82bau0k8eWCaPijQPWQ5lUvslwVCfHkXBMIehqUgtDNLeauH1huvZTbYmw+luPjyWoNGEuxRLR7LK5fSyXFUyK7PURQv2v8D3XOt2NJ6liBbmPGOsakw1kbeOs+31Wm5qpH+iJWSzqdPr2O7zc2TmtnrzCig6bBd/vgQmzOlz0STWIlmZEQfupogOZFHUZ7EkUnMn0RrpIMqAgHRJAOjIJ3yGw1I/MAp9q9S3Q/clADNm1wEeO+xbwg5OIYHZLY3ehG5lJk2xhco+6JWybpEVz2wrR6hZyD0QXZbeDVB+onmlimpkWprdAs4WEZDSQppsDlcdCBJJESIYFuAtUnC4GIF2C3Uu2Kv7L1bdz6FxtqxpG4TqQOqOUNAJ2HLvPWA2GgDy4O4vaDrtyl6P+1fAll+SyFcQ28GHqh7fvvf37udylf0fNwhzgz87Y+cf5x9GnF6ygHu18sAbipWeF0YPBgp2GaKeQduxxdEr3SgbH1kvH7tvqSLhedomOvZyts2dw8acu3dY/f+ucuMtCuP/e4zC4XnH3OLZ8ZuxTWxy8dJfU5dhDeKPSlJy5pn/+7u3XrJhmr9C5CuleGflGQocKnlAUaRKp0BAHV0ZwUt9VCqk6zYOgRIuMfePJzdmBdpPJ7/6B23+f+sp9NMDZevovvfYHG5dGPISQq1DojqNckchVrCcCYz/Q0hI0m3NKDRfkgsrnamo+p0CAq1FyvC3a3Nak/s5VX282x9Ufy3E39VAx6o7LpCvO2wK+ch9jNqpJCutcIOooKnYWtDK8gTRVYygRQfwgzKM5+jP2jOZdx3r32Py7rQUPOzAnoRs95NvRAR0qLGU11Taqu1bUYSzMcWjMEir067JQQHfIrLBHsrgv00/Wavd8HRLMEEYFSW3HCSNQehnrHztKqHcDyo4VfZ6gPKCR+gufwA8GegxUEo4A+gd0BASHiH6jYMLIsUdQJTs/C641KN4oCHWolCMLlMfIdtWKScjx7SM5LD9HnfmhrGI0S139UWfUnxgOXdJFW+AMcGjKr6eHAttHF5sUoeArYKDcxMSYcKA/xUDhPiEOEAPafSIUFArN0r24ynI91EPARDXvIDYyvqZaWeroBOUABQA/E+DXC7PWafDLQY2oiwpUEyj4RQtVlUp1GrM7In2p2A7VuiOW6otMiGOo5Mrp05ejVuTy6dNX/k/7mybZQ0nUmfrbx3U4KueDnlHm5wdh8FFeKnoaKKh/TK18StOPhwG9Xo5mqXAxvw/79YQwwDR+nAKQQ4izVXioB84qcppWB7IqjU45z4CE17OvF1Dw+oTFqxtz8dxwtogBnF9MjIl/in+K8s3hM9laIn0TiCbTAXL0T798bPXqx36p3chrv0O+GC9Xaj48Ecv8U8UEeBvUEsDlTepiU5OvlpeNGvpnKF0RvUooWhIjnx6GeBapXCQYTw9DNg6/OC3gZjp76oNTj9Kz6Jqobxb9NDqc08vcKReOpcsQV2K8InXFaXW3aI6Ofr1k48rp7CX7rx+v1UKPsfvzQU0Kc83i2VdILmd2/yX55zT9luN2+Cu4nKfwPcK/CvDVU+pHh8+LaldIf1fA5h3ndT6Fln9/W/9Ce1vndfvJtnPVO2xhm3qbafHVCN1X363UXHq9xuVD8OSD29Z8pZ5cZrern9cAdGW/uib/ud+VK0L9a42r6C90kL8KzxwLQw9NkIQJL0ASU8M+VG0KsUdgdvpgP/6NqqP0/gHZFUfGEijZLHpiIgvV5/Bltrj8Qd7XQd5p4P+7tJo30NMO6VGBwahSPMYiaaBYoLY6uEnciyhhh1Z/vvacG/rjpsvnpzs0B1Id6fmX8119l88XnOxe/uGrzzHcdu7UtY3+2vmXN5zUyj3ZcPl8p1sZSs6/nGXtwrV7Ka0XZdz83fwjjINpZWYw85lL8BRK4nGyIir2RiOsEyipuEcIakpGjWgBjLiHWOgj0Yi34gW1kKPxHt2Na5q+lwg1RdRSpFDNzosb44YJXnAfoEOpZW//6u1lhYA6leevezbI26zNHO811M2dc5HFxpk4i1jPC0s21/BWW5DnPQbn2X1WK43/aM2n18DfSoybbNHijFpamzXI31eRibGUOxSu/lT96YZlq1Yt20DaSBuG6knw2eusHs5EPBfNmVvHKdaQzcDfz9ZsXmLDWGXy2U5OsYSsIn8CS12jQIyD12KKqZrLPy7mSPdICmd6WGHG8NDZkkHuE4h9TU8FpmUO/VjC/EinToFyoNDz2p9XD6g78WgQdPG7Z3R0T/Z5dTM9lsL8Ktek7szl2L+gQwGgwkZHc2g5Su7NvVqwGy2Ua4KSXUwt1X4PaM5paaEu6jQ5zVFyNabxvUksVt2T/4VeamYPlLtffdQsk+2sUTY/zDXl/05W53/Bz9UK3p7LjapZ2ZxOm+UlZXrL3HHGqO8+wVroDaCTTnTxitMxmiAAYQzVJQH+nj3oIHnPaN6Zq6sNSLjBl8tKgVr2mj/9CWi9dnKca8rBQBsd5R1tzVlgrl5pbnPw6kZclCr2CHxMnHohLz+3KRQokzALyeIKFU1TNCiayJdoHvDYe7K6mZLm8S3uJ9dojuaJ62/qN/tjQxnSnhnKPw+LNrLi8ZKyJ3x1YhiI1aNAtP6NzCGzYv3DmaGh/LvQZnt0evgIhTFV0kE/PYxAnOHhCQUZdCWY5JWJwMzlAGl1mpNbDU7yyGnhRMILsYhH3VRAijrPcBU8/Cj1Y9NY6cnGVW0CjTLaz7E3epvaT/LtTV72Rs+0WVVmd0dz/MGTI5F0OsIviaqDlbbO5X6xT3PeXbXHRtf/z+fdka+eKPr8KF7IF4vBsT9MFPuPJMBTBMq9hQxXelQ+bewnf18ap4Ib+mSMrtDU5zqlD8QANa5MBGh/OwOvSDfcV2d66mfEWsbGWmIz6nsyZDWQSmqmxDneYyvjHPmRXHZxeueyRGLZzvRioKnGto9nIPkibAJA16adcOZRQr1iAP3bUyBR7T4RgAWTKxhkCYFwshq+7iV9r0whk50cmRcTg4fy5x4OmmNkHndIA2+YuMbmE9dwGYB4KFTsvnDE6Ah47r/fE3AYI+oXADpkdlENcZ8OZEEf8FFGZNxMs6ZLpG3SUFLL7Q2kcFU/A/Jsw+vWDa/7emewLaoeibaF1B9qUNnuqWK3+UfXYVL1v/omD15xxeDkPnXTOKSVcCbDGtOu0YQNpGAP7U1HU58UrqGu8xIbHtkQ3LVhb7Dx46ET3Ffcm1q0YcOizNmf3bC3VjWfAcpSv3MyTlgJ23FHQgmgvk+gk8pL0mcCDOn08MDAQlf+/SlTZ1z12fnqntOhbOTL9/ZdevbAPN+yby1f/uUtC/ixm8ZBo59LTXEW060hGrTDplNprWd58fwB/b/E27BdS/s7U+rGVCeQ46nzaw9QccnmZerGZZs3Yw9aVHt+Kh6HN4ti6lxIhT/wahnZtWwzlY9QHQ2c79C+dxzvVDKy8GqKWQERO9YAKbpsDUTLdWV5dE8PVPjvj9pqw7ah/PFVtkit7aj6G5xY9mfJrCz1j1e0BcnPol4UjtrCdbahIVtd2HaURujnFJR8CuOuUUfhrGhgKKgjCYNSvCc1WKlEp8wHUaAYynFNyzZn+2MnYv36dbMDBTonl/T/ma5IKAyEGz+4eRnVtaX6tss2o34u8mWorFtuFgm4A6qK/yp/gLEBVat5WnPDdKA574ubuFJ/IUfZ/Y2Nt6mN+ZNNTSTaeI56gKwkXerTe9DDHUw8/H35FY3nNN7GGuBKWhrV9ep+0k1WjNWVaHkW1yA+QHWNu8rtBw2a5YXuE40rs7/GA+j09V3hA98yRnFPOGr8ltGlsFdD/7tRce3LH6Trcneuiy7K7J3khKu+3qUaXPWaX7T6/Kfj9BX2eZq2XAcZT79u1ClJzUtHUqfqSMWBcZS43Ena0cUGLgpkKxB1QM+0Fxz10wgg6r5rltnFpH05pepUq3Y2HfYqeKRntmUFNz+XmcOs1H31U6cC6RTVLfCg7RNBF1UF2/wBgu0fFQtPEU1sSg3VcNsR7dWq3af87tUFn1l3ltXpaJxpNvtcZkH2WmMst3JqRpxUH+WC0E1qOGtP66s1MYv+VLu8/XFXvV/ZbunYYBeVN64ls0ur6NzpV9xzlmQwB5qC4Tq70WC0tk8dWJXeHvkD0h9zJOM0vD86/1NJMaIAolctvlByferCsqOKDKceOfUu1PsmoFCamV5mCrMUOCi6V6FJosMF22AcrKJgQDVhfYh6tepp/lYgvnCEAbJQ1L0rOpajEmRcasMiPfxhgGoVo4rwreQpV6fUJHH2e8fa1s2c13Apl1b89a58ozdoap2sjgLN9uISl7P1DrulyeIkt0zr6JjWocoPOZsaXPb6jtqBblsgsaRre2xHi4nELm0MhG1+x1SXwLpFi53b+aHRYo/IrbZtuWAKu5cSEXfybnnmUCaXGTpQr0xK2O2WWY76f+nAjNVf7nCZHU5XqIkTnpt6VtvsFlPXg1031g/VRdpkkyVpD7jnmax88QwDvg/66NnMRdRXTcGTmQc3cuINwN5IQqi0yzb+YFVHuVqI5s4ADfg5oE4ybDLd28mFSFmYvRoomsWXEdLU2Wl3GJy93ZNb/d5gqmNaqJZSO1l6PVRy0nZIj/45EetjLguh1rLqR+SK0hO6NrsqcNX8zoUdjQYDJ7tb4os6+i+Y0qpY2AWlnLRDWdGFTfGY1gV0zNAtJ7pdo24se0D88AwLY/gZmE9iuP4V5v7CSR/RThaHLh+UeBkXwU6BC7lGOevK65udTv+tS/PfW7qj3ljTcj3b9OkbV85t8xsMj7Ddj7DGpthZKwKPvso/c/1K9aLE12fMWLV1y1D9ua8lyJdWXr/bG+noCFutf/mLILe39ITUV4igr3876fpX5g2zeB52sWnIL4fXHlgeUzOx5QfIvJQyrKQE9wHUqVq+PEaOrz0wVvNbJZVSfsuMzxN4l9PkedFzw9V5Dj+nzpgoT4ZxCxJfC5RWLc74YVHxKlExCYt0JAOMatREhHBSCAtSfod6x6Ls8HCWECLwXZ9nd5Dz1T24JUdWs6fU3++fcnT49Qe+kBs+wdsMZgPXMp3U5S958snPP/EE7bvkOPCuTUDTUQ/UzirLhML9yPahoe1D5Fj5jWsaoveyP00PehdUAHk/seDVWsvDWXXXsyn/4wfpXc2V3/Qxli3jl/5hj/83avSCfpTNxOEKLmTjxOEKuxgNlsQn0xgct724mhynupNW1Ph6o3RYS3/+2TJrzLlkFz+ip3qCHKf6eqW02QJLjBYuuj4sobhCWqa/YHGEHpcnumuWSOhxeaL7sOakNR6vvmo+YcfFA8UFXEPZf9UjyudIOyNwx/i90DdsujS/FX2UAwvWSVK4NxaMhAGw3oowp/uc8CTi7D2rBgZWwb/60faR7SPsEbjkXy4G0XaqhXPwe2cePjxjxuHD6ssQuR1fq6PF0E+o2t1nePTn8TUmxz/A3crMoCc7egESuoTHYc7mYdg6etORoOhR7BBGD+qJopELrl4S6cJNRtEAsLP/OdvnJq0Wo0GolY2Et9VFB2Kf+4bZvVyxfOMz3WdFfSIryj6DwWghre7aQbdiDrkTL3A3vNDuDpk93HqXwam+bWmUJZfNn5ozKV5Pmmq8PF/jVY+2Tlk2M2RzSXKjmbQ4RZcQavEYrN/9rlXwtIQqzxQNMzPPfHYLvuPoO9TbT8bpGw5CQPGd+SyX/Cyf0Vxjd2R9NmsunnXYa8xGHzn+sSfM5J0y0DZEXWWxkXjcR75KBLNLHi7XvX2G8VOrf4Ykg0AMdBESIpo7MgAfyakA6rkqpI6UjNs0px7cMV+D5BF49Tez1VGnYmq0WIijp985m4Sn2gJR9b07riPPFo97OYbUZbxJCpot7H/lpZBicglCPN7WOfJkcHqc3ElWqvvz/1E6bIQrG+tz6WkM1SM9FBTR7FSs8KyBBytSmNEoquJNFN5EQyTiCrnKDx1h58yxCepPHU5nxGoxEQeeOZi2m80DxNxncVhr6BmEfUarxejw+WSiHhWk19bSY7aKR5MsteblJpfTLtjimBouXsm3d3djjYM+wEW0El9dM/ueVRWIsXwe43R7SgbVZqrnqoJ1X/kuF7pcgf8duv4q6vayV5U9zMV91GxO59UUjW8rHV6u799WzKMT7umRCXbYUKM+foaCcwgaoqZUtmodV3p+X7akb4dnU9B9La38RPFUG2SCC90tVA4XwEFhyOpZZrUCsgWYHsczLFBBVGNtstoN1bw0Z+O4fYIbvZVt4EUcJEKOhHeincWqONw+q6w5Go+WGOSR7LhKV+KBqbBPpfUvOf9QqkpDyVhBeyyZQGMsdA5FBUqvFMtUyGq9vjnsAJU4UcrxldP1CCaofyDkSAifoP5QwWx+SyUGxp75BzGAvtG7uQ38LehlyEQMeh0TeE6Bm7tYdXqdkt0uOb3kfYlNwmOdDyacOq/qlFo1v+PTmTi3E/glC9W11b34A22zmLzvb231Q0L2Bgg60OTW4YdstO+YOJnO38TtpH7zy9ymokWyA79qlVSn38HtpFlImFnhu3b4boNWXklOXV0Iwo7lQ1hrZyPFcwtjwFP7iEKSHSSJw509kh8kj6pr+H1jR7km9vcvqN9657vffefkv+fKxge1X+7RdjYUPIESN7gTvRkB/RMYtEkaVkdHApmdBPpnKmz0n1xSWFOyVIuLrinZwpoCRe6kyiVZoHX088F+UX4+WKS4iBTP0IWxGtZgOdMaV4KTayqHQF/VihBwTbgDXTCmKoOBJeNhwJMzEVjtjIFLuU38fPR7hqNG1JS7g/qRCuy3vmQ3W9Vu8qbVbP+SzazGRJH83MzP90Ck2m31mMjP8TiLn5uwD2Ugr2PFvPQjB5BnSJvQxGQZZEB+LopqzGzDbMmbkAPkZVJjeO5FzOSBKCgJze2ZS4Gemc9twrwY6u9H61iUQTcRvtdT9RW3tRxAWwFs2tcuJRnI6xjmBdWjbgFNRHMHiF1uHYBfUR/ut5Ug2jXAaT96+9RH/FToRwIzGbKmVJ1AZQnoabSB1yyIg7ByAridHApPMjyw0OiV6RjSbCuzwLAvFizBliWJua1tsuAgvNPbmljYbpt8lkWam7b3XZiOiKJskMOtmfScnsbPW208knwjuXrXK4Q1iKIgNyYXXDVT9C2Ye/78GQ5BEEXfFdde2RwauOysdJNL5AzCy84ard/nGAVN8alecnFdgu5Gbd5DJTL+hHZK0vApVy3OfU8XTSJg1TlssivsPYUlIqvn66PzrVTymCc4wgF6SDNR0pDf+9Gp+VnsUH5WtpHYsuhOaey8zdwLN47V8MTbm78g687+P3cx6tcAeNpjYGRgYGBk8s0/zBIfz2/zlUGeZQNQhOFCWfF0GP0/8P8c1jusIkAuBwMTSBQAYwQM6HjaY2BkYGAV+d8KJgP/XWG9wwAUQQGLAYqPBl942n1TvUoDQRCe1VM8kWARjNrZGIurBAsRBIuA2vkAFsJiKTYW4guIjT5ARMgTxCLoA1hcb5OgDyGHrY7f7M65e8fpLF++2W/nZ2eTmGfaIJi5I0qGDlZZcD51QzTTJirZPAI9JIwVA+wT8L5nOdMaV0AuMJ+icRHq8of6LSD18fzq8ds7xjpwBnQiSI9V5QVl6NwPvgM15NXn/AtWZyj3W0HjEXitOc/dIdbetPdFTZ+P6t+X7xU0/k6GJtOe1/B3arN0/pmz1J4UZc+D6ExwjD7vioeGd5HvhvU+R+DZcGZ6YBPNfAi0G97iBPwFXqph2cW8+D7kjMfwtinHb6kLb6Wygk3cZytSEoptGrlScdHtLPeri1JKueACMZfU1ViJG1Sq5E43dIt7SZZFl1zuRhb/GOs44xFVDbrJzB5tYs35OmaXTrEmkv0DajnMWQB42mNgYNCCwk0MLxheMPrhgUuY2JiUmOqY2pjWMD1hdmPOY+5hPsLCwWLEksSyiOUOawzrLrYiti/sCuxJ7Kc45DiSOPZxmnG2cG7jvMelweXDNYXrEbcBdxf3KR4OngheLd443g18fHwZfFv4NfiX8T8TEBIIEZggsEpQS7BMcJsQl5CFUI3QAWEp4RLhCyJaIldEbURXiJ4RYxEzE0sQ2yD2TzxIfJkEk4SeRJbENIkNEg8k/klqSGZITpE8InlL8p2UmVSG1A6pb9Jx0ltkjGSmyDySlZF1kc2RnSK7R/aZnJ5cmdwB+ST5SwpuCvsUjRTLFHcoOShNU9qhzKespGyhXKV8SPmBCpOKgUqcyjSVR6omqgmqe9RE1OrUnqkHqO9R/6FholGgsUZzgeYZLTUtL60WbS7tKh0OnQydXTpvdGV0O3S/6Gnopekt0ruhz6fvpl+nv0n/h4GdQYvBJUMhwwTDdYYvjFSM4oxmGd0zVjK2M84w3mYiYZJgssLkkqmO6TzTF2Z2ZjVmd8ylzP3MJ5lfsRCwcLJoszhhyWXpZdlhecZKxirHapbVPesF1ndsJGwCbBbZ/LA1sn1jZ2XXY3fFXsM+z36V/S8HD4cGh2OOTI51ThJOK5zeOUs4OzmXOS9wPuUi4JLgss7lm2uU6zY3NrcSty1u39zN3Mvct7l/8xDzMPLw88jyaPM44ynkaeEZ59niucqLyUvPKwgAn3OqOQAAAQAAARcApwARAAAAAAACAAAAAQABAAAAQAAuAAAAAHjarZK9TgJBEMf/d6CRaAyRhMLqCgsbL4ciglTGRPEjSiSKlnLycXJ86CEniU/hM9jYWPgIFkYfwd6nsDD+d1mBIIUx3mZnfzs3MzszuwDCeIYG8UUwQxmAFgxxPeeuyxrmcaNYxzTuFAewi0fFQSTxqXgM11pC8TgS2oPiCUS1d8Uh8ofiSczpYcVT5LjiCPlY8Qui+ncOr7D02y6/BTCrP/m+b5bdTrPi2I26Z9qNGtbRQBMdXMJBGRW0YOCecxEWYoiTCvxrYBunqHPdoX2bLOyrMKlZg8thDETw5K7Itci1TXlGy0124QRZZLDFU/exhxztMozlosTpMH6ZPge0L+OKGnFKjJ4WRwppHPL0PP3SI2P9jLQwFOu3GRhDfkeyDo//G7IHgzllZQxLdquvrdCyBVvat3seJlYo06gxapUxhU2JWnFygR03sSxnEkvcpf5Y5eibGq315TDp7fKWm8zbUVl71Aqq/ZtNnlkWmLnQtno9ycvXYbA6W2pF3aKfCayyC0Ja7Fr/PW70/HO4YM0OKxFvzf0C1MyPjwAAeNpt1VWUU2cYRuHsgxenQt1d8/3JOUnqAyR1d/cCLQVKO22pu7tQd3d3d3d3d3cXmGzumrWy3pWLs/NdPDMpZaWu1783l1Lpf14MnfzO6FbqVupfGkD30iR60JNe9KYP09CXfvRnAAMZxGCGMG3pW6ZjemZgKDMyEzMzC7MyG7MzB3MyF3MzD/MyH/OzAAuyEAuzCIuyGIuzBGWCRIUqOQU16jRYkqVYmmVYluVYng6GMZwRNGmxAiuyEiuzCquyGquzBmuyFmuzDuuyHuuzARuyERuzCZuyGZuzBVuyFVuzDduyHdszklGMZgd2ZAw7MZZxjGdnJrALu9LJbuzOHkxkT/Zib/ZhX/Zjfw7gQA7iYA7hUA7jcI7gSI7iaI7hWI7jeE7gRE7iZE5hEqdyGqdzBmdyFmdzDudyHudzARdyERdzCZdyGZdzBVdyFVdzDddyHddzAzdyEzdzC7dyG7dzB3dyF3dzD/dyH/fzAA/yEA/zCI/yGI/zBE/yFE/zDM/yHM/zAi/yEi/zCq/yGq/zBm/yFm/zDu/yHu/zAR/yER/zCZ/yGZ/zBV/yFV/zDd/yHd/zAz/yEz/zC7/yG7/zB3/yF3/zD/9mpYwsy7pl3bMeWc+sV9Y765NNk/XN+mX9swHZwGxQNjgb0nPkmInjR0V7Uq/OsaPL5Y7ylE3l8tQNN7kVt+rmbuHW3LrbcDvam1rtzVvdm50TxrU/DBvRtZUY1rV5a3jXFn550Wo/XDNWK3dFmh7X9LimxzU9qulRTY9qelTTo5rlKLt2wk7YiaprL+yFvbAX9pK9ZC/ZS/aSvWQv2Uv2kr1kr2KvYq9ir2KvYq9ir2KvYq9ir2Kvaq9qr2qvaq9qr2qvaq9qr2qvai+3l9vL7eX2cnu5vdxebi+3l9sr7BV2CjuFncJOYaewU9gp7NTs1LyrZq9mr2avZq9mr2avZq9mr26vbq9ur26vbq9ur26vbq9ur26vYa9hr2GvYa9hr2GvYa/R7oXuQ/eh+2j/UU7e3C3cqc/V3fYdof/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6D92H7kP3ofvQfeg+dB+6D92H7kP3ofvQfRT29B/6D/2H/kP/of/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6D/2H/kP/of/Qf+g/9B/6j6nuG3Ya7U5q/0hN3nCTW3Grbu4Wrs/rP+k/6T/pP+k/6T/pP+k+6T7pPek86TzpPOk86TzpOuk66TrpOuk66TrpOlWmPu/36zrpOuk66TrpOuk66TrpOvl/Pek76TvpO+k76TvpO+k76TvpO+k76TvpO7V9t+qtVs/OaOURU6bo6PgPt6rZbwAAAAABVFDDFwAA) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')} .glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} /** Modified: embed woff file as base64 to reduce https errors and reduce requests woff is used in lieu of the better compressed woff2 version for compatability reasons **/././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.461103 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/bootstrap/js/bootstrap.min.js0000644000000000000000000011026514625637243027313 0ustar00runnerstaff/*! * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. * Licensed under the MIT license */ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'

'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1595633 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/bootstrap/fonts/glyphicons-halflings-regular.eot0000644000000000000000000004723714625637207033177 0ustar00runnerstaffNAMLP',(GLYPHICONS HalflingsRegularxVersion 1.009;PS 001.009;hotconv 1.0.70;makeotf.lib2.5.583298GLYPHICONS Halflings RegularBSGPMMF٣(uʌ<0DB/X N CC^ rmR2skPJ"5+glW*iW/E4#ԣU~fUDĹJ1/!/s7k(hN8od$yq19@-HGS"Fjؠ6C3&W51BaQaRU/{*=@dh$1Tۗnc+cA Zɀ@Qcal2>Km' CHMĬfBX,Ype U*Ҕz miO1nE. hx!aC XTV‹ R%|IHP5"bN=r/_R_ %҄uzҘ52ġP)F7SqF{nia@Ds;}9⬥?ź R{Tk;޵ǜU\NZQ-^s7f 0S3A _n`W7Ppi!g/_pZ-=ץ~WZ#/4 KF` z0| Dѵ&däIÏ;M{'omm I !wi9|H:ۧ{~qO, L]&J09/9&Y 蓰{;'3`e@vHyDZ$3Dx28 W Cx5xwB`$C$'ElyhԀ DJ $(pQAA܉A@'$ hp0V0 `se$4$"t2=f4A{Tk0|rH`L&sh]A<`R'!1N;_t3# V *veF`E O${)W=p:F`22ړC^.ćG<.pNe2ִ+Ysl:˼ ܫu5tu^86ȄTmyQ%u~%~1rҘawߚ^_ZZa0!N`. uqYB\ᨀ[e:@J'Eہ,3ubj@pfeW9( ޅ=lG7gj SM609OˑlBa݁ <Bՙ(VRApf^+g9qMt]تpEr@]@VkV ud^X R@?EY2]#Ǽ4JK'dPC|mmn#$+48u'e&[n[L%{BCDL:^!bƙ:&g3-3ub iLZڂWFSId6.k5Pl77UzT:NN.")['|U"AIvwptdk9嫫9nDmq7I|6Kbc]MBABȪ_JT q  6@Fhd`GT:M7'L,IhFP ~j $¡„ 3hA-S^چ-%qe~Qqln"i&Qe?FlK"As(3Y;"Let'RzM1 0{=) K%$C 9M4c EotjVGD)l8,\w !%$3t TBzҴ iUJ[xgdBr$!eq"J> )\~3(^ R€8#>bHG'7_ fӫcκtDoAA߃(qB<``VΫ֘*buP4v@+.Qԥ$V@C0 RܐP[z:XH#e s>?EWO>@I$|si ES)0A?9ab,@K̩o&Q% ϞLu+ +H|Ɛ?NK4CnPt 'OT.j5Ĵ8vw֜I&+`yScaO[#gQd[KI矗`ČLP # )27aTi@c\ސ 0nCpߖ運4͵x*RzYbT[\kUvHʈqp঄IIŗ) bB XPNtz 2 I== ;}bqjiކa#" >11Ap1POOuxQ Fϲ(h݄O'MDxLK$ȵh& 14SirHJPtDM;rM+ *ؗ5u2$f3K %ѳb (@,2f,~"7R;E;HX(42Z'Tۿ2J+^!#oY~4-׃GW*!A0&8f{`W=DP8'= R g}iP>#4EBRY^4eN8V,[BĨD#X],LBsNC> +o^x jC.4Ya_{eA2=r+9POA!! }YPJeGn%x1/}RgHa ^3- 5 |qSaWK{ 1al`I1 Qf_yyCZ)L3X] W6@DMT<.uGK8DsбWr\7Z\V"ISd>CUjeD 3MtWcPӉ6#3QnቩJ\7#磱`؀K lV6 &T ~l. @61`! ` wYk/a0A¹ԁYhdxk:fEao̟^<IwYgq7s[ -y1ع5aMKאRBYFq}8*Nt'.YbZvK (]&ɜ(ՙ2:0 oΏхPKiBH4UX,[$ 0mXش f50VR 8%ާDtUs`-BPzPsvI8z-t1DiB "˶YTJ .?07jLN[2tĮ̎ #6?E׻:ɞY;A&qSIR)ss 9*x0Bj)mHAhyЏhMm&4Ŋ4 gV&tYOCS0Yd7MvNj)wA(o "͢[ E`7ezď-Q]6+Bca@^I:һ=sSnc 6 OB4LGpBq/>O pwj A*@JC[h&3B Qbϩ8 :%f~v/lS00a"B8(f uGoǚgyt_y~͔ %mL !I$Xt0~ePz]Ug Н=_?.j#+`li BM5 őGp7a ֒%Y[UG9@\bDY{{ED0 $Q+FvC`ݨ3Q E\uC9![$l 6DoDgG*+X!%#Cq ?8ZUB)U@opgީZq89|uccAќW;@">Ph_9}.6V/O:3}ZS {:~ykcO6;OB=bV. Rk o ^GV= }oI"+ ]wFzϷ`<30h3]Rf859s`KM8 XUq<\ZOssM&j&  .%PBL~^Gˈ3pD:Z<\ǠiW̆"(:zX~0PG]8RQMNTqfW~!0R%Ց0xvGFy/F-wu/*+ \8@6c<L;c[º nr QS'oQuT{qҐ_ͿSdA*ð:m8Yuz2PB Hh`lkpLLh cEb6eۏҋ ?!>| *=VK@rx0G`%ryr[6Y37 f**n%9df11ޢځ^'] Rq.,^%l e#wWs56!=!q[ %Ԯ]5^:m5)?V b|u7fw,:Ye R% [ o gFAzFPx{dxíw8ٔ{{L> d2CLL,L,(mS$=|%֝lu& ą83 N Xx \VnJ[)Iw/鹻 |GźYDH*Sp60cJ2@W%Ѧc_^$#*:G6n>D;~`9hXB UJB_вˈ%w'$v|#T<68KMϑ-5U+'B ĪNbJOv'|+*Mk(d }C˱@q&aR%} !VЃs3w2a2awHz/Q0F ]~;ä NDP mK3xke_ S!V&=v_PL9؃Yi NU_)J69f*S  17F|BR$y,Ʊ.&=uqsODBR=ɳeؽɇBH 2lu'h7^#S)Xi2..Pe/@FK$](%|2Y1pC8tI11N//+\pjdWmI=߽YZxMЉP81/ JG^U ,Pd1O^ypql2h$jvI%]V .'[+WU8[D,߻-=[ O wE)3J&dقݶR¡S\. 5J$I&oHȳ~ lz> Ux/Hu;?Gt{?;TH L|F8}{p:2t͆aѧp65Y"LD.rVS_ k]n&Hz~9æ p $4ق'{&M\ΰч!qi (.h' B T|{I6cL.빍iI꫿\!;g`1 j%C o3*60E؎]t.-%0 YK_nft] *VFCtJT+\WZ8gF^ ޞf 5I=#6.@2z;W`B/ęQghjyJNAX3, K66ڲM0T@O{4kj|"ftџۄU<-a5b)^R8:ilKa6@!]buvΏ$ oUœ~:.Lte JξP l$S[z~Rq39钺9Q/m"%ʤ7 5MKL鑧"IߏG XTގXLFݧV jp^/Mgۻ{w *9Oʈ<"aAq.M2@mp^'wߕmkxO8 $[&|YZy`2_|%r/J?QṈl3ÞKE$wvCh a@U1M%0?1* $GZ{!|ʿ$ە-٪Ev;͓:`Bl˸쌧ɬoQ0&,F?^s,ch˕$Ecl0w`⏺ň@/r^l8cT3k@JݔuP&ʪNdJjTKi *uX{tj~ɡ}i\BKenȵ|N u#]@lCZ$iPa㸩t04y20 s֪,Au!QBϖ^@Vsɑ\Za7쾉ш6-TrU u~1HJ(<αbRԖqi J?eG *jVħ ":Y);-Fd!HG~ux cb6m)&;0dU?8X~12ۼtIx5{(z '[ŃkZЅi,b1̇`(mHNeK/ [(#QGduT^m%!(7KgP=hϕkɐU+.[eC"GDΨ<*Ř 9&܂?)\<&Ŏ5 LJu@Y,냲ھ_w0^17p޻*>D8_)$UźR!jOF>{ t,-bP,m`D"/zA ͔إQZG&U]xejxLwv~=)@B6?!;53/ps@tOZS7ؙnlxZ?Zj a{6L41 2Qi&֥l]o=7ļ ofЖr MEV@H/aD٦HlK5)ŒZ OE3IG'г;D'zl(E$.ٜ-W R'\w+)w3꺾 @%R).~9;].šg+)%ȝk҉^NW>b1z:soD K2w[|>9vWMFu`axchիU`*ʆe]OV'6xd?H]_rA+zdFH ʋ<ǴkUsFzaH9-gvb=L/E).x9j%B)$AB t b.bAEZRbH(Jya9Wj0fF'Xz $DQ6q` o i={#4FYH@J3 3i~tYТhkHP17YD"pĦ;'16fpu>FoDQin̒- @P# hj ނŀfC 7°T5HVXpklĭ]yXr)?ͺBNJ B#9e&&_0=pZ6h) ̗a b=(p);.N,W^ *hԺCm}E7i6aIvͲxp*Ac#4N&`)ĉHWey7jloEh_n3 jp?4p2WE'kT_ &!ȖjVlHӻ_kɚʳaY s@[G"bYLܫXi Cq8&zVaY{#I@2m!d[1 AƢnKeם/>dmuX:xʷ\pNl+H+ctSǶC[~3e}6 \,Ʉ|Yݧv]'|&M2 ddsx-((76aXm=ӊQ<$Q†\ qiH阇i'i$"{S*VwF/tfQCWUZ{S;Nx}H&* 9׸qU1 a`(M-aG}n̽0 pmcn ɘ_\l} 9FvHþkJZNO mZQҤ aSf )QC+2 d[ H"t* c*bڢq,#S#u'Ҭ:4asCDMF|ɸm_1L]Y\*X>tgDd@&[)8;<{8<+VG\H^aae-4sJA \ hM[\`#pD5Z97g;BWmqTXX%0v&]E 4]FIJ&S_4R0D+meY gO+M{03v'ͅft:;ر Nn\ǔ^,)1laBZZ[  ZSUYh߆wS\/*?zQЋ`X4gr[CWG.Y0Q|RԃE[wy),ш$NK@c/b -#ZI G$ƗtmH#)XwPZAD|S ofTH)>M1b 7ɆSuq jK4[s xL Ǣ]5 !M!AdƧN><:ǻZ(8)e /W| bDDŃtT7rur0Ң`ܴh5 5S}4hrvalc!ZjB]xDbTxzYS6_)op>#@PS*bS\q ƋxYfQ><" Y6IEr_7Ұ VH!IrEL6!Nq"'daqMvA% v n.;A/2ʲa8D$GWv#̏ 9k'o؟o@ (]gk+}/ (nqK(f Ɵиp23YwpDdGq2$}KӯA"E&Ntg'Nes!Ю4qo}쿝S,ojr/s TMT&Qf\12h'&ctN'Tx7]2 ;G ʅ|T++:%/ 1T  ˀ<4͔˗ ,0~!WO' :suҦن(^ﮎ )7fmlҹ1ūtZh L0 6X"J҂ 49 ֩B}ԭ``Ӓ #Jn_F H|$OK=œi17o-Hqp[ɫ%%:Ɉi3۠G CLL4S:dBj|pYSDP>pv5KLe{t0yEND$*;z5NBIgn.N|׶nRaSZJcH mXek;_ 6,yb0#ZA e|wG U1lLD7ÄVqt[xuEQULPBlZSh.1Q0Uٱ8Rip;{H#GON!?t>Q |pkq!gT,j2sǍ4툊tjnƛ/IOE!ˋnF4M&1x$ew+vS  bm]e%8 P !s_06)Q2JB [t9'Ԝ,[fÆג]BB@r&Bs|Q gOC1J D&LJiC`A^#X8tH?daĖTSTaH0@U)^e}Jb7%ܔ%:ƿ@M+ysqL Y00ÔGD >ĩAW 2I:F 32ʠq:6S]K"g[ ϑHB5VEqLJX{CB!PIq9Llxʪ7>֤]@!@9H!pə$ ?)܎l/"́+@`}}:\ 8zQgS+򒤿C}R:HUF\Xg/AZ%c1wlETwX ZNhyf2D ø&vLq47z\iJyJ-kN3 -sJ5)V0N0d\ӛd0d-E[mf\UmxCR<(`ѕp4^!hQ `!l ~ƙ:JɠlW9˸ZXB=l)`jeVJUG!s1?Ƽ3Ê.}bIa6ʕ t?SxZJ'p i,.R2T`5-R BxrWH JPe#Bb|-[PEh‹(5Sfr/]IƊ dE#OS39ӻ]eۮɹ.9_beM9b#e(- 0Ra9"U,%~X܀z۽{'6[@t[W%* .d'vR {h!AedCE}x=E[|B$7J* B- ,=k7[_-I J5e̶{ ( ;WMw`~pAz 8f))(@ Īم<.a%N n@bz>%T*?lgbd<ĵw9Na8;<^*%y:tDҕZ<@0q4l\ 1`/$IJ ғsN);:A;)$ו Wwy%KrIv\bV\nd{6tv/~*O 7U>8rAC<jE-j牷xs)D1Ì/qp**̸$ّ,  Bȼpk MhpK7U]h&-$鎻Y;q6wzW˄֭AhD^R"s5fw +Q&/9ȂwNbz{Y> ]NEc,ߞ# BF:0/-EȾŒ׃F\I{tAZCORuk i)ytkdN&vA P{P'>xƆ`.%,;:Կ:aFoTQ}v#ףQk's~z5hMQʒY>CʍiUNF#J0uC8k! fv {E/IKIE> pyde ʾ=z:@7J|5g8x 3O 3H1؄F.yfzWIM j[.w%i?҆Uf|}@+[8k7CxSEOޯp$Q+:<]K3T-y[Nz;y-HZY^.M*'h8A.N2rLB 7:Or}CS˚S9Jq#WI}*8D!# g#Y>8` В ?a2H,^'?^nhOƒi<Ya2+6aFaMG-Gkè1TbL `*ـVX *xe§֊Z*c`VSbJU*6TK@zqPhg*ߔU(QU49L cM*TR!R,BȅE*C|TzpF@4*텰جXbL.T2y`Upb T,%@` #?@tGLŞS)ÿztϲFy׎ 14Lhfe(.)pK@\ Xe@TbvhD&0-IbD d@ZD1@ DyѧCN| 94Ӛ#Nc l;, `cX@(2$0 "@- $B@<$А8p7C b(@ PA@F 0tGORIJITySMW52\ToRKV0Ȏ( -$ !6wHGO r~e~/]V~/P~7SzKFv`;`9v# JBN,ӭ'`'`\LTApBs)r! ( i`././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1611056 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/bootstrap/fonts/glyphicons-halflings-regular.ttf0000644000000000000000000013053414625637207033176 0ustar00runnerstaffpFFTMm*GDEFD OS/2gk8`cmapڭrcvt ( gaspglyf}]oheadM/6hhea D$hmtx `tlocao0maxpj name,post5 webfTPT=vuvs Z 2UKWN@ { , h, h@( + / _ "#%&&' ' )9IY`iy )9FIYiy !'9IY` * / _ "#%&&' ' 0@P`bp 0@HP`p !#0@P`fbߵiY!     |vpjdc]WQKED 5 *+  / / _ _  ""##%%&&&&' ' '' !& )009:@IDPYN``XbiYpyaku } )09@FHIPY`ipy !!#'09@IPY `` ((h ./<2<2/<2<23!%3#(@ (ddLL[27>32+&/#"&/.=/&6?#"&'&546?>;'.?654676X& j  j )"& j  j )L j )"& j  j )"& j LL#32!2#!+"&5!"&=463!46^^L^^p@LE32!2+!2++"&=!"&?>;5!"&?>;&'&6;22?69  x } x }  x } x v L   d    d  l d;2#4.#"!!!!32>53#"'.'#7367#73>76p<#4@9+820{dd 09B49@4#bkv$B dpd>uhi-K0! .O2d22dJtB+"0J+ku0wd/5dW%{L>G!2+!2++"&=!"&?>;5!"&?>;4632654&#^CjB0  0BjC x  x u x u@--@$?2O*$ $*P2@%d    d   BVT@L!2#!"&=46 %A+32!546;5467.=#"&=!54&'.467>=2cQQc22cQQc2A7 7AA7 7Ad[##[[##[dd76!' Pԇ $ op zy#%**%$ pdL #7!2"'&6&546 6'&4#!"&7622?62~   \l lL 7  &   l 2'7' & c_"fn &\`tfjpO32!546;! 22&&L%6.676.67646p'0SFO$WOHBXAO$WOHB"7Q)mr *`)nq&* )2"'#'".4>"2>4&ȶNN;)wdNNrVVVVNdy%:MNȶ[VVVdXD>.54>0{xuX6Cy>>xC8ZvxyDH-Sv@9yUUy9@vS-H^{62!2'%&7%&63 a o  ^{"62!2'%&7%&63#7'7#'JJN a o  d⋌&2##!"&=467%>="&=46X|>& f   f &>|.hK  ]  ]  Kh.| L#'+/37GKOSW!2#!"&54635)"3!2654&33535!3535!35!"3!2654&35!3535!35~  Ud  & sdd dd d  & d dd dL   ddd  ^ ddddddddddd  ^ dddddddddLL/?!2#!"&546)2#!"&546!2#!"&546)2#!"&5462pmppmpLpppp LL/?O_o32+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=462LppL/?O_32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462DDDLpp&,  62"'&4?622;;nnBB# "' "/&47 &4?62 62    ;    %I2"'#".4>"2>4&3232++"&=#"&=46;546ijMN,mwbMMoXXXX K  K K  KMbyl+MMijMXXX# K K  K K %52"'#".4>"2>4&!2#!"&=46ijMN,mwbMMoXXXXX^  Mbyl+MMijMXXX  -32+"&5465".5472>54&&dd[֛[ҧg|rr|p>ٸu֛[[u'>7xtrrtxd/?32+"&54632+"&54632+"&54632+"&=46  ޖ  ޖ  ޖ    ~ p     >     GO27'#"/&/&'7'&/&54?6?'6776?6"264X!)&1-=+PP08,2&+!)&1-<,P  P/:-1&+x~~~P09,1&+"(&1,=,QQ09-0&* !(&0-=,P~~~d!%)-1!2!2!5463!546!5#!"&53333333,);  ;),,;)D);dddddddd;)d KK d);ddd);;) dDDDD 62++"&5!+"&5#"&l`    j`  w  ? d3!#!"&5463#"&=X;),Rp);vLp02".4>"2>4&3232+"&546֛[[֛[[rrrr|2   [֛[[֛;rrr   2  ^  )#!3333))p,p,d/3232"'&6;4632#!"&546;2!546& & T2   2 >p  ^  12".4>"2>4&3232"'&6;46֛[[֛[[rrrr|  & [֛[[֛;rrr   12".4>"2>4&%++"&5#"&762֛[[֛[[rrrr   &[֛[[֛;rrr  9!2#!"&'&547>!";2;26?>;26'.    W & & W tW    >     '2".4>"2>4&&546֛[[֛[[rrrr[֛[[֛;rrr] $  (76#!"&?&#"2>53".4>32  mtrrr[֛[[u$  Lrrrtu֛[[֛[576#!"&?&#"#4>323#"'&5463!232>  ntr[u[u  h ntr$  Krtu֛[u֛[v h  Lr d/?O_o!2#!"&546!"3!2654&32+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=46}    R 2  2   > 2  2   > 2  2   > 2  2   >   ~   R d 2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 L#54&#!"#"3!2654&#!546;2uSRvd);;));;) SuvR;));;)X);dLL 732#462#".'.#"#"'&5>763276}2 d!C@1?*'),GUKx;(.9)-EgPL 3 0[;P$ 97W W!1A2+"&54. +"&54>32+"&546!32+"&546ޣc 2  2 c*  `  ct  ,rr  ,tޣ 4  4  G9%6'%&+"&546;2762"/"/&4?'&4?62A   Xx"xx"xx"ww".   ^ x"xx"ww"xx"r/%6'%&+"&546;2%3"/.7654'&6?6A    `Z  HN.   ^ d  g~jb1K3#"/.7654&'&6?6%6'%&+"&546;2%3"/.7654'&6?6 D@  *o;7 *    `Z  HN iT "ZG !   ^ d  g~j  !%-;?CGKO3#!#!#3!##5!!!!#53#533!3533##5#535#5!!#53#53#53!5!ddpddX,,ddddD dddd,D,ddddd dd,dddX d,,d,,ddd dddddd,dddddd  #7#3#3#3#3#3!5!#53#53#53ddddddd,,dddd,Pdd[[[[[   "'463&"260V C;S;;S;V0 ;;T;;  ! "'463!"/ &"260V 08D;S;;S;V0 V08;;T;;d&!2&54&#!"3!2#!"&54?6,9K@  D@   K|@  @  J  L !2 46 >>CEU!"3!26?6'.#"#!"&/.+";26=463!2;2654&!"3!26/.6D N9  >SV N N      & X & l l- p  v       dL!)13232#!"&546;>35"264$2"&48]4$);;));;) '3]dϾV<?!(% _5,Ry:" *28 T2*BBW-ޑY". BB % Zd'2;#!5>54.'52%32654.+32654&+50;*7Xml0 ); !9uc>--Ni*S>vPR}^3:R.CuN7Y3(;  G)IsC3[:+ 1aJ);4ePZo!56764.'&'5mSB ,J   95(1(aaR@ 9%/#4.+!52>5#"#!#3'3#72 &2p"& 2KK}}KK} dd R ,১ !%/#4.+!52>5#"#!5!'7!5L2 &2p"& 2C১  vdd  ,}KK}}KKL/?!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462X LLddddddddL/?!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=46DLDLLddddddddL/?5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&Xp LddddddddL/?!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462LLLLLddddddddL/?O_o32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ddA ddA ddA ddA LddddddddddddddddL#*:J!#;2+"&=46!2#!"&=465#535!2#!"&=46!2#!"&=46dddd ,XLdddd}KdKddddL#*:J32+"&=46#3!2#!"&=463#'7!2#!"&=46!2#!"&=462ddgdd /ȧ,XLddLdddK}}dddd!2#!"&546 K,,,,,,v,,,D,,L!2#!"&5467'2"&4,XJ*J%pNNpNL d>tNoOOo62.'&54>"264usFE66 !^Xm)!fhHuXyHÂ2".4>"֛[[֛[[Ktrr[֛[[֛oVrru5.54>6?6&'.'&76#&*IOWN>%3Vp}?T|J$?LWPI)(!1 )  HuwsuEG^F&:cYEvsxv!K:%A'# " A)Y l */7>%!2!"3!26=7#!"&546 7l l27);;));Ȼp87cs* s ;) );;)2cL6!#"3!2657#!"&546&'5&>75>^i4);;));ȹpS 9dTX .9I@F* L6;) );;)g  0!;bA4 L5!2!"3!26=7#!"&546 62"/&4?622^^  Ȫ   ȯ  ȭ   ȭ   L326'+"&546d0dLJJL#3266''+"&5462d00dLJJJJ3''&47660J*J36 &546.2   d32+"&546!32+"&546  dL#!"&5463!2L  346&5&5460d * ;O#72#"&5&5&5464646dd12N: 9  > =,L32+"&5&54646Rdd0L;;dH  #!"&762!2#!"&=46  *9HdduJ  u`((&;(J ' 7(a#aa32".4>#"#";;26=326=4&+54&֛[[֛[[}dd[֛[[֛dd2".4>!"3!26=4&֛[[֛[[E [֛[[֛~dd32".4>"'&"2?2?64/764/֛[[֛[[ xx  xx  xx  xx [֛[[֛ xx  xx  xx  xx  $2".4>'&"2764/&"֛[[֛[[Tw[֛[[֛1Uw;K2".4>";7>32";2>54.#";26=4&֛[[֛[[?2".4>#";26=4&#";#"3!26=4&+4&֛[[֛[[    KK  ^  K[֛[[֛V   2  2  2  /_3232++"&=.'#"&=46;>7546+"&=32+546;2>7#"&=46;. g  g g  g Df  fD Df  f g g  g g ͨ  fD Df  fD Df?2".4>"2>4&"/"/&4?'&4?62762֛[[֛[[rrrr@||@||@||@||[֛[[֛;rrrZ@||@||@||@||02".4>"2>4&"/&4?62762֛[[֛[[rrrrjjO[֛[[֛;rrr}jjO!2".4>"&32>54֛[[֛[[KtrAKihstr[֛[[֛;rtxiKA>rtsS6!2#!'&4' &F   &S &5!"&=463!46 &U & U ## ] #!+"&5!"&762   && ]32!2"'&63!46&# U & U # &] &5>746 ^$,[~UU & U #$DuMiqF +!2/"/&4?'&6!"&546762R,^j^!^j^^j^P,^j^IIgg+#!"&546762!2/"/&4?'&6j^^ ,^j^`j^,^^j^/2".4>#";2676&#";26=4&֛[[֛[[:#6#:1  [֛[[֛.   IUaho276?67632;2+"!#!54&+"&=46;2654?67>;26/.'&;26!"&5)#!  &0  =  2 pp 2  =   353  X  v  v !{,  2  ,ԯ  2 0y    r w  +I6.'&&&547>7>'.>7>&67>7>7>-BlabD8=3*U  :1'Ra\{%&=>8\tYR-!q[Fak[)ȕX1 "@&J<7_?3J5%#/D &/q!!6ROg58<'([@1%@_U2]rO.>7'&767>.'&'.'&>77>.'&>' '8GB    `H  >JS>H7 '+" NA 5M[`/Pg!;('2"&"IbYCe\D9$ 886#1%)*J7gG:    8G\au9hoK$]54<&"&5476&2>76&'&6?6&'&'.{nO9:On{{nO:9On{FZ  2Z__Z2  Z# %8-#,- "F-I\b\I*I\b\I--I\b\I*I\b\I9>||;7Es1$F^D10E^E$1u$/D0 "%,I';L!#7.54>327377>76&'&%7.5476&6?'&'.P[vY,9On{R=A &/l'PjR.Mv&  6QFZ  *HLh5)k|# %8- ,- "xatzbI\b\I-yRU4Zrnc1?1FrEs11) ]@ @] )1ES>L'+/37;?CGKOSW[_c3232!546;546;2!546#!"&5353353353353353533533533533535335335335335Rd22ddddddddddd|ddddddddd|ddddddddd2222pddddddddddddddddddddddddddddddw%7&=#!"&=46;3546'#"&=463!&=#'73546oXz#z*dXzdM*zL!2#!#"&546d);;)d);;L;));,;)X);dL ?32!546!32!546".5!2>&54=(LffL(, '6B6'p)IjV\>((>\VjI), +'%! !%'*L 'L'a'M 7 Maa'aQd_)!232"/&6;!%+!!"&5#"&?62**p&032!2#!!2+"&=!"&=#"&/#"&468^&d,!02**6%%+*2222 *L !53463!2!!P;),);DPdd);;)L 3463!2!!;),*:,P, pX);;)dDEk+32"/&6;#"&?62{**YDk&=!/&4?6!546X`)  )   !.#!"!"3!26=4&53353$`$-);;));;ddd-(d;)d);;)d);dddddL #12"&54%##"+"&'=454>;%".=4>7i**d]&/T7 " LRQ  )2( Jf,53232#"./.46;7>7'&6327"&)^Sz?vdjO9t\U>/ v?zS$2451 7F8%M)(  ()GM~ 1==7'''7'7'7'77 N괴N--N괴N-N--N괴N--N괴d!-=32!2+"&/#"&54?>335!7532+"&5462(<H(<,F=-7` 1dd>2vddQ,}Q,d-!2$'$(ddw} L 0<32#!+"&/&546;632+"&546!#35'!5X,<(<(21 `7-=|dd_dd22L!-d,Qv,Q($'$dd dԯ}wdO7G%6!2+#!"&5467!>;26&#!*.'&?'32+"&546dkn  T.TlnTj:d%8   VOddip &yLN(  % H YS(22S dO6F#!"&'#"&463!'&6?6*#!32!7%32+"&546n jUmlT.U  nJ   %&jPddO (SNLy& pd(Y aL7G2#!"&/&?>454&/!7%.!2#!"&=46ސNS( % p &y22SY( nTjkn  T.T8   Vd% dd-I!26=4&#!""&5&/&7>3!2766=467%'^ NLy& p  (S22(SYLddjTnlT.T  nk V   8%d%2".4>%&!"3!7%64֛[[֛[[  [֛[[֛9   &%2".4> 6=!26=4&#!54&֛[[֛[[%  [֛[[֛ &   %2".4>&";;265326֛[[֛[[K &   [֛[[֛@  %2".4>#"#"276&+4&֛[[֛[[  & [֛[[֛  2".4>%&277>7.'.'"'&65.'6.'&767>'&>7>7&72267.'4>&'?6.'.'>72>՛\\՛\\d+: =?1 " "/ ?9 #hu!$ 0 E.(,3)  (     *!A 7 ,8 !?*  \՛\\՛  ' "r"v G  .&* r$>   #1    %  *  '"  $  g2( % 67'"/&47&6PM<;+oX"O\e~Y+" n+We`#'7;!2#!"&=46#3!2#!"&=46!!!2#!"&=46!!d);;));;);;));; );;));;,;)d);;)d);dd;)d);;)d);dd;)d);;)d);dddL !2#!"&46!|;**Dd%32!2!5#!463!54635#!"&=);,); ;),;);));;)d;)pdd);d);dddD);;)+AW!2"/&546)2/"/&4?'&6#!"&54676276#!"&?'&4?622,^j^5,^j^/j^^^^j^j^,^j^&j^,^^^j#;CK2".4>"2>4&$2"&4$2#"'"&546?&542"&4$2"&4ݟ__ݠ^^oooo-- - L- 73H3)z - - - - _ݠ^^ݟWooo -!!- -! $33$ 1~ - - - -Z[%676&'&#"3276'.#"&477>32#"&'&6767632'."[v_"A0?! -  Y7J3$$ )G"#A.,= # (wnkV8@Fv"0DG([kPHNg8B*[eb2!5(7>B3$$' )M"#!7)/c# *xnfL@9NDH7!$W]B$&dXDD>.54>"".#"2>767>54&0{xuX6Cy>>xC8Zvxy#!?2-*!')-?"CoA23:+1! "3)@ +)?jDH-Sv@9yUUy9@vS-H-&65&&56&oM8J41<*.0(@  )*D*2Om9w.2&/7'/&477"/&4?BB8"._{iBBi BBBBBB7._BB^*k"5._{jBBFi BBBBBB77/_2#!"&54>!"264d:;));XV==V=.2G);;)3-D=V==V "/''!'&462*$3, #**#4$*' 2@K#.'#5&'.'3'.54>75>4.&ER<, 3'@" MOW(kVMbO/9X6FpH*M6&+  4C4%dfJ2#4.#"3#>36327#".'>7>'#53&'.>761T^'<;%T)-6"b "S5268 jt&'V7  0 $ݦ -$aPN(?",9J0* d2>2 ""   7Gd/9+DAL!X32"/&6;3+##"&?62*Ȗ*,|%#5##!32"/&6;3353!57#5!ddd,*dc,dd|ddd!%32"/&6;33!57#5!#5##!35*X,ddd,d,ddPdddL32"/&6;3##53#5#!35*Xdddd,d, dPddL32"/&6;3#5#!35##53*d,ddd, ddd32"/&6;3#53!5!!5!!5!*d,dpd , 32"/&6;3!5!!5!!5!#53* dpd,d, LL!2#!"&546!"3!2654&^pg );;));;Lp;) );;));LL+!2#!"&546!"3!2654&&546^pd );;));;oLp;) );;)); $  LL+!2#!"&546!"3!2654&!2"/&6^pg );;));; $ Lp;) );;));LL+!2#!"&546!"3!2654&#!"&?62^pg );;));; p $Lp;) );;));L5!2#!"&=463!2654&#!"&=46&=#"&=46;546&p);;)>DLpd;));d&  #%2"+'&7>?!"'&766763 ,  P'' K    S#  nnV/L5!2#!"3!2#!"&546&=#"&=46;546^>);;)pDLd;) );d&  1!2/"/&47'&6#"3!26=7#!"&5463!m)8m);;));Ȼp,pm)8m;) );;)֥#2".4>"2>4&2"&4ٝ]]ٝ]]qqqq{rrr]ٝ]]ٝGqqqsrrrL#3232"'&6;46!2!54635 ' gdV^|d22L# ++"&=#"&7>!2!54635Gz " 'gdM !d22LK" 62"'&4?62!2!54635qgdq#d22L #'762'&476#"&?'7!2!54635*MMК=gdML*Л:d22L#'/'7'&6"/&4?!2!54635^WЛԛL*MgdКԚPM*MXd22% ! q3gqdL+!#"&546;!3#53LDdddp,E/'&"!#"&546;!3#53"/&4?6262L_  Ȗdddj\jO)_ p,j[jO) >'.!#"&546;!3#53"/"/&4?'&4?62762Lg%dddFF))FF))gp,F))FF))F/!"!#"&546;!3#533232"/&6;546L dddd*p,/'&"!#"&546;!3#53++"&=#"&?62L*ndddd*pp,L !2!546#!"&5!52LPdL&}-1;&=!5!546#"&=46;#5376!!/&4#5;2+p/22ddpddd33*ȖdȖ*yddQ%6+"&5.546%2+"&5.54>323<>3234>^%"% "  d d 1t5gD >?1) A..@  ^  ^ dL3"!5265!3!52>54&/5!"!4"2pK Kp"2KKL8 88 %v% 88 x88 %v% 8LL  $(4!2#5'!7!!2#!"&546!55%!5#!!'!73wipdw%,);;));;),p,ddibbd;) );;));dfdd&767>".'.7.wfw3 .1LOefx;JwF2 1vev/ 5Cc;J|sU@L#A2/.=& &=>2#!"&=46754>ud?,  1;ftpR&mm&L!((" """" '$+  222/2 ! '!'3353353!2+!7#"&46!2!546L J LP*dd*22dL #"!4&#"!4&!46;2d);,;gd);,;;)d);L;));;)D););;)L%)!2#!"&546!#3!535#!#33||D| ,dddL| |||Dddd,ddd,L%)!2#!"&546!#5##3353#33||D| dddddddddL| |||Dddd,L#!2#!"&546!#3!!#3!!||D| ,,L| |||DdddL!2#!"&546!- ||D| ,L| |||D ,L )!2#!"&546!!!#";32654&#||D|dDd&96) )69&L| |||DdVAAT,TAAVL%)!2#!"&546!#3!535#!##53#53||D| ,ddddL| |||Dddd, d dL#'!2#!"&546!3!3##5335#53||D|DdXddd,ddL| |||Dp ddL"&!2#!"&546!#575#5!##53#53||D| d,ddddL| |||Dp2Ȗd d d %2".4>"2>4&!!!'57!۞^^۞^^qqqql,dd,^۞^^۞Lqqqddd '+2".4>"2>4&#'##!35۞^^۞^^qqqql2dddd,^۞^^۞Lqqqd2d2dddddA 62632+54&#!"#"&5467&54>3232"/&6;46n,,.xxPpVAbz  & AwasOEkdb  A32632&"#"&5467&54>++"&5#"&76762n,+.yxZ % OqVAb   AwaxchsOEkdc  dLm%5!33 33!#"!54&#Ԫ2dd,,Md22y7/2#"'2!54635#"&547.546324&546X^Y{;2 iJ7--7Ji/9iJqYZ=gJi22iJX5Jit'*BJb{"&'&7>2"3276767>/&'&"327>7>/&'&&"267"327>76&/&"327>76&/&oOOoSSoOOoS=y" $GF`   Pu "Q9   ccccVQ:   Pu "GF`   y" $ooSWWSo++oSWW"y  `FG # uP  :Q # cccc:Q # uP  $`FG # "y  d "!#5!!463!#53'353!"&5+, ?,dԢdu       d !! 463!#5##5#7!"&=)+5, ?,>dԪ |  ^G |d 77 P#3!#732!!34>3!!ddԢ!,d!s, d,+$d$+ppLL293232#!"&=46;54652#!"'74633!265#535d22s);;);)X>,>XL2dd2;));FD);>XXԢddL6=3232#!"&=46;54652#3#!"&54633!265#535d22s);!);;)X>,>XL2dd2;) $+;) );>XXԢd  #!"&762#";2676&35} ,, }@D:#6#:&77&P'L. dd LL/?O_o32+"&=4632+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=46                  L                  )33#!2!&/&63!5#5353!2+!7#"&46!2!546dd^>1B)(()B1>^dd> J LPdO7S33S7Odd|*dd*22+52#4!!2!'&63!&54!2+!%5#"&46!2!5460P9<:H)"Z" )HJLP;))%&!!&**22$.2"&432!65463!2+!7#"&46!2!546 jjj."+''+# J LPjjj9:LkkL:9r*dd*22,62"&5477'632!65463!2+!7#"&46!2!546X/[3oo"o"."+''+# J LPk6NooN>Qo 9:LkkL:9r*dd*22",!!.54>7!2+!7#"&46!2!546X,%??M<=BmJ J LP9fQ?HSTTvK~*dd*22)2!546754!2#3#3#3#!"&546/R;.6p6.d6\uSpSuu;)N\6226\N)G6.dddddSuuSSudLL/3!2#!"&546!2#!"/!"&4?!"&=46!'|  % XW & dDdL D 2  % XX %  2 dddL#-7!2#4&+"#4&+"#546!2!46+"&=!+"&= Sud;));d;));du);P;ddLuS);;));;)Su ;),); 2222  !&4762 !2!546 'YV/ |UYY(n0U22!/.#!"3!26=326!546;546;33232!'p'q*}20/222,2 "!#!5463!#5!#!"&5463!#5,  w,, v  w, O,T    dGFV32676'&7>++"&?+"'+"&?&/.=46;67'&6;6#";26=4&KjI C   )V=>8'"d 1*) "dT,| -otE  GAkI ! "% ,=?W7|&F@Je5&2WO_e_ 2  2 ~ $4<Rb%6%32!2&'&#!"&=46#";2654&'&"2647>?&/&6%?6'.'.. +jCHf7" *:>XXP* @--@- -?0 !3P/|)( )f!% =  &* x"62&CX>>X83 D-@--@ۂ # =I+E( //}X&+ 5!H d9Q`o322#+"&=#+"&=#"&=46;#"&=46;546;23546!2>574.#!2>574.#q Oh ..40:*"6-@# d   KK   d)  )k)  ) m!mJ.M-(2N-;]<* K  KK  K X K  KK  "p "),!2#!"&'.546"!7.# Vz$RR(z }VG+0 )IU!zV`3BBWwvXZ3Vz&--% ,(1#32#!"&546+"&=ۖgT)>)TH66g )TT)g6633#!"&546+"&=`T)>)TH66B)TT)g66 %'5754&>?' %5%Ndd/\^^<ǔȖ  (Abd 2"&4$2"&4$2"&4|XX|X|XX|X|XX|X X|XX|XX|XX|XX|XX|L2"&42"&42"&4|XX|XX|XX|XX|XX|XLX|XX|X|XX|X|XX|ddLL/!2#!"&=46!2#!"&=46!2#!"&=46}  J    J    J L  p  p  /3!2#!"&546!"3!2654&!2#!"&546!5^ );;)X);; G ;));;)X);d,dddL;!2+32+32+32#!"&46;5#"&46;5#"&46;5#"&46222222222222L********, *.62"&%#462"&%#46"&=32W??WW??||||||*(CBB||||԰||||ӐB76+2+"47&"+".543#"&'&676/!'.6E*  '?) T 0I' *L #3{,# n  6F82 *5#"#!#4.+3#525#"#5!2 &2p"& 2D d 2d  dd R , W 22 L 05"'./#!5"&?!##!"&=463!2E  1;E%= !'y,2 " # 22+."A2VddGJ!2#!"&546#"3!26=4&#"'&?!#"3!26=4&'"'&'#&#2LFF &  7 ? 9   9 gLR   2 2  2 2 $ #'!5!!2#!"&546)2#!"&546!PpmpG,Ld|pd,#'!2#!"&546!2#!"&546!!5!2pmpG,P| pd,dd'+!235463!23##!"&=##!"&546!2dddpdp,d ,'3#3!2#!"&546!!2#!"&546dddpG,|dpd, pdL'+32+!2#!"&5463!5#"&546;53!X|^d,Lpdpdd,'!#3!2#!"&546!!2#!"&546ddvpG,|dpd, p,0o #"&54632a5*A2~ 6'&4O**{))*2A~ !2"'&6d)***2,~o #!"&762{))*a**( 5-5!5!Lc d 1#3!35#5!34>;!5".5323!,P2 &d2"d& 2dd,dd  dd & ,L%1#4.+!52>5#"#!#3!35#5! 2 &d2p"d& 2 ,, dd & ,dd,ddfrJ32 +"'&476 0  ) J 00   >fJ32+"&7 &6S )  0 J ))   fJr"'&=46 4 ))  w  )  0f>J ' &=4762j  00  )  0  =:#463267>"&#""'./.>'&6|Vd&O "(P3G*+*3M, :I G79_7&%*>7F1 ||5KmCKG\JBktl$#?hI7 !2+&5#"&546!5X,p dddL!2%!#4675'=DXDd dQ,[u}4]ddMo__<vsvsQQ(dpEHEd{ d&ndd ddddd5d!u ,d;I]ddQEJadd9'dddd dy'dddddddd,d,A22>ff****NNNNNNNNNNNNNN"~Fn2b\r bb 6 ( L 0  X * ^ h(T*v 8|t*<6`R.j(h6h^2Dl.vb F !2!v!"@""##"#8#z##$$0$^$$%4%`%&&~&'P''(4(p())*&*J*+ +z,,h,,---.(.f..//F/~//0>0011`112$2^223"3>3h344`445,556>6|677N7788B889 9J99::l::;;<:>>?(?n??@H@@AA~BBBCCBCvCCDD`DDEZEFFtFFG6GvGGHH2HNHjHHII8I^IIJJ.JR@. j (|  L 8 x6 6   $ $4 $X | 0 www.glyphicons.comCopyright 2014 by Jan Kovarik. All rights reserved.GLYPHICONS HalflingsRegular1.009;UKWN;GLYPHICONSHalflings-RegularGLYPHICONS Halflings RegularVersion 1.009;PS 001.009;hotconv 1.0.70;makeotf.lib2.5.58329GLYPHICONSHalflings-RegularJan KovarikJan Kovarikwww.glyphicons.comwww.glyphicons.comwww.glyphicons.comWebfont 1.0Wed Oct 29 06:36:07 2014Font Squirrel2       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~     glyph1glyph2uni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni20BDuni231Buni25FCuni2601uni26FAuni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200uniE201uniE202uniE203uniE204uniE205uniE206uniE209uniE210uniE211uniE212uniE213uniE214uniE215uniE216uniE218uniE219uniE221uniE223uniE224uniE225uniE226uniE227uniE230uniE231uniE232uniE233uniE234uniE235uniE236uniE237uniE238uniE239uniE240uniE241uniE242uniE243uniE244uniE245uniE246uniE247uniE248uniE249uniE250uniE251uniE252uniE253uniE254uniE255uniE256uniE257uniE258uniE259uniE260uniF8FFu1F511u1F6AATP././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1598988 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/bootstrap/fonts/glyphicons-halflings-regular.svg0000644000000000000000000032430214625637207033176 0ustar00runnerstaff ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4612067 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/css/chartist.min.css0000644000000000000000000002636414625637243025440 0ustar00runnerstaff.ct-double-octave:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-grid-background,.ct-line{fill:none}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4612844 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/css/Auto.css0000644000000000000000000000010114625637243023722 0ustar00runnerstaff@import url('Night.css') screen and (prefers-color-scheme: dark);././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.461372 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/css/login.css0000644000000000000000000000200214625637243024124 0ustar00runnerstaffbody { overflow-y: scroll; background-color: #E4E4E4; } * { border-radius: 0 !important; } .btn, .btn:hover, .btn:active, .btn:focus { box-shadow: 1px 1px 1px rgba(0,0,0,.1) !important; background-color: white !important; } .logo-header { padding-bottom: 10px; } .logo-header svg { height: 55px; width: 198px; } .account-wall { width: 300px; position: absolute; top: 30%; left: 50%; transform: translate(-50%, -30%); } .text-center a { position: absolute; right: 13px; top: 12px; color: #636363; font-size: 1.2em } .text-center a:hover { color: black; } .form-signin .alert { margin: 5px 0px; } .form-signin input { margin-top: 5px } .form-signin .btn { width: 100%; margin-top: 10px; font-weight: bold; } .btn .glyphicon { margin-left: 3px; float: right; top: 1px; font-size: 1.2em; } input[type="checkbox"] { width: 16px; height: 16px; margin-top: 2px; } label { color: #636363; }././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.461457 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/css/Night.css0000644000000000000000000001272414625637243024101 0ustar00runnerstaffbody { background-color: black; color: #EBEBEB !important; } a:not(.btn) { color: #63a7e1; } .btn { box-shadow: 1px 1px 1px rgba(255, 255, 255, .1) !important; } .btn:not(.btn-danger), .btn-default, input, select, textarea, .advanced-button, .list-group-item { border-color: #252525 !important; } #addFeed, #addFeedContent, .section { border-bottom: 1px solid #555555; } .col2 p, .col2-cats { color: #AAA; } .col2 h3 { background: none repeat scroll 0 0 #555555; } .catTable, .dropdown-menu, .dropdown-menu .divider, .even, .Key tr:nth-child(odd), .language:hover, .navbar-default .navbar-nav>.open>a, .navbar-default .navbar-nav>.open>a:focus, .navbar-default .navbar-nav>.open>a:hover, .navbar-default .navbar-nav>li>a.active, .navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus, .navbar-logo:hover, .quoteBlock, .selected, .server-disabled, #serverResponse, .table>tbody>tr:nth-child(odd), .table-striped>tbody>tr:nth-child(odd), ul.tabs li.active a, select[disabled], select:hover { background-color: #444444 !important; color: #EBEBEB !important; } .correct { border: 2px solid #00cc22 !important; } .failed, .required-star, .error-text { color: #ff3333 !important; } .unselected, .selected { border: 1px solid #EBEBEB !important; color: #EBEBEB !important; } .incorrect { border: 2px solid #ff3333 !important; } .disabled-text { color: #777 !important; } #rightGreyText, small { color: #c7c7c7 !important; } .Categories form.sorting-row:nth-child(2n-1) tr, .advanced-button, .advanced-buttonSeperator, .alt, .infoTableSeperator.alt, .btn:not(.btn-danger), .btn-default.disabled:active, .btn-default.disabled:focus, .btn-default.disabled:hover, a.btn.btn-default, select.form-control, .form-control[disabled], .input-group-addon, #inner, .navbar-default, .search-box input, .select, .table-striped>tbody>tr:nth-child(even), .table>tbody>tr:nth-child(even), .tab-pane tr:nth-child(odd), textarea, ul.tabs a.active, a.list-group-item, .dropdown-menu>li>a, input[type="text"], input[type="email"], input[type="url"], input[type="date"], input[type="number"], input[type="password"], input[disabled], textarea, select { background-color: #555555; color: #EBEBEB; } .btn:hover:not(.btn-danger), .btn-default:hover, .tab-content .catTable tr:hover td, input:hover, textarea:hover, a.list-group-item:hover, select:hover, textarea:hover, input[type="date"]:hover, input[type="datetime"]:hover, input[type="datetime-local"]:hover, input[type="email"]:hover, input[type="month"]:hover, input[type="number"]:hover, input[type="password"]:hover, input[type="search"]:hover, input[type="tel"]:hover, input[type="text"]:hover, input[type="time"]:hover, input[type="url"]:hover, input[type="week"]:hover, textarea:focus, select:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="email"]:focus, input[type="month"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus { background-color: #666; color: #EBEBEB; } .btn-default:focus, .form-control:focus, input:focus, textarea:focus, select:focus { border-color: #707070 !important; outline: initial !important; box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.3) !important; } .modal-backdrop { background-color: #262626 !important; } .Key tr { border: none; } .table>tbody>tr>td, .table>tbody>tr>th, .infoTableSeperator, .modal-footer, .data-row { border-top: 1px solid #555555; } hr { border-top: 1px solid #555555; } .btn-danger { border-color: #7b2b28; } .tab-content .catTable tbody, ul.tabs a, .colmask, #subscriptions, .RSS form[action="add_rss_feed"] tr:nth-child(even), .Config .table { border: 1px solid #555555 !important; } .Categories form:first-of-type tr:last-of-type, .default, .dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover { background-color: #696969; } .activeRSS, .activeRSS a, .activeRSS a:visited, .btn-default, .checkbox label, .feed-row td, .help-block, #content, .navbar-default .navbar-nav>li>a, .navbar-default .navbar-nav>li>a>.glyphicon, .path, .Servers .ct-label, .time, .main-restarting.in, #search-dropdown .dropdown-header, ul.tabs a, a.wizard-advanced-settings, .quoteBlock a, a.main-helplink, col2 h3 a, .text-center a, .text-center a:hover { color: #EBEBEB; } .container, #content { background-color: unset !important; } #content>div.colmask>div:nth-child(3) { border-bottom: 1px solid #555555 !important; } .Servers .ct-series-a .ct-line, .Servers .ct-series-a .ct-point { stroke: #EBEBEB; } #inner, .colmask { background-color: #303030; } .modal-header { background-color: #3C3C3C; } .modal-content, .modal-body, .modal-footer { background-color: #727272; } #modal_qr .modal-body { background-color: #EBEBEB; } .form-signin .btn.btn-default { color: black; } .rss-icon-svg { fill: white; } .rss-symbol { fill: #555555; } ::placeholder { color: #EBEBEB !important; opacity: 0.5; } .tooltip-inner { background-color: #E4E4E4 !important; color: #000 !important; } /* for login */ .tooltip.bottom .tooltip-arrow { border-bottom-color: #E4E4E4 !important; } /* config>general - host-warning */ .tooltip.top .tooltip-arrow { border-top-color: #E4E4E4 !important; } .Special .glyphicon-asterisk { color: #E4E4E4 !important; } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4615474 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/css/style.css0000644000000000000000000006333614625637243024175 0ustar00runnerstaffbody { overflow-y: scroll; background-color: #E4E4E4; } #logo { display: block; margin: 3px auto auto; } #content { color: #000; padding: 65px 20px 20px; font-size: 13px; } .colmask { z-index: 20; position: relative; clear: both; float: left; overflow: visible; border: 1px solid #dfdede; background-color: #FFF; width: 100% } .advanced-button { float: right; width: auto; margin: 0 4px 0px 0px; font-size: 13px; color: inherit; height: auto; padding-bottom: 5px; } #advanced-settings-button { float: left; margin: 2px 7px 0px 0px; } .advanced-buttonSeperator { width: 1px; height: 34px; background-color: #dfdede; float: right; margin: 0px 10px; } .section, #addFeed, #addFeedContent { border-bottom: 1px solid #dfdede; overflow: auto; } .col2 { z-index: 10; float: left; overflow: auto; padding: 12px; width: 250px; } .col1 { z-index: 11; width: 100%; float: none; padding: 12px 0 0; } .col2 h3 { background: none repeat scroll 0 0 #666; color: #fff; padding: 6px 8px; vertical-align: middle; margin: 0; font-size: 1.4em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; position: relative; } .col2 h3 a { display: none; position: absolute; right: 8px; bottom: 0.4em; color: white; font-size: 0.8em; } .section:hover .col2 h3 { padding-right: 25px; } .section:hover .col2 h3 a { display: inline-block; } .main-helplink { display: block; position: static; float: right; color: black; padding: 0px; font-size: 1.2em; } .example { background-color: #fefeee; } .presets strong { display: inline-block; width: 75px; } .presets { margin-bottom: -6px; max-width: 60%; } .presets input { margin: 2px 0; } .presets input[type="button"] { margin: 0px 2px 6px 0px; } label.config, .field-pair h5 { overflow: auto; float: left; width: 24%; font-weight: 700; display: block; text-align: left; margin-right: 10px; margin-left: 20px; padding-top: 5px; } label.config-hover { cursor: pointer; } label.narrow { width: 200px!important; } label.wide, .field-pair h5 { width: auto!important; } .field-pair h5 { margin-bottom: 5px; line-height: normal; } .desc { display: block; margin: 0 0 0 24%; padding: 3px 0 0 31px; font-size: 12px; font-style: italic; } .desc .btn { font-style: normal; } .desc.narrow { margin: 0 0 0 200px!important; } input[type="checkbox"]+.desc { padding-top: 6px; } .desc-check { font-size: 12px; font-style: italic; padding: 0 1px; } .col2 p, .col2-cats { font-size: 12px; color: #666; margin: 1em 0; } .field-pair { padding: 6px; clear: both; float: none; overflow: hidden; min-width: 555px; } .Key tr:nth-child(odd), .tab-pane tr:nth-child(odd), .even { background-color: #F8F8F8; } .field-pair:last-child, .field-pair.no-field-pair-bg { background-color: transparent !important; } .alt, .infoTableSeperator.alt { background-color: #F8F8F8; } .success { color: #5cb85c !important; } .typeahead.dropdown-menu { padding: 0; min-width: 300px; margin: 0; } .typeahead.dropdown-menu>li>a { padding-left: 12px; font-size: 13px; } .typeahead.dropdown-menu>.active>a, .typeahead.dropdown-menu>.active>a:focus, .typeahead.dropdown-menu>.active>a:hover { color: black; background-color: #E5E5E5; } #content fieldset { border: 0; outline: 0; min-width: 350px; margin: 0; padding: 0 12px 12px 6px; } textarea, select, input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"] { padding-left: 5px; border: 1px solid #d4d0c8; } select option { padding-left: 5px; } #check_new_rel option, #check_new_rel { text-transform: capitalize; } input[type='checkbox'] { display: block; white-space: nowrap; padding: 0; margin-left: 5px; } textarea:hover, input[type="date"]:hover, input[type="datetime"]:hover, input[type="datetime-local"]:hover, input[type="email"]:hover, input[type="month"]:hover, input[type="number"]:hover, input[type="password"]:hover, input[type="search"]:hover, input[type="tel"]:hover, input[type="text"]:hover, input[type="time"]:hover, input[type="url"]:hover, input[type="week"]:hover, textarea:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="email"]:focus, input[type="month"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus { background-color: #fffff0; border: 1px solid #aaa; } .col1 input[type='checkbox'] { position: absolute; top: auto!important; height: 16px; width: 16px; margin-left: 0; } .col2 input[type='checkbox'] { height: 16px; width: 16px; margin-top: 0; } .readonly { background-color: #eff; } .multiple_cats { padding: 5px 10px!important; margin-top: 2px; } .padding { padding: 6px; } .disabled, .disabled input, .disabled .clearBtn, .disabled .patternKey, .disabled .show_qrcode, .disabled .generate_key, .disabled .generate_cert { color: #aaa !important; } .padTable p { margin-top: 0; } .nomargin { margin: 0; } .copyright { margin: 0; padding: 6px; } .path { color: #000; font-weight: 400; } .darkred { color: #d9534f; } .scheduleEntry { padding: 8px 0; } .time { padding: 0 10px; color: #000; font-weight: 700; } .frequency { padding-right: 5px; letter-spacing: .5px; } .padTable { padding: 15px; overflow: auto; clear: both; } .label { font-style: normal; } .padTable h3 { margin-top: 0; } tr.separator { height: 30px; } .catTable th, .catTable td { padding: 5px; } .catTable th { text-align: center; } .catTable .glyphicon-option-vertical { color: #808080; display: block; margin-right: -5px; cursor: move; } .Categories form:not(.sorting-row) .glyphicon-option-vertical { visibility: hidden; } .Categories form.sorting-row:nth-child(2n-1) tr { background-color: #F8F8F8; } .Categories form:first-of-type tr:last-of-type { background-color: #FFFFE0; } .Categories hr { margin: 5px; } .Sorting .explain-pattern { border: none; width: 100%; } .Sorting .pattern-table { border:1px solid #ccc; } .Sorting .sorter-switch { margin-right: 0.2em; } .Sorting .sorter-switch-container { margin: 10px 0px; height: 1.5em; display: block; } .Sorting .sorter-placeholder { position: relative; } .Sorting .sorter-placeholder:after { content: "\e034"; font-family: "Glyphicons Halflings"; background: unset; text-align: center; position: absolute; bottom: 0; left: 0; right: 0; height: 30px; border-radius: 15px; border: 1px dashed #444; } .Sorting .glyphicon-option-vertical { margin-top: 1.5em; margin-right: 0.2em; cursor: move; } .Sorting form:not(.sorting-row) .glyphicon-option-vertical { visibility: hidden; } .Sorting .sorting-quick-setup { padding: 1.5em 2em 3em } .RSS .rss-section input[type="text"] { max-width: 180px; } .RSS .catTable select { max-width: 120px; } .RSS input[type="checkbox"] { width:16px; height: 16px; margin-top: 0px; } .RSS form[action="add_rss_feed"] tr:nth-child(even) { border: 1px solid #E5E5E5; } .RSS .tab-pane table th:not(.no-sort) { cursor: pointer; } .RSS .tab-pane table th:not(.sorted) { padding-right: 12px; } .RSS .tab-pane table th.sorted { padding-right: 0px; } .RSS .tab-pane table th.sorted.ascending:after { content:''; display: inline-block; width: 0; height: 0; margin-left: 4px; vertical-align: middle; border-bottom: 4px dashed; border-right: 4px solid transparent; border-left: 4px solid transparent; } .RSS .tab-pane table th.sorted.descending:after { content:''; display: inline-block; width: 0; height: 0; margin-left: 4px; vertical-align: middle; border-top: 4px dashed; border-right: 4px solid transparent; border-left: 4px solid transparent; } .Config .table { margin: 0; border: 1px solid #ddd } .Config .colmask { margin-bottom: 12px; } .Config .padding { padding: 13px; } .Config th { width: 20%; min-width: 150px; padding-left: 15px !important; } .Config .label { font-size: 90%; } .Config td .glyphicon-question-sign { color: black !important; top: 3px; } .tab-pane thead tr { background-color: transparent !important; } .default { background-color: #ffffe0; border-bottom: 1px solid #aaa; border-top: 1px solid #ddd; } .hidden { visibility: hidden; display: block!important; } .float-left { float: left; } .float-right { float: right; } .align-left { text-align: left; } .align-right { text-align: right; } .align-center { text-align: center; } .valign-top { vertical-align: top; } .nowrap { white-space: nowrap; } .Key { display: none; border: 1px solid #ccc; width: 425px; } .Key th { background: none repeat scroll 0 0 #666; color: #fff; margin: 0; padding: 3px 9px; } .Key td { padding: 2px; } .Key tr { border-bottom: 1px solid #ccc; } #infoTable { font-size: 12px; width: 100%} #infoTable tr { line-height: 17px; } .infoTableHeader, .infoTableCell { padding: 6px; word-break: break-all; } .infoTableHeader { font-weight: 700; width: 160px; } .infoTableSeperator { border-top: 1px solid #ddd; } .icon { padding-left: 5px; } .modal-content { box-shadow: none; } .modal-backdrop { background-color: white; } .modal-backdrop.in { opacity: 0.8; } .modal-body { padding-bottom: 0; } .modal-dialog { padding: 3px; } .modal-body h4 { word-break: break-all; } .modal-header { background-color: #3C3C3C; color: white; border: 0; padding:11px 12px 8px; } .modal-header .close { opacity: 0.5; background: transparent; color: white; text-shadow: none !important; font-weight: normal !important; font-size: 32px; vertical-align: middle; margin-top: -5px; font-family: arial, sans-serif !important; } .modal-header .close:hover { opacity: 1; } .modal-dialog { transform: scale(0.7) !important; -webkit-transform: scale(0.7) !important; opacity: 0 !important; transition: all 0.3s !important; } #modal_qr .modal-body canvas { padding: 10px; margin-bottom: 10px; } .modal.in .modal-dialog { transform: scale(1) !important; -webkit-transform: scale(1) !important; opacity: 1 !important; } .btn-default.fileBrowser, .btn-default.clearBtn { margin-left: -1px !important; box-shadow: 1px 0px 1px rgba(0,0,0,.1) !important; } #filebrowser_modal .list-group-item { font-weight: bold; } #filebrowser_modal .list-group-item span { margin-right: 10px; top: 0; } #filebrowser_modal .checkbox { float: left; margin: 8px 5px 0px; } #filebrowser_modal .checkbox input { margin-top: 1px; } #filebrowser_modal .checkbox input+span { opacity: 0.6; font-weight: bold; } #filebrowser_modal .checkbox input:checked+span, #filebrowser_modal .checkbox span:hover { opacity: 1; } /* Fix for shifting scrollbars when opening modals */ .modal-open[style="padding-right: 17px;"] .navbar-fixed-top { padding-right: 17px; } .modal-open[style="padding-right: 15px;"] .navbar-fixed-top { padding-right: 15px; } .modal-open[style="padding-right: 13px;"] .navbar-fixed-top { padding-right: 13px; } /* -- */ .RSS .addRssTable, .RSS .addRssTable input[type="text"] { width: 100%; } .RSS .addRssTable .new-feed-title { max-width: 250px; } .RSS .addRssTable .new-feed-url { width: 70%; } h2.activeRSS { margin-bottom: 10px; } .activeRSS a, .activeRSS a:visited { color: #000; text-decoration: underline !important; } .favicon { background-position: center center !important; background-size: 22px 22px; opacity: 1; top: -1px; height: 22px; width: 22px; float: left; margin: 0 6px 0 2px; text-align: center; color: black !important; } .source-icon span { top: -3px; } .feed { text-decoration: none; } .feed_enabled { color: #000; } .feed_disabled { color: red !important; } #subscriptions { border: 1px solid #E5E5E5; width: 100%; } .data-row { border-top: 1px solid #E5E5E5; } #subscriptions td { border: 0 none; padding-top: .4em; } #subscriptions .chk { padding: 8px 5px 5px; vertical-align: middle; width: 40px; } #subscriptions .title { font-weight: bold; padding-right: .3em; width: auto; } #subscriptions .favicon { margin-left: 7px; margin-top: -2px; } #subscriptions .glyphicon { margin-top: 3px; } .subscription-title, .subscription-title:hover { width: 20em; overflow: hidden; white-space: nowrap; display: block; text-decoration: underline; color: black; } .controls { text-align: right; padding-right: 5px; white-space: nowrap; } .feed-row td { color: #777; max-width: 515px; padding: 0 0 .5em; } .feed-row div { overflow:hidden; white-space: nowrap; text-overflow: ellipsis; } .tab-content .catTable { width: 100%; } .tab-content .catTable th { text-align: left; } .tab-content .catTable tbody { border: 1px solid #ddd; } .tab-content .catTable td { line-height: 2em; } .tab-content .catTable td:nth-child(4) { word-break: break-all; } .tab-content .catTable tr:hover td { background-color: #F2F2F2; } span.count { background-color: #6E6E6E; color: #fff; margin: -3px 0 0 5px; padding: 1px 10px; } a.current .count { background-color: #777!important; } a.current:hover .count { background-color: #333!important; } ul.tabs { margin: 0!important; padding: 0; height: 30px; } ul.tabs li { float: left; padding: 0; margin: 0; list-style-type: none; } ul.tabs a { float: left; font-size: 13px; display: block; padding: 5px 30px; text-decoration: none; border: 1px solid #dfdede; border-bottom: 0; color: black; margin-right: 2px; position: relative; top: 1px; outline: 0; } ul.tabs a:hover { background-color: #eee; color: #333; } ul.tabs li.active a { background-color: #eee; border-bottom: 1px solid #f8f4e7; color: #000; cursor: default; } .checkbox-days { float: left; } .checkbox-days p { margin: 0 0 5px 0; } .checkbox-days input { vertical-align: middle; margin-top: -1px; } .checkbox-days label { padding: 2px 20px; } /** EDITS 2015 **/ * { border-radius: 0 !important; } .collapsing { -webkit-transition: none; transition: none; } input[type=checkbox], input[type=radio] { margin-top: 2px; } input[type="button"], input[type="submit"] { color: #333; display:inline-block; padding:6px 12px; margin-bottom: 0; font-size:13px; font-weight:400; line-height:1.42857143; text-align:center; white-space:nowrap; vertical-align:middle; cursor:pointer; background: #fff none; border:1px solid #ccc; height: 34px; } input[type="button"]:hover, input[type="submit"]:hover { color: #333; background-color: #e6e6e6; border-color: #adadad; } input[type="text"], input[type="email"], input[type="url"], input[type="date"], input[type="number"], input[type="password"], textarea, select { line-height:1.42857143; padding:6px 12px; border: 1px solid #d4d0c8; box-shadow: inset 0 1px 1px rgba(0,0,0,.075); display:inline-block; vertical-align:middle; max-width: 100%; min-height: 34px; min-width: 55px; font-size: 13px; background-color: white; } input[type="text"]:not([size]), textarea { width: 300px; } input[type="number"], input[type="text"].smaller_input { width: 120px; } .btn { font-size: 13px; height: 34px; box-shadow: 1px 1px 1px rgba(0,0,0,.1) !important; } .btn .glyphicon { top: 2px; } .btn .glyphicon-ok, .btn .glyphicon-plus { top: 1px; } select { min-width: 200px; max-width: 300px; } input[disabled], select[disabled] { background-color: #eee; } select[multiple] { width:100%; padding: 0 !important; } .col1 select[multiple] { max-width: 300px; } select[multiple] option { padding:6px 12px; } input[type="checkbox"] { margin-top: 5px; } .Scheduling select, .Categories select, .RSS select { min-width: 120px; } .Categories select { max-width: 150px; } .Categories #content input { max-width: 150px !important; } .Scheduling form[action="addSchedule"] input[type="checkbox"] { margin-top: 0px; margin-left: -20px; } .Scheduling form[action="delSchedule"] input[type="checkbox"] { position: initial; float: left; margin: 9px 10px 0px 5px; } .navbar .container { padding-right: 0; } .navbar .nav>li>a { height: 50px; } .navbar-default { background-color: #FFF; border-bottom: 1px solid rgba(0, 0, 0, 0.2); margin-bottom: 10px; } .navbar-fixed-top { z-index: 1000; } .navbar-logo { display: inline-block; padding-right: 10px; padding-left: 10px; padding-top: 5px; margin-left: 5px; margin-bottom: -1px; } #search-menu .glyphicon { top: 3px; } #search-dropdown { right: 0; left: auto; width: 300px; padding: 5px; } #search-dropdown .dropdown-header { font-weight: bold; color: black; } #search-dropdown a { overflow: hidden; text-overflow: ellipsis; } .navbar-logo-small svg { height: 40px; width: 40px; } /* .navbar-logo-wide { display: none; } .navbar-logo-wide { padding-top: 9px; } .navbar-logo-wide svg { height: 36px; width: 130px; } */ .navbar-default .navbar-nav>li>a { color: black; } .navbar-default .navbar-nav>li>a:hover, .navbar-logo:hover { background-color: #e2e2e2 !important; } .navbar-default .navbar-nav>li>a.active { background-color: #ECECEC !important; } .navbar-default .navbar-nav>li>a>span, .navbar-default .navbar-nav>li>a>svg { display: none; } #navbar .glyphicon-folder-open { margin-right: 2px; } .rss-icon-svg { display: inline-block; margin-top: 1px; margin-bottom: -1px; width: 1em; height: 1em; } .rss-symbol { stroke: none; fill: white; } .col2 table { margin: 10px 0px; } .Servers .server-frame { position: relative; width: 220px; height: 325px; margin-bottom: -325px; left: -240px; display: none; } .Servers .server-frame a { color: black !important; text-decoration: none !important; opacity: 0.8; font-size: 2em; font-family: arial, sans-serif !important; position: absolute; right: 5px; top: -5px; } .Servers .server-frame iframe { width: 100%; height: 100%; border: 0; } .Servers .col2 .label { margin-top: 8px; font-size: 0.85em; float: right; line-height: 1.1em; } .Servers .col2.server-disabled .label { color: #777 !important; } .Servers .col2 .label:nth-child(2) { opacity: 0.7; } .Servers .server-amounts-text { width: 20%; float: left; } .Servers .server-chart { float: right; width: calc(100% - 250px - 25%); text-align: center; position: relative; } .Servers .ct-series-a .ct-line { stroke: #666666; } .Servers .ct-series-a .ct-point { stroke: #666666; stroke-width: 4px; } .Servers .ct-series-a .ct-area { fill: #666666 } .Servers .ct-label { font-size: 1em; color: black; } .Servers .chart-selector-container { float: right; } .Servers .chart-selector-container .glyphicon { font-size: 1.3em; padding-right: 4px; top: 5px; } .Servers .ct-grid.ct-vertical:first-of-type { display: none; } .advanced-settings { display: none; } .Servers .port-highlight { animation: highlight-fade 1s ease-in 1; } .Servers .col2 label, .Email .col2 label { margin: 2px 0 0 4px; cursor: pointer; } .Servers .col2 button:first-of-type { margin-bottom: 8px; } .result-box .alert { margin-bottom: 0px; display: none; } .alert-translate { display: none; margin: 5px 0px 0px; } .server-disabled { background-color: #eee; } .Special .glyphicon-asterisk { margin-left: 8px; top: 3px; color: #666; } .host-warning { color: #F0AD4E; margin-left: 13px; top: 5px; font-size: 1.2em; } .host-warning-highlight { border-color: #F0AD4E !important; } .fileBrowser .glyphicon { margin-right: 2px; top: 1px; } .main-restarting.in { text-align: center; opacity: 0.9; color: black; z-index: 2000; height: 100%; } .main-restarting.in div { position: relative; top: 30%; transform: translateY(-50%); } .main-restarting { display: block; background-color: white; } .main-restarting.in strong { font-size: 5em; display: block; } .main-restarting.in span { top: 10px; } .main-restarting small { font-size: 3rem !important; } .value-and-select input { margin-right: -5px; } .value-and-select select { min-width: 30px; margin-top: 1px; } .dotOne, .dotTwo, .dotThree { opacity: 0; animation: dot 1.3s infinite; animation-delay: 0.0s; } .dotTwo { animation-delay: 0.2s; } .dotThree { animation-delay: 0.3s; } @keyframes dot { 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1; } } @keyframes highlight-fade { 0% { background: #FEFEDA; } 100% { background: none; } } .spin-glyphicon { animation: spin 2s infinite linear; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(359deg); } } /*** RTL Fixes ***/ html[dir="rtl"] .col1 input[type='checkbox'], html[dir="rtl"] .col2 h3 a { left: 5px; } html[dir="rtl"] .modal-header .close { float: left; } html[dir="rtl"] .field-pair { position: relative; } html[dir="rtl"] .Sorting .presets.float-left, html[dir="rtl"] .checkbox-days { float: none; } html[dir="rtl"] .Scheduling form[action="addSchedule"] input[type="checkbox"] { right: 5px; } @media screen and (min-width: 1200px) { .Categories input[name="dir"] { max-width: 240px !important; } .navbar-nav { /* For extra wide languages like Polish */ margin-right: -150px; } } @media screen and (min-width: 768px) and (max-width: 1200px) { .navbar-default .navbar-nav>li>a>span, .navbar-default .navbar-nav>li>a:hover>strong, .navbar-default .navbar-nav>li>a.active>strong { display: inline; } .navbar-default .navbar-nav>li>a>svg { display: inline-block; } .navbar-default .navbar-nav>li>a>strong, .navbar-default .navbar-nav:hover>li>a.active>strong { display: none; } #search-menu>a>strong { display: none; } .RSS #content, .Categories #content { width: 100%; } } @media screen and (max-width: 1000px) { .col1 { float: right; padding: 5px 0px; } .col1 h5 { margin-left: 20px; } .col2 { width: 100%; padding: 10px; } .col2 p { margin-left: 20px; } .Servers .col2 button:first-of-type { margin-bottom: 0; } .Servers .server-chart, .Servers .chart-selector-container, .Servers .advanced-buttonSeperator { display: none; } .Servers .server-amounts-text { padding: 0px 15px 10px; width: inherit; } .Sorting .glyphicon-option-vertical { display: none; } .Sorting .sorter h3 { cursor: move; } } @media screen and (max-width: 768px) { .navbar-default .navbar-brand-small { display: none; } .navbar .container { padding-right: 15px; } .navbar-default .navbar-brand-mobile { display: block; } .navbar-collapse.in .navbar-nav>li>a>span, .navbar-collapse.collapsing .navbar-nav>li>a>span { display: inline-block; width: 1.5em; } .navbar-collapse.in .navbar-nav>li>a>svg, .navbar-collapse.collapsing .navbar-nav>li>a>svg { display: inline-block; margin-right: 0.5em; } .navbar .nav>li>a { height: auto; } #search-menu { display: none; } .section .col2 h3 { padding-right: 25px; } .section .col2 h3 a { display: inline-block; } .main-restarting.in strong { font-size: 2em; font-weight: bold; } .main-restarting.in span { top: 2px; } .main-restarting.in small { font-size: 2rem !important; } #content { margin: 0 !important; padding: 0 !important; padding-top: 55px !important; } #content fieldset { min-width: 0; padding: 0 !important; } .colmask { border: none !important; } .col2 { padding: 10px; } .col2 h3 { margin: -10px -10px 0px; padding-left: 10px; } .col2 p { margin-left: 0px; margin-bottom: 0; } .col1 h5 { margin-left: 0px; } label.config { margin-left: 0px; margin-bottom: 2px; width: 100%; float: none; } .desc { margin: 2px 0 0 3px; padding: 0 !important; } .col1 input[type="checkbox"] { position: inherit; float: left; margin-right: 5px; margin-top: 0px; } div.field-pair{ min-width: 0; padding: 5px 10px; } .fileBrowserField { max-width: 65% !important; } ul.tabs a { padding-left: 5px; padding-right: 5px; } } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1628532 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/images/logo-arrow.svg0000644000000000000000000000112214625637207025572 0ustar00runnerstaff././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1629608 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/images/logo-full.svg0000644000000000000000000000421014625637207025403 0ustar00runnerstaff././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993671.163057 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/images/logo-small.svg0000644000000000000000000000243314625637207025556 0ustar00runnerstaff././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1716993699.461741 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/js/jquery-ui.min.js0000644000000000000000000013437214625637243025220 0ustar00runnerstaff/*! jQuery UI - v1.12.1 - 2016-09-16 * http://jqueryui.com * Includes: widget.js, data.js, keycode.js, scroll-parent.js, widgets/sortable.js, widgets/mouse.js, widgets/slider.js * Copyright jQuery Foundation and other contributors; Licensed MIT */ (function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,l=r+t.height,h=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+h>r&&l>s+h,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&l>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],l=[],h=this._connectWith();if(h&&e)for(s=h.length-1;s>=0;s--)for(o=t(h[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&l.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(l.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=l.length-1;s>=0;s--)l[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,l,h,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,h=r.length;h>s;s++)l=t(r[s]),l.data(this.widgetName+"-item",a),c.push({item:l,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t(" ",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,l,h,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(l=this.items[s].item.offset()[a],h=!1,e[u]-l>this.items[s][r]/2&&(h=!0),n>Math.abs(e[u]-l)&&(n=Math.abs(e[u]-l),o=this.items[s],this.direction=h?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s} },_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():l?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():l?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.slider",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e).attr("tabIndex",0)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("
").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,l,h,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),l=o.offset(),h=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=h?{left:0,top:0}:{left:e.pageX-l.left-o.width()/2,top:e.pageY-l.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,l=this,h=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((l.values(s)-l._valueMin())/(l._valueMax()-l._valueMin())),c["horizontal"===l.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[h?"animate":"css"](c,r.animate),l.options.range===!0&&("horizontal"===l.orientation?(0===s&&l.range.stop(1,1)[h?"animate":"css"]({left:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&l.range.stop(1,1)[h?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[h?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}})});././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4618542 SABnzbd-4.3.2/interfaces/Config/templates/staticcfg/js/jquery-3.5.1.min.js0000644000000000000000000025660314625637243025251 0ustar00runnerstaff/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 00){this.$element.data("active",items[0])}else{this.$element.data("active",null)}if(this.options.addItem){items.push(this.options.addItem)}if(this.options.items=="all"){return this.render(items).show()}else{return this.render(items.slice(0,this.options.items)).show()}},matcher:function(item){var it=this.displayText(item);return~it.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(items){var beginswith=[];var caseSensitive=[];var caseInsensitive=[];var item;while(item=items.shift()){var it=this.displayText(item);if(!it.toLowerCase().indexOf(this.query.toLowerCase()))beginswith.push(item);else if(~it.indexOf(this.query))caseSensitive.push(item);else caseInsensitive.push(item)}return beginswith.concat(caseSensitive,caseInsensitive)},highlighter:function(item){var html=$("
");var query=this.query;var i=item.toLowerCase().indexOf(query.toLowerCase());var len=query.length;var leftPart;var middlePart;var rightPart;var strong;if(len===0){return html.text(item).html()}while(i>-1){leftPart=item.substr(0,i);middlePart=item.substr(i,len);rightPart=item.substr(i+len);strong=$("").text(middlePart);html.append(document.createTextNode(leftPart)).append(strong);item=rightPart;i=item.toLowerCase().indexOf(query.toLowerCase())}return html.append(document.createTextNode(item)).html()},render:function(items){var that=this;var self=this;var activeFound=false;var data=[];var _category=that.options.separator;$.each(items,function(key,value){if(key>0&&value[_category]!==items[key-1][_category]){data.push({__type:"divider"})}if(value[_category]&&(key===0||value[_category]!==items[key-1][_category])){data.push({__type:"category",name:value[_category]})}data.push(value)});items=$(data).map(function(i,item){if((item.__type||false)=="category"){return $(that.options.headerHtml).text(item.name)[0]}if((item.__type||false)=="divider"){return $(that.options.headerDivider)[0]}var text=self.displayText(item);i=$(that.options.item).data("value",item);i.find("a").html(that.highlighter(text,item));if(text==self.$element.val()){i.addClass("active");self.$element.data("active",item);activeFound=true}return i[0]});if(this.autoSelect&&!activeFound){items.filter(":not(.dropdown-header)").first().addClass("active");this.$element.data("active",items.first().data("value"))}this.$menu.html(items);return this},displayText:function(item){return typeof item!=="undefined"&&typeof item.name!="undefined"&&item.name||item},next:function(event){var active=this.$menu.find(".active").removeClass("active");var next=active.next();if(!next.length){next=$(this.$menu.find("li")[0])}next.addClass("active")},prev:function(event){var active=this.$menu.find(".active").removeClass("active");var prev=active.prev();if(!prev.length){prev=this.$menu.find("li").last()}prev.addClass("active")},listen:function(){this.$element.on("focus",$.proxy(this.focus,this)).on("blur",$.proxy(this.blur,this)).on("keypress",$.proxy(this.keypress,this)).on("input",$.proxy(this.input,this)).on("keyup",$.proxy(this.keyup,this));if(this.eventSupported("keydown")){this.$element.on("keydown",$.proxy(this.keydown,this))}this.$menu.on("click",$.proxy(this.click,this)).on("mouseenter","li",$.proxy(this.mouseenter,this)).on("mouseleave","li",$.proxy(this.mouseleave,this)).on("mousedown",$.proxy(this.mousedown,this))},destroy:function(){this.$element.data("typeahead",null);this.$element.data("active",null);this.$element.off("focus").off("blur").off("keypress").off("input").off("keyup");if(this.eventSupported("keydown")){this.$element.off("keydown")}this.$menu.remove();this.destroyed=true},eventSupported:function(eventName){var isSupported=eventName in this.$element;if(!isSupported){this.$element.setAttribute(eventName,"return;");isSupported=typeof this.$element[eventName]==="function"}return isSupported},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:if(e.shiftKey)return;e.preventDefault();this.prev();break;case 40:if(e.shiftKey)return;e.preventDefault();this.next();break}},keydown:function(e){this.suppressKeyPressRepeat=~$.inArray(e.keyCode,[40,38,9,13,27]);if(!this.shown&&e.keyCode==40){this.lookup()}else{this.move(e)}},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},input:function(e){var currentValue=this.$element.val()||this.$element.text();if(this.value!==currentValue){this.value=currentValue;this.lookup()}},keyup:function(e){if(this.destroyed){return}switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break}},focus:function(e){if(!this.focused){this.focused=true;if(this.options.showHintOnFocus&&this.skipShowHintOnFocus!==true){if(this.options.showHintOnFocus==="all"){this.lookup("")}else{this.lookup()}}}if(this.skipShowHintOnFocus){this.skipShowHintOnFocus=false}},blur:function(e){if(!this.mousedover&&!this.mouseddown&&this.shown){this.hide();this.focused=false}else if(this.mouseddown){this.skipShowHintOnFocus=true;this.$element.focus();this.mouseddown=false}},click:function(e){e.preventDefault();this.skipShowHintOnFocus=true;this.select();this.$element.focus();this.hide()},mouseenter:function(e){this.mousedover=true;this.$menu.find(".active").removeClass("active");$(e.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=false;if(!this.focused&&this.shown)this.hide()},mousedown:function(e){this.mouseddown=true;this.$menu.one("mouseup",function(e){this.mouseddown=false}.bind(this))}};var old=$.fn.typeahead;$.fn.typeahead=function(option){var arg=arguments;if(typeof option=="string"&&option=="getActive"){return this.data("active")}return this.each(function(){var $this=$(this);var data=$this.data("typeahead");var options=typeof option=="object"&&option;if(!data)$this.data("typeahead",data=new Typeahead(this,options));if(typeof option=="string"&&data[option]){if(arg.length>1){data[option].apply(data,Array.prototype.slice.call(arg,1))}else{data[option]()}}})};$.fn.typeahead.defaults={source:[],items:8,menu:'
    ',item:'
  • ',minLength:1,scrollHeight:0,autoSelect:true,afterSelect:$.noop,addItem:false,delay:0,separator:"category",headerHtml:'
  • ',headerDivider:'
  • '};$.fn.typeahead.Constructor=Typeahead;$.fn.typeahead.noConflict=function(){$.fn.typeahead=old;return this};$(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(e){var $this=$(this);if($this.data("typeahead"))return;$this.typeahead($this.data())})}); /*! * jQuery Form Plugin * version: 4.2.2 * Requires jQuery v1.7.2 or later * Project repository: https://github.com/jquery-form/form * Copyright 2017 Kevin Morris * Copyright 2006 M. Alsup * Dual licensed under the LGPL-2.1+ or MIT licenses * https://github.com/jquery-form/form#license * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,r){return void 0===r&&(r="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(r),r}:e(jQuery)}(function(e){"use strict";function t(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(t.target).closest("form").ajaxSubmit(r))}function r(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=r.form;if(i.clk=r,"image"===r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function a(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}var n=/\r?\n/g,i={};i.fileapi=void 0!==e('').get(0).files,i.formdata=void 0!==window.FormData;var o=!!e.fn.prop;e.fn.attr2=function(){if(!o)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t,r,n,s){function u(r){var a,n,i=e.param(r,t.traditional).split("&"),o=i.length,s=[];for(a=0;a',k).val(f.extraData[c].value).appendTo(w)[0]):u.push(e('',k).val(f.extraData[c]).appendTo(w)[0]));f.iframeTarget||h.appendTo(D),v.attachEvent?v.attachEvent("onload",s):v.addEventListener("load",s,!1),setTimeout(t,15);try{w.submit()}catch(e){document.createElement("form").submit.apply(w)}}finally{w.setAttribute("action",i),w.setAttribute("enctype",o),r?w.setAttribute("target",r):p.removeAttr("target"),e(u).remove()}}function s(t){if(!x.aborted&&!X){if((O=n(v))||(a("cannot access response document"),t=L),t===A&&x)return x.abort("timeout"),void S.reject(x,"timeout");if(t===L&&x)return x.abort("server abort"),void S.reject(x,"error","server abort");if(O&&O.location.href!==f.iframeSrc||T){v.detachEvent?v.detachEvent("onload",s):v.removeEventListener("load",s,!1);var r,i="success";try{if(T)throw"timeout";var o="xml"===f.dataType||O.XMLDocument||e.isXMLDoc(O);if(a("isXml="+o),!o&&window.opera&&(null===O.body||!O.body.innerHTML)&&--C)return a("requeing onLoad callback, DOM not available"),void setTimeout(s,250);var u=O.body?O.body:O.documentElement;x.responseText=u?u.innerHTML:null,x.responseXML=O.XMLDocument?O.XMLDocument:O,o&&(f.dataType="xml"),x.getResponseHeader=function(e){return{"content-type":f.dataType}[e.toLowerCase()]},u&&(x.status=Number(u.getAttribute("status"))||x.status,x.statusText=u.getAttribute("statusText")||x.statusText);var c=(f.dataType||"").toLowerCase(),l=/(json|script|text)/.test(c);if(l||f.textarea){var p=O.getElementsByTagName("textarea")[0];if(p)x.responseText=p.value,x.status=Number(p.getAttribute("status"))||x.status,x.statusText=p.getAttribute("statusText")||x.statusText;else if(l){var m=O.getElementsByTagName("pre")[0],g=O.getElementsByTagName("body")[0];m?x.responseText=m.textContent?m.textContent:m.innerText:g&&(x.responseText=g.textContent?g.textContent:g.innerText)}}else"xml"===c&&!x.responseXML&&x.responseText&&(x.responseXML=q(x.responseText));try{M=N(x,c,f)}catch(e){i="parsererror",x.error=r=e||i}}catch(e){a("error caught: ",e),i="error",x.error=r=e||i}x.aborted&&(a("upload aborted"),i=null),x.status&&(i=x.status>=200&&x.status<300||304===x.status?"success":"error"),"success"===i?(f.success&&f.success.call(f.context,M,"success",x),S.resolve(x.responseText,"success",x),d&&e.event.trigger("ajaxSuccess",[x,f])):i&&(void 0===r&&(r=x.statusText),f.error&&f.error.call(f.context,x,i,r),S.reject(x,"error",r),d&&e.event.trigger("ajaxError",[x,f,r])),d&&e.event.trigger("ajaxComplete",[x,f]),d&&!--e.active&&e.event.trigger("ajaxStop"),f.complete&&f.complete.call(f.context,x,i),X=!0,f.timeout&&clearTimeout(j),setTimeout(function(){f.iframeTarget?h.attr("src",f.iframeSrc):h.remove(),x.responseXML=null},100)}}}var u,c,f,d,m,h,v,x,y,b,T,j,w=p[0],S=e.Deferred();if(S.abort=function(e){x.abort(e)},r)for(c=0;c',k)).css({position:"absolute",top:"-1000px",left:"-1000px"}),v=h[0],x={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(t){var r="timeout"===t?"timeout":"aborted";a("aborting upload... "+r),this.aborted=1;try{v.contentWindow.document.execCommand&&v.contentWindow.document.execCommand("Stop")}catch(e){}h.attr("src",f.iframeSrc),x.error=r,f.error&&f.error.call(f.context,x,r,t),d&&e.event.trigger("ajaxError",[x,f,r]),f.complete&&f.complete.call(f.context,x,r)}},(d=f.global)&&0==e.active++&&e.event.trigger("ajaxStart"),d&&e.event.trigger("ajaxSend",[x,f]),f.beforeSend&&!1===f.beforeSend.call(f.context,x,f))return f.global&&e.active--,S.reject(),S;if(x.aborted)return S.reject(),S;(y=w.clk)&&(b=y.name)&&!y.disabled&&(f.extraData=f.extraData||{},f.extraData[b]=y.value,"image"===y.type&&(f.extraData[b+".x"]=w.clk_x,f.extraData[b+".y"]=w.clk_y));var A=1,L=2,F=e("meta[name=csrf-token]").attr("content"),E=e("meta[name=csrf-param]").attr("content");E&&F&&(f.extraData=f.extraData||{},f.extraData[E]=F),f.forceSync?i():setTimeout(i,10);var M,O,X,C=50,q=e.parseXML||function(e,t){return window.ActiveXObject?((t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!==t.documentElement.nodeName?t:null},_=e.parseJSON||function(e){return window.eval("("+e+")")},N=function(t,r,a){var n=t.getResponseHeader("content-type")||"",i=("xml"===r||!r)&&n.indexOf("xml")>=0,o=i?t.responseXML:t.responseText;return i&&"parsererror"===o.documentElement.nodeName&&e.error&&e.error("parsererror"),a&&a.dataFilter&&(o=a.dataFilter(o,r)),"string"==typeof o&&(("json"===r||!r)&&n.indexOf("json")>=0?o=_(o):("script"===r||!r)&&n.indexOf("javascript")>=0&&e.globalEval(o)),o};return S}if(!this.length)return a("ajaxSubmit: skipping submit process - no element selected"),this;var l,f,d,p=this;"function"==typeof t?t={success:t}:"string"==typeof t||!1===t&&arguments.length>0?(t={url:t,data:r,dataType:n},"function"==typeof s&&(t.success=s)):void 0===t&&(t={}),l=t.method||t.type||this.attr2("method"),(d=(d="string"==typeof(f=t.url||this.attr2("action"))?e.trim(f):"")||window.location.href||"")&&(d=(d.match(/^([^#]+)/)||[])[1]),t=e.extend(!0,{url:d,success:e.ajaxSettings.success,type:l||e.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},t);var m={};if(this.trigger("form-pre-serialize",[this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(t.beforeSerialize&&!1===t.beforeSerialize(this,t))return a("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var h=t.traditional;void 0===h&&(h=e.ajaxSettings.traditional);var v,g=[],x=this.formToArray(t.semantic,g,t.filtering);if(t.data){var y=e.isFunction(t.data)?t.data(x):t.data;t.extraData=y,v=e.param(y,h)}if(t.beforeSubmit&&!1===t.beforeSubmit(x,this,t))return a("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[x,this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var b=e.param(x,h);v&&(b=b?b+"&"+v:v),"GET"===t.type.toUpperCase()?(t.url+=(t.url.indexOf("?")>=0?"&":"?")+b,t.data=null):t.data=b;var T=[];if(t.resetForm&&T.push(function(){p.resetForm()}),t.clearForm&&T.push(function(){p.clearForm(t.includeHidden)}),!t.dataType&&t.target){var j=t.success||function(){};T.push(function(r,a,n){var i=arguments,o=t.replaceTarget?"replaceWith":"html";e(t.target)[o](r).each(function(){j.apply(this,i)})})}else t.success&&(e.isArray(t.success)?e.merge(T,t.success):T.push(t.success));if(t.success=function(e,r,a){for(var n=t.context||this,i=0,o=T.length;i0,D="multipart/form-data",A=p.attr("enctype")===D||p.attr("encoding")===D,L=i.fileapi&&i.formdata;a("fileAPI :"+L);var F,E=(k||A)&&!L;!1!==t.iframe&&(t.iframe||E)?t.closeKeepAlive?e.get(t.closeKeepAlive,function(){F=c(x)}):F=c(x):F=(k||A)&&L?function(r){for(var a=new FormData,n=0;n0)&&(n={url:n,data:i,dataType:o},"function"==typeof s&&(n.success=s)),n=n||{},n.delegation=n.delegation&&e.isFunction(e.fn.on),!n.delegation&&0===this.length){var u={s:this.selector,c:this.context};return!e.isReady&&u.s?(a("DOM not ready, queuing ajaxForm"),e(function(){e(u.s,u.c).ajaxForm(n)}),this):(a("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)")),this)}return n.delegation?(e(document).off("submit.form-plugin",this.selector,t).off("click.form-plugin",this.selector,r).on("submit.form-plugin",this.selector,n,t).on("click.form-plugin",this.selector,n,r),this):this.ajaxFormUnbind().on("submit.form-plugin",n,t).on("click.form-plugin",n,r)},e.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},e.fn.formToArray=function(t,r,a){var n=[];if(0===this.length)return n;var o,s=this[0],u=this.attr("id"),c=t||void 0===s.elements?s.getElementsByTagName("*"):s.elements;if(c&&(c=e.makeArray(c)),u&&(t||/(Edge|Trident)\//.test(navigator.userAgent))&&(o=e(':input[form="'+u+'"]').get()).length&&(c=(c||[]).concat(o)),!c||!c.length)return n;e.isFunction(a)&&(c=e.map(c,a));var l,f,d,p,m,h,v;for(l=0,h=c.length;lr||r>=c||0>t||t>=c?!1:f.isDark(r,t)}function i(r,t,e,n){var o=u.isDark,a=1/l;u.isDark=function(i,u){var f=u*a,c=i*a,l=f+a,g=c+a;return o(i,u)&&(r>l||f>e||t>g||c>n)}}var u={},f=r(n,e);f.addData(t),f.make(),o=o||0;var c=f.getModuleCount(),l=f.getModuleCount()+2*o;return u.text=t,u.level=e,u.version=n,u.moduleCount=l,u.isDark=a,u.addBlank=i,u}function e(r,e,n,o,a){n=Math.max(1,n||1),o=Math.min(40,o||40);for(var i=n;o>=i;i+=1)try{return t(r,e,i,a)}catch(u){}}function n(r,t,e){var n=e.size,o="bold "+e.mSize*n+"px "+e.fontname,a=w("")[0].getContext("2d");a.font=o;var i=a.measureText(e.label).width,u=e.mSize,f=i/n,c=(1-f)*e.mPosX,l=(1-u)*e.mPosY,g=c+f,s=l+u,v=.01;1===e.mode?r.addBlank(0,l-v,n,s+v):r.addBlank(c-v,l-v,g+v,s+v),t.fillStyle=e.fontcolor,t.font=o,t.fillText(e.label,c*n,l*n+.75*e.mSize*n)}function o(r,t,e){var n=e.size,o=e.image.naturalWidth||1,a=e.image.naturalHeight||1,i=e.mSize,u=i*o/a,f=(1-u)*e.mPosX,c=(1-i)*e.mPosY,l=f+u,g=c+i,s=.01;3===e.mode?r.addBlank(0,c-s,n,g+s):r.addBlank(f-s,c-s,l+s,g+s),t.drawImage(e.image,f*n,c*n,u*n,i*n)}function a(r,t,e){w(e.background).is("img")?t.drawImage(e.background,0,0,e.size,e.size):e.background&&(t.fillStyle=e.background,t.fillRect(e.left,e.top,e.size,e.size));var a=e.mode;1===a||2===a?n(r,t,e):(3===a||4===a)&&o(r,t,e)}function i(r,t,e,n,o,a,i,u){r.isDark(i,u)&&t.rect(n,o,a,a)}function u(r,t,e,n,o,a,i,u,f,c){i?r.moveTo(t+a,e):r.moveTo(t,e),u?(r.lineTo(n-a,e),r.arcTo(n,e,n,o,a)):r.lineTo(n,e),f?(r.lineTo(n,o-a),r.arcTo(n,o,t,o,a)):r.lineTo(n,o),c?(r.lineTo(t+a,o),r.arcTo(t,o,t,e,a)):r.lineTo(t,o),i?(r.lineTo(t,e+a),r.arcTo(t,e,n,e,a)):r.lineTo(t,e)}function f(r,t,e,n,o,a,i,u,f,c){i&&(r.moveTo(t+a,e),r.lineTo(t,e),r.lineTo(t,e+a),r.arcTo(t,e,t+a,e,a)),u&&(r.moveTo(n-a,e),r.lineTo(n,e),r.lineTo(n,e+a),r.arcTo(n,e,n-a,e,a)),f&&(r.moveTo(n-a,o),r.lineTo(n,o),r.lineTo(n,o-a),r.arcTo(n,o,n-a,o,a)),c&&(r.moveTo(t+a,o),r.lineTo(t,o),r.lineTo(t,o-a),r.arcTo(t,o,t+a,o,a))}function c(r,t,e,n,o,a,i,c){var l=r.isDark,g=n+a,s=o+a,v=e.radius*a,h=i-1,d=i+1,w=c-1,m=c+1,y=l(i,c),T=l(h,w),p=l(h,c),B=l(h,m),A=l(i,m),E=l(d,m),k=l(d,c),M=l(d,w),C=l(i,w);y?u(t,n,o,g,s,v,!p&&!C,!p&&!A,!k&&!A,!k&&!C):f(t,n,o,g,s,v,p&&C&&T,p&&A&&B,k&&A&&E,k&&C&&M)}function l(r,t,e){var n,o,a=r.moduleCount,u=e.size/a,f=i;for(e.radius>0&&e.radius<=.5&&(f=c),t.beginPath(),n=0;a>n;n+=1)for(o=0;a>o;o+=1){var l=e.left+o*u,g=e.top+n*u,s=u;f(r,t,e,l,g,s,n,o)}if(w(e.fill).is("img")){t.strokeStyle="rgba(0,0,0,0.5)",t.lineWidth=2,t.stroke();var v=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",t.fill(),t.globalCompositeOperation=v,t.clip(),t.drawImage(e.fill,0,0,e.size,e.size),t.restore()}else t.fillStyle=e.fill,t.fill()}function g(r,t){var n=e(t.text,t.ecLevel,t.minVersion,t.maxVersion,t.quiet);if(!n)return null;var o=w(r).data("qrcode",n),i=o[0].getContext("2d");return a(n,i,t),l(n,i,t),o}function s(r){var t=w("").attr("width",r.size).attr("height",r.size);return g(t,r)}function v(r){return w("").attr("src",s(r)[0].toDataURL("image/png"))}function h(r){var t=e(r.text,r.ecLevel,r.minVersion,r.maxVersion,r.quiet);if(!t)return null;var n,o,a=r.size,i=r.background,u=Math.floor,f=t.moduleCount,c=u(a/f),l=u(.5*(a-c*f)),g={position:"relative",left:0,top:0,padding:0,margin:0,width:a,height:a},s={position:"absolute",padding:0,margin:0,width:c,height:c,"background-color":r.fill},v=w("
    ").data("qrcode",t).css(g);for(i&&v.css("background-color",i),n=0;f>n;n+=1)for(o=0;f>o;o+=1)t.isDark(n,o)&&w("
    ").css(s).css({left:l+o*c,top:l+n*c}).appendTo(v);return v}function d(r){return m&&"canvas"===r.render?s(r):m&&"image"===r.render?v(r):h(r)}var w=window.jQuery,m=function(){var r=document.createElement("canvas");return!(!r.getContext||!r.getContext("2d"))}(),y={render:"canvas",minVersion:1,maxVersion:40,ecLevel:"L",left:0,top:0,size:200,fill:"#000",background:null,text:"no text",radius:0,quiet:0,mode:0,mSize:.1,mPosX:.5,mPosY:.5,label:"no label",fontname:"sans",fontcolor:"#000",image:null};w.fn.qrcode=function(r){var t=w.extend({},y,r);return this.each(function(r,e){"canvas"===e.nodeName.toLowerCase()?g(e,t):w(e).append(d(t))})}}(function(){var r=function(){function r(t,e){if("undefined"==typeof t.length)throw new Error(t.length+"/"+e);var n=function(){for(var r=0;re;e+=1){t[e]=new Array(r);for(var n=0;r>n;n+=1)t[e][n]=null}return t}(v),T(0,0),T(v-7,0),T(0,v-7),A(),B(),k(r,t),l>=7&&E(r),null==d&&(d=D(l,g,w)),M(d,t)},T=function(r,t){for(var e=-1;7>=e;e+=1)if(!(-1>=r+e||r+e>=v))for(var n=-1;7>=n;n+=1)-1>=t+n||t+n>=v||(e>=0&&6>=e&&(0==n||6==n)||n>=0&&6>=n&&(0==e||6==e)||e>=2&&4>=e&&n>=2&&4>=n?s[r+e][t+n]=!0:s[r+e][t+n]=!1)},p=function(){for(var r=0,t=0,e=0;8>e;e+=1){y(!0,e);var n=a.getLostPoint(m);(0==e||r>n)&&(r=n,t=e)}return t},B=function(){for(var r=8;v-8>r;r+=1)null==s[r][6]&&(s[r][6]=r%2==0);for(var t=8;v-8>t;t+=1)null==s[6][t]&&(s[6][t]=t%2==0)},A=function(){for(var r=a.getPatternPosition(l),t=0;t=i;i+=1)for(var u=-2;2>=u;u+=1)-2==i||2==i||-2==u||2==u||0==i&&0==u?s[n+i][o+u]=!0:s[n+i][o+u]=!1}},E=function(r){for(var t=a.getBCHTypeNumber(l),e=0;18>e;e+=1){var n=!r&&1==(t>>e&1);s[Math.floor(e/3)][e%3+v-8-3]=n}for(var e=0;18>e;e+=1){var n=!r&&1==(t>>e&1);s[e%3+v-8-3][Math.floor(e/3)]=n}},k=function(r,t){for(var e=g<<3|t,n=a.getBCHTypeInfo(e),o=0;15>o;o+=1){var i=!r&&1==(n>>o&1);6>o?s[o][8]=i:8>o?s[o+1][8]=i:s[v-15+o][8]=i}for(var o=0;15>o;o+=1){var i=!r&&1==(n>>o&1);8>o?s[8][v-o-1]=i:9>o?s[8][15-o-1+1]=i:s[8][15-o-1]=i}s[v-8][8]=!r},M=function(r,t){for(var e=-1,n=v-1,o=7,i=0,u=a.getMaskFunction(t),f=v-1;f>0;f-=2)for(6==f&&(f-=1);;){for(var c=0;2>c;c+=1)if(null==s[n][f-c]){var l=!1;i>>o&1));var g=u(n,f-c);g&&(l=!l),s[n][f-c]=l,o-=1,-1==o&&(i+=1,o=7)}if(n+=e,0>n||n>=v){n-=e,e=-e;break}}},C=function(t,e){for(var n=0,o=0,i=0,u=new Array(e.length),f=new Array(e.length),c=0;c=0?d.getAt(w):0}}for(var m=0,s=0;ss;s+=1)for(var c=0;cs;s+=1)for(var c=0;c8*s)throw new Error("code length overflow. ("+c.getLengthInBits()+">"+8*s+")");for(c.getLengthInBits()+4<=8*s&&c.put(0,4);c.getLengthInBits()%8!=0;)c.putBit(!1);for(;;){if(c.getLengthInBits()>=8*s)break;if(c.put(o,8),c.getLengthInBits()>=8*s)break;c.put(i,8)}return C(c,n)};return m.addData=function(r){var t=c(r);w.push(t),d=null},m.isDark=function(r,t){if(0>r||r>=v||0>t||t>=v)throw new Error(r+","+t);return s[r][t]},m.getModuleCount=function(){return v},m.make=function(){y(!1,p())},m.createTableTag=function(r,t){r=r||2,t="undefined"==typeof t?4*r:t;var e="";e+='";for(var o=0;o';e+=""}return e+="",e+="
    "},m.createImgTag=function(r,t){r=r||2,t="undefined"==typeof t?4*r:t;var e=m.getModuleCount()*r+2*t,n=t,o=e-t;return h(e,e,function(t,e){if(t>=n&&o>t&&e>=n&&o>e){var a=Math.floor((t-n)/r),i=Math.floor((e-n)/r);return m.isDark(i,a)?0:1}return 1})},m};t.stringToBytes=function(r){for(var t=new Array,e=0;ea)t.push(a);else{var i=e[r.charAt(o)];"number"==typeof i?(255&i)==i?t.push(i):(t.push(i>>>8),t.push(255&i)):t.push(n)}}return t}};var e={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},n={L:1,M:0,Q:3,H:2},o={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},a=function(){var t=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],n=1335,a=7973,u=21522,f={},c=function(r){for(var t=0;0!=r;)t+=1,r>>>=1;return t};return f.getBCHTypeInfo=function(r){for(var t=r<<10;c(t)-c(n)>=0;)t^=n<=0;)t^=a<n;n+=1)e=e.multiply(r([1,i.gexp(n)],0));return e},f.getLengthInBits=function(r,t){if(t>=1&&10>t)switch(r){case e.MODE_NUMBER:return 10;case e.MODE_ALPHA_NUM:return 9;case e.MODE_8BIT_BYTE:return 8;case e.MODE_KANJI:return 8;default:throw new Error("mode:"+r)}else if(27>t)switch(r){case e.MODE_NUMBER:return 12;case e.MODE_ALPHA_NUM:return 11;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 10;default:throw new Error("mode:"+r)}else{if(!(41>t))throw new Error("type:"+t);switch(r){case e.MODE_NUMBER:return 14;case e.MODE_ALPHA_NUM:return 13;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 12;default:throw new Error("mode:"+r)}}},f.getLostPoint=function(r){for(var t=r.getModuleCount(),e=0,n=0;t>n;n+=1)for(var o=0;t>o;o+=1){for(var a=0,i=r.isDark(n,o),u=-1;1>=u;u+=1)if(!(0>n+u||n+u>=t))for(var f=-1;1>=f;f+=1)0>o+f||o+f>=t||(0!=u||0!=f)&&i==r.isDark(n+u,o+f)&&(a+=1);a>5&&(e+=3+a-5)}for(var n=0;t-1>n;n+=1)for(var o=0;t-1>o;o+=1){var c=0;r.isDark(n,o)&&(c+=1),r.isDark(n+1,o)&&(c+=1),r.isDark(n,o+1)&&(c+=1),r.isDark(n+1,o+1)&&(c+=1),(0==c||4==c)&&(e+=3)}for(var n=0;t>n;n+=1)for(var o=0;t-6>o;o+=1)r.isDark(n,o)&&!r.isDark(n,o+1)&&r.isDark(n,o+2)&&r.isDark(n,o+3)&&r.isDark(n,o+4)&&!r.isDark(n,o+5)&&r.isDark(n,o+6)&&(e+=40);for(var o=0;t>o;o+=1)for(var n=0;t-6>n;n+=1)r.isDark(n,o)&&!r.isDark(n+1,o)&&r.isDark(n+2,o)&&r.isDark(n+3,o)&&r.isDark(n+4,o)&&!r.isDark(n+5,o)&&r.isDark(n+6,o)&&(e+=40);for(var l=0,o=0;t>o;o+=1)for(var n=0;t>n;n+=1)r.isDark(n,o)&&(l+=1);var g=Math.abs(100*l/t/t-50)/5;return e+=10*g},f}(),i=function(){for(var r=new Array(256),t=new Array(256),e=0;8>e;e+=1)r[e]=1<e;e+=1)r[e]=r[e-4]^r[e-5]^r[e-6]^r[e-8];for(var e=0;255>e;e+=1)t[r[e]]=e;var n={};return n.glog=function(r){if(1>r)throw new Error("glog("+r+")");return t[r]},n.gexp=function(t){for(;0>t;)t+=255;for(;t>=256;)t-=255;return r[t]},n}(),u=function(){var r=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],t=function(r,t){var e={};return e.totalCount=r,e.dataCount=t,e},e={},o=function(t,e){switch(e){case n.L:return r[4*(t-1)+0];case n.M:return r[4*(t-1)+1];case n.Q:return r[4*(t-1)+2];case n.H:return r[4*(t-1)+3];default:return}};return e.getRSBlocks=function(r,e){var n=o(r,e);if("undefined"==typeof n)throw new Error("bad rs block @ typeNumber:"+r+"/errorCorrectLevel:"+e);for(var a=n.length/3,i=new Array,u=0;a>u;u+=1)for(var f=n[3*u+0],c=n[3*u+1],l=n[3*u+2],g=0;f>g;g+=1)i.push(t(c,l));return i},e}(),f=function(){var r=new Array,t=0,e={};return e.getBuffer=function(){return r},e.getAt=function(t){var e=Math.floor(t/8);return 1==(r[e]>>>7-t%8&1)},e.put=function(r,t){for(var n=0;t>n;n+=1)e.putBit(1==(r>>>t-n-1&1))},e.getLengthInBits=function(){return t},e.putBit=function(e){var n=Math.floor(t/8);r.length<=n&&r.push(0),e&&(r[n]|=128>>>t%8),t+=1},e},c=function(r){var n=e.MODE_8BIT_BYTE,o=t.stringToBytes(r),a={};return a.getMode=function(){return n},a.getLength=function(r){return o.length},a.write=function(r){for(var t=0;t>>8)},t.writeBytes=function(r,e,n){e=e||0,n=n||r.length;for(var o=0;n>o;o+=1)t.writeByte(r[o+e])},t.writeString=function(r){for(var e=0;e0&&(t+=","),t+=r[e];return t+="]"},t},g=function(){var r=0,t=0,e=0,n="",o={},a=function(r){n+=String.fromCharCode(i(63&r))},i=function(r){if(0>r);else{if(26>r)return 65+r;if(52>r)return 97+(r-26);if(62>r)return 48+(r-52);if(62==r)return 43;if(63==r)return 47}throw new Error("n:"+r)};return o.writeByte=function(n){for(r=r<<8|255&n,t+=8,e+=1;t>=6;)a(r>>>t-6),t-=6},o.flush=function(){if(t>0&&(a(r<<6-t),r=0,t=0),e%3!=0)for(var o=3-e%3,i=0;o>i;i+=1)n+="="},o.toString=function(){return n},o},s=function(r){var t=r,e=0,n=0,o=0,a={};a.read=function(){for(;8>o;){if(e>=t.length){if(0==o)return-1;throw new Error("unexpected end of file./"+o)}var r=t.charAt(e);if(e+=1,"="==r)return o=0,-1;r.match(/^\s$/)||(n=n<<6|i(r.charCodeAt(0)),o+=6)}var a=n>>>o-8&255;return o-=8,a};var i=function(r){if(r>=65&&90>=r)return r-65;if(r>=97&&122>=r)return r-97+26;if(r>=48&&57>=r)return r-48+52;if(43==r)return 62;if(47==r)return 63;throw new Error("c:"+r)};return a},v=function(r,t){var e=r,n=t,o=new Array(r*t),a={};a.setPixel=function(r,t,n){o[t*e+r]=n},a.write=function(r){r.writeString("GIF87a"),r.writeShort(e),r.writeShort(n),r.writeByte(128),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(255),r.writeByte(255),r.writeByte(255),r.writeString(","),r.writeShort(0),r.writeShort(0),r.writeShort(e),r.writeShort(n),r.writeByte(0);var t=2,o=u(t);r.writeByte(t);for(var a=0;o.length-a>255;)r.writeByte(255),r.writeBytes(o,a,255),a+=255;r.writeByte(o.length-a),r.writeBytes(o,a,o.length-a),r.writeByte(0),r.writeString(";")};var i=function(r){var t=r,e=0,n=0,o={};return o.write=function(r,o){if(r>>>o!=0)throw new Error("length over");for(;e+o>=8;)t.writeByte(255&(r<>>=8-e,n=0,e=0;n=r<0&&t.writeByte(n)},o},u=function(r){for(var t=1<u;u+=1)a.add(String.fromCharCode(u));a.add(String.fromCharCode(t)),a.add(String.fromCharCode(e));var c=l(),g=i(c);g.write(t,n);var s=0,v=String.fromCharCode(o[s]);for(s+=1;sa;a+=1)for(var i=0;r>i;i+=1)o.setPixel(i,a,e(i,a));var u=l();o.write(u);for(var f=g(),c=u.toByteArray(),s=0;sn?t.push(n):2048>n?t.push(192|n>>6,128|63&n):55296>n||n>=57344?t.push(224|n>>12,128|n>>6&63,128|63&n):(e++,n=65536+((1023&n)<<10|1023&r.charCodeAt(e)),t.push(240|n>>18,128|n>>12&63,128|n>>6&63,128|63&n))}return t}return t(r)}}(r),r}()); /*! * jQuery PathBrowser * * (c) 2012 SABnzbd Team, Inc. All rights reserved. * * Dual licensed under MIT or GPLv2 licenses * http://en.wikipedia.org/wiki/MIT_License * http://en.wikipedia.org/wiki/GNU_General_Public_License * * Changed by Safihre - 11 Nov 2015 */ ;(function($) { // Building object function FileBrowser(element) { // Initialize this.element = $(element); this.initialDir = null; this.showFiles = false; this.currentBrowserPath = null; this.currentRequest = null; this.fileBrowserDialog = $('#filebrowser_modal .modal-body'); this.fileBrowserTitle = this.element.data('title') || $('label[for="'+this.element.attr('id')+'"]').text() || ''; // Start this.init() }; // Adding button FileBrowser.prototype.init = function () { // Self-reference var self = this; // Small or big button buttonText = this.element.hasClass('fileBrowserSmall') ? '' : configTranslate.browseText; // Add button this.element.addClass('fileBrowserField').after( $('').click(function () { self.openBrowser(); }) ) } // Open browser-window FileBrowser.prototype.openBrowser = function() { // Self-reference var self = this; // set up the browser and launch the dialog // textbox (not saved) path > textbox (saved) path > none this.initialDir = this.element.val() || this.element.data('initialdir') || ''; // If there's no seperator, it must be a relative path if(this.initialDir.split(folderSeperator).length < 2 && this.element.data('initialdir')) { this.initialDir = this.element.data('initialdir') + folderSeperator + this.element.val(); } // Are we selecting files or folders if(this.element.data('files')) { this.showFiles = true } // Browse this.browse(this.initialDir , folderBrowseUrl); // Choose path and close modal $('#filebrowser_modal_accept').click(function() { // Is it a relative path? if(self.currentBrowserPath.indexOf(self.element.data('initialdir')) === 0) { // Remove start self.currentBrowserPath = self.currentBrowserPath.replace(self.element.data('initialdir')+folderSeperator, ''); // If it's identical to the initial dir the replacement won't work if(self.currentBrowserPath === self.element.data('initialdir')) { self.currentBrowserPath = ''; } } // Changed? if(self.element.val() !== self.currentBrowserPath) { self.element.val(self.currentBrowserPath); formHasChanged = true; } // Hide and stop default action $('#filebrowser_modal').modal('hide'); return false; }) // Show hidden folders $('#show_hidden_folders').off('change') $('#show_hidden_folders').on('change', function() { self.browse(self.currentBrowserPath , folderBrowseUrl); }) // Use custom title instead of default and open modal $('#filebrowser_modal .modal-header h4').text(this.fileBrowserTitle); $('#filebrowser_modal').modal('show'); return false; } FileBrowser.prototype.browse = function(path, endpoint) { // Self-reference var self = this; // Still loading if (this.currentRequest) this.currentRequest.abort(); // Show hidden folders var params = { name: path} if($('#show_hidden_folders').is(':checked')) { params['show_hidden_folders'] = "1" } // Show files? if(this.showFiles) { params['show_files'] = "1" } // Get current folders this.currentBrowserPath = path; this.currentRequest = $.getJSON(endpoint, params, function (data) { // Clean self.fileBrowserDialog.empty(); // Make list var list = $('
    ').appendTo(self.fileBrowserDialog); $.each(data.paths, function (i, entry) { // Title for first one if(i === 0) { self.fileBrowserDialog.prepend($('

    ').text(entry.current_path)) return } // Regular link link = $('').click(function () { // Are we looking for files and did we select a file? if(self.showFiles && !entry.dir) { // Trigger selection self.currentBrowserPath = entry.path $('#filebrowser_modal_accept').click() } else { self.browse(entry.path, endpoint); } }).text(entry.name); // Back image if(entry.name === '..') { $(' ').prependTo(link); } else if(!entry.dir) { $(' ').prependTo(link); } else { $(' ').prependTo(link); } // Add to list link.appendTo(list); }); }); } // Make sure we have unique instances $.fn.fileBrowser = function () { return this.each(function () { if (!$.data(this, 'plugin_FileBrowser')) { $.data(this, 'plugin_FileBrowser', new FileBrowser(this)); } }); } })(jQuery); /* * Takes the inputs-elements found in the current selector * and extracts the values into the provided data-object. */ $.fn.extractFormDataTo = function(target) { var inputs = $("input[type != 'submit'][type != 'button']", this); // could use .serializeArray() but that omits unchecked items inputs.each(function (i,elem) { target[elem.name] = elem.value; }); var selects = $("select", this); selects.each(function (i,elem) { if (elem.selectedOptions.length > 1) { // Handle

    ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4626977 SABnzbd-4.3.2/interfaces/wizard/inc_bottom.tmpl0000644000000000000000000000002314625637243020674 0ustar00runnerstaff ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1818051 SABnzbd-4.3.2/interfaces/wizard/index.html0000644000000000000000000000411714625637207017646 0ustar00runnerstaff
    $T('wizard-version') $version

    $T('wizard-quickstart')


    $T('opt-language')

    $T('explain-language')


    No language files detected. Please run python tools/make_mo.py once and restart SABnzbd, or contact your package provider.

    $T('wizard-exit')
    $T('restore-backup')
    ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4627945 SABnzbd-4.3.2/interfaces/wizard/inc_top.tmpl0000644000000000000000000000175114625637243020203 0ustar00runnerstaff $T('wizard-quickstart')
    #include $webdir + "/../Config/templates/staticcfg/images/logo-full.svg"#
    ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1821723 SABnzbd-4.3.2/interfaces/wizard/two.html0000644000000000000000000000345414625637207017353 0ustar00runnerstaff
    $T('wizard-version') $version

    $T('wizard-quickstart')


    $T('wizard-complete')


    $T('wizard-tip1') $T('wizard-tip2')

    $T('wizard-tip4')

    $url

    $T('opt-complete_dir')

    $complete_dir

    $T('opt-download_dir')

    $download_dir

    $T('wizard-tip-wiki') $T('menu-wiki')


    $T('wizard-goto')
    ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993671.1818802 SABnzbd-4.3.2/interfaces/wizard/one.html0000644000000000000000000001525414625637207017324 0ustar00runnerstaff
    $T('wizard-version') $version

    $T('wizard-quickstart')


    $T('wizard-server')

    $T('wizard-explain-server')


    data-toggle="tooltip" data-placement="right" title="$T('wizard-server-ssl-explain')"/>
    $T('button-advanced')
    $T('wizard-server-text')

    $T('wizard-previous')
    ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4629278 SABnzbd-4.3.2/interfaces/wizard/README.TXT0000644000000000000000000000152714625637243017211 0ustar00runnerstaff# # Copyright 2009 The SABnzbd-Team (sabnzbd.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # This is the quick setup wizard for SABnzbd # It is used when first starting up sabnzbd # ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4630034 SABnzbd-4.3.2/interfaces/wizard/static/style.css0000644000000000000000000000544314625637243021015 0ustar00runnerstaffbody { background-color: #E4E4E4; text-align: center; } .container { max-width: 1000px; border: 1px solid rgba(0, 0, 0, 0.2); background-color: #fff; text-align: left; } #inner { background-color: #fff; padding: 4px 32px 20px 32px; } #content { min-height: 550px; } #logo { z-index: 40; margin-bottom: -39px; margin-top: 20px; } #logo svg { height: 55px; width: 198px; } .language { min-width: 150px; width: 18%; padding: 1em 0em; margin: 5px 5px; text-align: center; float: left; } .language:hover { background-color: #E4E4E4; } .float { float: left; } .clear { clear: left; } .spacer { clear: both; } .inline { display: inline; } .quoteBlock { padding: 12px; margin-top: 1px; margin-bottom: 15px; background-color: #f5f5f5; } .quoteBlock a, a[target="_blank"] { text-decoration: underline !important; } .success { color: #00cc22; } .failed { color: red !important; } #rightGreyText { color: #ccc; width: 100%; text-align: right; padding-top: 3px; font-style: italic; } .indented { padding-left: 10px; } label { cursor: pointer; } .input-checkbox { padding-top: 7px !important; } .input-checkbox input+.help-block { display: none; } .input-checkbox input:checked+.help-block { display: block; float: right; margin: 0; } .align-right { text-align: right; } .align-center { text-align: center; } .unselected, .selected { display: inline-block; } .unselected { padding: 6px 10px 6px 10px; border: 1px solid #636363; margin-left: 8px; margin-right: 8px; color: #636363; } .selected { padding: 6px 10px 6px 10px; color: white; background-color: #636363; border: 1px solid #636363; margin-left: 8px; margin-right: 8px; } .bigger { font-size: 14px; } .bigger input { font-size: 16px; } .required-star { color: red; } .full-width { width: 100%; } .correct { border: 2px solid #00cc22; } .incorrect { border: 2px solid red; } .hidden { display: none !important; } .text-input { width: 130px; } .text-input-wide { width: 230px; } #server-hidden-settings input[type="number"] { width: 100px; } .input-group-bw { width: 150px; } .disabled-text { text-decoration: line-through; color: #ccc; } #serverResponse { padding: 6px 10px; } #host-tip { margin-bottom: 5px; } .error-text { display: inline; color: red; } #bandwidth { display: inline-block; } /*** Bootstrap overwrites ***/ * { border-radius: 0 !important; } a, a:hover, a:active, a:visited, #serverResponse { color: #555; } .btn { box-shadow: 1px 1px 1px rgba(0, 0, 0, .1) !important; min-width: 150px; } .btn .glyphicon, a .glyphicon { top: 2px; } small { color: #777; }././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1716993699.4630883 SABnzbd-4.3.2/interfaces/wizard/static/javascript/checkserver.js0000644000000000000000000000464214625637243024153 0ustar00runnerstafffunction checkRequired() { if ($("#host").val() && $("#connections").val()) { $("#next-button").removeClass('disabled') return true; } else { $("#next-button").addClass('disabled') return false; } } $(document).ready(function() { // Add tooltips $('[data-toggle="tooltip"]').tooltip() // On form-submit $("#serverTest").click(function() { $('#serverResponse').html(txtChecking); $.getJSON( "../api?mode=config&name=test_server&output=json", $("form").serialize(), function(result) { if (result.value.result) { r = ' ' + result.value.message + ''; } else { r = ' ' + result.value.message + ''; } r = r.replace('https://sabnzbd.org/certificate-errors', 'https://sabnzbd.org/certificate-errors') $('#serverResponse').html(r); } ); return false; }); $("#port, #connections").bind('keyup blur', function() { if (this.value > 0) { $(this).removeClass("incorrect"); $(this).addClass("correct"); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); } checkRequired() }); $("#host, #username, #password").bind('keyup blur', function() { if (this.value) { $(this).removeClass("incorrect"); $(this).addClass("correct"); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); } checkRequired(); }); $('#ssl').click(function() { if(this.checked) { // Enabled SSL change port when not already a custom port if($('#port').val() === '119') { $('#port').val('563') } } else { // Remove SSL port if($('#port').val() === '563') { $('#port').val('119') } } }) checkRequired() $('form').submit(function(event) { // Double check if(!checkRequired()) { event.preventDefault(); } }) });./PaxHeaders/SABnzbd-4.3.20000644000000000000000000000013214626013607012146 xustar0030 mtime=1717049223.961365438 30 atime=1717049223.957365375 30 ctime=1717049223.961365438 SABnzbd-4.3.2/0000755000000000000000000000000014626013607013006 5ustar00rootroot00000000000000SABnzbd-4.3.2/PaxHeaders/interfaces0000644000000000000000000000007414336451277014150 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.961365438 SABnzbd-4.3.2/interfaces/0000755000000000000000000000000014336451277015140 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/PaxHeaders/Glitter0000644000000000000000000000007414336451277015562 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/0000755000000000000000000000000014336451277016552 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/PaxHeaders/templates0000644000000000000000000000007414336451277017560 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/0000755000000000000000000000000014336451277020550 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/PaxHeaders/static0000644000000000000000000000007414336451277021047 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/static/0000755000000000000000000000000014336451277022037 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/PaxHeaders/bootstrap0000644000000000000000000000007414336451277023064 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/0000755000000000000000000000000014336451277024054 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/PaxHeaders/css0000644000000000000000000000007414336451277023654 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/0000755000000000000000000000000014336451277024644 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/PaxHeaders/src0000644000000000000000000000007414336451277024443 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/src/0000755000000000000000000000000014336451277025433 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/src/PaxHeaders/bootstrap.css0000644000000000000000000000007414336451277027247 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/src/bootstrap.css0000777000000000000000000000000014336451277033434 2bootstrap_3.3.5.cssustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/src/PaxHeaders/bootstrap_3.3.5.css0000644000000000000000000000007414336451277027775 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/css/src/bootstrap_3.3.5.css0000644000000000000000000043774614336451277030735 0ustar00rootroot00000000000000/*! * Bootstrap v3.3.5 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ html { font-family: sans-serif; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } body { margin: 0; } article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; } audio, canvas, progress, video { display: inline-block; vertical-align: baseline; } audio:not([controls]) { display: none; height: 0; } [hidden], template { display: none; } a { background-color: transparent; } a:active, a:hover { outline: 0; } abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } dfn { font-style: italic; } h1 { margin: .67em 0; font-size: 2em; } mark { color: #000; background: #ff0; } small { font-size: 80%; } sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; } sup { top: -.5em; } sub { bottom: -.25em; } img { border: 0; } svg:not(:root) { overflow: hidden; } figure { margin: 1em 40px; } hr { height: 0; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } pre { overflow: auto; } code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; } button, input, optgroup, select, textarea { margin: 0; font: inherit; color: inherit; } button { overflow: visible; } button, select { text-transform: none; } button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; cursor: pointer; } button[disabled], html input[disabled] { cursor: default; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0; } input { line-height: normal; } input[type="checkbox"], input[type="radio"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 0; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { height: auto; } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } fieldset { padding: .35em .625em .75em; margin: 0 2px; border: 1px solid #c0c0c0; } legend { padding: 0; border: 0; } textarea { overflow: auto; } optgroup { font-weight: bold; } table { border-spacing: 0; border-collapse: collapse; } td, th { padding: 0; } /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ @media print { *, *:before, *:after { color: #000 !important; text-shadow: none !important; background: transparent !important; -webkit-box-shadow: none !important; box-shadow: none !important; } a, a:visited { text-decoration: underline; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } a[href^="#"]:after, a[href^="javascript:"]:after { content: ""; } pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } .navbar { display: none; } .btn > .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px solid #000; } .table { border-collapse: collapse !important; } .table td, .table th { background-color: #fff !important; } .table-bordered th, .table-bordered td { border: 1px solid #ddd !important; } } @font-face { font-family: 'Glyphicons Halflings'; src: url('../fonts/glyphicons-halflings-regular.eot'); src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } .glyphicon { position: relative; top: 1px; display: inline-block; font-family: 'Glyphicons Halflings'; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .glyphicon-asterisk:before { content: "\2a"; } .glyphicon-plus:before { content: "\2b"; } .glyphicon-euro:before, .glyphicon-eur:before { content: "\20ac"; } .glyphicon-minus:before { content: "\2212"; } .glyphicon-cloud:before { content: "\2601"; } .glyphicon-envelope:before { content: "\2709"; } .glyphicon-pencil:before { content: "\270f"; } .glyphicon-glass:before { content: "\e001"; } .glyphicon-music:before { content: "\e002"; } .glyphicon-search:before { content: "\e003"; } .glyphicon-heart:before { content: "\e005"; } .glyphicon-star:before { content: "\e006"; } .glyphicon-star-empty:before { content: "\e007"; } .glyphicon-user:before { content: "\e008"; } .glyphicon-film:before { content: "\e009"; } .glyphicon-th-large:before { content: "\e010"; } .glyphicon-th:before { content: "\e011"; } .glyphicon-th-list:before { content: "\e012"; } .glyphicon-ok:before { content: "\e013"; } .glyphicon-remove:before { content: "\e014"; } .glyphicon-zoom-in:before { content: "\e015"; } .glyphicon-zoom-out:before { content: "\e016"; } .glyphicon-off:before { content: "\e017"; } .glyphicon-signal:before { content: "\e018"; } .glyphicon-cog:before { content: "\e019"; } .glyphicon-trash:before { content: "\e020"; } .glyphicon-home:before { content: "\e021"; } .glyphicon-file:before { content: "\e022"; } .glyphicon-time:before { content: "\e023"; } .glyphicon-road:before { content: "\e024"; } .glyphicon-download-alt:before { content: "\e025"; } .glyphicon-download:before { content: "\e026"; } .glyphicon-upload:before { content: "\e027"; } .glyphicon-inbox:before { content: "\e028"; } .glyphicon-play-circle:before { content: "\e029"; } .glyphicon-repeat:before { content: "\e030"; } .glyphicon-refresh:before { content: "\e031"; } .glyphicon-list-alt:before { content: "\e032"; } .glyphicon-lock:before { content: "\e033"; } .glyphicon-flag:before { content: "\e034"; } .glyphicon-headphones:before { content: "\e035"; } .glyphicon-volume-off:before { content: "\e036"; } .glyphicon-volume-down:before { content: "\e037"; } .glyphicon-volume-up:before { content: "\e038"; } .glyphicon-qrcode:before { content: "\e039"; } .glyphicon-barcode:before { content: "\e040"; } .glyphicon-tag:before { content: "\e041"; } .glyphicon-tags:before { content: "\e042"; } .glyphicon-book:before { content: "\e043"; } .glyphicon-bookmark:before { content: "\e044"; } .glyphicon-print:before { content: "\e045"; } .glyphicon-camera:before { content: "\e046"; } .glyphicon-font:before { content: "\e047"; } .glyphicon-bold:before { content: "\e048"; } .glyphicon-italic:before { content: "\e049"; } .glyphicon-text-height:before { content: "\e050"; } .glyphicon-text-width:before { content: "\e051"; } .glyphicon-align-left:before { content: "\e052"; } .glyphicon-align-center:before { content: "\e053"; } .glyphicon-align-right:before { content: "\e054"; } .glyphicon-align-justify:before { content: "\e055"; } .glyphicon-list:before { content: "\e056"; } .glyphicon-indent-left:before { content: "\e057"; } .glyphicon-indent-right:before { content: "\e058"; } .glyphicon-facetime-video:before { content: "\e059"; } .glyphicon-picture:before { content: "\e060"; } .glyphicon-map-marker:before { content: "\e062"; } .glyphicon-adjust:before { content: "\e063"; } .glyphicon-tint:before { content: "\e064"; } .glyphicon-edit:before { content: "\e065"; } .glyphicon-share:before { content: "\e066"; } .glyphicon-check:before { content: "\e067"; } .glyphicon-move:before { content: "\e068"; } .glyphicon-step-backward:before { content: "\e069"; } .glyphicon-fast-backward:before { content: "\e070"; } .glyphicon-backward:before { content: "\e071"; } .glyphicon-play:before { content: "\e072"; } .glyphicon-pause:before { content: "\e073"; } .glyphicon-stop:before { content: "\e074"; } .glyphicon-forward:before { content: "\e075"; } .glyphicon-fast-forward:before { content: "\e076"; } .glyphicon-step-forward:before { content: "\e077"; } .glyphicon-eject:before { content: "\e078"; } .glyphicon-chevron-left:before { content: "\e079"; } .glyphicon-chevron-right:before { content: "\e080"; } .glyphicon-plus-sign:before { content: "\e081"; } .glyphicon-minus-sign:before { content: "\e082"; } .glyphicon-remove-sign:before { content: "\e083"; } .glyphicon-ok-sign:before { content: "\e084"; } .glyphicon-question-sign:before { content: "\e085"; } .glyphicon-info-sign:before { content: "\e086"; } .glyphicon-screenshot:before { content: "\e087"; } .glyphicon-remove-circle:before { content: "\e088"; } .glyphicon-ok-circle:before { content: "\e089"; } .glyphicon-ban-circle:before { content: "\e090"; } .glyphicon-arrow-left:before { content: "\e091"; } .glyphicon-arrow-right:before { content: "\e092"; } .glyphicon-arrow-up:before { content: "\e093"; } .glyphicon-arrow-down:before { content: "\e094"; } .glyphicon-share-alt:before { content: "\e095"; } .glyphicon-resize-full:before { content: "\e096"; } .glyphicon-resize-small:before { content: "\e097"; } .glyphicon-exclamation-sign:before { content: "\e101"; } .glyphicon-gift:before { content: "\e102"; } .glyphicon-leaf:before { content: "\e103"; } .glyphicon-fire:before { content: "\e104"; } .glyphicon-eye-open:before { content: "\e105"; } .glyphicon-eye-close:before { content: "\e106"; } .glyphicon-warning-sign:before { content: "\e107"; } .glyphicon-plane:before { content: "\e108"; } .glyphicon-calendar:before { content: "\e109"; } .glyphicon-random:before { content: "\e110"; } .glyphicon-comment:before { content: "\e111"; } .glyphicon-magnet:before { content: "\e112"; } .glyphicon-chevron-up:before { content: "\e113"; } .glyphicon-chevron-down:before { content: "\e114"; } .glyphicon-retweet:before { content: "\e115"; } .glyphicon-shopping-cart:before { content: "\e116"; } .glyphicon-folder-close:before { content: "\e117"; } .glyphicon-folder-open:before { content: "\e118"; } .glyphicon-resize-vertical:before { content: "\e119"; } .glyphicon-resize-horizontal:before { content: "\e120"; } .glyphicon-hdd:before { content: "\e121"; } .glyphicon-bullhorn:before { content: "\e122"; } .glyphicon-bell:before { content: "\e123"; } .glyphicon-certificate:before { content: "\e124"; } .glyphicon-thumbs-up:before { content: "\e125"; } .glyphicon-thumbs-down:before { content: "\e126"; } .glyphicon-hand-right:before { content: "\e127"; } .glyphicon-hand-left:before { content: "\e128"; } .glyphicon-hand-up:before { content: "\e129"; } .glyphicon-hand-down:before { content: "\e130"; } .glyphicon-circle-arrow-right:before { content: "\e131"; } .glyphicon-circle-arrow-left:before { content: "\e132"; } .glyphicon-circle-arrow-up:before { content: "\e133"; } .glyphicon-circle-arrow-down:before { content: "\e134"; } .glyphicon-globe:before { content: "\e135"; } .glyphicon-wrench:before { content: "\e136"; } .glyphicon-tasks:before { content: "\e137"; } .glyphicon-filter:before { content: "\e138"; } .glyphicon-briefcase:before { content: "\e139"; } .glyphicon-fullscreen:before { content: "\e140"; } .glyphicon-dashboard:before { content: "\e141"; } .glyphicon-paperclip:before { content: "\e142"; } .glyphicon-heart-empty:before { content: "\e143"; } .glyphicon-link:before { content: "\e144"; } .glyphicon-phone:before { content: "\e145"; } .glyphicon-pushpin:before { content: "\e146"; } .glyphicon-usd:before { content: "\e148"; } .glyphicon-gbp:before { content: "\e149"; } .glyphicon-sort:before { content: "\e150"; } .glyphicon-sort-by-alphabet:before { content: "\e151"; } .glyphicon-sort-by-alphabet-alt:before { content: "\e152"; } .glyphicon-sort-by-order:before { content: "\e153"; } .glyphicon-sort-by-order-alt:before { content: "\e154"; } .glyphicon-sort-by-attributes:before { content: "\e155"; } .glyphicon-sort-by-attributes-alt:before { content: "\e156"; } .glyphicon-unchecked:before { content: "\e157"; } .glyphicon-expand:before { content: "\e158"; } .glyphicon-collapse-down:before { content: "\e159"; } .glyphicon-collapse-up:before { content: "\e160"; } .glyphicon-log-in:before { content: "\e161"; } .glyphicon-flash:before { content: "\e162"; } .glyphicon-log-out:before { content: "\e163"; } .glyphicon-new-window:before { content: "\e164"; } .glyphicon-record:before { content: "\e165"; } .glyphicon-save:before { content: "\e166"; } .glyphicon-open:before { content: "\e167"; } .glyphicon-saved:before { content: "\e168"; } .glyphicon-import:before { content: "\e169"; } .glyphicon-export:before { content: "\e170"; } .glyphicon-send:before { content: "\e171"; } .glyphicon-floppy-disk:before { content: "\e172"; } .glyphicon-floppy-saved:before { content: "\e173"; } .glyphicon-floppy-remove:before { content: "\e174"; } .glyphicon-floppy-save:before { content: "\e175"; } .glyphicon-floppy-open:before { content: "\e176"; } .glyphicon-credit-card:before { content: "\e177"; } .glyphicon-transfer:before { content: "\e178"; } .glyphicon-cutlery:before { content: "\e179"; } .glyphicon-header:before { content: "\e180"; } .glyphicon-compressed:before { content: "\e181"; } .glyphicon-earphone:before { content: "\e182"; } .glyphicon-phone-alt:before { content: "\e183"; } .glyphicon-tower:before { content: "\e184"; } .glyphicon-stats:before { content: "\e185"; } .glyphicon-sd-video:before { content: "\e186"; } .glyphicon-hd-video:before { content: "\e187"; } .glyphicon-subtitles:before { content: "\e188"; } .glyphicon-sound-stereo:before { content: "\e189"; } .glyphicon-sound-dolby:before { content: "\e190"; } .glyphicon-sound-5-1:before { content: "\e191"; } .glyphicon-sound-6-1:before { content: "\e192"; } .glyphicon-sound-7-1:before { content: "\e193"; } .glyphicon-copyright-mark:before { content: "\e194"; } .glyphicon-registration-mark:before { content: "\e195"; } .glyphicon-cloud-download:before { content: "\e197"; } .glyphicon-cloud-upload:before { content: "\e198"; } .glyphicon-tree-conifer:before { content: "\e199"; } .glyphicon-tree-deciduous:before { content: "\e200"; } .glyphicon-cd:before { content: "\e201"; } .glyphicon-save-file:before { content: "\e202"; } .glyphicon-open-file:before { content: "\e203"; } .glyphicon-level-up:before { content: "\e204"; } .glyphicon-copy:before { content: "\e205"; } .glyphicon-paste:before { content: "\e206"; } .glyphicon-alert:before { content: "\e209"; } .glyphicon-equalizer:before { content: "\e210"; } .glyphicon-king:before { content: "\e211"; } .glyphicon-queen:before { content: "\e212"; } .glyphicon-pawn:before { content: "\e213"; } .glyphicon-bishop:before { content: "\e214"; } .glyphicon-knight:before { content: "\e215"; } .glyphicon-baby-formula:before { content: "\e216"; } .glyphicon-tent:before { content: "\26fa"; } .glyphicon-blackboard:before { content: "\e218"; } .glyphicon-bed:before { content: "\e219"; } .glyphicon-apple:before { content: "\f8ff"; } .glyphicon-erase:before { content: "\e221"; } .glyphicon-hourglass:before { content: "\231b"; } .glyphicon-lamp:before { content: "\e223"; } .glyphicon-duplicate:before { content: "\e224"; } .glyphicon-piggy-bank:before { content: "\e225"; } .glyphicon-scissors:before { content: "\e226"; } .glyphicon-bitcoin:before { content: "\e227"; } .glyphicon-btc:before { content: "\e227"; } .glyphicon-xbt:before { content: "\e227"; } .glyphicon-yen:before { content: "\00a5"; } .glyphicon-jpy:before { content: "\00a5"; } .glyphicon-ruble:before { content: "\20bd"; } .glyphicon-rub:before { content: "\20bd"; } .glyphicon-scale:before { content: "\e230"; } .glyphicon-ice-lolly:before { content: "\e231"; } .glyphicon-ice-lolly-tasted:before { content: "\e232"; } .glyphicon-education:before { content: "\e233"; } .glyphicon-option-horizontal:before { content: "\e234"; } .glyphicon-option-vertical:before { content: "\e235"; } .glyphicon-menu-hamburger:before { content: "\e236"; } .glyphicon-modal-window:before { content: "\e237"; } .glyphicon-oil:before { content: "\e238"; } .glyphicon-grain:before { content: "\e239"; } .glyphicon-sunglasses:before { content: "\e240"; } .glyphicon-text-size:before { content: "\e241"; } .glyphicon-text-color:before { content: "\e242"; } .glyphicon-text-background:before { content: "\e243"; } .glyphicon-object-align-top:before { content: "\e244"; } .glyphicon-object-align-bottom:before { content: "\e245"; } .glyphicon-object-align-horizontal:before { content: "\e246"; } .glyphicon-object-align-left:before { content: "\e247"; } .glyphicon-object-align-vertical:before { content: "\e248"; } .glyphicon-object-align-right:before { content: "\e249"; } .glyphicon-triangle-right:before { content: "\e250"; } .glyphicon-triangle-left:before { content: "\e251"; } .glyphicon-triangle-bottom:before { content: "\e252"; } .glyphicon-triangle-top:before { content: "\e253"; } .glyphicon-console:before { content: "\e254"; } .glyphicon-superscript:before { content: "\e255"; } .glyphicon-subscript:before { content: "\e256"; } .glyphicon-menu-left:before { content: "\e257"; } .glyphicon-menu-right:before { content: "\e258"; } .glyphicon-menu-down:before { content: "\e259"; } .glyphicon-menu-up:before { content: "\e260"; } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } html { font-size: 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.42857143; color: #333; background-color: #fff; } input, button, select, textarea { font-family: inherit; font-size: inherit; line-height: inherit; } a { color: #337ab7; text-decoration: none; } a:hover, a:focus { color: #23527c; text-decoration: underline; } a:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } figure { margin: 0; } img { vertical-align: middle; } .img-responsive, .thumbnail > img, .thumbnail a > img, .carousel-inner > .item > img, .carousel-inner > .item > a > img { display: block; max-width: 100%; height: auto; } .img-rounded { border-radius: 6px; } .img-thumbnail { display: inline-block; max-width: 100%; height: auto; padding: 4px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .img-circle { border-radius: 50%; } hr { margin-top: 20px; margin-bottom: 20px; border: 0; border-top: 1px solid #eee; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; } [role="button"] { cursor: pointer; } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-family: inherit; font-weight: 500; line-height: 1.1; color: inherit; } h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { font-weight: normal; line-height: 1; color: #777; } h1, .h1, h2, .h2, h3, .h3 { margin-top: 20px; margin-bottom: 10px; } h1 small, .h1 small, h2 small, .h2 small, h3 small, .h3 small, h1 .small, .h1 .small, h2 .small, .h2 .small, h3 .small, .h3 .small { font-size: 65%; } h4, .h4, h5, .h5, h6, .h6 { margin-top: 10px; margin-bottom: 10px; } h4 small, .h4 small, h5 small, .h5 small, h6 small, .h6 small, h4 .small, .h4 .small, h5 .small, .h5 .small, h6 .small, .h6 .small { font-size: 75%; } h1, .h1 { font-size: 36px; } h2, .h2 { font-size: 30px; } h3, .h3 { font-size: 24px; } h4, .h4 { font-size: 18px; } h5, .h5 { font-size: 14px; } h6, .h6 { font-size: 12px; } p { margin: 0 0 10px; } .lead { margin-bottom: 20px; font-size: 16px; font-weight: 300; line-height: 1.4; } @media (min-width: 768px) { .lead { font-size: 21px; } } small, .small { font-size: 85%; } mark, .mark { padding: .2em; background-color: #fcf8e3; } .text-left { text-align: left; } .text-right { text-align: right; } .text-center { text-align: center; } .text-justify { text-align: justify; } .text-nowrap { white-space: nowrap; } .text-lowercase { text-transform: lowercase; } .text-uppercase { text-transform: uppercase; } .text-capitalize { text-transform: capitalize; } .text-muted { color: #777; } .text-primary { color: #337ab7; } a.text-primary:hover, a.text-primary:focus { color: #286090; } .text-success { color: #3c763d; } a.text-success:hover, a.text-success:focus { color: #2b542c; } .text-info { color: #31708f; } a.text-info:hover, a.text-info:focus { color: #245269; } .text-warning { color: #8a6d3b; } a.text-warning:hover, a.text-warning:focus { color: #66512c; } .text-danger { color: #a94442; } a.text-danger:hover, a.text-danger:focus { color: #843534; } .bg-primary { color: #fff; background-color: #337ab7; } a.bg-primary:hover, a.bg-primary:focus { background-color: #286090; } .bg-success { background-color: #dff0d8; } a.bg-success:hover, a.bg-success:focus { background-color: #c1e2b3; } .bg-info { background-color: #d9edf7; } a.bg-info:hover, a.bg-info:focus { background-color: #afd9ee; } .bg-warning { background-color: #fcf8e3; } a.bg-warning:hover, a.bg-warning:focus { background-color: #f7ecb5; } .bg-danger { background-color: #f2dede; } a.bg-danger:hover, a.bg-danger:focus { background-color: #e4b9b9; } .page-header { padding-bottom: 9px; margin: 40px 0 20px; border-bottom: 1px solid #eee; } ul, ol { margin-top: 0; margin-bottom: 10px; } ul ul, ol ul, ul ol, ol ol { margin-bottom: 0; } .list-unstyled { padding-left: 0; list-style: none; } .list-inline { padding-left: 0; margin-left: -5px; list-style: none; } .list-inline > li { display: inline-block; padding-right: 5px; padding-left: 5px; } dl { margin-top: 0; margin-bottom: 20px; } dt, dd { line-height: 1.42857143; } dt { font-weight: bold; } dd { margin-left: 0; } @media (min-width: 768px) { .dl-horizontal dt { float: left; width: 160px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; } .dl-horizontal dd { margin-left: 180px; } } abbr[title], abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #777; } .initialism { font-size: 90%; text-transform: uppercase; } blockquote { padding: 10px 20px; margin: 0 0 20px; font-size: 17.5px; border-left: 5px solid #eee; } blockquote p:last-child, blockquote ul:last-child, blockquote ol:last-child { margin-bottom: 0; } blockquote footer, blockquote small, blockquote .small { display: block; font-size: 80%; line-height: 1.42857143; color: #777; } blockquote footer:before, blockquote small:before, blockquote .small:before { content: '\2014 \00A0'; } .blockquote-reverse, blockquote.pull-right { padding-right: 15px; padding-left: 0; text-align: right; border-right: 5px solid #eee; border-left: 0; } .blockquote-reverse footer:before, blockquote.pull-right footer:before, .blockquote-reverse small:before, blockquote.pull-right small:before, .blockquote-reverse .small:before, blockquote.pull-right .small:before { content: ''; } .blockquote-reverse footer:after, blockquote.pull-right footer:after, .blockquote-reverse small:after, blockquote.pull-right small:after, .blockquote-reverse .small:after, blockquote.pull-right .small:after { content: '\00A0 \2014'; } address { margin-bottom: 20px; font-style: normal; line-height: 1.42857143; } code, kbd, pre, samp { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; border-radius: 4px; } kbd { padding: 2px 4px; font-size: 90%; color: #fff; background-color: #333; border-radius: 3px; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); } kbd kbd { padding: 0; font-size: 100%; font-weight: bold; -webkit-box-shadow: none; box-shadow: none; } pre { display: block; padding: 9.5px; margin: 0 0 10px; font-size: 13px; line-height: 1.42857143; color: #333; word-break: break-all; word-wrap: break-word; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; } pre code { padding: 0; font-size: inherit; color: inherit; white-space: pre-wrap; background-color: transparent; border-radius: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } .container { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } @media (min-width: 768px) { .container { width: 750px; } } @media (min-width: 992px) { .container { width: 970px; } } @media (min-width: 1200px) { .container { width: 1170px; } } .container-fluid { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } .row { margin-right: -15px; margin-left: -15px; } .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { position: relative; min-height: 1px; padding-right: 15px; padding-left: 15px; } .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { float: left; } .col-xs-12 { width: 100%; } .col-xs-11 { width: 91.66666667%; } .col-xs-10 { width: 83.33333333%; } .col-xs-9 { width: 75%; } .col-xs-8 { width: 66.66666667%; } .col-xs-7 { width: 58.33333333%; } .col-xs-6 { width: 50%; } .col-xs-5 { width: 41.66666667%; } .col-xs-4 { width: 33.33333333%; } .col-xs-3 { width: 25%; } .col-xs-2 { width: 16.66666667%; } .col-xs-1 { width: 8.33333333%; } .col-xs-pull-12 { right: 100%; } .col-xs-pull-11 { right: 91.66666667%; } .col-xs-pull-10 { right: 83.33333333%; } .col-xs-pull-9 { right: 75%; } .col-xs-pull-8 { right: 66.66666667%; } .col-xs-pull-7 { right: 58.33333333%; } .col-xs-pull-6 { right: 50%; } .col-xs-pull-5 { right: 41.66666667%; } .col-xs-pull-4 { right: 33.33333333%; } .col-xs-pull-3 { right: 25%; } .col-xs-pull-2 { right: 16.66666667%; } .col-xs-pull-1 { right: 8.33333333%; } .col-xs-pull-0 { right: auto; } .col-xs-push-12 { left: 100%; } .col-xs-push-11 { left: 91.66666667%; } .col-xs-push-10 { left: 83.33333333%; } .col-xs-push-9 { left: 75%; } .col-xs-push-8 { left: 66.66666667%; } .col-xs-push-7 { left: 58.33333333%; } .col-xs-push-6 { left: 50%; } .col-xs-push-5 { left: 41.66666667%; } .col-xs-push-4 { left: 33.33333333%; } .col-xs-push-3 { left: 25%; } .col-xs-push-2 { left: 16.66666667%; } .col-xs-push-1 { left: 8.33333333%; } .col-xs-push-0 { left: auto; } .col-xs-offset-12 { margin-left: 100%; } .col-xs-offset-11 { margin-left: 91.66666667%; } .col-xs-offset-10 { margin-left: 83.33333333%; } .col-xs-offset-9 { margin-left: 75%; } .col-xs-offset-8 { margin-left: 66.66666667%; } .col-xs-offset-7 { margin-left: 58.33333333%; } .col-xs-offset-6 { margin-left: 50%; } .col-xs-offset-5 { margin-left: 41.66666667%; } .col-xs-offset-4 { margin-left: 33.33333333%; } .col-xs-offset-3 { margin-left: 25%; } .col-xs-offset-2 { margin-left: 16.66666667%; } .col-xs-offset-1 { margin-left: 8.33333333%; } .col-xs-offset-0 { margin-left: 0; } @media (min-width: 768px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { float: left; } .col-sm-12 { width: 100%; } .col-sm-11 { width: 91.66666667%; } .col-sm-10 { width: 83.33333333%; } .col-sm-9 { width: 75%; } .col-sm-8 { width: 66.66666667%; } .col-sm-7 { width: 58.33333333%; } .col-sm-6 { width: 50%; } .col-sm-5 { width: 41.66666667%; } .col-sm-4 { width: 33.33333333%; } .col-sm-3 { width: 25%; } .col-sm-2 { width: 16.66666667%; } .col-sm-1 { width: 8.33333333%; } .col-sm-pull-12 { right: 100%; } .col-sm-pull-11 { right: 91.66666667%; } .col-sm-pull-10 { right: 83.33333333%; } .col-sm-pull-9 { right: 75%; } .col-sm-pull-8 { right: 66.66666667%; } .col-sm-pull-7 { right: 58.33333333%; } .col-sm-pull-6 { right: 50%; } .col-sm-pull-5 { right: 41.66666667%; } .col-sm-pull-4 { right: 33.33333333%; } .col-sm-pull-3 { right: 25%; } .col-sm-pull-2 { right: 16.66666667%; } .col-sm-pull-1 { right: 8.33333333%; } .col-sm-pull-0 { right: auto; } .col-sm-push-12 { left: 100%; } .col-sm-push-11 { left: 91.66666667%; } .col-sm-push-10 { left: 83.33333333%; } .col-sm-push-9 { left: 75%; } .col-sm-push-8 { left: 66.66666667%; } .col-sm-push-7 { left: 58.33333333%; } .col-sm-push-6 { left: 50%; } .col-sm-push-5 { left: 41.66666667%; } .col-sm-push-4 { left: 33.33333333%; } .col-sm-push-3 { left: 25%; } .col-sm-push-2 { left: 16.66666667%; } .col-sm-push-1 { left: 8.33333333%; } .col-sm-push-0 { left: auto; } .col-sm-offset-12 { margin-left: 100%; } .col-sm-offset-11 { margin-left: 91.66666667%; } .col-sm-offset-10 { margin-left: 83.33333333%; } .col-sm-offset-9 { margin-left: 75%; } .col-sm-offset-8 { margin-left: 66.66666667%; } .col-sm-offset-7 { margin-left: 58.33333333%; } .col-sm-offset-6 { margin-left: 50%; } .col-sm-offset-5 { margin-left: 41.66666667%; } .col-sm-offset-4 { margin-left: 33.33333333%; } .col-sm-offset-3 { margin-left: 25%; } .col-sm-offset-2 { margin-left: 16.66666667%; } .col-sm-offset-1 { margin-left: 8.33333333%; } .col-sm-offset-0 { margin-left: 0; } } @media (min-width: 992px) { .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { float: left; } .col-md-12 { width: 100%; } .col-md-11 { width: 91.66666667%; } .col-md-10 { width: 83.33333333%; } .col-md-9 { width: 75%; } .col-md-8 { width: 66.66666667%; } .col-md-7 { width: 58.33333333%; } .col-md-6 { width: 50%; } .col-md-5 { width: 41.66666667%; } .col-md-4 { width: 33.33333333%; } .col-md-3 { width: 25%; } .col-md-2 { width: 16.66666667%; } .col-md-1 { width: 8.33333333%; } .col-md-pull-12 { right: 100%; } .col-md-pull-11 { right: 91.66666667%; } .col-md-pull-10 { right: 83.33333333%; } .col-md-pull-9 { right: 75%; } .col-md-pull-8 { right: 66.66666667%; } .col-md-pull-7 { right: 58.33333333%; } .col-md-pull-6 { right: 50%; } .col-md-pull-5 { right: 41.66666667%; } .col-md-pull-4 { right: 33.33333333%; } .col-md-pull-3 { right: 25%; } .col-md-pull-2 { right: 16.66666667%; } .col-md-pull-1 { right: 8.33333333%; } .col-md-pull-0 { right: auto; } .col-md-push-12 { left: 100%; } .col-md-push-11 { left: 91.66666667%; } .col-md-push-10 { left: 83.33333333%; } .col-md-push-9 { left: 75%; } .col-md-push-8 { left: 66.66666667%; } .col-md-push-7 { left: 58.33333333%; } .col-md-push-6 { left: 50%; } .col-md-push-5 { left: 41.66666667%; } .col-md-push-4 { left: 33.33333333%; } .col-md-push-3 { left: 25%; } .col-md-push-2 { left: 16.66666667%; } .col-md-push-1 { left: 8.33333333%; } .col-md-push-0 { left: auto; } .col-md-offset-12 { margin-left: 100%; } .col-md-offset-11 { margin-left: 91.66666667%; } .col-md-offset-10 { margin-left: 83.33333333%; } .col-md-offset-9 { margin-left: 75%; } .col-md-offset-8 { margin-left: 66.66666667%; } .col-md-offset-7 { margin-left: 58.33333333%; } .col-md-offset-6 { margin-left: 50%; } .col-md-offset-5 { margin-left: 41.66666667%; } .col-md-offset-4 { margin-left: 33.33333333%; } .col-md-offset-3 { margin-left: 25%; } .col-md-offset-2 { margin-left: 16.66666667%; } .col-md-offset-1 { margin-left: 8.33333333%; } .col-md-offset-0 { margin-left: 0; } } @media (min-width: 1200px) { .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { float: left; } .col-lg-12 { width: 100%; } .col-lg-11 { width: 91.66666667%; } .col-lg-10 { width: 83.33333333%; } .col-lg-9 { width: 75%; } .col-lg-8 { width: 66.66666667%; } .col-lg-7 { width: 58.33333333%; } .col-lg-6 { width: 50%; } .col-lg-5 { width: 41.66666667%; } .col-lg-4 { width: 33.33333333%; } .col-lg-3 { width: 25%; } .col-lg-2 { width: 16.66666667%; } .col-lg-1 { width: 8.33333333%; } .col-lg-pull-12 { right: 100%; } .col-lg-pull-11 { right: 91.66666667%; } .col-lg-pull-10 { right: 83.33333333%; } .col-lg-pull-9 { right: 75%; } .col-lg-pull-8 { right: 66.66666667%; } .col-lg-pull-7 { right: 58.33333333%; } .col-lg-pull-6 { right: 50%; } .col-lg-pull-5 { right: 41.66666667%; } .col-lg-pull-4 { right: 33.33333333%; } .col-lg-pull-3 { right: 25%; } .col-lg-pull-2 { right: 16.66666667%; } .col-lg-pull-1 { right: 8.33333333%; } .col-lg-pull-0 { right: auto; } .col-lg-push-12 { left: 100%; } .col-lg-push-11 { left: 91.66666667%; } .col-lg-push-10 { left: 83.33333333%; } .col-lg-push-9 { left: 75%; } .col-lg-push-8 { left: 66.66666667%; } .col-lg-push-7 { left: 58.33333333%; } .col-lg-push-6 { left: 50%; } .col-lg-push-5 { left: 41.66666667%; } .col-lg-push-4 { left: 33.33333333%; } .col-lg-push-3 { left: 25%; } .col-lg-push-2 { left: 16.66666667%; } .col-lg-push-1 { left: 8.33333333%; } .col-lg-push-0 { left: auto; } .col-lg-offset-12 { margin-left: 100%; } .col-lg-offset-11 { margin-left: 91.66666667%; } .col-lg-offset-10 { margin-left: 83.33333333%; } .col-lg-offset-9 { margin-left: 75%; } .col-lg-offset-8 { margin-left: 66.66666667%; } .col-lg-offset-7 { margin-left: 58.33333333%; } .col-lg-offset-6 { margin-left: 50%; } .col-lg-offset-5 { margin-left: 41.66666667%; } .col-lg-offset-4 { margin-left: 33.33333333%; } .col-lg-offset-3 { margin-left: 25%; } .col-lg-offset-2 { margin-left: 16.66666667%; } .col-lg-offset-1 { margin-left: 8.33333333%; } .col-lg-offset-0 { margin-left: 0; } } table { background-color: transparent; } caption { padding-top: 8px; padding-bottom: 8px; color: #777; text-align: left; } th { text-align: left; } .table { width: 100%; max-width: 100%; margin-bottom: 20px; } .table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td { padding: 8px; line-height: 1.42857143; vertical-align: top; border-top: 1px solid #ddd; } .table > thead > tr > th { vertical-align: bottom; border-bottom: 2px solid #ddd; } .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > th, .table > thead:first-child > tr:first-child > th, .table > caption + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > td, .table > thead:first-child > tr:first-child > td { border-top: 0; } .table > tbody + tbody { border-top: 2px solid #ddd; } .table .table { background-color: #fff; } .table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td { padding: 5px; } .table-bordered { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td { border-bottom-width: 2px; } .table-striped > tbody > tr:nth-of-type(odd) { background-color: #f9f9f9; } .table-hover > tbody > tr:hover { background-color: #f5f5f5; } table col[class*="col-"] { position: static; display: table-column; float: none; } table td[class*="col-"], table th[class*="col-"] { position: static; display: table-cell; float: none; } .table > thead > tr > td.active, .table > tbody > tr > td.active, .table > tfoot > tr > td.active, .table > thead > tr > th.active, .table > tbody > tr > th.active, .table > tfoot > tr > th.active, .table > thead > tr.active > td, .table > tbody > tr.active > td, .table > tfoot > tr.active > td, .table > thead > tr.active > th, .table > tbody > tr.active > th, .table > tfoot > tr.active > th { background-color: #f5f5f5; } .table-hover > tbody > tr > td.active:hover, .table-hover > tbody > tr > th.active:hover, .table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr.active:hover > th { background-color: #e8e8e8; } .table > thead > tr > td.success, .table > tbody > tr > td.success, .table > tfoot > tr > td.success, .table > thead > tr > th.success, .table > tbody > tr > th.success, .table > tfoot > tr > th.success, .table > thead > tr.success > td, .table > tbody > tr.success > td, .table > tfoot > tr.success > td, .table > thead > tr.success > th, .table > tbody > tr.success > th, .table > tfoot > tr.success > th { background-color: #dff0d8; } .table-hover > tbody > tr > td.success:hover, .table-hover > tbody > tr > th.success:hover, .table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr.success:hover > th { background-color: #d0e9c6; } .table > thead > tr > td.info, .table > tbody > tr > td.info, .table > tfoot > tr > td.info, .table > thead > tr > th.info, .table > tbody > tr > th.info, .table > tfoot > tr > th.info, .table > thead > tr.info > td, .table > tbody > tr.info > td, .table > tfoot > tr.info > td, .table > thead > tr.info > th, .table > tbody > tr.info > th, .table > tfoot > tr.info > th { background-color: #d9edf7; } .table-hover > tbody > tr > td.info:hover, .table-hover > tbody > tr > th.info:hover, .table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr.info:hover > th { background-color: #c4e3f3; } .table > thead > tr > td.warning, .table > tbody > tr > td.warning, .table > tfoot > tr > td.warning, .table > thead > tr > th.warning, .table > tbody > tr > th.warning, .table > tfoot > tr > th.warning, .table > thead > tr.warning > td, .table > tbody > tr.warning > td, .table > tfoot > tr.warning > td, .table > thead > tr.warning > th, .table > tbody > tr.warning > th, .table > tfoot > tr.warning > th { background-color: #fcf8e3; } .table-hover > tbody > tr > td.warning:hover, .table-hover > tbody > tr > th.warning:hover, .table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr.warning:hover > th { background-color: #faf2cc; } .table > thead > tr > td.danger, .table > tbody > tr > td.danger, .table > tfoot > tr > td.danger, .table > thead > tr > th.danger, .table > tbody > tr > th.danger, .table > tfoot > tr > th.danger, .table > thead > tr.danger > td, .table > tbody > tr.danger > td, .table > tfoot > tr.danger > td, .table > thead > tr.danger > th, .table > tbody > tr.danger > th, .table > tfoot > tr.danger > th { background-color: #f2dede; } .table-hover > tbody > tr > td.danger:hover, .table-hover > tbody > tr > th.danger:hover, .table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr.danger:hover > th { background-color: #ebcccc; } .table-responsive { min-height: .01%; overflow-x: auto; } @media screen and (max-width: 767px) { .table-responsive { width: 100%; margin-bottom: 15px; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; border: 1px solid #ddd; } .table-responsive > .table { margin-bottom: 0; } .table-responsive > .table > thead > tr > th, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tfoot > tr > td { white-space: nowrap; } .table-responsive > .table-bordered { border: 0; } .table-responsive > .table-bordered > thead > tr > th:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child, .table-responsive > .table-bordered > tbody > tr > td:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .table-responsive > .table-bordered > thead > tr > th:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child, .table-responsive > .table-bordered > tbody > tr > td:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .table-responsive > .table-bordered > tbody > tr:last-child > th, .table-responsive > .table-bordered > tfoot > tr:last-child > th, .table-responsive > .table-bordered > tbody > tr:last-child > td, .table-responsive > .table-bordered > tfoot > tr:last-child > td { border-bottom: 0; } } fieldset { min-width: 0; padding: 0; margin: 0; border: 0; } legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 21px; line-height: inherit; color: #333; border: 0; border-bottom: 1px solid #e5e5e5; } label { display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: bold; } input[type="search"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } input[type="radio"], input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; line-height: normal; } input[type="file"] { display: block; } input[type="range"] { display: block; width: 100%; } select[multiple], select[size] { height: auto; } input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } output { display: block; padding-top: 7px; font-size: 14px; line-height: 1.42857143; color: #555; } .form-control { display: block; width: 100%; height: 34px; padding: 6px 12px; font-size: 14px; line-height: 1.42857143; color: #555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); } .form-control::-moz-placeholder { color: #999; opacity: 1; } .form-control:-ms-input-placeholder { color: #999; } .form-control::-webkit-input-placeholder { color: #999; } .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { background-color: #eee; opacity: 1; } .form-control[disabled], fieldset[disabled] .form-control { cursor: not-allowed; } textarea.form-control { height: auto; } input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { input[type="date"].form-control, input[type="time"].form-control, input[type="datetime-local"].form-control, input[type="month"].form-control { line-height: 34px; } input[type="date"].input-sm, input[type="time"].input-sm, input[type="datetime-local"].input-sm, input[type="month"].input-sm, .input-group-sm input[type="date"], .input-group-sm input[type="time"], .input-group-sm input[type="datetime-local"], .input-group-sm input[type="month"] { line-height: 30px; } input[type="date"].input-lg, input[type="time"].input-lg, input[type="datetime-local"].input-lg, input[type="month"].input-lg, .input-group-lg input[type="date"], .input-group-lg input[type="time"], .input-group-lg input[type="datetime-local"], .input-group-lg input[type="month"] { line-height: 46px; } } .form-group { margin-bottom: 15px; } .radio, .checkbox { position: relative; display: block; margin-top: 10px; margin-bottom: 10px; } .radio label, .checkbox label { min-height: 20px; padding-left: 20px; margin-bottom: 0; font-weight: normal; cursor: pointer; } .radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { position: absolute; margin-top: 4px \9; margin-left: -20px; } .radio + .radio, .checkbox + .checkbox { margin-top: -5px; } .radio-inline, .checkbox-inline { position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; font-weight: normal; vertical-align: middle; cursor: pointer; } .radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline { margin-top: 0; margin-left: 10px; } input[type="radio"][disabled], input[type="checkbox"][disabled], input[type="radio"].disabled, input[type="checkbox"].disabled, fieldset[disabled] input[type="radio"], fieldset[disabled] input[type="checkbox"] { cursor: not-allowed; } .radio-inline.disabled, .checkbox-inline.disabled, fieldset[disabled] .radio-inline, fieldset[disabled] .checkbox-inline { cursor: not-allowed; } .radio.disabled label, .checkbox.disabled label, fieldset[disabled] .radio label, fieldset[disabled] .checkbox label { cursor: not-allowed; } .form-control-static { min-height: 34px; padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; } .form-control-static.input-lg, .form-control-static.input-sm { padding-right: 0; padding-left: 0; } .input-sm { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.input-sm { height: 30px; line-height: 30px; } textarea.input-sm, select[multiple].input-sm { height: auto; } .form-group-sm .form-control { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .form-group-sm select.form-control { height: 30px; line-height: 30px; } .form-group-sm textarea.form-control, .form-group-sm select[multiple].form-control { height: auto; } .form-group-sm .form-control-static { height: 30px; min-height: 32px; padding: 6px 10px; font-size: 12px; line-height: 1.5; } .input-lg { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.input-lg { height: 46px; line-height: 46px; } textarea.input-lg, select[multiple].input-lg { height: auto; } .form-group-lg .form-control { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } .form-group-lg select.form-control { height: 46px; line-height: 46px; } .form-group-lg textarea.form-control, .form-group-lg select[multiple].form-control { height: auto; } .form-group-lg .form-control-static { height: 46px; min-height: 38px; padding: 11px 16px; font-size: 18px; line-height: 1.3333333; } .has-feedback { position: relative; } .has-feedback .form-control { padding-right: 42.5px; } .form-control-feedback { position: absolute; top: 0; right: 0; z-index: 2; display: block; width: 34px; height: 34px; line-height: 34px; text-align: center; pointer-events: none; } .input-lg + .form-control-feedback, .input-group-lg + .form-control-feedback, .form-group-lg .form-control + .form-control-feedback { width: 46px; height: 46px; line-height: 46px; } .input-sm + .form-control-feedback, .input-group-sm + .form-control-feedback, .form-group-sm .form-control + .form-control-feedback { width: 30px; height: 30px; line-height: 30px; } .has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline, .has-success.radio label, .has-success.checkbox label, .has-success.radio-inline label, .has-success.checkbox-inline label { color: #3c763d; } .has-success .form-control { border-color: #3c763d; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-success .form-control:focus { border-color: #2b542c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; } .has-success .input-group-addon { color: #3c763d; background-color: #dff0d8; border-color: #3c763d; } .has-success .form-control-feedback { color: #3c763d; } .has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline, .has-warning.radio label, .has-warning.checkbox label, .has-warning.radio-inline label, .has-warning.checkbox-inline label { color: #8a6d3b; } .has-warning .form-control { border-color: #8a6d3b; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-warning .form-control:focus { border-color: #66512c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; } .has-warning .input-group-addon { color: #8a6d3b; background-color: #fcf8e3; border-color: #8a6d3b; } .has-warning .form-control-feedback { color: #8a6d3b; } .has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline, .has-error.radio label, .has-error.checkbox label, .has-error.radio-inline label, .has-error.checkbox-inline label { color: #a94442; } .has-error .form-control { border-color: #a94442; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-error .form-control:focus { border-color: #843534; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; } .has-error .input-group-addon { color: #a94442; background-color: #f2dede; border-color: #a94442; } .has-error .form-control-feedback { color: #a94442; } .has-feedback label ~ .form-control-feedback { top: 25px; } .has-feedback label.sr-only ~ .form-control-feedback { top: 0; } .help-block { display: block; margin-top: 5px; margin-bottom: 10px; color: #737373; } @media (min-width: 768px) { .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; } .form-inline .form-control-static { display: inline-block; } .form-inline .input-group { display: inline-table; vertical-align: middle; } .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn, .form-inline .input-group .form-control { width: auto; } .form-inline .input-group > .form-control { width: 100%; } .form-inline .control-label { margin-bottom: 0; vertical-align: middle; } .form-inline .radio, .form-inline .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .form-inline .radio label, .form-inline .checkbox label { padding-left: 0; } .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .form-inline .has-feedback .form-control-feedback { top: 0; } } .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { padding-top: 7px; margin-top: 0; margin-bottom: 0; } .form-horizontal .radio, .form-horizontal .checkbox { min-height: 27px; } .form-horizontal .form-group { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .form-horizontal .control-label { padding-top: 7px; margin-bottom: 0; text-align: right; } } .form-horizontal .has-feedback .form-control-feedback { right: 15px; } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { padding-top: 14.333333px; font-size: 18px; } } @media (min-width: 768px) { .form-horizontal .form-group-sm .control-label { padding-top: 6px; font-size: 12px; } } .btn { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: normal; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-image: none; border: 1px solid transparent; border-radius: 4px; } .btn:focus, .btn:active:focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn.active.focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .btn:hover, .btn:focus, .btn.focus { color: #333; text-decoration: none; } .btn:active, .btn.active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn.disabled, .btn[disabled], fieldset[disabled] .btn { cursor: not-allowed; filter: alpha(opacity=65); -webkit-box-shadow: none; box-shadow: none; opacity: .65; } a.btn.disabled, fieldset[disabled] a.btn { pointer-events: none; } .btn-default { color: #333; background-color: #fff; border-color: #ccc; } .btn-default:focus, .btn-default.focus { color: #333; background-color: #e6e6e6; border-color: #8c8c8c; } .btn-default:hover { color: #333; background-color: #e6e6e6; border-color: #adadad; } .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { color: #333; background-color: #e6e6e6; border-color: #adadad; } .btn-default:active:hover, .btn-default.active:hover, .open > .dropdown-toggle.btn-default:hover, .btn-default:active:focus, .btn-default.active:focus, .open > .dropdown-toggle.btn-default:focus, .btn-default:active.focus, .btn-default.active.focus, .open > .dropdown-toggle.btn-default.focus { color: #333; background-color: #d4d4d4; border-color: #8c8c8c; } .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { background-image: none; } .btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, .btn-default.disabled:focus, .btn-default[disabled]:focus, fieldset[disabled] .btn-default:focus, .btn-default.disabled.focus, .btn-default[disabled].focus, fieldset[disabled] .btn-default.focus, .btn-default.disabled:active, .btn-default[disabled]:active, fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { background-color: #fff; border-color: #ccc; } .btn-default .badge { color: #fff; background-color: #333; } .btn-primary { color: #fff; background-color: #337ab7; border-color: #2e6da4; } .btn-primary:focus, .btn-primary.focus { color: #fff; background-color: #286090; border-color: #122b40; } .btn-primary:hover { color: #fff; background-color: #286090; border-color: #204d74; } .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { color: #fff; background-color: #286090; border-color: #204d74; } .btn-primary:active:hover, .btn-primary.active:hover, .open > .dropdown-toggle.btn-primary:hover, .btn-primary:active:focus, .btn-primary.active:focus, .open > .dropdown-toggle.btn-primary:focus, .btn-primary:active.focus, .btn-primary.active.focus, .open > .dropdown-toggle.btn-primary.focus { color: #fff; background-color: #204d74; border-color: #122b40; } .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { background-image: none; } .btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled.focus, .btn-primary[disabled].focus, fieldset[disabled] .btn-primary.focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { background-color: #337ab7; border-color: #2e6da4; } .btn-primary .badge { color: #337ab7; background-color: #fff; } .btn-success { color: #fff; background-color: #5cb85c; border-color: #4cae4c; } .btn-success:focus, .btn-success.focus { color: #fff; background-color: #449d44; border-color: #255625; } .btn-success:hover { color: #fff; background-color: #449d44; border-color: #398439; } .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { color: #fff; background-color: #449d44; border-color: #398439; } .btn-success:active:hover, .btn-success.active:hover, .open > .dropdown-toggle.btn-success:hover, .btn-success:active:focus, .btn-success.active:focus, .open > .dropdown-toggle.btn-success:focus, .btn-success:active.focus, .btn-success.active.focus, .open > .dropdown-toggle.btn-success.focus { color: #fff; background-color: #398439; border-color: #255625; } .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { background-image: none; } .btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, .btn-success.disabled:focus, .btn-success[disabled]:focus, fieldset[disabled] .btn-success:focus, .btn-success.disabled.focus, .btn-success[disabled].focus, fieldset[disabled] .btn-success.focus, .btn-success.disabled:active, .btn-success[disabled]:active, fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { background-color: #5cb85c; border-color: #4cae4c; } .btn-success .badge { color: #5cb85c; background-color: #fff; } .btn-info { color: #fff; background-color: #5bc0de; border-color: #46b8da; } .btn-info:focus, .btn-info.focus { color: #fff; background-color: #31b0d5; border-color: #1b6d85; } .btn-info:hover { color: #fff; background-color: #31b0d5; border-color: #269abc; } .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { color: #fff; background-color: #31b0d5; border-color: #269abc; } .btn-info:active:hover, .btn-info.active:hover, .open > .dropdown-toggle.btn-info:hover, .btn-info:active:focus, .btn-info.active:focus, .open > .dropdown-toggle.btn-info:focus, .btn-info:active.focus, .btn-info.active.focus, .open > .dropdown-toggle.btn-info.focus { color: #fff; background-color: #269abc; border-color: #1b6d85; } .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { background-image: none; } .btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, .btn-info.disabled:focus, .btn-info[disabled]:focus, fieldset[disabled] .btn-info:focus, .btn-info.disabled.focus, .btn-info[disabled].focus, fieldset[disabled] .btn-info.focus, .btn-info.disabled:active, .btn-info[disabled]:active, fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { background-color: #5bc0de; border-color: #46b8da; } .btn-info .badge { color: #5bc0de; background-color: #fff; } .btn-warning { color: #fff; background-color: #f0ad4e; border-color: #eea236; } .btn-warning:focus, .btn-warning.focus { color: #fff; background-color: #ec971f; border-color: #985f0d; } .btn-warning:hover { color: #fff; background-color: #ec971f; border-color: #d58512; } .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { color: #fff; background-color: #ec971f; border-color: #d58512; } .btn-warning:active:hover, .btn-warning.active:hover, .open > .dropdown-toggle.btn-warning:hover, .btn-warning:active:focus, .btn-warning.active:focus, .open > .dropdown-toggle.btn-warning:focus, .btn-warning:active.focus, .btn-warning.active.focus, .open > .dropdown-toggle.btn-warning.focus { color: #fff; background-color: #d58512; border-color: #985f0d; } .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { background-image: none; } .btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, .btn-warning.disabled:focus, .btn-warning[disabled]:focus, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled.focus, .btn-warning[disabled].focus, fieldset[disabled] .btn-warning.focus, .btn-warning.disabled:active, .btn-warning[disabled]:active, fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { background-color: #f0ad4e; border-color: #eea236; } .btn-warning .badge { color: #f0ad4e; background-color: #fff; } .btn-danger { color: #fff; background-color: #d9534f; border-color: #d43f3a; } .btn-danger:focus, .btn-danger.focus { color: #fff; background-color: #c9302c; border-color: #761c19; } .btn-danger:hover { color: #fff; background-color: #c9302c; border-color: #ac2925; } .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { color: #fff; background-color: #c9302c; border-color: #ac2925; } .btn-danger:active:hover, .btn-danger.active:hover, .open > .dropdown-toggle.btn-danger:hover, .btn-danger:active:focus, .btn-danger.active:focus, .open > .dropdown-toggle.btn-danger:focus, .btn-danger:active.focus, .btn-danger.active.focus, .open > .dropdown-toggle.btn-danger.focus { color: #fff; background-color: #ac2925; border-color: #761c19; } .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { background-image: none; } .btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, .btn-danger.disabled:focus, .btn-danger[disabled]:focus, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled.focus, .btn-danger[disabled].focus, fieldset[disabled] .btn-danger.focus, .btn-danger.disabled:active, .btn-danger[disabled]:active, fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { background-color: #d9534f; border-color: #d43f3a; } .btn-danger .badge { color: #d9534f; background-color: #fff; } .btn-link { font-weight: normal; color: #337ab7; border-radius: 0; } .btn-link, .btn-link:active, .btn-link.active, .btn-link[disabled], fieldset[disabled] .btn-link { background-color: transparent; -webkit-box-shadow: none; box-shadow: none; } .btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { border-color: transparent; } .btn-link:hover, .btn-link:focus { color: #23527c; text-decoration: underline; background-color: transparent; } .btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { color: #777; text-decoration: none; } .btn-lg, .btn-group-lg > .btn { padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } .btn-sm, .btn-group-sm > .btn { padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .btn-xs, .btn-group-xs > .btn { padding: 1px 5px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .btn-block { display: block; width: 100%; } .btn-block + .btn-block { margin-top: 5px; } input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { width: 100%; } .fade { opacity: 0; -webkit-transition: opacity .15s linear; -o-transition: opacity .15s linear; transition: opacity .15s linear; } .fade.in { opacity: 1; } .collapse { display: none; } .collapse.in { display: block; } tr.collapse.in { display: table-row; } tbody.collapse.in { display: table-row-group; } .collapsing { position: relative; height: 0; overflow: hidden; -webkit-transition-timing-function: ease; -o-transition-timing-function: ease; transition-timing-function: ease; -webkit-transition-duration: .35s; -o-transition-duration: .35s; transition-duration: .35s; -webkit-transition-property: height, visibility; -o-transition-property: height, visibility; transition-property: height, visibility; } .caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: 4px dashed; border-top: 4px solid \9; border-right: 4px solid transparent; border-left: 4px solid transparent; } .dropup, .dropdown { position: relative; } .dropdown-toggle:focus { outline: 0; } .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; font-size: 14px; text-align: left; list-style: none; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, .15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); box-shadow: 0 6px 12px rgba(0, 0, 0, .175); } .dropdown-menu.pull-right { right: 0; left: auto; } .dropdown-menu .divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .dropdown-menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.42857143; color: #333; white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { color: #262626; text-decoration: none; background-color: #f5f5f5; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { color: #fff; text-decoration: none; background-color: #337ab7; outline: 0; } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { color: #777; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { text-decoration: none; cursor: not-allowed; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } .open > .dropdown-menu { display: block; } .open > a { outline: 0; } .dropdown-menu-right { right: 0; left: auto; } .dropdown-menu-left { right: auto; left: 0; } .dropdown-header { display: block; padding: 3px 20px; font-size: 12px; line-height: 1.42857143; color: #777; white-space: nowrap; } .dropdown-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 990; } .pull-right > .dropdown-menu { right: 0; left: auto; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { content: ""; border-top: 0; border-bottom: 4px dashed; border-bottom: 4px solid \9; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 2px; } @media (min-width: 768px) { .navbar-right .dropdown-menu { right: 0; left: auto; } .navbar-right .dropdown-menu-left { right: auto; left: 0; } } .btn-group, .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; } .btn-group > .btn, .btn-group-vertical > .btn { position: relative; float: left; } .btn-group > .btn:hover, .btn-group-vertical > .btn:hover, .btn-group > .btn:focus, .btn-group-vertical > .btn:focus, .btn-group > .btn:active, .btn-group-vertical > .btn:active, .btn-group > .btn.active, .btn-group-vertical > .btn.active { z-index: 2; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { margin-left: -1px; } .btn-toolbar { margin-left: -5px; } .btn-toolbar .btn, .btn-toolbar .btn-group, .btn-toolbar .input-group { float: left; } .btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group { margin-left: 5px; } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } .btn-group > .btn:first-child { margin-left: 0; } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; } .btn-group > .btn-group { float: left; } .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } .btn-group > .btn + .dropdown-toggle { padding-right: 8px; padding-left: 8px; } .btn-group > .btn-lg + .dropdown-toggle { padding-right: 12px; padding-left: 12px; } .btn-group.open .dropdown-toggle { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn-group.open .dropdown-toggle.btn-link { -webkit-box-shadow: none; box-shadow: none; } .btn .caret { margin-left: 0; } .btn-lg .caret { border-width: 5px 5px 0; border-bottom-width: 0; } .dropup .btn-lg .caret { border-width: 0 5px 5px; } .btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } .btn-group-vertical > .btn-group > .btn { float: none; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } .btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0; } .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-left-radius: 4px; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-top-right-radius: 0; } .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; } .btn-group-justified > .btn, .btn-group-justified > .btn-group { display: table-cell; float: none; width: 1%; } .btn-group-justified > .btn-group .btn { width: 100%; } .btn-group-justified > .btn-group .dropdown-menu { left: auto; } [data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; } .input-group { position: relative; display: table; border-collapse: separate; } .input-group[class*="col-"] { float: none; padding-right: 0; padding-left: 0; } .input-group .form-control { position: relative; z-index: 2; float: left; width: 100%; margin-bottom: 0; } .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.input-group-lg > .form-control, select.input-group-lg > .input-group-addon, select.input-group-lg > .input-group-btn > .btn { height: 46px; line-height: 46px; } textarea.input-group-lg > .form-control, textarea.input-group-lg > .input-group-addon, textarea.input-group-lg > .input-group-btn > .btn, select[multiple].input-group-lg > .form-control, select[multiple].input-group-lg > .input-group-addon, select[multiple].input-group-lg > .input-group-btn > .btn { height: auto; } .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.input-group-sm > .form-control, select.input-group-sm > .input-group-addon, select.input-group-sm > .input-group-btn > .btn { height: 30px; line-height: 30px; } textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group-addon, textarea.input-group-sm > .input-group-btn > .btn, select[multiple].input-group-sm > .form-control, select[multiple].input-group-sm > .input-group-addon, select[multiple].input-group-sm > .input-group-btn > .btn { height: auto; } .input-group-addon, .input-group-btn, .input-group .form-control { display: table-cell; } .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { border-radius: 0; } .input-group-addon, .input-group-btn { width: 1%; white-space: nowrap; vertical-align: middle; } .input-group-addon { padding: 6px 12px; font-size: 14px; font-weight: normal; line-height: 1; color: #555; text-align: center; background-color: #eee; border: 1px solid #ccc; border-radius: 4px; } .input-group-addon.input-sm { padding: 5px 10px; font-size: 12px; border-radius: 3px; } .input-group-addon.input-lg { padding: 10px 16px; font-size: 18px; border-radius: 6px; } .input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { margin-top: 0; } .input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group > .btn, .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { border-top-right-radius: 0; border-bottom-right-radius: 0; } .input-group-addon:first-child { border-right: 0; } .input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group > .btn, .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { border-top-left-radius: 0; border-bottom-left-radius: 0; } .input-group-addon:last-child { border-left: 0; } .input-group-btn { position: relative; font-size: 0; white-space: nowrap; } .input-group-btn > .btn { position: relative; } .input-group-btn > .btn + .btn { margin-left: -1px; } .input-group-btn > .btn:hover, .input-group-btn > .btn:focus, .input-group-btn > .btn:active { z-index: 2; } .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group { margin-right: -1px; } .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group { z-index: 2; margin-left: -1px; } .nav { padding-left: 0; margin-bottom: 0; list-style: none; } .nav > li { position: relative; display: block; } .nav > li > a { position: relative; display: block; padding: 10px 15px; } .nav > li > a:hover, .nav > li > a:focus { text-decoration: none; background-color: #eee; } .nav > li.disabled > a { color: #777; } .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { color: #777; text-decoration: none; cursor: not-allowed; background-color: transparent; } .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { background-color: #eee; border-color: #337ab7; } .nav .nav-divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .nav > li > a > img { max-width: none; } .nav-tabs { border-bottom: 1px solid #ddd; } .nav-tabs > li { float: left; margin-bottom: -1px; } .nav-tabs > li > a { margin-right: 2px; line-height: 1.42857143; border: 1px solid transparent; border-radius: 4px 4px 0 0; } .nav-tabs > li > a:hover { border-color: #eee #eee #ddd; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { color: #555; cursor: default; background-color: #fff; border: 1px solid #ddd; border-bottom-color: transparent; } .nav-tabs.nav-justified { width: 100%; border-bottom: 0; } .nav-tabs.nav-justified > li { float: none; } .nav-tabs.nav-justified > li > a { margin-bottom: 5px; text-align: center; } .nav-tabs.nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-tabs.nav-justified > li { display: table-cell; width: 1%; } .nav-tabs.nav-justified > li > a { margin-bottom: 0; } } .nav-tabs.nav-justified > li > a { margin-right: 0; border-radius: 4px; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs.nav-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border-bottom-color: #fff; } } .nav-pills > li { float: left; } .nav-pills > li > a { border-radius: 4px; } .nav-pills > li + li { margin-left: 2px; } .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { color: #fff; background-color: #337ab7; } .nav-stacked > li { float: none; } .nav-stacked > li + li { margin-top: 2px; margin-left: 0; } .nav-justified { width: 100%; } .nav-justified > li { float: none; } .nav-justified > li > a { margin-bottom: 5px; text-align: center; } .nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-justified > li { display: table-cell; width: 1%; } .nav-justified > li > a { margin-bottom: 0; } } .nav-tabs-justified { border-bottom: 0; } .nav-tabs-justified > li > a { margin-right: 0; border-radius: 4px; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { border-bottom-color: #fff; } } .tab-content > .tab-pane { display: none; } .tab-content > .active { display: block; } .nav-tabs .dropdown-menu { margin-top: -1px; border-top-left-radius: 0; border-top-right-radius: 0; } .navbar { position: relative; min-height: 50px; margin-bottom: 20px; border: 1px solid transparent; } @media (min-width: 768px) { .navbar { border-radius: 4px; } } @media (min-width: 768px) { .navbar-header { float: left; } } .navbar-collapse { padding-right: 15px; padding-left: 15px; overflow-x: visible; -webkit-overflow-scrolling: touch; border-top: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); } .navbar-collapse.in { overflow-y: auto; } @media (min-width: 768px) { .navbar-collapse { width: auto; border-top: 0; -webkit-box-shadow: none; box-shadow: none; } .navbar-collapse.collapse { display: block !important; height: auto !important; padding-bottom: 0; overflow: visible !important; } .navbar-collapse.in { overflow-y: visible; } .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { padding-right: 0; padding-left: 0; } } .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 340px; } @media (max-device-width: 480px) and (orientation: landscape) { .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 200px; } } .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { margin-right: 0; margin-left: 0; } } .navbar-static-top { z-index: 1000; border-width: 0 0 1px; } @media (min-width: 768px) { .navbar-static-top { border-radius: 0; } } .navbar-fixed-top, .navbar-fixed-bottom { position: fixed; right: 0; left: 0; z-index: 1030; } @media (min-width: 768px) { .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; } } .navbar-fixed-top { top: 0; border-width: 0 0 1px; } .navbar-fixed-bottom { bottom: 0; margin-bottom: 0; border-width: 1px 0 0; } .navbar-brand { float: left; height: 50px; padding: 15px 15px; font-size: 18px; line-height: 20px; } .navbar-brand:hover, .navbar-brand:focus { text-decoration: none; } .navbar-brand > img { display: block; } @media (min-width: 768px) { .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand { margin-left: -15px; } } .navbar-toggle { position: relative; float: right; padding: 9px 10px; margin-top: 8px; margin-right: 15px; margin-bottom: 8px; background-color: transparent; background-image: none; border: 1px solid transparent; border-radius: 4px; } .navbar-toggle:focus { outline: 0; } .navbar-toggle .icon-bar { display: block; width: 22px; height: 2px; border-radius: 1px; } .navbar-toggle .icon-bar + .icon-bar { margin-top: 4px; } @media (min-width: 768px) { .navbar-toggle { display: none; } } .navbar-nav { margin: 7.5px -15px; } .navbar-nav > li > a { padding-top: 10px; padding-bottom: 10px; line-height: 20px; } @media (max-width: 767px) { .navbar-nav .open .dropdown-menu { position: static; float: none; width: auto; margin-top: 0; background-color: transparent; border: 0; -webkit-box-shadow: none; box-shadow: none; } .navbar-nav .open .dropdown-menu > li > a, .navbar-nav .open .dropdown-menu .dropdown-header { padding: 5px 15px 5px 25px; } .navbar-nav .open .dropdown-menu > li > a { line-height: 20px; } .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-nav .open .dropdown-menu > li > a:focus { background-image: none; } } @media (min-width: 768px) { .navbar-nav { float: left; margin: 0; } .navbar-nav > li { float: left; } .navbar-nav > li > a { padding-top: 15px; padding-bottom: 15px; } } .navbar-form { padding: 10px 15px; margin-top: 8px; margin-right: -15px; margin-bottom: 8px; margin-left: -15px; border-top: 1px solid transparent; border-bottom: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); } @media (min-width: 768px) { .navbar-form .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .navbar-form .form-control { display: inline-block; width: auto; vertical-align: middle; } .navbar-form .form-control-static { display: inline-block; } .navbar-form .input-group { display: inline-table; vertical-align: middle; } .navbar-form .input-group .input-group-addon, .navbar-form .input-group .input-group-btn, .navbar-form .input-group .form-control { width: auto; } .navbar-form .input-group > .form-control { width: 100%; } .navbar-form .control-label { margin-bottom: 0; vertical-align: middle; } .navbar-form .radio, .navbar-form .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .navbar-form .radio label, .navbar-form .checkbox label { padding-left: 0; } .navbar-form .radio input[type="radio"], .navbar-form .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .navbar-form .has-feedback .form-control-feedback { top: 0; } } @media (max-width: 767px) { .navbar-form .form-group { margin-bottom: 5px; } .navbar-form .form-group:last-child { margin-bottom: 0; } } @media (min-width: 768px) { .navbar-form { width: auto; padding-top: 0; padding-bottom: 0; margin-right: 0; margin-left: 0; border: 0; -webkit-box-shadow: none; box-shadow: none; } } .navbar-nav > li > .dropdown-menu { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { margin-bottom: 0; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .navbar-btn { margin-top: 8px; margin-bottom: 8px; } .navbar-btn.btn-sm { margin-top: 10px; margin-bottom: 10px; } .navbar-btn.btn-xs { margin-top: 14px; margin-bottom: 14px; } .navbar-text { margin-top: 15px; margin-bottom: 15px; } @media (min-width: 768px) { .navbar-text { float: left; margin-right: 15px; margin-left: 15px; } } @media (min-width: 768px) { .navbar-left { float: left !important; } .navbar-right { float: right !important; margin-right: -15px; } .navbar-right ~ .navbar-right { margin-right: 0; } } .navbar-default { background-color: #f8f8f8; border-color: #e7e7e7; } .navbar-default .navbar-brand { color: #777; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { color: #5e5e5e; background-color: transparent; } .navbar-default .navbar-text { color: #777; } .navbar-default .navbar-nav > li > a { color: #777; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { color: #333; background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { color: #ccc; background-color: transparent; } .navbar-default .navbar-toggle { border-color: #ddd; } .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { background-color: #ddd; } .navbar-default .navbar-toggle .icon-bar { background-color: #888; } .navbar-default .navbar-collapse, .navbar-default .navbar-form { border-color: #e7e7e7; } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { color: #555; background-color: #e7e7e7; } @media (max-width: 767px) { .navbar-default .navbar-nav .open .dropdown-menu > li > a { color: #777; } .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { color: #333; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #ccc; background-color: transparent; } } .navbar-default .navbar-link { color: #777; } .navbar-default .navbar-link:hover { color: #333; } .navbar-default .btn-link { color: #777; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { color: #333; } .navbar-default .btn-link[disabled]:hover, fieldset[disabled] .navbar-default .btn-link:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:focus { color: #ccc; } .navbar-inverse { background-color: #222; border-color: #080808; } .navbar-inverse .navbar-brand { color: #9d9d9d; } .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-text { color: #9d9d9d; } .navbar-inverse .navbar-nav > li > a { color: #9d9d9d; } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { color: #444; background-color: transparent; } .navbar-inverse .navbar-toggle { border-color: #333; } .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { background-color: #333; } .navbar-inverse .navbar-toggle .icon-bar { background-color: #fff; } .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { border-color: #101010; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { color: #fff; background-color: #080808; } @media (max-width: 767px) { .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { border-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu .divider { background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { color: #9d9d9d; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #444; background-color: transparent; } } .navbar-inverse .navbar-link { color: #9d9d9d; } .navbar-inverse .navbar-link:hover { color: #fff; } .navbar-inverse .btn-link { color: #9d9d9d; } .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { color: #fff; } .navbar-inverse .btn-link[disabled]:hover, fieldset[disabled] .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:focus { color: #444; } .breadcrumb { padding: 8px 15px; margin-bottom: 20px; list-style: none; background-color: #f5f5f5; border-radius: 4px; } .breadcrumb > li { display: inline-block; } .breadcrumb > li + li:before { padding: 0 5px; color: #ccc; content: "/\00a0"; } .breadcrumb > .active { color: #777; } .pagination { display: inline-block; padding-left: 0; margin: 20px 0; border-radius: 4px; } .pagination > li { display: inline; } .pagination > li > a, .pagination > li > span { position: relative; float: left; padding: 6px 12px; margin-left: -1px; line-height: 1.42857143; color: #337ab7; text-decoration: none; background-color: #fff; border: 1px solid #ddd; } .pagination > li:first-child > a, .pagination > li:first-child > span { margin-left: 0; border-top-left-radius: 4px; border-bottom-left-radius: 4px; } .pagination > li:last-child > a, .pagination > li:last-child > span { border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .pagination > li > a:hover, .pagination > li > span:hover, .pagination > li > a:focus, .pagination > li > span:focus { z-index: 3; color: #23527c; background-color: #eee; border-color: #ddd; } .pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { z-index: 2; color: #fff; cursor: default; background-color: #337ab7; border-color: #337ab7; } .pagination > .disabled > span, .pagination > .disabled > span:hover, .pagination > .disabled > span:focus, .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus { color: #777; cursor: not-allowed; background-color: #fff; border-color: #ddd; } .pagination-lg > li > a, .pagination-lg > li > span { padding: 10px 16px; font-size: 18px; line-height: 1.3333333; } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { border-top-left-radius: 6px; border-bottom-left-radius: 6px; } .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span { border-top-right-radius: 6px; border-bottom-right-radius: 6px; } .pagination-sm > li > a, .pagination-sm > li > span { padding: 5px 10px; font-size: 12px; line-height: 1.5; } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { border-top-left-radius: 3px; border-bottom-left-radius: 3px; } .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } .pager { padding-left: 0; margin: 20px 0; text-align: center; list-style: none; } .pager li { display: inline; } .pager li > a, .pager li > span { display: inline-block; padding: 5px 14px; background-color: #fff; border: 1px solid #ddd; border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { text-decoration: none; background-color: #eee; } .pager .next > a, .pager .next > span { float: right; } .pager .previous > a, .pager .previous > span { float: left; } .pager .disabled > a, .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { color: #777; cursor: not-allowed; background-color: #fff; } .label { display: inline; padding: .2em .6em .3em; font-size: 75%; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25em; } a.label:hover, a.label:focus { color: #fff; text-decoration: none; cursor: pointer; } .label:empty { display: none; } .btn .label { position: relative; top: -1px; } .label-default { background-color: #777; } .label-default[href]:hover, .label-default[href]:focus { background-color: #5e5e5e; } .label-primary { background-color: #337ab7; } .label-primary[href]:hover, .label-primary[href]:focus { background-color: #286090; } .label-success { background-color: #5cb85c; } .label-success[href]:hover, .label-success[href]:focus { background-color: #449d44; } .label-info { background-color: #5bc0de; } .label-info[href]:hover, .label-info[href]:focus { background-color: #31b0d5; } .label-warning { background-color: #f0ad4e; } .label-warning[href]:hover, .label-warning[href]:focus { background-color: #ec971f; } .label-danger { background-color: #d9534f; } .label-danger[href]:hover, .label-danger[href]:focus { background-color: #c9302c; } .badge { display: inline-block; min-width: 10px; padding: 3px 7px; font-size: 12px; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: middle; background-color: #777; border-radius: 10px; } .badge:empty { display: none; } .btn .badge { position: relative; top: -1px; } .btn-xs .badge, .btn-group-xs > .btn .badge { top: 0; padding: 1px 5px; } a.badge:hover, a.badge:focus { color: #fff; text-decoration: none; cursor: pointer; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { color: #337ab7; background-color: #fff; } .list-group-item > .badge { float: right; } .list-group-item > .badge + .badge { margin-right: 5px; } .nav-pills > li > a > .badge { margin-left: 3px; } .jumbotron { padding-top: 30px; padding-bottom: 30px; margin-bottom: 30px; color: inherit; background-color: #eee; } .jumbotron h1, .jumbotron .h1 { color: inherit; } .jumbotron p { margin-bottom: 15px; font-size: 21px; font-weight: 200; } .jumbotron > hr { border-top-color: #d5d5d5; } .container .jumbotron, .container-fluid .jumbotron { border-radius: 6px; } .jumbotron .container { max-width: 100%; } @media screen and (min-width: 768px) { .jumbotron { padding-top: 48px; padding-bottom: 48px; } .container .jumbotron, .container-fluid .jumbotron { padding-right: 60px; padding-left: 60px; } .jumbotron h1, .jumbotron .h1 { font-size: 63px; } } .thumbnail { display: block; padding: 4px; margin-bottom: 20px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: border .2s ease-in-out; -o-transition: border .2s ease-in-out; transition: border .2s ease-in-out; } .thumbnail > img, .thumbnail a > img { margin-right: auto; margin-left: auto; } a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { border-color: #337ab7; } .thumbnail .caption { padding: 9px; color: #333; } .alert { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .alert h4 { margin-top: 0; color: inherit; } .alert .alert-link { font-weight: bold; } .alert > p, .alert > ul { margin-bottom: 0; } .alert > p + p { margin-top: 5px; } .alert-dismissable, .alert-dismissible { padding-right: 35px; } .alert-dismissable .close, .alert-dismissible .close { position: relative; top: -2px; right: -21px; color: inherit; } .alert-success { color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; } .alert-success hr { border-top-color: #c9e2b3; } .alert-success .alert-link { color: #2b542c; } .alert-info { color: #31708f; background-color: #d9edf7; border-color: #bce8f1; } .alert-info hr { border-top-color: #a6e1ec; } .alert-info .alert-link { color: #245269; } .alert-warning { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .alert-warning hr { border-top-color: #f7e1b5; } .alert-warning .alert-link { color: #66512c; } .alert-danger { color: #a94442; background-color: #f2dede; border-color: #ebccd1; } .alert-danger hr { border-top-color: #e4b9c0; } .alert-danger .alert-link { color: #843534; } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @-o-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } .progress { height: 20px; margin-bottom: 20px; overflow: hidden; background-color: #f5f5f5; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); } .progress-bar { float: left; width: 0; height: 100%; font-size: 12px; line-height: 20px; color: #fff; text-align: center; background-color: #337ab7; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); -webkit-transition: width .6s ease; -o-transition: width .6s ease; transition: width .6s ease; } .progress-striped .progress-bar, .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); -webkit-background-size: 40px 40px; background-size: 40px 40px; } .progress.active .progress-bar, .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } .progress-bar-success { background-color: #5cb85c; } .progress-striped .progress-bar-success { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-info { background-color: #5bc0de; } .progress-striped .progress-bar-info { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-warning { background-color: #f0ad4e; } .progress-striped .progress-bar-warning { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-danger { background-color: #d9534f; } .progress-striped .progress-bar-danger { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .media { margin-top: 15px; } .media:first-child { margin-top: 0; } .media, .media-body { overflow: hidden; zoom: 1; } .media-body { width: 10000px; } .media-object { display: block; } .media-object.img-thumbnail { max-width: none; } .media-right, .media > .pull-right { padding-left: 10px; } .media-left, .media > .pull-left { padding-right: 10px; } .media-left, .media-right, .media-body { display: table-cell; vertical-align: top; } .media-middle { vertical-align: middle; } .media-bottom { vertical-align: bottom; } .media-heading { margin-top: 0; margin-bottom: 5px; } .media-list { padding-left: 0; list-style: none; } .list-group { padding-left: 0; margin-bottom: 20px; } .list-group-item { position: relative; display: block; padding: 10px 15px; margin-bottom: -1px; background-color: #fff; border: 1px solid #ddd; } .list-group-item:first-child { border-top-left-radius: 4px; border-top-right-radius: 4px; } .list-group-item:last-child { margin-bottom: 0; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; } a.list-group-item, button.list-group-item { color: #555; } a.list-group-item .list-group-item-heading, button.list-group-item .list-group-item-heading { color: #333; } a.list-group-item:hover, button.list-group-item:hover, a.list-group-item:focus, button.list-group-item:focus { color: #555; text-decoration: none; background-color: #f5f5f5; } button.list-group-item { width: 100%; text-align: left; } .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { color: #777; cursor: not-allowed; background-color: #eee; } .list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading { color: inherit; } .list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text { color: #777; } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { z-index: 2; color: #fff; background-color: #337ab7; border-color: #337ab7; } .list-group-item.active .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading, .list-group-item.active:focus .list-group-item-heading, .list-group-item.active .list-group-item-heading > small, .list-group-item.active:hover .list-group-item-heading > small, .list-group-item.active:focus .list-group-item-heading > small, .list-group-item.active .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading > .small { color: inherit; } .list-group-item.active .list-group-item-text, .list-group-item.active:hover .list-group-item-text, .list-group-item.active:focus .list-group-item-text { color: #c7ddef; } .list-group-item-success { color: #3c763d; background-color: #dff0d8; } a.list-group-item-success, button.list-group-item-success { color: #3c763d; } a.list-group-item-success .list-group-item-heading, button.list-group-item-success .list-group-item-heading { color: inherit; } a.list-group-item-success:hover, button.list-group-item-success:hover, a.list-group-item-success:focus, button.list-group-item-success:focus { color: #3c763d; background-color: #d0e9c6; } a.list-group-item-success.active, button.list-group-item-success.active, a.list-group-item-success.active:hover, button.list-group-item-success.active:hover, a.list-group-item-success.active:focus, button.list-group-item-success.active:focus { color: #fff; background-color: #3c763d; border-color: #3c763d; } .list-group-item-info { color: #31708f; background-color: #d9edf7; } a.list-group-item-info, button.list-group-item-info { color: #31708f; } a.list-group-item-info .list-group-item-heading, button.list-group-item-info .list-group-item-heading { color: inherit; } a.list-group-item-info:hover, button.list-group-item-info:hover, a.list-group-item-info:focus, button.list-group-item-info:focus { color: #31708f; background-color: #c4e3f3; } a.list-group-item-info.active, button.list-group-item-info.active, a.list-group-item-info.active:hover, button.list-group-item-info.active:hover, a.list-group-item-info.active:focus, button.list-group-item-info.active:focus { color: #fff; background-color: #31708f; border-color: #31708f; } .list-group-item-warning { color: #8a6d3b; background-color: #fcf8e3; } a.list-group-item-warning, button.list-group-item-warning { color: #8a6d3b; } a.list-group-item-warning .list-group-item-heading, button.list-group-item-warning .list-group-item-heading { color: inherit; } a.list-group-item-warning:hover, button.list-group-item-warning:hover, a.list-group-item-warning:focus, button.list-group-item-warning:focus { color: #8a6d3b; background-color: #faf2cc; } a.list-group-item-warning.active, button.list-group-item-warning.active, a.list-group-item-warning.active:hover, button.list-group-item-warning.active:hover, a.list-group-item-warning.active:focus, button.list-group-item-warning.active:focus { color: #fff; background-color: #8a6d3b; border-color: #8a6d3b; } .list-group-item-danger { color: #a94442; background-color: #f2dede; } a.list-group-item-danger, button.list-group-item-danger { color: #a94442; } a.list-group-item-danger .list-group-item-heading, button.list-group-item-danger .list-group-item-heading { color: inherit; } a.list-group-item-danger:hover, button.list-group-item-danger:hover, a.list-group-item-danger:focus, button.list-group-item-danger:focus { color: #a94442; background-color: #ebcccc; } a.list-group-item-danger.active, button.list-group-item-danger.active, a.list-group-item-danger.active:hover, button.list-group-item-danger.active:hover, a.list-group-item-danger.active:focus, button.list-group-item-danger.active:focus { color: #fff; background-color: #a94442; border-color: #a94442; } .list-group-item-heading { margin-top: 0; margin-bottom: 5px; } .list-group-item-text { margin-bottom: 0; line-height: 1.3; } .panel { margin-bottom: 20px; background-color: #fff; border: 1px solid transparent; border-radius: 4px; -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); box-shadow: 0 1px 1px rgba(0, 0, 0, .05); } .panel-body { padding: 15px; } .panel-heading { padding: 10px 15px; border-bottom: 1px solid transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel-heading > .dropdown .dropdown-toggle { color: inherit; } .panel-title { margin-top: 0; margin-bottom: 0; font-size: 16px; color: inherit; } .panel-title > a, .panel-title > small, .panel-title > .small, .panel-title > small > a, .panel-title > .small > a { color: inherit; } .panel-footer { padding: 10px 15px; background-color: #f5f5f5; border-top: 1px solid #ddd; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .list-group, .panel > .panel-collapse > .list-group { margin-bottom: 0; } .panel > .list-group .list-group-item, .panel > .panel-collapse > .list-group .list-group-item { border-width: 1px 0; border-radius: 0; } .panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { border-top: 0; border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { border-bottom: 0; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { border-top-left-radius: 0; border-top-right-radius: 0; } .panel-heading + .list-group .list-group-item:first-child { border-top-width: 0; } .list-group + .panel-footer { border-top-width: 0; } .panel > .table, .panel > .table-responsive > .table, .panel > .panel-collapse > .table { margin-bottom: 0; } .panel > .table caption, .panel > .table-responsive > .table caption, .panel > .panel-collapse > .table caption { padding-right: 15px; padding-left: 15px; } .panel > .table:first-child, .panel > .table-responsive:first-child > .table:first-child { border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { border-top-left-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { border-top-right-radius: 3px; } .panel > .table:last-child, .panel > .table-responsive:last-child > .table:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { border-bottom-right-radius: 3px; } .panel > .panel-body + .table, .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body { border-top: 1px solid #ddd; } .panel > .table > tbody:first-child > tr:first-child th, .panel > .table > tbody:first-child > tr:first-child td { border-top: 0; } .panel > .table-bordered, .panel > .table-responsive > .table-bordered { border: 0; } .panel > .table-bordered > thead > tr > th:first-child, .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, .panel > .table-bordered > tbody > tr > th:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, .panel > .table-bordered > tfoot > tr > th:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, .panel > .table-bordered > thead > tr > td:first-child, .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, .panel > .table-bordered > tbody > tr > td:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, .panel > .table-bordered > tfoot > tr > td:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .panel > .table-bordered > thead > tr > th:last-child, .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, .panel > .table-bordered > tbody > tr > th:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, .panel > .table-bordered > tfoot > tr > th:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, .panel > .table-bordered > thead > tr > td:last-child, .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, .panel > .table-bordered > tbody > tr > td:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, .panel > .table-bordered > tfoot > tr > td:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .panel > .table-bordered > thead > tr:first-child > td, .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, .panel > .table-bordered > tbody > tr:first-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, .panel > .table-bordered > thead > tr:first-child > th, .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, .panel > .table-bordered > tbody > tr:first-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { border-bottom: 0; } .panel > .table-bordered > tbody > tr:last-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, .panel > .table-bordered > tfoot > tr:last-child > td, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, .panel > .table-bordered > tbody > tr:last-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, .panel > .table-bordered > tfoot > tr:last-child > th, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { border-bottom: 0; } .panel > .table-responsive { margin-bottom: 0; border: 0; } .panel-group { margin-bottom: 20px; } .panel-group .panel { margin-bottom: 0; border-radius: 4px; } .panel-group .panel + .panel { margin-top: 5px; } .panel-group .panel-heading { border-bottom: 0; } .panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group { border-top: 1px solid #ddd; } .panel-group .panel-footer { border-top: 0; } .panel-group .panel-footer + .panel-collapse .panel-body { border-bottom: 1px solid #ddd; } .panel-default { border-color: #ddd; } .panel-default > .panel-heading { color: #333; background-color: #f5f5f5; border-color: #ddd; } .panel-default > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ddd; } .panel-default > .panel-heading .badge { color: #f5f5f5; background-color: #333; } .panel-default > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ddd; } .panel-primary { border-color: #337ab7; } .panel-primary > .panel-heading { color: #fff; background-color: #337ab7; border-color: #337ab7; } .panel-primary > .panel-heading + .panel-collapse > .panel-body { border-top-color: #337ab7; } .panel-primary > .panel-heading .badge { color: #337ab7; background-color: #fff; } .panel-primary > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #337ab7; } .panel-success { border-color: #d6e9c6; } .panel-success > .panel-heading { color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; } .panel-success > .panel-heading + .panel-collapse > .panel-body { border-top-color: #d6e9c6; } .panel-success > .panel-heading .badge { color: #dff0d8; background-color: #3c763d; } .panel-success > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #d6e9c6; } .panel-info { border-color: #bce8f1; } .panel-info > .panel-heading { color: #31708f; background-color: #d9edf7; border-color: #bce8f1; } .panel-info > .panel-heading + .panel-collapse > .panel-body { border-top-color: #bce8f1; } .panel-info > .panel-heading .badge { color: #d9edf7; background-color: #31708f; } .panel-info > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #bce8f1; } .panel-warning { border-color: #faebcc; } .panel-warning > .panel-heading { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .panel-warning > .panel-heading + .panel-collapse > .panel-body { border-top-color: #faebcc; } .panel-warning > .panel-heading .badge { color: #fcf8e3; background-color: #8a6d3b; } .panel-warning > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #faebcc; } .panel-danger { border-color: #ebccd1; } .panel-danger > .panel-heading { color: #a94442; background-color: #f2dede; border-color: #ebccd1; } .panel-danger > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ebccd1; } .panel-danger > .panel-heading .badge { color: #f2dede; background-color: #a94442; } .panel-danger > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ebccd1; } .embed-responsive { position: relative; display: block; height: 0; padding: 0; overflow: hidden; } .embed-responsive .embed-responsive-item, .embed-responsive iframe, .embed-responsive embed, .embed-responsive object, .embed-responsive video { position: absolute; top: 0; bottom: 0; left: 0; width: 100%; height: 100%; border: 0; } .embed-responsive-16by9 { padding-bottom: 56.25%; } .embed-responsive-4by3 { padding-bottom: 75%; } .well { min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); } .well blockquote { border-color: #ddd; border-color: rgba(0, 0, 0, .15); } .well-lg { padding: 24px; border-radius: 6px; } .well-sm { padding: 9px; border-radius: 3px; } .close { float: right; font-size: 21px; font-weight: bold; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .2; } .close:hover, .close:focus { color: #000; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .5; } button.close { -webkit-appearance: none; padding: 0; cursor: pointer; background: transparent; border: 0; } .modal-open { overflow: hidden; } .modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1050; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; } .modal.fade .modal-dialog { -webkit-transition: -webkit-transform .3s ease-out; -o-transition: -o-transform .3s ease-out; transition: transform .3s ease-out; -webkit-transform: translate(0, -25%); -ms-transform: translate(0, -25%); -o-transform: translate(0, -25%); transform: translate(0, -25%); } .modal.in .modal-dialog { -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); } .modal-open .modal { overflow-x: hidden; overflow-y: auto; } .modal-dialog { position: relative; width: auto; margin: 10px; } .modal-content { position: relative; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #999; border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; outline: 0; -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); box-shadow: 0 3px 9px rgba(0, 0, 0, .5); } .modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000; } .modal-backdrop.fade { filter: alpha(opacity=0); opacity: 0; } .modal-backdrop.in { filter: alpha(opacity=50); opacity: .5; } .modal-header { min-height: 16.42857143px; padding: 15px; border-bottom: 1px solid #e5e5e5; } .modal-header .close { margin-top: -2px; } .modal-title { margin: 0; line-height: 1.42857143; } .modal-body { position: relative; padding: 15px; } .modal-footer { padding: 15px; text-align: right; border-top: 1px solid #e5e5e5; } .modal-footer .btn + .btn { margin-bottom: 0; margin-left: 5px; } .modal-footer .btn-group .btn + .btn { margin-left: -1px; } .modal-footer .btn-block + .btn-block { margin-left: 0; } .modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; } @media (min-width: 768px) { .modal-dialog { width: 600px; margin: 30px auto; } .modal-content { -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); box-shadow: 0 5px 15px rgba(0, 0, 0, .5); } .modal-sm { width: 300px; } } @media (min-width: 992px) { .modal-lg { width: 900px; } } .tooltip { position: absolute; z-index: 1070; display: block; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 12px; font-style: normal; font-weight: normal; line-height: 1.42857143; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-break: normal; word-spacing: normal; word-wrap: normal; white-space: normal; filter: alpha(opacity=0); opacity: 0; line-break: auto; } .tooltip.in { filter: alpha(opacity=90); opacity: .9; } .tooltip.top { padding: 5px 0; margin-top: -3px; } .tooltip.right { padding: 0 5px; margin-left: 3px; } .tooltip.bottom { padding: 5px 0; margin-top: 3px; } .tooltip.left { padding: 0 5px; margin-left: -3px; } .tooltip-inner { max-width: 200px; padding: 3px 8px; color: #fff; text-align: center; background-color: #000; border-radius: 4px; } .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid; } .tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.top-left .tooltip-arrow { right: 5px; bottom: 0; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.top-right .tooltip-arrow { bottom: 0; left: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; border-right-color: #000; } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; border-left-color: #000; } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .tooltip.bottom-left .tooltip-arrow { top: 0; right: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .tooltip.bottom-right .tooltip-arrow { top: 0; left: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .popover { position: absolute; top: 0; left: 0; z-index: 1060; display: none; max-width: 276px; padding: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: normal; line-height: 1.42857143; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-break: normal; word-spacing: normal; word-wrap: normal; white-space: normal; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); box-shadow: 0 5px 10px rgba(0, 0, 0, .2); line-break: auto; } .popover.top { margin-top: -10px; } .popover.right { margin-left: 10px; } .popover.bottom { margin-top: 10px; } .popover.left { margin-left: -10px; } .popover-title { padding: 8px 14px; margin: 0; font-size: 14px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; border-radius: 5px 5px 0 0; } .popover-content { padding: 9px 14px; } .popover > .arrow, .popover > .arrow:after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popover > .arrow { border-width: 11px; } .popover > .arrow:after { content: ""; border-width: 10px; } .popover.top > .arrow { bottom: -11px; left: 50%; margin-left: -11px; border-top-color: #999; border-top-color: rgba(0, 0, 0, .25); border-bottom-width: 0; } .popover.top > .arrow:after { bottom: 1px; margin-left: -10px; content: " "; border-top-color: #fff; border-bottom-width: 0; } .popover.right > .arrow { top: 50%; left: -11px; margin-top: -11px; border-right-color: #999; border-right-color: rgba(0, 0, 0, .25); border-left-width: 0; } .popover.right > .arrow:after { bottom: -10px; left: 1px; content: " "; border-right-color: #fff; border-left-width: 0; } .popover.bottom > .arrow { top: -11px; left: 50%; margin-left: -11px; border-top-width: 0; border-bottom-color: #999; border-bottom-color: rgba(0, 0, 0, .25); } .popover.bottom > .arrow:after { top: 1px; margin-left: -10px; content: " "; border-top-width: 0; border-bottom-color: #fff; } .popover.left > .arrow { top: 50%; right: -11px; margin-top: -11px; border-right-width: 0; border-left-color: #999; border-left-color: rgba(0, 0, 0, .25); } .popover.left > .arrow:after { right: 1px; bottom: -10px; content: " "; border-right-width: 0; border-left-color: #fff; } .carousel { position: relative; } .carousel-inner { position: relative; width: 100%; overflow: hidden; } .carousel-inner > .item { position: relative; display: none; -webkit-transition: .6s ease-in-out left; -o-transition: .6s ease-in-out left; transition: .6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { line-height: 1; } @media all and (transform-3d), (-webkit-transform-3d) { .carousel-inner > .item { -webkit-transition: -webkit-transform .6s ease-in-out; -o-transition: -o-transform .6s ease-in-out; transition: transform .6s ease-in-out; -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-perspective: 1000px; perspective: 1000px; } .carousel-inner > .item.next, .carousel-inner > .item.active.right { left: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } .carousel-inner > .item.prev, .carousel-inner > .item.active.left { left: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right, .carousel-inner > .item.active { left: 0; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { display: block; } .carousel-inner > .active { left: 0; } .carousel-inner > .next, .carousel-inner > .prev { position: absolute; top: 0; width: 100%; } .carousel-inner > .next { left: 100%; } .carousel-inner > .prev { left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { left: 0; } .carousel-inner > .active.left { left: -100%; } .carousel-inner > .active.right { left: 100%; } .carousel-control { position: absolute; top: 0; bottom: 0; left: 0; width: 15%; font-size: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, .6); filter: alpha(opacity=50); opacity: .5; } .carousel-control.left { background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); background-repeat: repeat-x; } .carousel-control.right { right: 0; left: auto; background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); background-repeat: repeat-x; } .carousel-control:hover, .carousel-control:focus { color: #fff; text-decoration: none; filter: alpha(opacity=90); outline: 0; opacity: .9; } .carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { position: absolute; top: 50%; z-index: 5; display: inline-block; margin-top: -10px; } .carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { left: 50%; margin-left: -10px; } .carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { right: 50%; margin-right: -10px; } .carousel-control .icon-prev, .carousel-control .icon-next { width: 20px; height: 20px; font-family: serif; line-height: 1; } .carousel-control .icon-prev:before { content: '\2039'; } .carousel-control .icon-next:before { content: '\203a'; } .carousel-indicators { position: absolute; bottom: 10px; left: 50%; z-index: 15; width: 60%; padding-left: 0; margin-left: -30%; text-align: center; list-style: none; } .carousel-indicators li { display: inline-block; width: 10px; height: 10px; margin: 1px; text-indent: -999px; cursor: pointer; background-color: #000 \9; background-color: rgba(0, 0, 0, 0); border: 1px solid #fff; border-radius: 10px; } .carousel-indicators .active { width: 12px; height: 12px; margin: 0; background-color: #fff; } .carousel-caption { position: absolute; right: 15%; bottom: 20px; left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, .6); } .carousel-caption .btn { text-shadow: none; } @media screen and (min-width: 768px) { .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next { width: 30px; height: 30px; margin-top: -15px; font-size: 30px; } .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev { margin-left: -15px; } .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next { margin-right: -15px; } .carousel-caption { right: 20%; left: 20%; padding-bottom: 30px; } .carousel-indicators { bottom: 20px; } } .clearfix:before, .clearfix:after, .dl-horizontal dd:before, .dl-horizontal dd:after, .container:before, .container:after, .container-fluid:before, .container-fluid:after, .row:before, .row:after, .form-horizontal .form-group:before, .form-horizontal .form-group:after, .btn-toolbar:before, .btn-toolbar:after, .btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after, .nav:before, .nav:after, .navbar:before, .navbar:after, .navbar-header:before, .navbar-header:after, .navbar-collapse:before, .navbar-collapse:after, .pager:before, .pager:after, .panel-body:before, .panel-body:after, .modal-footer:before, .modal-footer:after { display: table; content: " "; } .clearfix:after, .dl-horizontal dd:after, .container:after, .container-fluid:after, .row:after, .form-horizontal .form-group:after, .btn-toolbar:after, .btn-group-vertical > .btn-group:after, .nav:after, .navbar:after, .navbar-header:after, .navbar-collapse:after, .pager:after, .panel-body:after, .modal-footer:after { clear: both; } .center-block { display: block; margin-right: auto; margin-left: auto; } .pull-right { float: right !important; } .pull-left { float: left !important; } .hide { display: none !important; } .show { display: block !important; } .invisible { visibility: hidden; } .text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } .hidden { display: none !important; } .affix { position: fixed; } @-ms-viewport { width: device-width; } .visible-xs, .visible-sm, .visible-md, .visible-lg { display: none !important; } .visible-xs-block, .visible-xs-inline, .visible-xs-inline-block, .visible-sm-block, .visible-sm-inline, .visible-sm-inline-block, .visible-md-block, .visible-md-inline, .visible-md-inline-block, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block { display: none !important; } @media (max-width: 767px) { .visible-xs { display: block !important; } table.visible-xs { display: table !important; } tr.visible-xs { display: table-row !important; } th.visible-xs, td.visible-xs { display: table-cell !important; } } @media (max-width: 767px) { .visible-xs-block { display: block !important; } } @media (max-width: 767px) { .visible-xs-inline { display: inline !important; } } @media (max-width: 767px) { .visible-xs-inline-block { display: inline-block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm { display: block !important; } table.visible-sm { display: table !important; } tr.visible-sm { display: table-row !important; } th.visible-sm, td.visible-sm { display: table-cell !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-block { display: block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline { display: inline !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline-block { display: inline-block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md { display: block !important; } table.visible-md { display: table !important; } tr.visible-md { display: table-row !important; } th.visible-md, td.visible-md { display: table-cell !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-block { display: block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline { display: inline !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline-block { display: inline-block !important; } } @media (min-width: 1200px) { .visible-lg { display: block !important; } table.visible-lg { display: table !important; } tr.visible-lg { display: table-row !important; } th.visible-lg, td.visible-lg { display: table-cell !important; } } @media (min-width: 1200px) { .visible-lg-block { display: block !important; } } @media (min-width: 1200px) { .visible-lg-inline { display: inline !important; } } @media (min-width: 1200px) { .visible-lg-inline-block { display: inline-block !important; } } @media (max-width: 767px) { .hidden-xs { display: none !important; } } @media (min-width: 768px) and (max-width: 991px) { .hidden-sm { display: none !important; } } @media (min-width: 992px) and (max-width: 1199px) { .hidden-md { display: none !important; } } @media (min-width: 1200px) { .hidden-lg { display: none !important; } } .visible-print { display: none !important; } @media print { .visible-print { display: block !important; } table.visible-print { display: table !important; } tr.visible-print { display: table-row !important; } th.visible-print, td.visible-print { display: table-cell !important; } } .visible-print-block { display: none !important; } @media print { .visible-print-block { display: block !important; } } .visible-print-inline { display: none !important; } @media print { .visible-print-inline { display: inline !important; } } .visible-print-inline-block { display: none !important; } @media print { .visible-print-inline-block { display: inline-block !important; } } @media print { .hidden-print { display: none !important; } } /*# sourceMappingURL=bootstrap.css.map */ SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/PaxHeaders/js0000644000000000000000000000007414336451277023500 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/0000755000000000000000000000000014336451277024470 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/PaxHeaders/src0000644000000000000000000000007414336451277024267 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/src/0000755000000000000000000000000014336451277025257 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/src/PaxHeaders/bootstrap_3.3.5.js0000644000000000000000000000007414336451277027445 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/src/bootstrap_3.3.5.js0000644000000000000000000020643214336451277030367 0ustar00rootroot00000000000000/*! * Bootstrap v3.3.5 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under the MIT license */ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') } +function ($) { 'use strict'; var version = $.fn.jquery.split(' ')[0].split('.') if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') } }(jQuery); /* ======================================================================== * Bootstrap: transition.js v3.3.5 * http://getbootstrap.com/javascript/#transitions * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) // ============================================================ function transitionEnd() { var el = document.createElement('bootstrap') var transEndEventNames = { WebkitTransition : 'webkitTransitionEnd', MozTransition : 'transitionend', OTransition : 'oTransitionEnd otransitionend', transition : 'transitionend' } for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return { end: transEndEventNames[name] } } } return false // explicit for ie8 ( ._.) } // http://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function (duration) { var called = false var $el = this $(this).one('bsTransitionEnd', function () { called = true }) var callback = function () { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(function () { $.support.transition = transitionEnd() if (!$.support.transition) return $.event.special.bsTransitionEnd = { bindType: $.support.transition.end, delegateType: $.support.transition.end, handle: function (e) { if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) } } }) }(jQuery); /* ======================================================================== * Bootstrap: alert.js v3.3.5 * http://getbootstrap.com/javascript/#alerts * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // ALERT CLASS DEFINITION // ====================== var dismiss = '[data-dismiss="alert"]' var Alert = function (el) { $(el).on('click', dismiss, this.close) } Alert.VERSION = '3.3.5' Alert.TRANSITION_DURATION = 150 Alert.prototype.close = function (e) { var $this = $(this) var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.closest('.alert') } $parent.trigger(e = $.Event('close.bs.alert')) if (e.isDefaultPrevented()) return $parent.removeClass('in') function removeElement() { // detach from parent, fire event then clean up data $parent.detach().trigger('closed.bs.alert').remove() } $.support.transition && $parent.hasClass('fade') ? $parent .one('bsTransitionEnd', removeElement) .emulateTransitionEnd(Alert.TRANSITION_DURATION) : removeElement() } // ALERT PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.alert') if (!data) $this.data('bs.alert', (data = new Alert(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.alert $.fn.alert = Plugin $.fn.alert.Constructor = Alert // ALERT NO CONFLICT // ================= $.fn.alert.noConflict = function () { $.fn.alert = old return this } // ALERT DATA-API // ============== $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) }(jQuery); /* ======================================================================== * Bootstrap: button.js v3.3.5 * http://getbootstrap.com/javascript/#buttons * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // BUTTON PUBLIC CLASS DEFINITION // ============================== var Button = function (element, options) { this.$element = $(element) this.options = $.extend({}, Button.DEFAULTS, options) this.isLoading = false } Button.VERSION = '3.3.5' Button.DEFAULTS = { loadingText: 'loading...' } Button.prototype.setState = function (state) { var d = 'disabled' var $el = this.$element var val = $el.is('input') ? 'val' : 'html' var data = $el.data() state += 'Text' if (data.resetText == null) $el.data('resetText', $el[val]()) // push to event loop to allow forms to submit setTimeout($.proxy(function () { $el[val](data[state] == null ? this.options[state] : data[state]) if (state == 'loadingText') { this.isLoading = true $el.addClass(d).attr(d, d) } else if (this.isLoading) { this.isLoading = false $el.removeClass(d).removeAttr(d) } }, this), 0) } Button.prototype.toggle = function () { var changed = true var $parent = this.$element.closest('[data-toggle="buttons"]') if ($parent.length) { var $input = this.$element.find('input') if ($input.prop('type') == 'radio') { if ($input.prop('checked')) changed = false $parent.find('.active').removeClass('active') this.$element.addClass('active') } else if ($input.prop('type') == 'checkbox') { if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false this.$element.toggleClass('active') } $input.prop('checked', this.$element.hasClass('active')) if (changed) $input.trigger('change') } else { this.$element.attr('aria-pressed', !this.$element.hasClass('active')) this.$element.toggleClass('active') } } // BUTTON PLUGIN DEFINITION // ======================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.button') var options = typeof option == 'object' && option if (!data) $this.data('bs.button', (data = new Button(this, options))) if (option == 'toggle') data.toggle() else if (option) data.setState(option) }) } var old = $.fn.button $.fn.button = Plugin $.fn.button.Constructor = Button // BUTTON NO CONFLICT // ================== $.fn.button.noConflict = function () { $.fn.button = old return this } // BUTTON DATA-API // =============== $(document) .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { var $btn = $(e.target) if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') Plugin.call($btn, 'toggle') if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() }) .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) }) }(jQuery); /* ======================================================================== * Bootstrap: carousel.js v3.3.5 * http://getbootstrap.com/javascript/#carousel * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CAROUSEL CLASS DEFINITION // ========================= var Carousel = function (element, options) { this.$element = $(element) this.$indicators = this.$element.find('.carousel-indicators') this.options = options this.paused = null this.sliding = null this.interval = null this.$active = null this.$items = null this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) } Carousel.VERSION = '3.3.5' Carousel.TRANSITION_DURATION = 600 Carousel.DEFAULTS = { interval: 5000, pause: 'hover', wrap: true, keyboard: true } Carousel.prototype.keydown = function (e) { if (/input|textarea/i.test(e.target.tagName)) return switch (e.which) { case 37: this.prev(); break case 39: this.next(); break default: return } e.preventDefault() } Carousel.prototype.cycle = function (e) { e || (this.paused = false) this.interval && clearInterval(this.interval) this.options.interval && !this.paused && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) return this } Carousel.prototype.getItemIndex = function (item) { this.$items = item.parent().children('.item') return this.$items.index(item || this.$active) } Carousel.prototype.getItemForDirection = function (direction, active) { var activeIndex = this.getItemIndex(active) var willWrap = (direction == 'prev' && activeIndex === 0) || (direction == 'next' && activeIndex == (this.$items.length - 1)) if (willWrap && !this.options.wrap) return active var delta = direction == 'prev' ? -1 : 1 var itemIndex = (activeIndex + delta) % this.$items.length return this.$items.eq(itemIndex) } Carousel.prototype.to = function (pos) { var that = this var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) if (pos > (this.$items.length - 1) || pos < 0) return if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" if (activeIndex == pos) return this.pause().cycle() return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) } Carousel.prototype.pause = function (e) { e || (this.paused = true) if (this.$element.find('.next, .prev').length && $.support.transition) { this.$element.trigger($.support.transition.end) this.cycle(true) } this.interval = clearInterval(this.interval) return this } Carousel.prototype.next = function () { if (this.sliding) return return this.slide('next') } Carousel.prototype.prev = function () { if (this.sliding) return return this.slide('prev') } Carousel.prototype.slide = function (type, next) { var $active = this.$element.find('.item.active') var $next = next || this.getItemForDirection(type, $active) var isCycling = this.interval var direction = type == 'next' ? 'left' : 'right' var that = this if ($next.hasClass('active')) return (this.sliding = false) var relatedTarget = $next[0] var slideEvent = $.Event('slide.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) this.$element.trigger(slideEvent) if (slideEvent.isDefaultPrevented()) return this.sliding = true isCycling && this.pause() if (this.$indicators.length) { this.$indicators.find('.active').removeClass('active') var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) $nextIndicator && $nextIndicator.addClass('active') } var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" if ($.support.transition && this.$element.hasClass('slide')) { $next.addClass(type) $next[0].offsetWidth // force reflow $active.addClass(direction) $next.addClass(direction) $active .one('bsTransitionEnd', function () { $next.removeClass([type, direction].join(' ')).addClass('active') $active.removeClass(['active', direction].join(' ')) that.sliding = false setTimeout(function () { that.$element.trigger(slidEvent) }, 0) }) .emulateTransitionEnd(Carousel.TRANSITION_DURATION) } else { $active.removeClass('active') $next.addClass('active') this.sliding = false this.$element.trigger(slidEvent) } isCycling && this.cycle() return this } // CAROUSEL PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.carousel') var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) var action = typeof option == 'string' ? option : options.slide if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) if (typeof option == 'number') data.to(option) else if (action) data[action]() else if (options.interval) data.pause().cycle() }) } var old = $.fn.carousel $.fn.carousel = Plugin $.fn.carousel.Constructor = Carousel // CAROUSEL NO CONFLICT // ==================== $.fn.carousel.noConflict = function () { $.fn.carousel = old return this } // CAROUSEL DATA-API // ================= var clickHandler = function (e) { var href var $this = $(this) var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 if (!$target.hasClass('carousel')) return var options = $.extend({}, $target.data(), $this.data()) var slideIndex = $this.attr('data-slide-to') if (slideIndex) options.interval = false Plugin.call($target, options) if (slideIndex) { $target.data('bs.carousel').to(slideIndex) } e.preventDefault() } $(document) .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) $(window).on('load', function () { $('[data-ride="carousel"]').each(function () { var $carousel = $(this) Plugin.call($carousel, $carousel.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: collapse.js v3.3.5 * http://getbootstrap.com/javascript/#collapse * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // COLLAPSE PUBLIC CLASS DEFINITION // ================================ var Collapse = function (element, options) { this.$element = $(element) this.options = $.extend({}, Collapse.DEFAULTS, options) this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + '[data-toggle="collapse"][data-target="#' + element.id + '"]') this.transitioning = null if (this.options.parent) { this.$parent = this.getParent() } else { this.addAriaAndCollapsedClass(this.$element, this.$trigger) } if (this.options.toggle) this.toggle() } Collapse.VERSION = '3.3.5' Collapse.TRANSITION_DURATION = 350 Collapse.DEFAULTS = { toggle: true } Collapse.prototype.dimension = function () { var hasWidth = this.$element.hasClass('width') return hasWidth ? 'width' : 'height' } Collapse.prototype.show = function () { if (this.transitioning || this.$element.hasClass('in')) return var activesData var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') if (actives && actives.length) { activesData = actives.data('bs.collapse') if (activesData && activesData.transitioning) return } var startEvent = $.Event('show.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return if (actives && actives.length) { Plugin.call(actives, 'hide') activesData || actives.data('bs.collapse', null) } var dimension = this.dimension() this.$element .removeClass('collapse') .addClass('collapsing')[dimension](0) .attr('aria-expanded', true) this.$trigger .removeClass('collapsed') .attr('aria-expanded', true) this.transitioning = 1 var complete = function () { this.$element .removeClass('collapsing') .addClass('collapse in')[dimension]('') this.transitioning = 0 this.$element .trigger('shown.bs.collapse') } if (!$.support.transition) return complete.call(this) var scrollSize = $.camelCase(['scroll', dimension].join('-')) this.$element .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) } Collapse.prototype.hide = function () { if (this.transitioning || !this.$element.hasClass('in')) return var startEvent = $.Event('hide.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return var dimension = this.dimension() this.$element[dimension](this.$element[dimension]())[0].offsetHeight this.$element .addClass('collapsing') .removeClass('collapse in') .attr('aria-expanded', false) this.$trigger .addClass('collapsed') .attr('aria-expanded', false) this.transitioning = 1 var complete = function () { this.transitioning = 0 this.$element .removeClass('collapsing') .addClass('collapse') .trigger('hidden.bs.collapse') } if (!$.support.transition) return complete.call(this) this.$element [dimension](0) .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION) } Collapse.prototype.toggle = function () { this[this.$element.hasClass('in') ? 'hide' : 'show']() } Collapse.prototype.getParent = function () { return $(this.options.parent) .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') .each($.proxy(function (i, element) { var $element = $(element) this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) }, this)) .end() } Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { var isOpen = $element.hasClass('in') $element.attr('aria-expanded', isOpen) $trigger .toggleClass('collapsed', !isOpen) .attr('aria-expanded', isOpen) } function getTargetFromTrigger($trigger) { var href var target = $trigger.attr('data-target') || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 return $(target) } // COLLAPSE PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.collapse') var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.collapse $.fn.collapse = Plugin $.fn.collapse.Constructor = Collapse // COLLAPSE NO CONFLICT // ==================== $.fn.collapse.noConflict = function () { $.fn.collapse = old return this } // COLLAPSE DATA-API // ================= $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { var $this = $(this) if (!$this.attr('data-target')) e.preventDefault() var $target = getTargetFromTrigger($this) var data = $target.data('bs.collapse') var option = data ? 'toggle' : $this.data() Plugin.call($target, option) }) }(jQuery); /* ======================================================================== * Bootstrap: dropdown.js v3.3.5 * http://getbootstrap.com/javascript/#dropdowns * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // DROPDOWN CLASS DEFINITION // ========================= var backdrop = '.dropdown-backdrop' var toggle = '[data-toggle="dropdown"]' var Dropdown = function (element) { $(element).on('click.bs.dropdown', this.toggle) } Dropdown.VERSION = '3.3.5' function getParent($this) { var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = selector && $(selector) return $parent && $parent.length ? $parent : $this.parent() } function clearMenus(e) { if (e && e.which === 3) return $(backdrop).remove() $(toggle).each(function () { var $this = $(this) var $parent = getParent($this) var relatedTarget = { relatedTarget: this } if (!$parent.hasClass('open')) return if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this.attr('aria-expanded', 'false') $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) }) } Dropdown.prototype.toggle = function (e) { var $this = $(this) if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') clearMenus() if (!isActive) { if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { // if mobile we use a backdrop because click events don't delegate $(document.createElement('div')) .addClass('dropdown-backdrop') .insertAfter($(this)) .on('click', clearMenus) } var relatedTarget = { relatedTarget: this } $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this .trigger('focus') .attr('aria-expanded', 'true') $parent .toggleClass('open') .trigger('shown.bs.dropdown', relatedTarget) } return false } Dropdown.prototype.keydown = function (e) { if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return var $this = $(this) e.preventDefault() e.stopPropagation() if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') if (!isActive && e.which != 27 || isActive && e.which == 27) { if (e.which == 27) $parent.find(toggle).trigger('focus') return $this.trigger('click') } var desc = ' li:not(.disabled):visible a' var $items = $parent.find('.dropdown-menu' + desc) if (!$items.length) return var index = $items.index(e.target) if (e.which == 38 && index > 0) index-- // up if (e.which == 40 && index < $items.length - 1) index++ // down if (!~index) index = 0 $items.eq(index).trigger('focus') } // DROPDOWN PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.dropdown') if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.dropdown $.fn.dropdown = Plugin $.fn.dropdown.Constructor = Dropdown // DROPDOWN NO CONFLICT // ==================== $.fn.dropdown.noConflict = function () { $.fn.dropdown = old return this } // APPLY TO STANDARD DROPDOWN ELEMENTS // =================================== $(document) .on('click.bs.dropdown.data-api', clearMenus) .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) }(jQuery); /* ======================================================================== * Bootstrap: modal.js v3.3.5 * http://getbootstrap.com/javascript/#modals * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // MODAL CLASS DEFINITION // ====================== var Modal = function (element, options) { this.options = options this.$body = $(document.body) this.$element = $(element) this.$dialog = this.$element.find('.modal-dialog') this.$backdrop = null this.isShown = null this.originalBodyPad = null this.scrollbarWidth = 0 this.ignoreBackdropClick = false if (this.options.remote) { this.$element .find('.modal-content') .load(this.options.remote, $.proxy(function () { this.$element.trigger('loaded.bs.modal') }, this)) } } Modal.VERSION = '3.3.5' Modal.TRANSITION_DURATION = 300 Modal.BACKDROP_TRANSITION_DURATION = 150 Modal.DEFAULTS = { backdrop: true, keyboard: true, show: true } Modal.prototype.toggle = function (_relatedTarget) { return this.isShown ? this.hide() : this.show(_relatedTarget) } Modal.prototype.show = function (_relatedTarget) { var that = this var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) this.$element.trigger(e) if (this.isShown || e.isDefaultPrevented()) return this.isShown = true this.checkScrollbar() this.setScrollbar() this.$body.addClass('modal-open') this.escape() this.resize() this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) this.$dialog.on('mousedown.dismiss.bs.modal', function () { that.$element.one('mouseup.dismiss.bs.modal', function (e) { if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true }) }) this.backdrop(function () { var transition = $.support.transition && that.$element.hasClass('fade') if (!that.$element.parent().length) { that.$element.appendTo(that.$body) // don't move modals dom position } that.$element .show() .scrollTop(0) that.adjustDialog() if (transition) { that.$element[0].offsetWidth // force reflow } that.$element.addClass('in') that.enforceFocus() var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) transition ? that.$dialog // wait for modal to slide in .one('bsTransitionEnd', function () { that.$element.trigger('focus').trigger(e) }) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : that.$element.trigger('focus').trigger(e) }) } Modal.prototype.hide = function (e) { if (e) e.preventDefault() e = $.Event('hide.bs.modal') this.$element.trigger(e) if (!this.isShown || e.isDefaultPrevented()) return this.isShown = false this.escape() this.resize() $(document).off('focusin.bs.modal') this.$element .removeClass('in') .off('click.dismiss.bs.modal') .off('mouseup.dismiss.bs.modal') this.$dialog.off('mousedown.dismiss.bs.modal') $.support.transition && this.$element.hasClass('fade') ? this.$element .one('bsTransitionEnd', $.proxy(this.hideModal, this)) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : this.hideModal() } Modal.prototype.enforceFocus = function () { $(document) .off('focusin.bs.modal') // guard against infinite focus loop .on('focusin.bs.modal', $.proxy(function (e) { if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { this.$element.trigger('focus') } }, this)) } Modal.prototype.escape = function () { if (this.isShown && this.options.keyboard) { this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { e.which == 27 && this.hide() }, this)) } else if (!this.isShown) { this.$element.off('keydown.dismiss.bs.modal') } } Modal.prototype.resize = function () { if (this.isShown) { $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) } else { $(window).off('resize.bs.modal') } } Modal.prototype.hideModal = function () { var that = this this.$element.hide() this.backdrop(function () { that.$body.removeClass('modal-open') that.resetAdjustments() that.resetScrollbar() that.$element.trigger('hidden.bs.modal') }) } Modal.prototype.removeBackdrop = function () { this.$backdrop && this.$backdrop.remove() this.$backdrop = null } Modal.prototype.backdrop = function (callback) { var that = this var animate = this.$element.hasClass('fade') ? 'fade' : '' if (this.isShown && this.options.backdrop) { var doAnimate = $.support.transition && animate this.$backdrop = $(document.createElement('div')) .addClass('modal-backdrop ' + animate) .appendTo(this.$body) this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { if (this.ignoreBackdropClick) { this.ignoreBackdropClick = false return } if (e.target !== e.currentTarget) return this.options.backdrop == 'static' ? this.$element[0].focus() : this.hide() }, this)) if (doAnimate) this.$backdrop[0].offsetWidth // force reflow this.$backdrop.addClass('in') if (!callback) return doAnimate ? this.$backdrop .one('bsTransitionEnd', callback) .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : callback() } else if (!this.isShown && this.$backdrop) { this.$backdrop.removeClass('in') var callbackRemove = function () { that.removeBackdrop() callback && callback() } $.support.transition && this.$element.hasClass('fade') ? this.$backdrop .one('bsTransitionEnd', callbackRemove) .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : callbackRemove() } else if (callback) { callback() } } // these following methods are used to handle overflowing modals Modal.prototype.handleUpdate = function () { this.adjustDialog() } Modal.prototype.adjustDialog = function () { var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight this.$element.css({ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' }) } Modal.prototype.resetAdjustments = function () { this.$element.css({ paddingLeft: '', paddingRight: '' }) } Modal.prototype.checkScrollbar = function () { var fullWindowWidth = window.innerWidth if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 var documentElementRect = document.documentElement.getBoundingClientRect() fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) } this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth this.scrollbarWidth = this.measureScrollbar() } Modal.prototype.setScrollbar = function () { var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) this.originalBodyPad = document.body.style.paddingRight || '' if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) } Modal.prototype.resetScrollbar = function () { this.$body.css('padding-right', this.originalBodyPad) } Modal.prototype.measureScrollbar = function () { // thx walsh var scrollDiv = document.createElement('div') scrollDiv.className = 'modal-scrollbar-measure' this.$body.append(scrollDiv) var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth this.$body[0].removeChild(scrollDiv) return scrollbarWidth } // MODAL PLUGIN DEFINITION // ======================= function Plugin(option, _relatedTarget) { return this.each(function () { var $this = $(this) var data = $this.data('bs.modal') var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data) $this.data('bs.modal', (data = new Modal(this, options))) if (typeof option == 'string') data[option](_relatedTarget) else if (options.show) data.show(_relatedTarget) }) } var old = $.fn.modal $.fn.modal = Plugin $.fn.modal.Constructor = Modal // MODAL NO CONFLICT // ================= $.fn.modal.noConflict = function () { $.fn.modal = old return this } // MODAL DATA-API // ============== $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { var $this = $(this) var href = $this.attr('href') var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) if ($this.is('a')) e.preventDefault() $target.one('show.bs.modal', function (showEvent) { if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown $target.one('hidden.bs.modal', function () { $this.is(':visible') && $this.trigger('focus') }) }) Plugin.call($target, option, this) }) }(jQuery); /* ======================================================================== * Bootstrap: tooltip.js v3.3.5 * http://getbootstrap.com/javascript/#tooltip * Inspired by the original jQuery.tipsy by Jason Frame * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // TOOLTIP PUBLIC CLASS DEFINITION // =============================== var Tooltip = function (element, options) { this.type = null this.options = null this.enabled = null this.timeout = null this.hoverState = null this.$element = null this.inState = null this.init('tooltip', element, options) } Tooltip.VERSION = '3.3.5' Tooltip.TRANSITION_DURATION = 150 Tooltip.DEFAULTS = { animation: true, placement: 'top', selector: false, template: '
    ', trigger: 'hover focus', title: '', delay: 0, html: false, container: false, viewport: { selector: 'body', padding: 0 } } Tooltip.prototype.init = function (type, element, options) { this.enabled = true this.type = type this.$element = $(element) this.options = this.getOptions(options) this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) this.inState = { click: false, hover: false, focus: false } if (this.$element[0] instanceof document.constructor && !this.options.selector) { throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') } var triggers = this.options.trigger.split(' ') for (var i = triggers.length; i--;) { var trigger = triggers[i] if (trigger == 'click') { this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) } else if (trigger != 'manual') { var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) } } this.options.selector ? (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : this.fixTitle() } Tooltip.prototype.getDefaults = function () { return Tooltip.DEFAULTS } Tooltip.prototype.getOptions = function (options) { options = $.extend({}, this.getDefaults(), this.$element.data(), options) if (options.delay && typeof options.delay == 'number') { options.delay = { show: options.delay, hide: options.delay } } return options } Tooltip.prototype.getDelegateOptions = function () { var options = {} var defaults = this.getDefaults() this._options && $.each(this._options, function (key, value) { if (defaults[key] != value) options[key] = value }) return options } Tooltip.prototype.enter = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } if (obj instanceof $.Event) { self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true } if (self.tip().hasClass('in') || self.hoverState == 'in') { self.hoverState = 'in' return } clearTimeout(self.timeout) self.hoverState = 'in' if (!self.options.delay || !self.options.delay.show) return self.show() self.timeout = setTimeout(function () { if (self.hoverState == 'in') self.show() }, self.options.delay.show) } Tooltip.prototype.isInStateTrue = function () { for (var key in this.inState) { if (this.inState[key]) return true } return false } Tooltip.prototype.leave = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } if (obj instanceof $.Event) { self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false } if (self.isInStateTrue()) return clearTimeout(self.timeout) self.hoverState = 'out' if (!self.options.delay || !self.options.delay.hide) return self.hide() self.timeout = setTimeout(function () { if (self.hoverState == 'out') self.hide() }, self.options.delay.hide) } Tooltip.prototype.show = function () { var e = $.Event('show.bs.' + this.type) if (this.hasContent() && this.enabled) { this.$element.trigger(e) var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) if (e.isDefaultPrevented() || !inDom) return var that = this var $tip = this.tip() var tipId = this.getUID(this.type) this.setContent() $tip.attr('id', tipId) this.$element.attr('aria-describedby', tipId) if (this.options.animation) $tip.addClass('fade') var placement = typeof this.options.placement == 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement var autoToken = /\s?auto?\s?/i var autoPlace = autoToken.test(placement) if (autoPlace) placement = placement.replace(autoToken, '') || 'top' $tip .detach() .css({ top: 0, left: 0, display: 'block' }) .addClass(placement) .data('bs.' + this.type, this) this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) this.$element.trigger('inserted.bs.' + this.type) var pos = this.getPosition() var actualWidth = $tip[0].offsetWidth var actualHeight = $tip[0].offsetHeight if (autoPlace) { var orgPlacement = placement var viewportDim = this.getPosition(this.$viewport) placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : placement $tip .removeClass(orgPlacement) .addClass(placement) } var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) this.applyPlacement(calculatedOffset, placement) var complete = function () { var prevHoverState = that.hoverState that.$element.trigger('shown.bs.' + that.type) that.hoverState = null if (prevHoverState == 'out') that.leave(that) } $.support.transition && this.$tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : complete() } } Tooltip.prototype.applyPlacement = function (offset, placement) { var $tip = this.tip() var width = $tip[0].offsetWidth var height = $tip[0].offsetHeight // manually read margins because getBoundingClientRect includes difference var marginTop = parseInt($tip.css('margin-top'), 10) var marginLeft = parseInt($tip.css('margin-left'), 10) // we must check for NaN for ie 8/9 if (isNaN(marginTop)) marginTop = 0 if (isNaN(marginLeft)) marginLeft = 0 offset.top += marginTop offset.left += marginLeft // $.fn.offset doesn't round pixel values // so we use setOffset directly with our own function B-0 $.offset.setOffset($tip[0], $.extend({ using: function (props) { $tip.css({ top: Math.round(props.top), left: Math.round(props.left) }) } }, offset), 0) $tip.addClass('in') // check to see if placing tip in new offset caused the tip to resize itself var actualWidth = $tip[0].offsetWidth var actualHeight = $tip[0].offsetHeight if (placement == 'top' && actualHeight != height) { offset.top = offset.top + height - actualHeight } var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) if (delta.left) offset.left += delta.left else offset.top += delta.top var isVertical = /top|bottom/.test(placement) var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' $tip.offset(offset) this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) } Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { this.arrow() .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') .css(isVertical ? 'top' : 'left', '') } Tooltip.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) $tip.removeClass('fade in top bottom left right') } Tooltip.prototype.hide = function (callback) { var that = this var $tip = $(this.$tip) var e = $.Event('hide.bs.' + this.type) function complete() { if (that.hoverState != 'in') $tip.detach() that.$element .removeAttr('aria-describedby') .trigger('hidden.bs.' + that.type) callback && callback() } this.$element.trigger(e) if (e.isDefaultPrevented()) return $tip.removeClass('in') $.support.transition && $tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : complete() this.hoverState = null return this } Tooltip.prototype.fixTitle = function () { var $e = this.$element if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') } } Tooltip.prototype.hasContent = function () { return this.getTitle() } Tooltip.prototype.getPosition = function ($element) { $element = $element || this.$element var el = $element[0] var isBody = el.tagName == 'BODY' var elRect = el.getBoundingClientRect() if (elRect.width == null) { // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) } var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null return $.extend({}, elRect, scroll, outerDims, elOffset) } Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } } Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { var delta = { top: 0, left: 0 } if (!this.$viewport) return delta var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 var viewportDimensions = this.getPosition(this.$viewport) if (/right|left/.test(placement)) { var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight if (topEdgeOffset < viewportDimensions.top) { // top overflow delta.top = viewportDimensions.top - topEdgeOffset } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset } } else { var leftEdgeOffset = pos.left - viewportPadding var rightEdgeOffset = pos.left + viewportPadding + actualWidth if (leftEdgeOffset < viewportDimensions.left) { // left overflow delta.left = viewportDimensions.left - leftEdgeOffset } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset } } return delta } Tooltip.prototype.getTitle = function () { var title var $e = this.$element var o = this.options title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) return title } Tooltip.prototype.getUID = function (prefix) { do prefix += ~~(Math.random() * 1000000) while (document.getElementById(prefix)) return prefix } Tooltip.prototype.tip = function () { if (!this.$tip) { this.$tip = $(this.options.template) if (this.$tip.length != 1) { throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') } } return this.$tip } Tooltip.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) } Tooltip.prototype.enable = function () { this.enabled = true } Tooltip.prototype.disable = function () { this.enabled = false } Tooltip.prototype.toggleEnabled = function () { this.enabled = !this.enabled } Tooltip.prototype.toggle = function (e) { var self = this if (e) { self = $(e.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(e.currentTarget, this.getDelegateOptions()) $(e.currentTarget).data('bs.' + this.type, self) } } if (e) { self.inState.click = !self.inState.click if (self.isInStateTrue()) self.enter(self) else self.leave(self) } else { self.tip().hasClass('in') ? self.leave(self) : self.enter(self) } } Tooltip.prototype.destroy = function () { var that = this clearTimeout(this.timeout) this.hide(function () { that.$element.off('.' + that.type).removeData('bs.' + that.type) if (that.$tip) { that.$tip.detach() } that.$tip = null that.$arrow = null that.$viewport = null }) } // TOOLTIP PLUGIN DEFINITION // ========================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.tooltip') var options = typeof option == 'object' && option if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.tooltip $.fn.tooltip = Plugin $.fn.tooltip.Constructor = Tooltip // TOOLTIP NO CONFLICT // =================== $.fn.tooltip.noConflict = function () { $.fn.tooltip = old return this } }(jQuery); /* ======================================================================== * Bootstrap: popover.js v3.3.5 * http://getbootstrap.com/javascript/#popovers * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // POPOVER PUBLIC CLASS DEFINITION // =============================== var Popover = function (element, options) { this.init('popover', element, options) } if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') Popover.VERSION = '3.3.5' Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { placement: 'right', trigger: 'click', content: '', template: '

    ' }) // NOTE: POPOVER EXTENDS tooltip.js // ================================ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) Popover.prototype.constructor = Popover Popover.prototype.getDefaults = function () { return Popover.DEFAULTS } Popover.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() var content = this.getContent() $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' ](content) $tip.removeClass('fade top bottom left right in') // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do // this manually by checking the contents. if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() } Popover.prototype.hasContent = function () { return this.getTitle() || this.getContent() } Popover.prototype.getContent = function () { var $e = this.$element var o = this.options return $e.attr('data-content') || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) } Popover.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.arrow')) } // POPOVER PLUGIN DEFINITION // ========================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.popover') var options = typeof option == 'object' && option if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.popover', (data = new Popover(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.popover $.fn.popover = Plugin $.fn.popover.Constructor = Popover // POPOVER NO CONFLICT // =================== $.fn.popover.noConflict = function () { $.fn.popover = old return this } }(jQuery); /* ======================================================================== * Bootstrap: scrollspy.js v3.3.5 * http://getbootstrap.com/javascript/#scrollspy * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // SCROLLSPY CLASS DEFINITION // ========================== function ScrollSpy(element, options) { this.$body = $(document.body) this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) this.options = $.extend({}, ScrollSpy.DEFAULTS, options) this.selector = (this.options.target || '') + ' .nav li > a' this.offsets = [] this.targets = [] this.activeTarget = null this.scrollHeight = 0 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) this.refresh() this.process() } ScrollSpy.VERSION = '3.3.5' ScrollSpy.DEFAULTS = { offset: 10 } ScrollSpy.prototype.getScrollHeight = function () { return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) } ScrollSpy.prototype.refresh = function () { var that = this var offsetMethod = 'offset' var offsetBase = 0 this.offsets = [] this.targets = [] this.scrollHeight = this.getScrollHeight() if (!$.isWindow(this.$scrollElement[0])) { offsetMethod = 'position' offsetBase = this.$scrollElement.scrollTop() } this.$body .find(this.selector) .map(function () { var $el = $(this) var href = $el.data('target') || $el.attr('href') var $href = /^#./.test(href) && $(href) return ($href && $href.length && $href.is(':visible') && [[$href[offsetMethod]().top + offsetBase, href]]) || null }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { that.offsets.push(this[0]) that.targets.push(this[1]) }) } ScrollSpy.prototype.process = function () { var scrollTop = this.$scrollElement.scrollTop() + this.options.offset var scrollHeight = this.getScrollHeight() var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() var offsets = this.offsets var targets = this.targets var activeTarget = this.activeTarget var i if (this.scrollHeight != scrollHeight) { this.refresh() } if (scrollTop >= maxScroll) { return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) } if (activeTarget && scrollTop < offsets[0]) { this.activeTarget = null return this.clear() } for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) && this.activate(targets[i]) } } ScrollSpy.prototype.activate = function (target) { this.activeTarget = target this.clear() var selector = this.selector + '[data-target="' + target + '"],' + this.selector + '[href="' + target + '"]' var active = $(selector) .parents('li') .addClass('active') if (active.parent('.dropdown-menu').length) { active = active .closest('li.dropdown') .addClass('active') } active.trigger('activate.bs.scrollspy') } ScrollSpy.prototype.clear = function () { $(this.selector) .parentsUntil(this.options.target, '.active') .removeClass('active') } // SCROLLSPY PLUGIN DEFINITION // =========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.scrollspy') var options = typeof option == 'object' && option if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.scrollspy $.fn.scrollspy = Plugin $.fn.scrollspy.Constructor = ScrollSpy // SCROLLSPY NO CONFLICT // ===================== $.fn.scrollspy.noConflict = function () { $.fn.scrollspy = old return this } // SCROLLSPY DATA-API // ================== $(window).on('load.bs.scrollspy.data-api', function () { $('[data-spy="scroll"]').each(function () { var $spy = $(this) Plugin.call($spy, $spy.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: tab.js v3.3.5 * http://getbootstrap.com/javascript/#tabs * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // TAB CLASS DEFINITION // ==================== var Tab = function (element) { // jscs:disable requireDollarBeforejQueryAssignment this.element = $(element) // jscs:enable requireDollarBeforejQueryAssignment } Tab.VERSION = '3.3.5' Tab.TRANSITION_DURATION = 150 Tab.prototype.show = function () { var $this = this.element var $ul = $this.closest('ul:not(.dropdown-menu)') var selector = $this.data('target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } if ($this.parent('li').hasClass('active')) return var $previous = $ul.find('.active:last a') var hideEvent = $.Event('hide.bs.tab', { relatedTarget: $this[0] }) var showEvent = $.Event('show.bs.tab', { relatedTarget: $previous[0] }) $previous.trigger(hideEvent) $this.trigger(showEvent) if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return var $target = $(selector) this.activate($this.closest('li'), $ul) this.activate($target, $target.parent(), function () { $previous.trigger({ type: 'hidden.bs.tab', relatedTarget: $this[0] }) $this.trigger({ type: 'shown.bs.tab', relatedTarget: $previous[0] }) }) } Tab.prototype.activate = function (element, container, callback) { var $active = container.find('> .active') var transition = callback && $.support.transition && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') .removeClass('active') .end() .find('[data-toggle="tab"]') .attr('aria-expanded', false) element .addClass('active') .find('[data-toggle="tab"]') .attr('aria-expanded', true) if (transition) { element[0].offsetWidth // reflow for transition element.addClass('in') } else { element.removeClass('fade') } if (element.parent('.dropdown-menu').length) { element .closest('li.dropdown') .addClass('active') .end() .find('[data-toggle="tab"]') .attr('aria-expanded', true) } callback && callback() } $active.length && transition ? $active .one('bsTransitionEnd', next) .emulateTransitionEnd(Tab.TRANSITION_DURATION) : next() $active.removeClass('in') } // TAB PLUGIN DEFINITION // ===================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.tab') if (!data) $this.data('bs.tab', (data = new Tab(this))) if (typeof option == 'string') data[option]() }) } var old = $.fn.tab $.fn.tab = Plugin $.fn.tab.Constructor = Tab // TAB NO CONFLICT // =============== $.fn.tab.noConflict = function () { $.fn.tab = old return this } // TAB DATA-API // ============ var clickHandler = function (e) { e.preventDefault() Plugin.call($(this), 'show') } $(document) .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) }(jQuery); /* ======================================================================== * Bootstrap: affix.js v3.3.5 * http://getbootstrap.com/javascript/#affix * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // AFFIX CLASS DEFINITION // ====================== var Affix = function (element, options) { this.options = $.extend({}, Affix.DEFAULTS, options) this.$target = $(this.options.target) .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) this.$element = $(element) this.affixed = null this.unpin = null this.pinnedOffset = null this.checkPosition() } Affix.VERSION = '3.3.5' Affix.RESET = 'affix affix-top affix-bottom' Affix.DEFAULTS = { offset: 0, target: window } Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { var scrollTop = this.$target.scrollTop() var position = this.$element.offset() var targetHeight = this.$target.height() if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false if (this.affixed == 'bottom') { if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' } var initializing = this.affixed == null var colliderTop = initializing ? scrollTop : position.top var colliderHeight = initializing ? targetHeight : height if (offsetTop != null && scrollTop <= offsetTop) return 'top' if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' return false } Affix.prototype.getPinnedOffset = function () { if (this.pinnedOffset) return this.pinnedOffset this.$element.removeClass(Affix.RESET).addClass('affix') var scrollTop = this.$target.scrollTop() var position = this.$element.offset() return (this.pinnedOffset = position.top - scrollTop) } Affix.prototype.checkPositionWithEventLoop = function () { setTimeout($.proxy(this.checkPosition, this), 1) } Affix.prototype.checkPosition = function () { if (!this.$element.is(':visible')) return var height = this.$element.height() var offset = this.options.offset var offsetTop = offset.top var offsetBottom = offset.bottom var scrollHeight = Math.max($(document).height(), $(document.body).height()) if (typeof offset != 'object') offsetBottom = offsetTop = offset if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) if (this.affixed != affix) { if (this.unpin != null) this.$element.css('top', '') var affixType = 'affix' + (affix ? '-' + affix : '') var e = $.Event(affixType + '.bs.affix') this.$element.trigger(e) if (e.isDefaultPrevented()) return this.affixed = affix this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null this.$element .removeClass(Affix.RESET) .addClass(affixType) .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') } if (affix == 'bottom') { this.$element.offset({ top: scrollHeight - height - offsetBottom }) } } // AFFIX PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.affix') var options = typeof option == 'object' && option if (!data) $this.data('bs.affix', (data = new Affix(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.affix $.fn.affix = Plugin $.fn.affix.Constructor = Affix // AFFIX NO CONFLICT // ================= $.fn.affix.noConflict = function () { $.fn.affix = old return this } // AFFIX DATA-API // ============== $(window).on('load', function () { $('[data-spy="affix"]').each(function () { var $spy = $(this) var data = $spy.data() data.offset = data.offset || {} if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom if (data.offsetTop != null) data.offset.top = data.offsetTop Plugin.call($spy, data) }) }) }(jQuery); SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/src/PaxHeaders/bootstrap.js0000644000000000000000000000007414336451277026717 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.953365314 SABnzbd-4.3.2/interfaces/Glitter/templates/static/bootstrap/js/src/bootstrap.js0000777000000000000000000000000014336451277032730 2bootstrap_3.3.5.jsustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/PaxHeaders/javascripts0000644000000000000000000000007414336451277023400 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/0000755000000000000000000000000014336451277024370 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/PaxHeaders/src0000644000000000000000000000007414336451277024167 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/0000755000000000000000000000000014336451277025157 5ustar00rootroot00000000000000SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/PaxHeaders/jquery-ui_1.12.1.js0000644000000000000000000000007414336451277027334 xustar0030 atime=1717049223.957365375 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/jquery-ui_1.12.1.js0000644000000000000000000026616114336451277030263 0ustar00rootroot00000000000000/*! jQuery UI - v1.12.1 - 2016-11-11 * http://jqueryui.com * Includes: widget.js, data.js, keycode.js, scroll-parent.js, widgets/sortable.js, widgets/mouse.js, widgets/slider.js * Copyright jQuery Foundation and other contributors; Licensed MIT */ (function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define([ "jquery" ], factory ); } else { // Browser globals factory( jQuery ); } }(function( $ ) { $.ui = $.ui || {}; var version = $.ui.version = "1.12.1"; /*! * jQuery UI Widget 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: Widget //>>group: Core //>>description: Provides a factory for creating stateful widgets with a common API. //>>docs: http://api.jqueryui.com/jQuery.widget/ //>>demos: http://jqueryui.com/widget/ var widgetUuid = 0; var widgetSlice = Array.prototype.slice; $.cleanData = ( function( orig ) { return function( elems ) { var events, elem, i; for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { try { // Only trigger remove when necessary to save time events = $._data( elem, "events" ); if ( events && events.remove ) { $( elem ).triggerHandler( "remove" ); } // Http://bugs.jquery.com/ticket/8235 } catch ( e ) {} } orig( elems ); }; } )( $.cleanData ); $.widget = function( name, base, prototype ) { var existingConstructor, constructor, basePrototype; // ProxiedPrototype allows the provided prototype to remain unmodified // so that it can be used as a mixin for multiple widgets (#8876) var proxiedPrototype = {}; var namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; var fullName = namespace + "-" + name; if ( !prototype ) { prototype = base; base = $.Widget; } if ( $.isArray( prototype ) ) { prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); } // Create selector for plugin $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { return !!$.data( elem, fullName ); }; $[ namespace ] = $[ namespace ] || {}; existingConstructor = $[ namespace ][ name ]; constructor = $[ namespace ][ name ] = function( options, element ) { // Allow instantiation without "new" keyword if ( !this._createWidget ) { return new constructor( options, element ); } // Allow instantiation without initializing for simple inheritance // must use "new" keyword (the code above always passes args) if ( arguments.length ) { this._createWidget( options, element ); } }; // Extend with the existing constructor to carry over any static properties $.extend( constructor, existingConstructor, { version: prototype.version, // Copy the object used to create the prototype in case we need to // redefine the widget later _proto: $.extend( {}, prototype ), // Track widgets that inherit from this widget in case this widget is // redefined after a widget inherits from it _childConstructors: [] } ); basePrototype = new base(); // We need to make the options hash a property directly on the new instance // otherwise we'll modify the options hash on the prototype that we're // inheriting from basePrototype.options = $.widget.extend( {}, basePrototype.options ); $.each( prototype, function( prop, value ) { if ( !$.isFunction( value ) ) { proxiedPrototype[ prop ] = value; return; } proxiedPrototype[ prop ] = ( function() { function _super() { return base.prototype[ prop ].apply( this, arguments ); } function _superApply( args ) { return base.prototype[ prop ].apply( this, args ); } return function() { var __super = this._super; var __superApply = this._superApply; var returnValue; this._super = _super; this._superApply = _superApply; returnValue = value.apply( this, arguments ); this._super = __super; this._superApply = __superApply; return returnValue; }; } )(); } ); constructor.prototype = $.widget.extend( basePrototype, { // TODO: remove support for widgetEventPrefix // always use the name + a colon as the prefix, e.g., draggable:start // don't prefix for widgets that aren't DOM-based widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name }, proxiedPrototype, { constructor: constructor, namespace: namespace, widgetName: name, widgetFullName: fullName } ); // If this widget is being redefined then we need to find all widgets that // are inheriting from it and redefine all of them so that they inherit from // the new version of this widget. We're essentially trying to replace one // level in the prototype chain. if ( existingConstructor ) { $.each( existingConstructor._childConstructors, function( i, child ) { var childPrototype = child.prototype; // Redefine the child widget using the same prototype that was // originally used, but inherit from the new version of the base $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); } ); // Remove the list of existing child constructors from the old constructor // so the old child constructors can be garbage collected delete existingConstructor._childConstructors; } else { base._childConstructors.push( constructor ); } $.widget.bridge( name, constructor ); return constructor; }; $.widget.extend = function( target ) { var input = widgetSlice.call( arguments, 1 ); var inputIndex = 0; var inputLength = input.length; var key; var value; for ( ; inputIndex < inputLength; inputIndex++ ) { for ( key in input[ inputIndex ] ) { value = input[ inputIndex ][ key ]; if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { // Clone objects if ( $.isPlainObject( value ) ) { target[ key ] = $.isPlainObject( target[ key ] ) ? $.widget.extend( {}, target[ key ], value ) : // Don't extend strings, arrays, etc. with objects $.widget.extend( {}, value ); // Copy everything else by reference } else { target[ key ] = value; } } } } return target; }; $.widget.bridge = function( name, object ) { var fullName = object.prototype.widgetFullName || name; $.fn[ name ] = function( options ) { var isMethodCall = typeof options === "string"; var args = widgetSlice.call( arguments, 1 ); var returnValue = this; if ( isMethodCall ) { // If this is an empty collection, we need to have the instance method // return undefined instead of the jQuery instance if ( !this.length && options === "instance" ) { returnValue = undefined; } else { this.each( function() { var methodValue; var instance = $.data( this, fullName ); if ( options === "instance" ) { returnValue = instance; return false; } if ( !instance ) { return $.error( "cannot call methods on " + name + " prior to initialization; " + "attempted to call method '" + options + "'" ); } if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { return $.error( "no such method '" + options + "' for " + name + " widget instance" ); } methodValue = instance[ options ].apply( instance, args ); if ( methodValue !== instance && methodValue !== undefined ) { returnValue = methodValue && methodValue.jquery ? returnValue.pushStack( methodValue.get() ) : methodValue; return false; } } ); } } else { // Allow multiple hashes to be passed on init if ( args.length ) { options = $.widget.extend.apply( null, [ options ].concat( args ) ); } this.each( function() { var instance = $.data( this, fullName ); if ( instance ) { instance.option( options || {} ); if ( instance._init ) { instance._init(); } } else { $.data( this, fullName, new object( options, this ) ); } } ); } return returnValue; }; }; $.Widget = function( /* options, element */ ) {}; $.Widget._childConstructors = []; $.Widget.prototype = { widgetName: "widget", widgetEventPrefix: "", defaultElement: "
    ", options: { classes: {}, disabled: false, // Callbacks create: null }, _createWidget: function( options, element ) { element = $( element || this.defaultElement || this )[ 0 ]; this.element = $( element ); this.uuid = widgetUuid++; this.eventNamespace = "." + this.widgetName + this.uuid; this.bindings = $(); this.hoverable = $(); this.focusable = $(); this.classesElementLookup = {}; if ( element !== this ) { $.data( element, this.widgetFullName, this ); this._on( true, this.element, { remove: function( event ) { if ( event.target === element ) { this.destroy(); } } } ); this.document = $( element.style ? // Element within the document element.ownerDocument : // Element is window or document element.document || element ); this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); } this.options = $.widget.extend( {}, this.options, this._getCreateOptions(), options ); this._create(); if ( this.options.disabled ) { this._setOptionDisabled( this.options.disabled ); } this._trigger( "create", null, this._getCreateEventData() ); this._init(); }, _getCreateOptions: function() { return {}; }, _getCreateEventData: $.noop, _create: $.noop, _init: $.noop, destroy: function() { var that = this; this._destroy(); $.each( this.classesElementLookup, function( key, value ) { that._removeClass( value, key ); } ); // We can probably remove the unbind calls in 2.0 // all event bindings should go through this._on() this.element .off( this.eventNamespace ) .removeData( this.widgetFullName ); this.widget() .off( this.eventNamespace ) .removeAttr( "aria-disabled" ); // Clean up events and states this.bindings.off( this.eventNamespace ); }, _destroy: $.noop, widget: function() { return this.element; }, option: function( key, value ) { var options = key; var parts; var curOption; var i; if ( arguments.length === 0 ) { // Don't return a reference to the internal hash return $.widget.extend( {}, this.options ); } if ( typeof key === "string" ) { // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } options = {}; parts = key.split( "." ); key = parts.shift(); if ( parts.length ) { curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); for ( i = 0; i < parts.length - 1; i++ ) { curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; curOption = curOption[ parts[ i ] ]; } key = parts.pop(); if ( arguments.length === 1 ) { return curOption[ key ] === undefined ? null : curOption[ key ]; } curOption[ key ] = value; } else { if ( arguments.length === 1 ) { return this.options[ key ] === undefined ? null : this.options[ key ]; } options[ key ] = value; } } this._setOptions( options ); return this; }, _setOptions: function( options ) { var key; for ( key in options ) { this._setOption( key, options[ key ] ); } return this; }, _setOption: function( key, value ) { if ( key === "classes" ) { this._setOptionClasses( value ); } this.options[ key ] = value; if ( key === "disabled" ) { this._setOptionDisabled( value ); } return this; }, _setOptionClasses: function( value ) { var classKey, elements, currentElements; for ( classKey in value ) { currentElements = this.classesElementLookup[ classKey ]; if ( value[ classKey ] === this.options.classes[ classKey ] || !currentElements || !currentElements.length ) { continue; } // We are doing this to create a new jQuery object because the _removeClass() call // on the next line is going to destroy the reference to the current elements being // tracked. We need to save a copy of this collection so that we can add the new classes // below. elements = $( currentElements.get() ); this._removeClass( currentElements, classKey ); // We don't use _addClass() here, because that uses this.options.classes // for generating the string of classes. We want to use the value passed in from // _setOption(), this is the new value of the classes option which was passed to // _setOption(). We pass this value directly to _classes(). elements.addClass( this._classes( { element: elements, keys: classKey, classes: value, add: true } ) ); } }, _setOptionDisabled: function( value ) { this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); // If the widget is becoming disabled, then nothing is interactive if ( value ) { this._removeClass( this.hoverable, null, "ui-state-hover" ); this._removeClass( this.focusable, null, "ui-state-focus" ); } }, enable: function() { return this._setOptions( { disabled: false } ); }, disable: function() { return this._setOptions( { disabled: true } ); }, _classes: function( options ) { var full = []; var that = this; options = $.extend( { element: this.element, classes: this.options.classes || {} }, options ); function processClassString( classes, checkOption ) { var current, i; for ( i = 0; i < classes.length; i++ ) { current = that.classesElementLookup[ classes[ i ] ] || $(); if ( options.add ) { current = $( $.unique( current.get().concat( options.element.get() ) ) ); } else { current = $( current.not( options.element ).get() ); } that.classesElementLookup[ classes[ i ] ] = current; full.push( classes[ i ] ); if ( checkOption && options.classes[ classes[ i ] ] ) { full.push( options.classes[ classes[ i ] ] ); } } } this._on( options.element, { "remove": "_untrackClassesElement" } ); if ( options.keys ) { processClassString( options.keys.match( /\S+/g ) || [], true ); } if ( options.extra ) { processClassString( options.extra.match( /\S+/g ) || [] ); } return full.join( " " ); }, _untrackClassesElement: function( event ) { var that = this; $.each( that.classesElementLookup, function( key, value ) { if ( $.inArray( event.target, value ) !== -1 ) { that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); } } ); }, _removeClass: function( element, keys, extra ) { return this._toggleClass( element, keys, extra, false ); }, _addClass: function( element, keys, extra ) { return this._toggleClass( element, keys, extra, true ); }, _toggleClass: function( element, keys, extra, add ) { add = ( typeof add === "boolean" ) ? add : extra; var shift = ( typeof element === "string" || element === null ), options = { extra: shift ? keys : extra, keys: shift ? element : keys, element: shift ? this.element : element, add: add }; options.element.toggleClass( this._classes( options ), add ); return this; }, _on: function( suppressDisabledCheck, element, handlers ) { var delegateElement; var instance = this; // No suppressDisabledCheck flag, shuffle arguments if ( typeof suppressDisabledCheck !== "boolean" ) { handlers = element; element = suppressDisabledCheck; suppressDisabledCheck = false; } // No element argument, shuffle and use this.element if ( !handlers ) { handlers = element; element = this.element; delegateElement = this.widget(); } else { element = delegateElement = $( element ); this.bindings = this.bindings.add( element ); } $.each( handlers, function( event, handler ) { function handlerProxy() { // Allow widgets to customize the disabled handling // - disabled as an array instead of boolean // - disabled class as method for disabling individual parts if ( !suppressDisabledCheck && ( instance.options.disabled === true || $( this ).hasClass( "ui-state-disabled" ) ) ) { return; } return ( typeof handler === "string" ? instance[ handler ] : handler ) .apply( instance, arguments ); } // Copy the guid so direct unbinding works if ( typeof handler !== "string" ) { handlerProxy.guid = handler.guid = handler.guid || handlerProxy.guid || $.guid++; } var match = event.match( /^([\w:-]*)\s*(.*)$/ ); var eventName = match[ 1 ] + instance.eventNamespace; var selector = match[ 2 ]; if ( selector ) { delegateElement.on( eventName, selector, handlerProxy ); } else { element.on( eventName, handlerProxy ); } } ); }, _off: function( element, eventName ) { eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; element.off( eventName ).off( eventName ); // Clear the stack to avoid memory leaks (#10056) this.bindings = $( this.bindings.not( element ).get() ); this.focusable = $( this.focusable.not( element ).get() ); this.hoverable = $( this.hoverable.not( element ).get() ); }, _delay: function( handler, delay ) { function handlerProxy() { return ( typeof handler === "string" ? instance[ handler ] : handler ) .apply( instance, arguments ); } var instance = this; return setTimeout( handlerProxy, delay || 0 ); }, _hoverable: function( element ) { this.hoverable = this.hoverable.add( element ); this._on( element, { mouseenter: function( event ) { this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); }, mouseleave: function( event ) { this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); } } ); }, _focusable: function( element ) { this.focusable = this.focusable.add( element ); this._on( element, { focusin: function( event ) { this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); }, focusout: function( event ) { this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); } } ); }, _trigger: function( type, event, data ) { var prop, orig; var callback = this.options[ type ]; data = data || {}; event = $.Event( event ); event.type = ( type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type ).toLowerCase(); // The original event may come from any element // so we need to reset the target on the new event event.target = this.element[ 0 ]; // Copy original event properties over to the new event orig = event.originalEvent; if ( orig ) { for ( prop in orig ) { if ( !( prop in event ) ) { event[ prop ] = orig[ prop ]; } } } this.element.trigger( event, data ); return !( $.isFunction( callback ) && callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || event.isDefaultPrevented() ); } }; $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { if ( typeof options === "string" ) { options = { effect: options }; } var hasOptions; var effectName = !options ? method : options === true || typeof options === "number" ? defaultEffect : options.effect || defaultEffect; options = options || {}; if ( typeof options === "number" ) { options = { duration: options }; } hasOptions = !$.isEmptyObject( options ); options.complete = callback; if ( options.delay ) { element.delay( options.delay ); } if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { element[ method ]( options ); } else if ( effectName !== method && element[ effectName ] ) { element[ effectName ]( options.duration, options.easing, callback ); } else { element.queue( function( next ) { $( this )[ method ](); if ( callback ) { callback.call( element[ 0 ] ); } next(); } ); } }; } ); var widget = $.widget; /*! * jQuery UI :data 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: :data Selector //>>group: Core //>>description: Selects elements which have data stored under the specified key. //>>docs: http://api.jqueryui.com/data-selector/ var data = $.extend( $.expr[ ":" ], { data: $.expr.createPseudo ? $.expr.createPseudo( function( dataName ) { return function( elem ) { return !!$.data( elem, dataName ); }; } ) : // Support: jQuery <1.8 function( elem, i, match ) { return !!$.data( elem, match[ 3 ] ); } } ); /*! * jQuery UI Keycode 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: Keycode //>>group: Core //>>description: Provide keycodes as keynames //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ var keycode = $.ui.keyCode = { BACKSPACE: 8, COMMA: 188, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, LEFT: 37, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SPACE: 32, TAB: 9, UP: 38 }; /*! * jQuery UI Scroll Parent 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: scrollParent //>>group: Core //>>description: Get the closest ancestor element that is scrollable. //>>docs: http://api.jqueryui.com/scrollParent/ var scrollParent = $.fn.scrollParent = function( includeHidden ) { var position = this.css( "position" ), excludeStaticParent = position === "absolute", overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, scrollParent = this.parents().filter( function() { var parent = $( this ); if ( excludeStaticParent && parent.css( "position" ) === "static" ) { return false; } return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); } ).eq( 0 ); return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; }; // This file is deprecated var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); /*! * jQuery UI Mouse 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: Mouse //>>group: Widgets //>>description: Abstracts mouse-based interactions to assist in creating certain widgets. //>>docs: http://api.jqueryui.com/mouse/ var mouseHandled = false; $( document ).on( "mouseup", function() { mouseHandled = false; } ); var widgetsMouse = $.widget( "ui.mouse", { version: "1.12.1", options: { cancel: "input, textarea, button, select, option", distance: 1, delay: 0 }, _mouseInit: function() { var that = this; this.element .on( "mousedown." + this.widgetName, function( event ) { return that._mouseDown( event ); } ) .on( "click." + this.widgetName, function( event ) { if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { $.removeData( event.target, that.widgetName + ".preventClickEvent" ); event.stopImmediatePropagation(); return false; } } ); this.started = false; }, // TODO: make sure destroying one instance of mouse doesn't mess with // other instances of mouse _mouseDestroy: function() { this.element.off( "." + this.widgetName ); if ( this._mouseMoveDelegate ) { this.document .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); } }, _mouseDown: function( event ) { // don't let more than one widget handle mouseStart if ( mouseHandled ) { return; } this._mouseMoved = false; // We may have missed mouseup (out of window) ( this._mouseStarted && this._mouseUp( event ) ); this._mouseDownEvent = event; var that = this, btnIsLeft = ( event.which === 1 ), // event.target.nodeName works around a bug in IE 8 with // disabled inputs (#7620) elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? $( event.target ).closest( this.options.cancel ).length : false ); if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { return true; } this.mouseDelayMet = !this.options.delay; if ( !this.mouseDelayMet ) { this._mouseDelayTimer = setTimeout( function() { that.mouseDelayMet = true; }, this.options.delay ); } if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { this._mouseStarted = ( this._mouseStart( event ) !== false ); if ( !this._mouseStarted ) { event.preventDefault(); return true; } } // Click event may never have fired (Gecko & Opera) if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { $.removeData( event.target, this.widgetName + ".preventClickEvent" ); } // These delegates are required to keep context this._mouseMoveDelegate = function( event ) { return that._mouseMove( event ); }; this._mouseUpDelegate = function( event ) { return that._mouseUp( event ); }; this.document .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); event.preventDefault(); mouseHandled = true; return true; }, _mouseMove: function( event ) { // Only check for mouseups outside the document if you've moved inside the document // at least once. This prevents the firing of mouseup in the case of IE<9, which will // fire a mousemove event if content is placed under the cursor. See #7778 // Support: IE <9 if ( this._mouseMoved ) { // IE mouseup check - mouseup happened when mouse was out of window if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button ) { return this._mouseUp( event ); // Iframe mouseup check - mouseup occurred in another document } else if ( !event.which ) { // Support: Safari <=8 - 9 // Safari sets which to 0 if you press any of the following keys // during a drag (#14461) if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || event.originalEvent.metaKey || event.originalEvent.shiftKey ) { this.ignoreMissingWhich = true; } else if ( !this.ignoreMissingWhich ) { return this._mouseUp( event ); } } } if ( event.which || event.button ) { this._mouseMoved = true; } if ( this._mouseStarted ) { this._mouseDrag( event ); return event.preventDefault(); } if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { this._mouseStarted = ( this._mouseStart( this._mouseDownEvent, event ) !== false ); ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) ); } return !this._mouseStarted; }, _mouseUp: function( event ) { this.document .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); if ( this._mouseStarted ) { this._mouseStarted = false; if ( event.target === this._mouseDownEvent.target ) { $.data( event.target, this.widgetName + ".preventClickEvent", true ); } this._mouseStop( event ); } if ( this._mouseDelayTimer ) { clearTimeout( this._mouseDelayTimer ); delete this._mouseDelayTimer; } this.ignoreMissingWhich = false; mouseHandled = false; event.preventDefault(); }, _mouseDistanceMet: function( event ) { return ( Math.max( Math.abs( this._mouseDownEvent.pageX - event.pageX ), Math.abs( this._mouseDownEvent.pageY - event.pageY ) ) >= this.options.distance ); }, _mouseDelayMet: function( /* event */ ) { return this.mouseDelayMet; }, // These are placeholder methods, to be overriden by extending plugin _mouseStart: function( /* event */ ) {}, _mouseDrag: function( /* event */ ) {}, _mouseStop: function( /* event */ ) {}, _mouseCapture: function( /* event */ ) { return true; } } ); /*! * jQuery UI Sortable 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: Sortable //>>group: Interactions //>>description: Enables items in a list to be sorted using the mouse. //>>docs: http://api.jqueryui.com/sortable/ //>>demos: http://jqueryui.com/sortable/ //>>css.structure: ../../themes/base/sortable.css var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { version: "1.12.1", widgetEventPrefix: "sort", ready: false, options: { appendTo: "parent", axis: false, connectWith: false, containment: false, cursor: "auto", cursorAt: false, dropOnEmpty: true, forcePlaceholderSize: false, forceHelperSize: false, grid: false, handle: false, helper: "original", items: "> *", opacity: false, placeholder: false, revert: false, scroll: true, scrollSensitivity: 20, scrollSpeed: 20, scope: "default", tolerance: "intersect", zIndex: 1000, // Callbacks activate: null, beforeStop: null, change: null, deactivate: null, out: null, over: null, receive: null, remove: null, sort: null, start: null, stop: null, update: null }, _isOverAxis: function( x, reference, size ) { return ( x >= reference ) && ( x < ( reference + size ) ); }, _isFloating: function( item ) { return ( /left|right/ ).test( item.css( "float" ) ) || ( /inline|table-cell/ ).test( item.css( "display" ) ); }, _create: function() { this.containerCache = {}; this._addClass( "ui-sortable" ); //Get the items this.refresh(); //Let's determine the parent's offset this.offset = this.element.offset(); //Initialize mouse events for interaction this._mouseInit(); this._setHandleClassName(); //We're ready to go this.ready = true; }, _setOption: function( key, value ) { this._super( key, value ); if ( key === "handle" ) { this._setHandleClassName(); } }, _setHandleClassName: function() { var that = this; this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); $.each( this.items, function() { that._addClass( this.instance.options.handle ? this.item.find( this.instance.options.handle ) : this.item, "ui-sortable-handle" ); } ); }, _destroy: function() { this._mouseDestroy(); for ( var i = this.items.length - 1; i >= 0; i-- ) { this.items[ i ].item.removeData( this.widgetName + "-item" ); } return this; }, _mouseCapture: function( event, overrideHandle ) { var currentItem = null, validHandle = false, that = this; if ( this.reverting ) { return false; } if ( this.options.disabled || this.options.type === "static" ) { return false; } //We have to refresh the items data once first this._refreshItems( event ); //Find out if the clicked node (or one of its parents) is a actual item in this.items $( event.target ).parents().each( function() { if ( $.data( this, that.widgetName + "-item" ) === that ) { currentItem = $( this ); return false; } } ); if ( $.data( event.target, that.widgetName + "-item" ) === that ) { currentItem = $( event.target ); } if ( !currentItem ) { return false; } if ( this.options.handle && !overrideHandle ) { $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { if ( this === event.target ) { validHandle = true; } } ); if ( !validHandle ) { return false; } } this.currentItem = currentItem; this._removeCurrentsFromItems(); return true; }, _mouseStart: function( event, overrideHandle, noActivation ) { var i, body, o = this.options; this.currentContainer = this; //We only need to call refreshPositions, because the refreshItems call has been moved to // mouseCapture this.refreshPositions(); //Create and append the visible helper this.helper = this._createHelper( event ); //Cache the helper size this._cacheHelperProportions(); /* * - Position generation - * This block generates everything position related - it's the core of draggables. */ //Cache the margins of the original element this._cacheMargins(); //Get the next scrolling parent this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins this.offset = this.currentItem.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; $.extend( this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), // This is a relative to absolute position minus the actual position calculation - // only used for relative positioned helper relative: this._getRelativeOffset() } ); // Only after we got the offset, we can change the helper's position to absolute // TODO: Still need to figure out a way to make relative sorting possible this.helper.css( "position", "absolute" ); this.cssPosition = this.helper.css( "position" ); //Generate the original position this.originalPosition = this._generatePosition( event ); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if "cursorAt" is supplied ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); //Cache the former DOM position this.domPosition = { prev: this.currentItem.prev()[ 0 ], parent: this.currentItem.parent()[ 0 ] }; // If the helper is not the original, hide the original so it's not playing any role during // the drag, won't cause anything bad this way if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { this.currentItem.hide(); } //Create the placeholder this._createPlaceholder(); //Set a containment if given in the options if ( o.containment ) { this._setContainment(); } if ( o.cursor && o.cursor !== "auto" ) { // cursor option body = this.document.find( "body" ); // Support: IE this.storedCursor = body.css( "cursor" ); body.css( "cursor", o.cursor ); this.storedStylesheet = $( "" ).appendTo( body ); } if ( o.opacity ) { // opacity option if ( this.helper.css( "opacity" ) ) { this._storedOpacity = this.helper.css( "opacity" ); } this.helper.css( "opacity", o.opacity ); } if ( o.zIndex ) { // zIndex option if ( this.helper.css( "zIndex" ) ) { this._storedZIndex = this.helper.css( "zIndex" ); } this.helper.css( "zIndex", o.zIndex ); } //Prepare scrolling if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && this.scrollParent[ 0 ].tagName !== "HTML" ) { this.overflowOffset = this.scrollParent.offset(); } //Call callbacks this._trigger( "start", event, this._uiHash() ); //Recache the helper size if ( !this._preserveHelperProportions ) { this._cacheHelperProportions(); } //Post "activate" events to possible containers if ( !noActivation ) { for ( i = this.containers.length - 1; i >= 0; i-- ) { this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); } } //Prepare possible droppables if ( $.ui.ddmanager ) { $.ui.ddmanager.current = this; } if ( $.ui.ddmanager && !o.dropBehaviour ) { $.ui.ddmanager.prepareOffsets( this, event ); } this.dragging = true; this._addClass( this.helper, "ui-sortable-helper" ); // Execute the drag once - this causes the helper not to be visiblebefore getting its // correct position this._mouseDrag( event ); return true; }, _mouseDrag: function( event ) { var i, item, itemElement, intersection, o = this.options, scrolled = false; //Compute the helpers position this.position = this._generatePosition( event ); this.positionAbs = this._convertPositionTo( "absolute" ); if ( !this.lastPositionAbs ) { this.lastPositionAbs = this.positionAbs; } //Do scrolling if ( this.options.scroll ) { if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && this.scrollParent[ 0 ].tagName !== "HTML" ) { if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - event.pageY < o.scrollSensitivity ) { this.scrollParent[ 0 ].scrollTop = scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { this.scrollParent[ 0 ].scrollTop = scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; } if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - event.pageX < o.scrollSensitivity ) { this.scrollParent[ 0 ].scrollLeft = scrolled = this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { this.scrollParent[ 0 ].scrollLeft = scrolled = this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; } } else { if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < o.scrollSensitivity ) { scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); } if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { scrolled = this.document.scrollLeft( this.document.scrollLeft() - o.scrollSpeed ); } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < o.scrollSensitivity ) { scrolled = this.document.scrollLeft( this.document.scrollLeft() + o.scrollSpeed ); } } if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { $.ui.ddmanager.prepareOffsets( this, event ); } } //Regenerate the absolute position used for position checks this.positionAbs = this._convertPositionTo( "absolute" ); //Set the helper position if ( !this.options.axis || this.options.axis !== "y" ) { this.helper[ 0 ].style.left = this.position.left + "px"; } if ( !this.options.axis || this.options.axis !== "x" ) { this.helper[ 0 ].style.top = this.position.top + "px"; } //Rearrange for ( i = this.items.length - 1; i >= 0; i-- ) { //Cache variables and intersection, continue if no intersection item = this.items[ i ]; itemElement = item.item[ 0 ]; intersection = this._intersectsWithPointer( item ); if ( !intersection ) { continue; } // Only put the placeholder inside the current Container, skip all // items from other containers. This works because when moving // an item from one container to another the // currentContainer is switched before the placeholder is moved. // // Without this, moving items in "sub-sortables" can cause // the placeholder to jitter between the outer and inner container. if ( item.instance !== this.currentContainer ) { continue; } // Cannot intersect with itself // no useless actions that have been done before // no action if the item moved is the parent of the item checked if ( itemElement !== this.currentItem[ 0 ] && this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement && !$.contains( this.placeholder[ 0 ], itemElement ) && ( this.options.type === "semi-dynamic" ? !$.contains( this.element[ 0 ], itemElement ) : true ) ) { this.direction = intersection === 1 ? "down" : "up"; if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) { this._rearrange( event, item ); } else { break; } this._trigger( "change", event, this._uiHash() ); break; } } //Post events to containers this._contactContainers( event ); //Interconnect with droppables if ( $.ui.ddmanager ) { $.ui.ddmanager.drag( this, event ); } //Call callbacks this._trigger( "sort", event, this._uiHash() ); this.lastPositionAbs = this.positionAbs; return false; }, _mouseStop: function( event, noPropagation ) { if ( !event ) { return; } //If we are using droppables, inform the manager about the drop if ( $.ui.ddmanager && !this.options.dropBehaviour ) { $.ui.ddmanager.drop( this, event ); } if ( this.options.revert ) { var that = this, cur = this.placeholder.offset(), axis = this.options.axis, animation = {}; if ( !axis || axis === "x" ) { animation.left = cur.left - this.offset.parent.left - this.margins.left + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 0 : this.offsetParent[ 0 ].scrollLeft ); } if ( !axis || axis === "y" ) { animation.top = cur.top - this.offset.parent.top - this.margins.top + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 0 : this.offsetParent[ 0 ].scrollTop ); } this.reverting = true; $( this.helper ).animate( animation, parseInt( this.options.revert, 10 ) || 500, function() { that._clear( event ); } ); } else { this._clear( event, noPropagation ); } return false; }, cancel: function() { if ( this.dragging ) { this._mouseUp( new $.Event( "mouseup", { target: null } ) ); if ( this.options.helper === "original" ) { this.currentItem.css( this._storedCSS ); this._removeClass( this.currentItem, "ui-sortable-helper" ); } else { this.currentItem.show(); } //Post deactivating events to containers for ( var i = this.containers.length - 1; i >= 0; i-- ) { this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); if ( this.containers[ i ].containerCache.over ) { this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); this.containers[ i ].containerCache.over = 0; } } } if ( this.placeholder ) { //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, // it unbinds ALL events from the original node! if ( this.placeholder[ 0 ].parentNode ) { this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); } if ( this.options.helper !== "original" && this.helper && this.helper[ 0 ].parentNode ) { this.helper.remove(); } $.extend( this, { helper: null, dragging: false, reverting: false, _noFinalSort: null } ); if ( this.domPosition.prev ) { $( this.domPosition.prev ).after( this.currentItem ); } else { $( this.domPosition.parent ).prepend( this.currentItem ); } } return this; }, serialize: function( o ) { var items = this._getItemsAsjQuery( o && o.connected ), str = []; o = o || {}; $( items ).each( function() { var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); if ( res ) { str.push( ( o.key || res[ 1 ] + "[]" ) + "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); } } ); if ( !str.length && o.key ) { str.push( o.key + "=" ); } return str.join( "&" ); }, toArray: function( o ) { var items = this._getItemsAsjQuery( o && o.connected ), ret = []; o = o || {}; items.each( function() { ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); } ); return ret; }, /* Be careful with the following core functions */ _intersectsWith: function( item ) { var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width, y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height, l = item.left, r = l + item.width, t = item.top, b = t + item.height, dyClick = this.offset.click.top, dxClick = this.offset.click.left, isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), isOverElement = isOverElementHeight && isOverElementWidth; if ( this.options.tolerance === "pointer" || this.options.forcePointerForContainers || ( this.options.tolerance !== "pointer" && this.helperProportions[ this.floating ? "width" : "height" ] > item[ this.floating ? "width" : "height" ] ) ) { return isOverElement; } else { return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half x2 - ( this.helperProportions.width / 2 ) < r && // Left Half t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half } }, _intersectsWithPointer: function( item ) { var verticalDirection, horizontalDirection, isOverElementHeight = ( this.options.axis === "x" ) || this._isOverAxis( this.positionAbs.top + this.offset.click.top, item.top, item.height ), isOverElementWidth = ( this.options.axis === "y" ) || this._isOverAxis( this.positionAbs.left + this.offset.click.left, item.left, item.width ), isOverElement = isOverElementHeight && isOverElementWidth; if ( !isOverElement ) { return false; } verticalDirection = this._getDragVerticalDirection(); horizontalDirection = this._getDragHorizontalDirection(); return this.floating ? ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); }, _intersectsWithSides: function( item ) { var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + this.offset.click.top, item.top + ( item.height / 2 ), item.height ), isOverRightHalf = this._isOverAxis( this.positionAbs.left + this.offset.click.left, item.left + ( item.width / 2 ), item.width ), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if ( this.floating && horizontalDirection ) { return ( ( horizontalDirection === "right" && isOverRightHalf ) || ( horizontalDirection === "left" && !isOverRightHalf ) ); } else { return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || ( verticalDirection === "up" && !isOverBottomHalf ) ); } }, _getDragVerticalDirection: function() { var delta = this.positionAbs.top - this.lastPositionAbs.top; return delta !== 0 && ( delta > 0 ? "down" : "up" ); }, _getDragHorizontalDirection: function() { var delta = this.positionAbs.left - this.lastPositionAbs.left; return delta !== 0 && ( delta > 0 ? "right" : "left" ); }, refresh: function( event ) { this._refreshItems( event ); this._setHandleClassName(); this.refreshPositions(); return this; }, _connectWith: function() { var options = this.options; return options.connectWith.constructor === String ? [ options.connectWith ] : options.connectWith; }, _getItemsAsjQuery: function( connected ) { var i, j, cur, inst, items = [], queries = [], connectWith = this._connectWith(); if ( connectWith && connected ) { for ( i = connectWith.length - 1; i >= 0; i-- ) { cur = $( connectWith[ i ], this.document[ 0 ] ); for ( j = cur.length - 1; j >= 0; j-- ) { inst = $.data( cur[ j ], this.widgetFullName ); if ( inst && inst !== this && !inst.options.disabled ) { queries.push( [ $.isFunction( inst.options.items ) ? inst.options.items.call( inst.element ) : $( inst.options.items, inst.element ) .not( ".ui-sortable-helper" ) .not( ".ui-sortable-placeholder" ), inst ] ); } } } } queries.push( [ $.isFunction( this.options.items ) ? this.options.items .call( this.element, null, { options: this.options, item: this.currentItem } ) : $( this.options.items, this.element ) .not( ".ui-sortable-helper" ) .not( ".ui-sortable-placeholder" ), this ] ); function addItems() { items.push( this ); } for ( i = queries.length - 1; i >= 0; i-- ) { queries[ i ][ 0 ].each( addItems ); } return $( items ); }, _removeCurrentsFromItems: function() { var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); this.items = $.grep( this.items, function( item ) { for ( var j = 0; j < list.length; j++ ) { if ( list[ j ] === item.item[ 0 ] ) { return false; } } return true; } ); }, _refreshItems: function( event ) { this.items = []; this.containers = [ this ]; var i, j, cur, inst, targetData, _queries, item, queriesLength, items = this.items, queries = [ [ $.isFunction( this.options.items ) ? this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : $( this.options.items, this.element ), this ] ], connectWith = this._connectWith(); //Shouldn't be run the first time through due to massive slow-down if ( connectWith && this.ready ) { for ( i = connectWith.length - 1; i >= 0; i-- ) { cur = $( connectWith[ i ], this.document[ 0 ] ); for ( j = cur.length - 1; j >= 0; j-- ) { inst = $.data( cur[ j ], this.widgetFullName ); if ( inst && inst !== this && !inst.options.disabled ) { queries.push( [ $.isFunction( inst.options.items ) ? inst.options.items .call( inst.element[ 0 ], event, { item: this.currentItem } ) : $( inst.options.items, inst.element ), inst ] ); this.containers.push( inst ); } } } } for ( i = queries.length - 1; i >= 0; i-- ) { targetData = queries[ i ][ 1 ]; _queries = queries[ i ][ 0 ]; for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { item = $( _queries[ j ] ); // Data for target checking (mouse manager) item.data( this.widgetName + "-item", targetData ); items.push( { item: item, instance: targetData, width: 0, height: 0, left: 0, top: 0 } ); } } }, refreshPositions: function( fast ) { // Determine whether items are being displayed horizontally this.floating = this.items.length ? this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : false; //This has to be redone because due to the item being moved out/into the offsetParent, // the offsetParent's position will change if ( this.offsetParent && this.helper ) { this.offset.parent = this._getParentOffset(); } var i, item, t, p; for ( i = this.items.length - 1; i >= 0; i-- ) { item = this.items[ i ]; //We ignore calculating positions of all connected containers when we're not over them if ( item.instance !== this.currentContainer && this.currentContainer && item.item[ 0 ] !== this.currentItem[ 0 ] ) { continue; } t = this.options.toleranceElement ? $( this.options.toleranceElement, item.item ) : item.item; if ( !fast ) { item.width = t.outerWidth(); item.height = t.outerHeight(); } p = t.offset(); item.left = p.left; item.top = p.top; } if ( this.options.custom && this.options.custom.refreshContainers ) { this.options.custom.refreshContainers.call( this ); } else { for ( i = this.containers.length - 1; i >= 0; i-- ) { p = this.containers[ i ].element.offset(); this.containers[ i ].containerCache.left = p.left; this.containers[ i ].containerCache.top = p.top; this.containers[ i ].containerCache.width = this.containers[ i ].element.outerWidth(); this.containers[ i ].containerCache.height = this.containers[ i ].element.outerHeight(); } } return this; }, _createPlaceholder: function( that ) { that = that || this; var className, o = that.options; if ( !o.placeholder || o.placeholder.constructor === String ) { className = o.placeholder; o.placeholder = { element: function() { var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(), element = $( "<" + nodeName + ">", that.document[ 0 ] ); that._addClass( element, "ui-sortable-placeholder", className || that.currentItem[ 0 ].className ) ._removeClass( element, "ui-sortable-helper" ); if ( nodeName === "tbody" ) { that._createTrPlaceholder( that.currentItem.find( "tr" ).eq( 0 ), $( "", that.document[ 0 ] ).appendTo( element ) ); } else if ( nodeName === "tr" ) { that._createTrPlaceholder( that.currentItem, element ); } else if ( nodeName === "img" ) { element.attr( "src", that.currentItem.attr( "src" ) ); } if ( !className ) { element.css( "visibility", "hidden" ); } return element; }, update: function( container, p ) { // 1. If a className is set as 'placeholder option, we don't force sizes - // the class is responsible for that // 2. The option 'forcePlaceholderSize can be enabled to force it even if a // class name is specified if ( className && !o.forcePlaceholderSize ) { return; } //If the element doesn't have a actual height by itself (without styles coming // from a stylesheet), it receives the inline height from the dragged item if ( !p.height() ) { p.height( that.currentItem.innerHeight() - parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); } if ( !p.width() ) { p.width( that.currentItem.innerWidth() - parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); } } }; } //Create the placeholder that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); //Append it after the actual current item that.currentItem.after( that.placeholder ); //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) o.placeholder.update( that, that.placeholder ); }, _createTrPlaceholder: function( sourceTr, targetTr ) { var that = this; sourceTr.children().each( function() { $( " ", that.document[ 0 ] ) .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) .appendTo( targetTr ); } ); }, _contactContainers: function( event ) { var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, innermostContainer = null, innermostIndex = null; // Get innermost container that intersects with item for ( i = this.containers.length - 1; i >= 0; i-- ) { // Never consider a container that's located within the item itself if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { continue; } if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { // If we've already found a container and it's more "inner" than this, then continue if ( innermostContainer && $.contains( this.containers[ i ].element[ 0 ], innermostContainer.element[ 0 ] ) ) { continue; } innermostContainer = this.containers[ i ]; innermostIndex = i; } else { // container doesn't intersect. trigger "out" event if necessary if ( this.containers[ i ].containerCache.over ) { this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); this.containers[ i ].containerCache.over = 0; } } } // If no intersecting containers found, return if ( !innermostContainer ) { return; } // Move the item into the container if it's not there already if ( this.containers.length === 1 ) { if ( !this.containers[ innermostIndex ].containerCache.over ) { this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); this.containers[ innermostIndex ].containerCache.over = 1; } } else { // When entering a new container, we will find the item with the least distance and // append our item near it dist = 10000; itemWithLeastDistance = null; floating = innermostContainer.floating || this._isFloating( this.currentItem ); posProperty = floating ? "left" : "top"; sizeProperty = floating ? "width" : "height"; axis = floating ? "pageX" : "pageY"; for ( j = this.items.length - 1; j >= 0; j-- ) { if ( !$.contains( this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) ) { continue; } if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { continue; } cur = this.items[ j ].item.offset()[ posProperty ]; nearBottom = false; if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { nearBottom = true; } if ( Math.abs( event[ axis ] - cur ) < dist ) { dist = Math.abs( event[ axis ] - cur ); itemWithLeastDistance = this.items[ j ]; this.direction = nearBottom ? "up" : "down"; } } //Check if dropOnEmpty is enabled if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { return; } if ( this.currentContainer === this.containers[ innermostIndex ] ) { if ( !this.currentContainer.containerCache.over ) { this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); this.currentContainer.containerCache.over = 1; } return; } itemWithLeastDistance ? this._rearrange( event, itemWithLeastDistance, null, true ) : this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); this._trigger( "change", event, this._uiHash() ); this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); this.currentContainer = this.containers[ innermostIndex ]; //Update the placeholder this.options.placeholder.update( this.currentContainer, this.placeholder ); this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); this.containers[ innermostIndex ].containerCache.over = 1; } }, _createHelper: function( event ) { var o = this.options, helper = $.isFunction( o.helper ) ? $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); //Add the helper to the DOM if that didn't happen already if ( !helper.parents( "body" ).length ) { $( o.appendTo !== "parent" ? o.appendTo : this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] ); } if ( helper[ 0 ] === this.currentItem[ 0 ] ) { this._storedCSS = { width: this.currentItem[ 0 ].style.width, height: this.currentItem[ 0 ].style.height, position: this.currentItem.css( "position" ), top: this.currentItem.css( "top" ), left: this.currentItem.css( "left" ) }; } if ( !helper[ 0 ].style.width || o.forceHelperSize ) { helper.width( this.currentItem.width() ); } if ( !helper[ 0 ].style.height || o.forceHelperSize ) { helper.height( this.currentItem.height() ); } return helper; }, _adjustOffsetFromHelper: function( obj ) { if ( typeof obj === "string" ) { obj = obj.split( " " ); } if ( $.isArray( obj ) ) { obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; } if ( "left" in obj ) { this.offset.click.left = obj.left + this.margins.left; } if ( "right" in obj ) { this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; } if ( "top" in obj ) { this.offset.click.top = obj.top + this.margins.top; } if ( "bottom" in obj ) { this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } }, _getParentOffset: function() { //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the // following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the // next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't // the document, which means that the scroll is included in the initial calculation of the // offset of the parent, and never recalculated upon drag if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } // This needs to be actually done for all browsers, since pageX/pageY includes this // information with an ugly IE fix if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || ( this.offsetParent[ 0 ].tagName && this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { po = { top: 0, left: 0 }; } return { top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) }; }, _getRelativeOffset: function() { if ( this.cssPosition === "relative" ) { var p = this.currentItem.position(); return { top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + this.scrollParent.scrollTop(), left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; } }, _cacheMargins: function() { this.margins = { left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) }; }, _cacheHelperProportions: function() { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, _setContainment: function() { var ce, co, over, o = this.options; if ( o.containment === "parent" ) { o.containment = this.helper[ 0 ].parentNode; } if ( o.containment === "document" || o.containment === "window" ) { this.containment = [ 0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, ( o.containment === "document" ? ( this.document.height() || document.body.parentNode.scrollHeight ) : this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top ]; } if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { ce = $( o.containment )[ 0 ]; co = $( o.containment ).offset(); over = ( $( ce ).css( "overflow" ) !== "hidden" ); this.containment = [ co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left, co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top ]; } }, _convertPositionTo: function( d, pos ) { if ( !pos ) { pos = this.position; } var mod = d === "absolute" ? 1 : -1, scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); return { top: ( // The absolute mouse position pos.top + // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.relative.top * mod + // The offsetParent's offset without borders (offset + border) this.offset.parent.top * mod - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) ), left: ( // The absolute mouse position pos.left + // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.relative.left * mod + // The offsetParent's offset without borders (offset + border) this.offset.parent.left * mod - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod ) ) }; }, _generatePosition: function( event ) { var top, left, o = this.options, pageX = event.pageX, pageY = event.pageY, scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); // This is another very weird special case that only happens for relative elements: // 1. If the css position is relative // 2. and the scroll parent is the document or similar to the offset parent // we have to refresh the relative offset during the scroll so there are no jumps if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { this.offset.relative = this._getRelativeOffset(); } /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options if ( this.containment ) { if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { pageX = this.containment[ 0 ] + this.offset.click.left; } if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { pageY = this.containment[ 1 ] + this.offset.click.top; } if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { pageX = this.containment[ 2 ] + this.offset.click.left; } if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { pageY = this.containment[ 3 ] + this.offset.click.top; } } if ( o.grid ) { top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ]; pageY = this.containment ? ( ( top - this.offset.click.top >= this.containment[ 1 ] && top - this.offset.click.top <= this.containment[ 3 ] ) ? top : ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ]; pageX = this.containment ? ( ( left - this.offset.click.left >= this.containment[ 0 ] && left - this.offset.click.left <= this.containment[ 2 ] ) ? left : ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; } } return { top: ( // The absolute mouse position pageY - // Click offset (relative to the element) this.offset.click.top - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.relative.top - // The offsetParent's offset without borders (offset + border) this.offset.parent.top + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) ), left: ( // The absolute mouse position pageX - // Click offset (relative to the element) this.offset.click.left - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.relative.left - // The offsetParent's offset without borders (offset + border) this.offset.parent.left + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) ) }; }, _rearrange: function( event, i, a, hardRefresh ) { a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) : i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); //Various things done here to improve the performance: // 1. we create a setTimeout, that calls refreshPositions // 2. on the instance, we have a counter variable, that get's higher after every append // 3. on the local scope, we copy the counter variable, and check in the timeout, // if it's still the same // 4. this lets only the last addition to the timeout stack through this.counter = this.counter ? ++this.counter : 1; var counter = this.counter; this._delay( function() { if ( counter === this.counter ) { //Precompute after each DOM insertion, NOT on mousemove this.refreshPositions( !hardRefresh ); } } ); }, _clear: function( event, noPropagation ) { this.reverting = false; // We delay all events that have to be triggered to after the point where the placeholder // has been removed and everything else normalized again var i, delayedTriggers = []; // We first have to update the dom position of the actual currentItem // Note: don't do it if the current item is already removed (by a user), or it gets // reappended (see #4088) if ( !this._noFinalSort && this.currentItem.parent().length ) { this.placeholder.before( this.currentItem ); } this._noFinalSort = null; if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { for ( i in this._storedCSS ) { if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { this._storedCSS[ i ] = ""; } } this.currentItem.css( this._storedCSS ); this._removeClass( this.currentItem, "ui-sortable-helper" ); } else { this.currentItem.show(); } if ( this.fromOutside && !noPropagation ) { delayedTriggers.push( function( event ) { this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); } ); } if ( ( this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { // Trigger update callback if the DOM position has changed delayedTriggers.push( function( event ) { this._trigger( "update", event, this._uiHash() ); } ); } // Check if the items Container has Changed and trigger appropriate // events. if ( this !== this.currentContainer ) { if ( !noPropagation ) { delayedTriggers.push( function( event ) { this._trigger( "remove", event, this._uiHash() ); } ); delayedTriggers.push( ( function( c ) { return function( event ) { c._trigger( "receive", event, this._uiHash( this ) ); }; } ).call( this, this.currentContainer ) ); delayedTriggers.push( ( function( c ) { return function( event ) { c._trigger( "update", event, this._uiHash( this ) ); }; } ).call( this, this.currentContainer ) ); } } //Post events to containers function delayEvent( type, instance, container ) { return function( event ) { container._trigger( type, event, instance._uiHash( instance ) ); }; } for ( i = this.containers.length - 1; i >= 0; i-- ) { if ( !noPropagation ) { delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); } if ( this.containers[ i ].containerCache.over ) { delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); this.containers[ i ].containerCache.over = 0; } } //Do what was originally in plugins if ( this.storedCursor ) { this.document.find( "body" ).css( "cursor", this.storedCursor ); this.storedStylesheet.remove(); } if ( this._storedOpacity ) { this.helper.css( "opacity", this._storedOpacity ); } if ( this._storedZIndex ) { this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); } this.dragging = false; if ( !noPropagation ) { this._trigger( "beforeStop", event, this._uiHash() ); } //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, // it unbinds ALL events from the original node! this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); if ( !this.cancelHelperRemoval ) { if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { this.helper.remove(); } this.helper = null; } if ( !noPropagation ) { for ( i = 0; i < delayedTriggers.length; i++ ) { // Trigger all delayed events delayedTriggers[ i ].call( this, event ); } this._trigger( "stop", event, this._uiHash() ); } this.fromOutside = false; return !this.cancelHelperRemoval; }, _trigger: function() { if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { this.cancel(); } }, _uiHash: function( _inst ) { var inst = _inst || this; return { helper: inst.helper, placeholder: inst.placeholder || $( [] ), position: inst.position, originalPosition: inst.originalPosition, offset: inst.positionAbs, item: inst.currentItem, sender: _inst ? _inst.element : null }; } } ); /*! * jQuery UI Slider 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license */ //>>label: Slider //>>group: Widgets //>>description: Displays a flexible slider with ranges and accessibility via keyboard. //>>docs: http://api.jqueryui.com/slider/ //>>demos: http://jqueryui.com/slider/ //>>css.structure: ../../themes/base/core.css //>>css.structure: ../../themes/base/slider.css //>>css.theme: ../../themes/base/theme.css var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { version: "1.12.1", widgetEventPrefix: "slide", options: { animate: false, classes: { "ui-slider": "ui-corner-all", "ui-slider-handle": "ui-corner-all", // Note: ui-widget-header isn't the most fittingly semantic framework class for this // element, but worked best visually with a variety of themes "ui-slider-range": "ui-corner-all ui-widget-header" }, distance: 0, max: 100, min: 0, orientation: "horizontal", range: false, step: 1, value: 0, values: null, // Callbacks change: null, slide: null, start: null, stop: null }, // Number of pages in a slider // (how many times can you page up/down to go through the whole range) numPages: 5, _create: function() { this._keySliding = false; this._mouseSliding = false; this._animateOff = true; this._handleIndex = null; this._detectOrientation(); this._mouseInit(); this._calculateNewMax(); this._addClass( "ui-slider ui-slider-" + this.orientation, "ui-widget ui-widget-content" ); this._refresh(); this._animateOff = false; }, _refresh: function() { this._createRange(); this._createHandles(); this._setupEvents(); this._refreshValue(); }, _createHandles: function() { var i, handleCount, options = this.options, existingHandles = this.element.find( ".ui-slider-handle" ), handle = "", handles = []; handleCount = ( options.values && options.values.length ) || 1; if ( existingHandles.length > handleCount ) { existingHandles.slice( handleCount ).remove(); existingHandles = existingHandles.slice( 0, handleCount ); } for ( i = existingHandles.length; i < handleCount; i++ ) { handles.push( handle ); } this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); this.handle = this.handles.eq( 0 ); this.handles.each( function( i ) { $( this ) .data( "ui-slider-handle-index", i ) .attr( "tabIndex", 0 ); } ); }, _createRange: function() { var options = this.options; if ( options.range ) { if ( options.range === true ) { if ( !options.values ) { options.values = [ this._valueMin(), this._valueMin() ]; } else if ( options.values.length && options.values.length !== 2 ) { options.values = [ options.values[ 0 ], options.values[ 0 ] ]; } else if ( $.isArray( options.values ) ) { options.values = options.values.slice( 0 ); } } if ( !this.range || !this.range.length ) { this.range = $( "
    " ) .appendTo( this.element ); this._addClass( this.range, "ui-slider-range" ); } else { this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); // Handle range switching from true to min/max this.range.css( { "left": "", "bottom": "" } ); } if ( options.range === "min" || options.range === "max" ) { this._addClass( this.range, "ui-slider-range-" + options.range ); } } else { if ( this.range ) { this.range.remove(); } this.range = null; } }, _setupEvents: function() { this._off( this.handles ); this._on( this.handles, this._handleEvents ); this._hoverable( this.handles ); this._focusable( this.handles ); }, _destroy: function() { this.handles.remove(); if ( this.range ) { this.range.remove(); } this._mouseDestroy(); }, _mouseCapture: function( event ) { var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, that = this, o = this.options; if ( o.disabled ) { return false; } this.elementSize = { width: this.element.outerWidth(), height: this.element.outerHeight() }; this.elementOffset = this.element.offset(); position = { x: event.pageX, y: event.pageY }; normValue = this._normValueFromMouse( position ); distance = this._valueMax() - this._valueMin() + 1; this.handles.each( function( i ) { var thisDistance = Math.abs( normValue - that.values( i ) ); if ( ( distance > thisDistance ) || ( distance === thisDistance && ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { distance = thisDistance; closestHandle = $( this ); index = i; } } ); allowed = this._start( event, index ); if ( allowed === false ) { return false; } this._mouseSliding = true; this._handleIndex = index; this._addClass( closestHandle, null, "ui-state-active" ); closestHandle.trigger( "focus" ); offset = closestHandle.offset(); mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { left: event.pageX - offset.left - ( closestHandle.width() / 2 ), top: event.pageY - offset.top - ( closestHandle.height() / 2 ) - ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) }; if ( !this.handles.hasClass( "ui-state-hover" ) ) { this._slide( event, index, normValue ); } this._animateOff = true; return true; }, _mouseStart: function() { return true; }, _mouseDrag: function( event ) { var position = { x: event.pageX, y: event.pageY }, normValue = this._normValueFromMouse( position ); this._slide( event, this._handleIndex, normValue ); return false; }, _mouseStop: function( event ) { this._removeClass( this.handles, null, "ui-state-active" ); this._mouseSliding = false; this._stop( event, this._handleIndex ); this._change( event, this._handleIndex ); this._handleIndex = null; this._clickOffset = null; this._animateOff = false; return false; }, _detectOrientation: function() { this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; }, _normValueFromMouse: function( position ) { var pixelTotal, pixelMouse, percentMouse, valueTotal, valueMouse; if ( this.orientation === "horizontal" ) { pixelTotal = this.elementSize.width; pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); } else { pixelTotal = this.elementSize.height; pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); } percentMouse = ( pixelMouse / pixelTotal ); if ( percentMouse > 1 ) { percentMouse = 1; } if ( percentMouse < 0 ) { percentMouse = 0; } if ( this.orientation === "vertical" ) { percentMouse = 1 - percentMouse; } valueTotal = this._valueMax() - this._valueMin(); valueMouse = this._valueMin() + percentMouse * valueTotal; return this._trimAlignValue( valueMouse ); }, _uiHash: function( index, value, values ) { var uiHash = { handle: this.handles[ index ], handleIndex: index, value: value !== undefined ? value : this.value() }; if ( this._hasMultipleValues() ) { uiHash.value = value !== undefined ? value : this.values( index ); uiHash.values = values || this.values(); } return uiHash; }, _hasMultipleValues: function() { return this.options.values && this.options.values.length; }, _start: function( event, index ) { return this._trigger( "start", event, this._uiHash( index ) ); }, _slide: function( event, index, newVal ) { var allowed, otherVal, currentValue = this.value(), newValues = this.values(); if ( this._hasMultipleValues() ) { otherVal = this.values( index ? 0 : 1 ); currentValue = this.values( index ); if ( this.options.values.length === 2 && this.options.range === true ) { newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); } newValues[ index ] = newVal; } if ( newVal === currentValue ) { return; } allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); // A slide can be canceled by returning false from the slide callback if ( allowed === false ) { return; } if ( this._hasMultipleValues() ) { this.values( index, newVal ); } else { this.value( newVal ); } }, _stop: function( event, index ) { this._trigger( "stop", event, this._uiHash( index ) ); }, _change: function( event, index ) { if ( !this._keySliding && !this._mouseSliding ) { //store the last changed value index for reference when handles overlap this._lastChangedValue = index; this._trigger( "change", event, this._uiHash( index ) ); } }, value: function( newValue ) { if ( arguments.length ) { this.options.value = this._trimAlignValue( newValue ); this._refreshValue(); this._change( null, 0 ); return; } return this._value(); }, values: function( index, newValue ) { var vals, newValues, i; if ( arguments.length > 1 ) { this.options.values[ index ] = this._trimAlignValue( newValue ); this._refreshValue(); this._change( null, index ); return; } if ( arguments.length ) { if ( $.isArray( arguments[ 0 ] ) ) { vals = this.options.values; newValues = arguments[ 0 ]; for ( i = 0; i < vals.length; i += 1 ) { vals[ i ] = this._trimAlignValue( newValues[ i ] ); this._change( null, i ); } this._refreshValue(); } else { if ( this._hasMultipleValues() ) { return this._values( index ); } else { return this.value(); } } } else { return this._values(); } }, _setOption: function( key, value ) { var i, valsLength = 0; if ( key === "range" && this.options.range === true ) { if ( value === "min" ) { this.options.value = this._values( 0 ); this.options.values = null; } else if ( value === "max" ) { this.options.value = this._values( this.options.values.length - 1 ); this.options.values = null; } } if ( $.isArray( this.options.values ) ) { valsLength = this.options.values.length; } this._super( key, value ); switch ( key ) { case "orientation": this._detectOrientation(); this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) ._addClass( "ui-slider-" + this.orientation ); this._refreshValue(); if ( this.options.range ) { this._refreshRange( value ); } // Reset positioning from previous orientation this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); break; case "value": this._animateOff = true; this._refreshValue(); this._change( null, 0 ); this._animateOff = false; break; case "values": this._animateOff = true; this._refreshValue(); // Start from the last handle to prevent unreachable handles (#9046) for ( i = valsLength - 1; i >= 0; i-- ) { this._change( null, i ); } this._animateOff = false; break; case "step": case "min": case "max": this._animateOff = true; this._calculateNewMax(); this._refreshValue(); this._animateOff = false; break; case "range": this._animateOff = true; this._refresh(); this._animateOff = false; break; } }, _setOptionDisabled: function( value ) { this._super( value ); this._toggleClass( null, "ui-state-disabled", !!value ); }, //internal value getter // _value() returns value trimmed by min and max, aligned by step _value: function() { var val = this.options.value; val = this._trimAlignValue( val ); return val; }, //internal values getter // _values() returns array of values trimmed by min and max, aligned by step // _values( index ) returns single value trimmed by min and max, aligned by step _values: function( index ) { var val, vals, i; if ( arguments.length ) { val = this.options.values[ index ]; val = this._trimAlignValue( val ); return val; } else if ( this._hasMultipleValues() ) { // .slice() creates a copy of the array // this copy gets trimmed by min and max and then returned vals = this.options.values.slice(); for ( i = 0; i < vals.length; i += 1 ) { vals[ i ] = this._trimAlignValue( vals[ i ] ); } return vals; } else { return []; } }, // Returns the step-aligned value that val is closest to, between (inclusive) min and max _trimAlignValue: function( val ) { if ( val <= this._valueMin() ) { return this._valueMin(); } if ( val >= this._valueMax() ) { return this._valueMax(); } var step = ( this.options.step > 0 ) ? this.options.step : 1, valModStep = ( val - this._valueMin() ) % step, alignValue = val - valModStep; if ( Math.abs( valModStep ) * 2 >= step ) { alignValue += ( valModStep > 0 ) ? step : ( -step ); } // Since JavaScript has problems with large floats, round // the final value to 5 digits after the decimal point (see #4124) return parseFloat( alignValue.toFixed( 5 ) ); }, _calculateNewMax: function() { var max = this.options.max, min = this._valueMin(), step = this.options.step, aboveMin = Math.round( ( max - min ) / step ) * step; max = aboveMin + min; if ( max > this.options.max ) { //If max is not divisible by step, rounding off may increase its value max -= step; } this.max = parseFloat( max.toFixed( this._precision() ) ); }, _precision: function() { var precision = this._precisionOf( this.options.step ); if ( this.options.min !== null ) { precision = Math.max( precision, this._precisionOf( this.options.min ) ); } return precision; }, _precisionOf: function( num ) { var str = num.toString(), decimal = str.indexOf( "." ); return decimal === -1 ? 0 : str.length - decimal - 1; }, _valueMin: function() { return this.options.min; }, _valueMax: function() { return this.max; }, _refreshRange: function( orientation ) { if ( orientation === "vertical" ) { this.range.css( { "width": "", "left": "" } ); } if ( orientation === "horizontal" ) { this.range.css( { "height": "", "bottom": "" } ); } }, _refreshValue: function() { var lastValPercent, valPercent, value, valueMin, valueMax, oRange = this.options.range, o = this.options, that = this, animate = ( !this._animateOff ) ? o.animate : false, _set = {}; if ( this._hasMultipleValues() ) { this.handles.each( function( i ) { valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); if ( that.options.range === true ) { if ( that.orientation === "horizontal" ) { if ( i === 0 ) { that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); } if ( i === 1 ) { that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); } } else { if ( i === 0 ) { that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); } if ( i === 1 ) { that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); } } } lastValPercent = valPercent; } ); } else { value = this.value(); valueMin = this._valueMin(); valueMax = this._valueMax(); valPercent = ( valueMax !== valueMin ) ? ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 0; _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); if ( oRange === "min" && this.orientation === "horizontal" ) { this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); } if ( oRange === "max" && this.orientation === "horizontal" ) { this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, o.animate ); } if ( oRange === "min" && this.orientation === "vertical" ) { this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); } if ( oRange === "max" && this.orientation === "vertical" ) { this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, o.animate ); } } }, _handleEvents: { keydown: function( event ) { var allowed, curVal, newVal, step, index = $( event.target ).data( "ui-slider-handle-index" ); switch ( event.keyCode ) { case $.ui.keyCode.HOME: case $.ui.keyCode.END: case $.ui.keyCode.PAGE_UP: case $.ui.keyCode.PAGE_DOWN: case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: event.preventDefault(); if ( !this._keySliding ) { this._keySliding = true; this._addClass( $( event.target ), null, "ui-state-active" ); allowed = this._start( event, index ); if ( allowed === false ) { return; } } break; } step = this.options.step; if ( this._hasMultipleValues() ) { curVal = newVal = this.values( index ); } else { curVal = newVal = this.value(); } switch ( event.keyCode ) { case $.ui.keyCode.HOME: newVal = this._valueMin(); break; case $.ui.keyCode.END: newVal = this._valueMax(); break; case $.ui.keyCode.PAGE_UP: newVal = this._trimAlignValue( curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); break; case $.ui.keyCode.PAGE_DOWN: newVal = this._trimAlignValue( curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: if ( curVal === this._valueMax() ) { return; } newVal = this._trimAlignValue( curVal + step ); break; case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: if ( curVal === this._valueMin() ) { return; } newVal = this._trimAlignValue( curVal - step ); break; } this._slide( event, index, newVal ); }, keyup: function( event ) { var index = $( event.target ).data( "ui-slider-handle-index" ); if ( this._keySliding ) { this._keySliding = false; this._stop( event, index ); this._change( event, index ); this._removeClass( $( event.target ), null, "ui-state-active" ); } } } } ); }));SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/PaxHeaders/date-en-US_1.0.0-rc3.js0000644000000000000000000000007414336451277027645 xustar0030 atime=1717049223.953365314 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/date-en-US_1.0.0-rc3.js0000644000000000000000000037615514336451277030601 0ustar00rootroot00000000000000/** * @overview datejs * @version 1.0.0-beta-2014-03-25 * @author Gregory Wild-Smith * @copyright 2014 Gregory Wild-Smith * @license MIT * @homepage https://github.com/abritinthebay/datejs */ /* * DateJS Culture String File * Country Code: en-US * Name: English (United States) * Format: "key" : "value" * Key is the en-US term, Value is the Key in the current language. */ Date.CultureStrings = Date.CultureStrings || {}; Date.CultureStrings["en-US"] = { "name": "en-US", "englishName": "English (United States)", "nativeName": "English (United States)", "Sunday": "Sunday", "Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", "Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", "Sun": "Sun", "Mon": "Mon", "Tue": "Tue", "Wed": "Wed", "Thu": "Thu", "Fri": "Fri", "Sat": "Sat", "Su": "Su", "Mo": "Mo", "Tu": "Tu", "We": "We", "Th": "Th", "Fr": "Fr", "Sa": "Sa", "S_Sun_Initial": "S", "M_Mon_Initial": "M", "T_Tue_Initial": "T", "W_Wed_Initial": "W", "T_Thu_Initial": "T", "F_Fri_Initial": "F", "S_Sat_Initial": "S", "January": "January", "February": "February", "March": "March", "April": "April", "May": "May", "June": "June", "July": "July", "August": "August", "September": "September", "October": "October", "November": "November", "December": "December", "Jan_Abbr": "Jan", "Feb_Abbr": "Feb", "Mar_Abbr": "Mar", "Apr_Abbr": "Apr", "May_Abbr": "May", "Jun_Abbr": "Jun", "Jul_Abbr": "Jul", "Aug_Abbr": "Aug", "Sep_Abbr": "Sep", "Oct_Abbr": "Oct", "Nov_Abbr": "Nov", "Dec_Abbr": "Dec", "AM": "AM", "PM": "PM", "firstDayOfWeek": 0, "twoDigitYearMax": 2049, "mdy": "mdy", "M/d/yyyy": "M/d/yyyy", "dddd, MMMM dd, yyyy": "dddd, MMMM dd, yyyy", "h:mm tt": "h:mm tt", "h:mm:ss tt": "h:mm:ss tt", "dddd, MMMM dd, yyyy h:mm:ss tt": "dddd, MMMM dd, yyyy h:mm:ss tt", "yyyy-MM-ddTHH:mm:ss": "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-dd HH:mm:ssZ": "yyyy-MM-dd HH:mm:ssZ", "ddd, dd MMM yyyy HH:mm:ss": "ddd, dd MMM yyyy HH:mm:ss", "MMMM dd": "MMMM dd", "MMMM, yyyy": "MMMM, yyyy", "/jan(uary)?/": "jan(uary)?", "/feb(ruary)?/": "feb(ruary)?", "/mar(ch)?/": "mar(ch)?", "/apr(il)?/": "apr(il)?", "/may/": "may", "/jun(e)?/": "jun(e)?", "/jul(y)?/": "jul(y)?", "/aug(ust)?/": "aug(ust)?", "/sep(t(ember)?)?/": "sep(t(ember)?)?", "/oct(ober)?/": "oct(ober)?", "/nov(ember)?/": "nov(ember)?", "/dec(ember)?/": "dec(ember)?", "/^su(n(day)?)?/": "^su(n(day)?)?", "/^mo(n(day)?)?/": "^mo(n(day)?)?", "/^tu(e(s(day)?)?)?/": "^tu(e(s(day)?)?)?", "/^we(d(nesday)?)?/": "^we(d(nesday)?)?", "/^th(u(r(s(day)?)?)?)?/": "^th(u(r(s(day)?)?)?)?", "/^fr(i(day)?)?/": "^fr(i(day)?)?", "/^sa(t(urday)?)?/": "^sa(t(urday)?)?", "/^next/": "^next", "/^last|past|prev(ious)?/": "^last|past|prev(ious)?", "/^(\\+|aft(er)?|from|hence)/": "^(\\+|aft(er)?|from|hence)", "/^(\\-|bef(ore)?|ago)/": "^(\\-|bef(ore)?|ago)", "/^yes(terday)?/": "^yes(terday)?", "/^t(od(ay)?)?/": "^t(od(ay)?)?", "/^tom(orrow)?/": "^tom(orrow)?", "/^n(ow)?/": "^n(ow)?", "/^ms|milli(second)?s?/": "^ms|milli(second)?s?", "/^sec(ond)?s?/": "^sec(ond)?s?", "/^mn|min(ute)?s?/": "^mn|min(ute)?s?", "/^h(our)?s?/": "^h(our)?s?", "/^w(eek)?s?/": "^w(eek)?s?", "/^m(onth)?s?/": "^m(onth)?s?", "/^d(ay)?s?/": "^d(ay)?s?", "/^y(ear)?s?/": "^y(ear)?s?", "/^(a|p)/": "^(a|p)", "/^(a\\.?m?\\.?|p\\.?m?\\.?)/": "^(a\\.?m?\\.?|p\\.?m?\\.?)", "/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\\s*(\\+|\\-)\\s*\\d\\d\\d\\d?)|gmt|utc)/": "^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\\s*(\\+|\\-)\\s*\\d\\d\\d\\d?)|gmt|utc)", "/^\\s*(st|nd|rd|th)/": "^\\s*(st|nd|rd|th)", "/^\\s*(\\:|a(?!u|p)|p)/": "^\\s*(\\:|a(?!u|p)|p)", "LINT": "LINT", "TOT": "TOT", "CHAST": "CHAST", "NZST": "NZST", "NFT": "NFT", "SBT": "SBT", "AEST": "AEST", "ACST": "ACST", "JST": "JST", "CWST": "CWST", "CT": "CT", "ICT": "ICT", "MMT": "MMT", "BIOT": "BST", "NPT": "NPT", "IST": "IST", "PKT": "PKT", "AFT": "AFT", "MSK": "MSK", "IRST": "IRST", "FET": "FET", "EET": "EET", "CET": "CET", "UTC": "UTC", "GMT": "GMT", "CVT": "CVT", "GST": "GST", "BRT": "BRT", "NST": "NST", "AST": "AST", "EST": "EST", "CST": "CST", "MST": "MST", "PST": "PST", "AKST": "AKST", "MIT": "MIT", "HST": "HST", "SST": "SST", "BIT": "BIT", "CHADT": "CHADT", "NZDT": "NZDT", "AEDT": "AEDT", "ACDT": "ACDT", "AZST": "AZST", "IRDT": "IRDT", "EEST": "EEST", "CEST": "CEST", "BST": "BST", "PMDT": "PMDT", "ADT": "ADT", "NDT": "NDT", "EDT": "EDT", "CDT": "CDT", "MDT": "MDT", "PDT": "PDT", "AKDT": "AKDT", "HADT": "HADT" }; Date.CultureStrings.lang = "en-US"; /** * @overview datejs * @version 1.0.0-beta-2014-03-25 * @author Gregory Wild-Smith * @copyright 2014 Gregory Wild-Smith * @license MIT * @homepage https://github.com/abritinthebay/datejs */(function () { var $D = Date; var lang = Date.CultureStrings ? Date.CultureStrings.lang : null; var loggedKeys = {}; // for debug purposes. var __ = function (key, language) { var output, split, length, last; var countryCode = (language) ? language : lang; if (Date.CultureStrings && Date.CultureStrings[countryCode] && Date.CultureStrings[countryCode][key]) { output = Date.CultureStrings[countryCode][key]; } else { switch(key) { case "name": output = "en-US"; break; case "englishName": output = "English (United States)"; break; case "nativeName": output = "English (United States)"; break; case "twoDigitYearMax": output = 2049; break; case "firstDayOfWeek": output = 0; break; default: output = key; split = key.split("_"); length = split.length; if (length > 1 && key.charAt(0) !== "/") { // if the key isn't a regex and it has a split. last = split[(length - 1)].toLowerCase(); if (last === "initial" || last === "abbr") { output = split[0]; } } } } if (key.charAt(0) === "/") { // Assume it's a regex if (Date.CultureStrings && Date.CultureStrings[countryCode] && Date.CultureStrings[countryCode][key]) { output = new RegExp(Date.CultureStrings[countryCode][key], "i"); } else { output = new RegExp(key.replace(new RegExp("/", "g"),""), "i"); } } loggedKeys[key] = key; return output; }; var loadI18nScript = function (code) { // paatterned after jQuery's getScript. var url = Date.Config.i18n + code + '.js'; var head = document.getElementsByTagName("head")[0] || document.documentElement; var script = document.createElement("script"); script.src = url; var completed = false; var events = { done: function (){} // dummy function }; // Attach handlers for all browsers script.onload = script.onreadystatechange = function() { if ( !completed && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") ) { done = true; events.done(); head.removeChild(script); } }; setTimeout(function() { head.insertBefore(script, head.firstChild); }, 0); // allows return to execute first return { done: function (f) { events.done = function() { if (f) { f(); } }; } }; }; var CultureInfo = function () { var buildTimeZones = function (data) { var zone; for (zone in data.abbreviatedTimeZoneStandard) { if (data.abbreviatedTimeZoneStandard.hasOwnProperty(zone)) { data.timezones.push({ name: zone, offset: data.abbreviatedTimeZoneStandard[zone]}); } } for (zone in data.abbreviatedTimeZoneDST) { if (data.abbreviatedTimeZoneDST.hasOwnProperty(zone)) { data.timezones.push({ name: zone, offset: data.abbreviatedTimeZoneDST[zone], dst: true}); } } return data.timezones; }; var info = { name: __("name"), englishName: __("englishName"), nativeName: __("nativeName"), /* Day Name Strings */ dayNames: [ __("Sunday"), __("Monday"), __("Tuesday"), __("Wednesday"), __("Thursday"), __("Friday"), __("Saturday") ], abbreviatedDayNames: [ __("Sun"), __("Mon"), __("Tue"), __("Wed"), __("Thu"), __("Fri"), __("Sat") ], shortestDayNames: [ __("Su"), __("Mo"), __("Tu"), __("We"), __("Th"), __("Fr"), __("Sa") ], firstLetterDayNames: [ __("S_Sun_Initial"), __("M_Mon_Initial"), __("T_Tues_Initial"), __("W_Wed_Initial"), __("T_Thu_Initial"), __("F_Fri_Initial"), __("S_Sat_Initial") ], /* Month Name Strings */ monthNames: [ __("January"), __("February"), __("March"), __("April"), __("May"), __("June"), __("July"), __("August"), __("September"), __("October"), __("November"), __("December") ], abbreviatedMonthNames: [ __("Jan_Abbr"), __("Feb_Abbr"), __("Mar_Abbr"), __("Apr_Abbr"), __("May_Abbr"), __("Jun_Abbr"), __("Jul_Abbr"), __("Aug_Abbr"), __("Sep_Abbr"), __("Oct_Abbr"), __("Nov_Abbr"), __("Dec_Abbr") ], /* AM/PM Designators */ amDesignator: __("AM"), pmDesignator: __("PM"), firstDayOfWeek: __("firstDayOfWeek"), twoDigitYearMax: __("twoDigitYearMax"), dateElementOrder: __("mdy"), /* Standard date and time format patterns */ formatPatterns: { shortDate: __("M/d/yyyy"), longDate: __("dddd, MMMM dd, yyyy"), shortTime: __("h:mm tt"), longTime: __("h:mm:ss tt"), fullDateTime: __("dddd, MMMM dd, yyyy h:mm:ss tt"), sortableDateTime: __("yyyy-MM-ddTHH:mm:ss"), universalSortableDateTime: __("yyyy-MM-dd HH:mm:ssZ"), rfc1123: __("ddd, dd MMM yyyy HH:mm:ss"), monthDay: __("MMMM dd"), yearMonth: __("MMMM, yyyy") }, regexPatterns: { inTheMorning: __("/( in the )(morn(ing)?)\\b/"), thisMorning: __("/(this )(morn(ing)?)\\b/"), amThisMorning: __("/(\b\\d(am)? )(this )(morn(ing)?)/"), inTheEvening: __("/( in the )(even(ing)?)\\b/"), thisEvening: __("/(this )(even(ing)?)\\b/"), pmThisEvening: __("/(\b\\d(pm)? )(this )(even(ing)?)/"), jan: __("/jan(uary)?/"), feb: __("/feb(ruary)?/"), mar: __("/mar(ch)?/"), apr: __("/apr(il)?/"), may: __("/may/"), jun: __("/jun(e)?/"), jul: __("/jul(y)?/"), aug: __("/aug(ust)?/"), sep: __("/sep(t(ember)?)?/"), oct: __("/oct(ober)?/"), nov: __("/nov(ember)?/"), dec: __("/dec(ember)?/"), sun: __("/^su(n(day)?)?/"), mon: __("/^mo(n(day)?)?/"), tue: __("/^tu(e(s(day)?)?)?/"), wed: __("/^we(d(nesday)?)?/"), thu: __("/^th(u(r(s(day)?)?)?)?/"), fri: __("/fr(i(day)?)?/"), sat: __("/^sa(t(urday)?)?/"), future: __("/^next/"), past: __("/last|past|prev(ious)?/"), add: __("/^(\\+|aft(er)?|from|hence)/"), subtract: __("/^(\\-|bef(ore)?|ago)/"), yesterday: __("/^yes(terday)?/"), today: __("/^t(od(ay)?)?/"), tomorrow: __("/^tom(orrow)?/"), now: __("/^n(ow)?/"), millisecond: __("/^ms|milli(second)?s?/"), second: __("/^sec(ond)?s?/"), minute: __("/^mn|min(ute)?s?/"), hour: __("/^h(our)?s?/"), week: __("/^w(eek)?s?/"), month: __("/^m(onth)?s?/"), day: __("/^d(ay)?s?/"), year: __("/^y(ear)?s?/"), shortMeridian: __("/^(a|p)/"), longMeridian: __("/^(a\\.?m?\\.?|p\\.?m?\\.?)/"), timezone: __("/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\\s*(\\+|\\-)\\s*\\d\\d\\d\\d?)|gmt|utc)/"), ordinalSuffix: __("/^\\s*(st|nd|rd|th)/"), timeContext: __("/^\\s*(\\:|a(?!u|p)|p)/") }, timezones: [], abbreviatedTimeZoneDST: {}, abbreviatedTimeZoneStandard: {} }; info.abbreviatedTimeZoneDST[__("CHADT")] = "+1345"; info.abbreviatedTimeZoneDST[__("NZDT")] = "+1300"; info.abbreviatedTimeZoneDST[__("AEDT")] = "+1100"; info.abbreviatedTimeZoneDST[__("ACDT")] = "+1030"; info.abbreviatedTimeZoneDST[__("AZST")] = "+0500"; info.abbreviatedTimeZoneDST[__("IRDT")] = "+0430"; info.abbreviatedTimeZoneDST[__("EEST")] = "+0300"; info.abbreviatedTimeZoneDST[__("CEST")] = "+0200"; info.abbreviatedTimeZoneDST[__("BST")] = "+0100"; info.abbreviatedTimeZoneDST[__("PMDT")] = "-0200"; info.abbreviatedTimeZoneDST[__("ADT")] = "-0300"; info.abbreviatedTimeZoneDST[__("NDT")] = "-0230"; info.abbreviatedTimeZoneDST[__("EDT")] = "-0400"; info.abbreviatedTimeZoneDST[__("CDT")] = "-0500"; info.abbreviatedTimeZoneDST[__("MDT")] = "-0600"; info.abbreviatedTimeZoneDST[__("PDT")] = "-0700"; info.abbreviatedTimeZoneDST[__("AKDT")] = "-0800"; info.abbreviatedTimeZoneDST[__("HADT")] = "-0900"; info.abbreviatedTimeZoneStandard[__("LINT")] = "+1400"; info.abbreviatedTimeZoneStandard[__("TOT")] = "+1300"; info.abbreviatedTimeZoneStandard[__("CHAST")] = "+1245"; info.abbreviatedTimeZoneStandard[__("NZST")] = "+1200"; info.abbreviatedTimeZoneStandard[__("NFT")] = "+1130"; info.abbreviatedTimeZoneStandard[__("SBT")] = "+1100"; info.abbreviatedTimeZoneStandard[__("AEST")] = "+1000"; info.abbreviatedTimeZoneStandard[__("ACST")] = "+0930"; info.abbreviatedTimeZoneStandard[__("JST")] = "+0900"; info.abbreviatedTimeZoneStandard[__("CWST")] = "+0845"; info.abbreviatedTimeZoneStandard[__("CT")] = "+0800"; info.abbreviatedTimeZoneStandard[__("ICT")] = "+0700"; info.abbreviatedTimeZoneStandard[__("MMT")] = "+0630"; info.abbreviatedTimeZoneStandard[__("BST")] = "+0600"; info.abbreviatedTimeZoneStandard[__("NPT")] = "+0545"; info.abbreviatedTimeZoneStandard[__("IST")] = "+0530"; info.abbreviatedTimeZoneStandard[__("PKT")] = "+0500"; info.abbreviatedTimeZoneStandard[__("AFT")] = "+0430"; info.abbreviatedTimeZoneStandard[__("MSK")] = "+0400"; info.abbreviatedTimeZoneStandard[__("IRST")] = "+0330"; info.abbreviatedTimeZoneStandard[__("FET")] = "+0300"; info.abbreviatedTimeZoneStandard[__("EET")] = "+0200"; info.abbreviatedTimeZoneStandard[__("CET")] = "+0100"; info.abbreviatedTimeZoneStandard[__("GMT")] = "+0000"; info.abbreviatedTimeZoneStandard[__("UTC")] = "+0000"; info.abbreviatedTimeZoneStandard[__("CVT")] = "-0100"; info.abbreviatedTimeZoneStandard[__("GST")] = "-0200"; info.abbreviatedTimeZoneStandard[__("BRT")] = "-0300"; info.abbreviatedTimeZoneStandard[__("NST")] = "-0330"; info.abbreviatedTimeZoneStandard[__("AST")] = "-0400"; info.abbreviatedTimeZoneStandard[__("EST")] = "-0500"; info.abbreviatedTimeZoneStandard[__("CST")] = "-0600"; info.abbreviatedTimeZoneStandard[__("MST")] = "-0700"; info.abbreviatedTimeZoneStandard[__("PST")] = "-0800"; info.abbreviatedTimeZoneStandard[__("AKST")] = "-0900"; info.abbreviatedTimeZoneStandard[__("MIT")] = "-0930"; info.abbreviatedTimeZoneStandard[__("HST")] = "-1000"; info.abbreviatedTimeZoneStandard[__("SST")] = "-1100"; info.abbreviatedTimeZoneStandard[__("BIT")] = "-1200"; buildTimeZones(info); return info; }; $D.i18n = { __: function (key, lang) { return __(key, lang); }, currentLanguage: function () { return lang || "en-US"; }, setLanguage: function (code, force) { if (force || code === "en-US" || (!!Date.CultureStrings && !!Date.CultureStrings[code])) { lang = code; Date.CultureStrings.lang = code; Date.CultureInfo = CultureInfo(); } else { if (!(!!Date.CultureStrings && !!Date.CultureStrings[code])) { if (typeof exports !== 'undefined' && this.exports !== exports) { // we're in a Node enviroment, load it using require try { require("../i18n/" + code + ".js"); lang = code; Date.CultureStrings.lang = code; Date.CultureInfo = CultureInfo(); } catch (e) { // var str = "The language for '" + code + "' could not be loaded by Node. It likely does not exist."; throw new Error("The DateJS IETF language tag '" + code + "' could not be loaded by Node. It likely does not exist."); } } else if (Date.Config && Date.Config.i18n) { // we know the location of the files, so lets load them loadI18nScript(code).done(function(){ lang = code; Date.CultureStrings.lang = code; Date.CultureInfo = CultureInfo(); }); } else { Date.console.error("The DateJS IETF language tag '" + code + "' is not available and has not been loaded."); } } } }, getLoggedKeys: function () { return loggedKeys; }, updateCultureInfo: function () { Date.CultureInfo = CultureInfo(); } }; $D.i18n.updateCultureInfo(); // run automatically }()); (function () { var $D = Date, $P = $D.prototype, p = function (s, l) { if (!l) { l = 2; } return ("000" + s).slice(l * -1); }; if (typeof window !== "undefined" && typeof window.console !== "undefined" && typeof window.console.log !== "undefined") { $D.console = console; // used only to raise non-critical errors if available } else { // set mock so we don't give errors. $D.console = { log: function(){}, error: function(){} }; } $D.Config = {}; $D.initOverloads = function() { /** * Overload of Date.now. Allows an alternate call for Date.now where it returns the * current Date as an object rather than just milliseconds since the Unix Epoch. * * Also provides an implementation of now() for browsers (IE<9) that don't have it. * * Backwards compatible so with work with either: * Date.now() [returns ms] * or * Date.now(true) [returns Date] */ if (!$D.now) { $D._now = function now() { return new Date().getTime(); }; } else if (!$D._now) { $D._now = $D.now; } $D.now = function (returnObj) { if (returnObj) { return $D.present(); } else { return $D._now(); } }; if ( !$P.toISOString ) { $P.toISOString = function() { return this.getUTCFullYear() + "-" + p(this.getUTCMonth() + 1) + "-" + p(this.getUTCDate()) + "T" + p(this.getUTCHours()) + ":" + p(this.getUTCMinutes()) + ":" + p(this.getUTCSeconds()) + "." + String( (this.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) + "Z"; }; } // private if ( $P._toString === undefined ){ $P._toString = $P.toString; } }; $D.initOverloads(); /** * Resets the time of this Date object to 12:00 AM (00:00), which is the start of the day. * @param {Boolean} .clone() this date instance before clearing Time * @return {Date} this */ $P.clearTime = function () { this.setHours(0); this.setMinutes(0); this.setSeconds(0); this.setMilliseconds(0); return this; }; /** * Resets the time of this Date object to the current time ('now'). * @return {Date} this */ $P.setTimeToNow = function () { var n = new Date(); this.setHours(n.getHours()); this.setMinutes(n.getMinutes()); this.setSeconds(n.getSeconds()); this.setMilliseconds(n.getMilliseconds()); return this; }; /** * Gets a date that is set to the current date. The time is set to the start of the day (00:00 or 12:00 AM). * @return {Date} The current date. */ $D.today = function () { return new Date().clearTime(); }; /** * Gets a date that is set to the current date and time (same as new Date, but chainable) * @return {Date} The current date. */ $D.present = function () { return new Date(); }; /** * Compares the first date to the second date and returns an number indication of their relative values. * @param {Date} First Date object to compare [Required]. * @param {Date} Second Date object to compare to [Required]. * @return {Number} -1 = date1 is lessthan date2. 0 = values are equal. 1 = date1 is greaterthan date2. */ $D.compare = function (date1, date2) { if (isNaN(date1) || isNaN(date2)) { throw new Error(date1 + " - " + date2); } else if (date1 instanceof Date && date2 instanceof Date) { return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0; } else { throw new TypeError(date1 + " - " + date2); } }; /** * Compares the first Date object to the second Date object and returns true if they are equal. * @param {Date} First Date object to compare [Required] * @param {Date} Second Date object to compare to [Required] * @return {Boolean} true if dates are equal. false if they are not equal. */ $D.equals = function (date1, date2) { return (date1.compareTo(date2) === 0); }; /** * Gets the language appropriate day name when given the day number(0-6) * eg - 0 == Sunday * @return {String} The day name */ $D.getDayName = function (n) { return Date.CultureInfo.dayNames[n]; }; /** * Gets the day number (0-6) if given a CultureInfo specific string which is a valid dayName, abbreviatedDayName or shortestDayName (two char). * @param {String} The name of the day (eg. "Monday, "Mon", "tuesday", "tue", "We", "we"). * @return {Number} The day number */ $D.getDayNumberFromName = function (name) { var n = Date.CultureInfo.dayNames, m = Date.CultureInfo.abbreviatedDayNames, o = Date.CultureInfo.shortestDayNames, s = name.toLowerCase(); for (var i = 0; i < n.length; i++) { if (n[i].toLowerCase() === s || m[i].toLowerCase() === s || o[i].toLowerCase() === s) { return i; } } return -1; }; /** * Gets the month number (0-11) if given a Culture Info specific string which is a valid monthName or abbreviatedMonthName. * @param {String} The name of the month (eg. "February, "Feb", "october", "oct"). * @return {Number} The day number */ $D.getMonthNumberFromName = function (name) { var n = Date.CultureInfo.monthNames, m = Date.CultureInfo.abbreviatedMonthNames, s = name.toLowerCase(); for (var i = 0; i < n.length; i++) { if (n[i].toLowerCase() === s || m[i].toLowerCase() === s) { return i; } } return -1; }; /** * Gets the language appropriate month name when given the month number(0-11) * eg - 0 == January * @return {String} The month name */ $D.getMonthName = function (n) { return Date.CultureInfo.monthNames[n]; }; /** * Determines if the current date instance is within a LeapYear. * @param {Number} The year. * @return {Boolean} true if date is within a LeapYear, otherwise false. */ $D.isLeapYear = function (year) { return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); }; /** * Gets the number of days in the month, given a year and month value. Automatically corrects for LeapYear. * @param {Number} The year. * @param {Number} The month (0-11). * @return {Number} The number of days in the month. */ $D.getDaysInMonth = function (year, month) { if (!month && $D.validateMonth(year)) { month = year; year = Date.today().getFullYear(); } return [31, ($D.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; }; $D.getTimezoneAbbreviation = function (offset, dst) { var p, n = (dst || false) ? Date.CultureInfo.abbreviatedTimeZoneDST : Date.CultureInfo.abbreviatedTimeZoneStandard; for (p in n) { if (n.hasOwnProperty(p)) { if (n[p] === offset) { return p; } } } return null; }; $D.getTimezoneOffset = function (name, dst) { var i, a =[], z = Date.CultureInfo.timezones; if (!name) { name = (new Date()).getTimezone()} for (i = 0; i < z.length; i++) { if (z[i].name === name.toUpperCase()) { a.push(i); } } if (!z[a[0]]) { return null; } if (a.length === 1 || !dst) { return z[a[0]].offset; } else { for (i=0; i < a.length; i++) { if (z[a[i]].dst) { return z[a[i]].offset; } } } }; $D.getQuarter = function (d) { d = d || new Date(); // If no date supplied, use today var q = [1,2,3,4]; return q[Math.floor(d.getMonth() / 3)]; // ~~~ is a bitwise op. Faster than Math.floor }; $D.getDaysLeftInQuarter = function (d) { d = d || new Date(); var qEnd = new Date(d); qEnd.setMonth(qEnd.getMonth() + 3 - qEnd.getMonth() % 3, 0); return Math.floor((qEnd - d) / 8.64e7); }; /** * Returns a new Date object that is an exact date and time copy of the original instance. * @return {Date} A new Date instance */ $P.clone = function () { return new Date(this.getTime()); }; /** * Compares this instance to a Date object and returns an number indication of their relative values. * @param {Date} Date object to compare [Required] * @return {Number} -1 = this is lessthan date. 0 = values are equal. 1 = this is greaterthan date. */ $P.compareTo = function (date) { return Date.compare(this, date); }; /** * Compares this instance to another Date object and returns true if they are equal. * @param {Date} Date object to compare. If no date to compare, new Date() [now] is used. * @return {Boolean} true if dates are equal. false if they are not equal. */ $P.equals = function (date) { return Date.equals(this, (date !== undefined ? date : new Date())); }; /** * Determines if this instance is between a range of two dates or equal to either the start or end dates. * @param {Date} Start of range [Required] * @param {Date} End of range [Required] * @return {Boolean} true is this is between or equal to the start and end dates, else false */ $P.between = function (start, end) { return this.getTime() >= start.getTime() && this.getTime() <= end.getTime(); }; /** * Determines if this date occurs after the date to compare to. * @param {Date} Date object to compare. If no date to compare, new Date() ("now") is used. * @return {Boolean} true if this date instance is greater than the date to compare to (or "now"), otherwise false. */ $P.isAfter = function (date) { return this.compareTo(date || new Date()) === 1; }; /** * Determines if this date occurs before the date to compare to. * @param {Date} Date object to compare. If no date to compare, new Date() ("now") is used. * @return {Boolean} true if this date instance is less than the date to compare to (or "now"). */ $P.isBefore = function (date) { return (this.compareTo(date || new Date()) === -1); }; /** * Determines if the current Date instance occurs today. * @return {Boolean} true if this date instance is 'today', otherwise false. */ /** * Determines if the current Date instance occurs on the same Date as the supplied 'date'. * If no 'date' to compare to is provided, the current Date instance is compared to 'today'. * @param {date} Date object to compare. If no date to compare, the current Date ("now") is used. * @return {Boolean} true if this Date instance occurs on the same Day as the supplied 'date'. */ $P.isToday = $P.isSameDay = function (date) { return this.clone().clearTime().equals((date || new Date()).clone().clearTime()); }; /** * Adds the specified number of milliseconds to this instance. * @param {Number} The number of milliseconds to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addMilliseconds = function (value) { if (!value) { return this; } this.setTime(this.getTime() + value * 1); return this; }; /** * Adds the specified number of seconds to this instance. * @param {Number} The number of seconds to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addSeconds = function (value) { if (!value) { return this; } return this.addMilliseconds(value * 1000); }; /** * Adds the specified number of seconds to this instance. * @param {Number} The number of seconds to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addMinutes = function (value) { if (!value) { return this; } return this.addMilliseconds(value * 60000); /* 60*1000 */ }; /** * Adds the specified number of hours to this instance. * @param {Number} The number of hours to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addHours = function (value) { if (!value) { return this; } return this.addMilliseconds(value * 3600000); /* 60*60*1000 */ }; /** * Adds the specified number of days to this instance. * @param {Number} The number of days to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addDays = function (value) { if (!value) { return this; } this.setDate(this.getDate() + value * 1); return this; }; /** * Adds the specified number of weekdays (ie - not sat or sun) to this instance. * @param {Number} The number of days to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addWeekdays = function (value) { if (!value) { return this; } var day = this.getDay(); var weeks = (Math.ceil(Math.abs(value)/7)); if (day === 0 || day === 6) { if (value > 0) { this.next().monday(); this.addDays(-1); } } if (value < 0) { while (value < 0) { this.addDays(-1); day = this.getDay(); if (day !== 0 && day !== 6) { value++; } } return this; } else if (value > 5 || (6-day) <= value) { value = value + (weeks * 2); } return this.addDays(value); }; /** * Adds the specified number of weeks to this instance. * @param {Number} The number of weeks to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addWeeks = function (value) { if (!value) { return this; } return this.addDays(value * 7); }; /** * Adds the specified number of months to this instance. * @param {Number} The number of months to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addMonths = function (value) { if (!value) { return this; } var n = this.getDate(); this.setDate(1); this.setMonth(this.getMonth() + value * 1); this.setDate(Math.min(n, $D.getDaysInMonth(this.getFullYear(), this.getMonth()))); return this; }; $P.addQuarters = function (value) { if (!value) { return this; } // note this will take you to the same point in the quarter as you are now. // i.e. - if you are 15 days into the quarter you'll be 15 days into the resulting one. // bonus: this allows adding fractional quarters return this.addMonths(value * 3); }; /** * Adds the specified number of years to this instance. * @param {Number} The number of years to add. The number can be positive or negative [Required] * @return {Date} this */ $P.addYears = function (value) { if (!value) { return this; } return this.addMonths(value * 12); }; /** * Adds (or subtracts) to the value of the years, months, weeks, days, hours, minutes, seconds, milliseconds of the date instance using given configuration object. Positive and Negative values allowed. * Example
    
    	Date.today().add( { days: 1, months: 1 } )
    	 
    	new Date().add( { years: -1 } )
    	
    * @param {Object} Configuration object containing attributes (months, days, etc.) * @return {Date} this */ $P.add = function (config) { if (typeof config === "number") { this._orient = config; return this; } var x = config; if (x.day) { // If we should be a different date than today (eg: for 'tomorrow -1d', etc). // Should only effect parsing, not direct usage (eg, Finish and FinishExact) if ((x.day - this.getDate()) !== 0) { this.setDate(x.day); } } if (x.milliseconds) { this.addMilliseconds(x.milliseconds); } if (x.seconds) { this.addSeconds(x.seconds); } if (x.minutes) { this.addMinutes(x.minutes); } if (x.hours) { this.addHours(x.hours); } if (x.weeks) { this.addWeeks(x.weeks); } if (x.months) { this.addMonths(x.months); } if (x.years) { this.addYears(x.years); } if (x.days) { this.addDays(x.days); } return this; }; /** * Get the week number. Week one (1) is the week which contains the first Thursday of the year. Monday is considered the first day of the week. * The .getWeek() function does NOT convert the date to UTC. The local datetime is used. * Please use .getISOWeek() to get the week of the UTC converted date. * @return {Number} 1 to 53 */ $P.getWeek = function (utc) { // Create a copy of this date object var self, target = new Date(this.valueOf()); if (utc) { target.addMinutes(target.getTimezoneOffset()); self = target.clone(); } else { self = this; } // ISO week date weeks start on monday // so correct the day number var dayNr = (self.getDay() + 6) % 7; // ISO 8601 states that week 1 is the week // with the first thursday of that year. // Set the target date to the thursday in the target week target.setDate(target.getDate() - dayNr + 3); // Store the millisecond value of the target date var firstThursday = target.valueOf(); // Set the target to the first thursday of the year // First set the target to january first target.setMonth(0, 1); // Not a thursday? Correct the date to the next thursday if (target.getDay() !== 4) { target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7); } // The weeknumber is the number of weeks between the // first thursday of the year and the thursday in the target week return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000 }; /** * Get the ISO 8601 week number. Week one ("01") is the week which contains the first Thursday of the year. Monday is considered the first day of the week. * The .getISOWeek() function does convert the date to it's UTC value. Please use .getWeek() to get the week of the local date. * @return {String} "01" to "53" */ $P.getISOWeek = function () { return p(this.getWeek(true)); }; /** * Moves the date to Monday of the week set. Week one (1) is the week which contains the first Thursday of the year. * @param {Number} A Number (1 to 53) that represents the week of the year. * @return {Date} this */ $P.setWeek = function (n) { if ((n - this.getWeek()) === 0) { if (this.getDay() !== 1) { return this.moveToDayOfWeek(1, (this.getDay() > 1 ? -1 : 1)); } else { return this; } } else { return this.moveToDayOfWeek(1, (this.getDay() > 1 ? -1 : 1)).addWeeks(n - this.getWeek()); } }; $P.setQuarter = function (qtr) { var month = Math.abs(((qtr-1) * 3) + 1); return this.setMonth(month, 1); }; $P.getQuarter = function () { return Date.getQuarter(this); }; $P.getDaysLeftInQuarter = function () { return Date.getDaysLeftInQuarter(this); }; // private var validate = function (n, min, max, name) { name = name ? name : "Object"; if (typeof n === "undefined") { return false; } else if (typeof n !== "number") { throw new TypeError(n + " is not a Number."); } else if (n < min || n > max) { // As failing validation is *not* an exceptional circumstance // lets not throw a RangeError Exception here. // It's semantically correct but it's not sensible. return false; } return true; }; /** * Validates the number is within an acceptable range for milliseconds [0-999]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateMillisecond = function (value) { return validate(value, 0, 999, "millisecond"); }; /** * Validates the number is within an acceptable range for seconds [0-59]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateSecond = function (value) { return validate(value, 0, 59, "second"); }; /** * Validates the number is within an acceptable range for minutes [0-59]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateMinute = function (value) { return validate(value, 0, 59, "minute"); }; /** * Validates the number is within an acceptable range for hours [0-23]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateHour = function (value) { return validate(value, 0, 23, "hour"); }; /** * Validates the number is within an acceptable range for the days in a month [0-MaxDaysInMonth]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateDay = function (value, year, month) { return validate(value, 1, $D.getDaysInMonth(year, month), "day"); }; /** * Validates the number is within an acceptable range for months [0-11]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateWeek = function (value) { return validate(value, 0, 53, "week"); }; /** * Validates the number is within an acceptable range for months [0-11]. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateMonth = function (value) { return validate(value, 0, 11, "month"); }; /** * Validates the number is within an acceptable range for years. * @param {Number} The number to check if within range. * @return {Boolean} true if within range, otherwise false. */ $D.validateYear = function (value) { /** * Per ECMAScript spec the range of times supported by Date objects is * exactly –100,000,000 days to 100,000,000 days measured relative to * midnight at the beginning of 01 January, 1970 UTC. * This gives a range of 8,640,000,000,000,000 milliseconds to either * side of 01 January, 1970 UTC. * * Earliest possible date: Tue, 20 Apr 271,822 B.C. 00:00:00 UTC * Latest possible date: Sat, 13 Sep 275,760 00:00:00 UTC */ return validate(value, -271822, 275760, "year"); }; /** * Set the value of year, month, day, hour, minute, second, millisecond of date instance using given configuration object. * Example
    
    	Date.today().set( { day: 20, month: 1 } )
    
    	new Date().set( { millisecond: 0 } )
    	
    * * @param {Object} Configuration object containing attributes (month, day, etc.) * @return {Date} this */ $P.set = function (config) { if ($D.validateMillisecond(config.millisecond)) { this.addMilliseconds(config.millisecond - this.getMilliseconds()); } if ($D.validateSecond(config.second)) { this.addSeconds(config.second - this.getSeconds()); } if ($D.validateMinute(config.minute)) { this.addMinutes(config.minute - this.getMinutes()); } if ($D.validateHour(config.hour)) { this.addHours(config.hour - this.getHours()); } if ($D.validateMonth(config.month)) { this.addMonths(config.month - this.getMonth()); } if ($D.validateYear(config.year)) { this.addYears(config.year - this.getFullYear()); } /* day has to go last because you can't validate the day without first knowing the month */ if ($D.validateDay(config.day, this.getFullYear(), this.getMonth())) { this.addDays(config.day - this.getDate()); } if (config.timezone) { this.setTimezone(config.timezone); } if (config.timezoneOffset) { this.setTimezoneOffset(config.timezoneOffset); } if (config.week && $D.validateWeek(config.week)) { this.setWeek(config.week); } return this; }; /** * Moves the date to the first day of the month. * @return {Date} this */ $P.moveToFirstDayOfMonth = function () { return this.set({ day: 1 }); }; /** * Moves the date to the last day of the month. * @return {Date} this */ $P.moveToLastDayOfMonth = function () { return this.set({ day: $D.getDaysInMonth(this.getFullYear(), this.getMonth())}); }; /** * Moves the date to the next n'th occurrence of the dayOfWeek starting from the beginning of the month. The number (-1) is a magic number and will return the last occurrence of the dayOfWeek in the month. * @param {Number} The dayOfWeek to move to * @param {Number} The n'th occurrence to move to. Use (-1) to return the last occurrence in the month * @return {Date} this */ $P.moveToNthOccurrence = function (dayOfWeek, occurrence) { if (dayOfWeek === "Weekday") { if (occurrence > 0) { this.moveToFirstDayOfMonth(); if (this.is().weekday()) { occurrence -= 1; } } else if (occurrence < 0) { this.moveToLastDayOfMonth(); if (this.is().weekday()) { occurrence += 1; } } else { return this; } return this.addWeekdays(occurrence); } var shift = 0; if (occurrence > 0) { shift = occurrence - 1; } else if (occurrence === -1) { this.moveToLastDayOfMonth(); if (this.getDay() !== dayOfWeek) { this.moveToDayOfWeek(dayOfWeek, -1); } return this; } return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek, +1).addWeeks(shift); }; /** * Move to the next or last dayOfWeek based on the orient value. * @param {Number} The dayOfWeek to move to * @param {Number} Forward (+1) or Back (-1). Defaults to +1. [Optional] * @return {Date} this */ $P.moveToDayOfWeek = function (dayOfWeek, orient) { var diff = (dayOfWeek - this.getDay() + 7 * (orient || +1)) % 7; return this.addDays((diff === 0) ? diff += 7 * (orient || +1) : diff); }; /** * Move to the next or last month based on the orient value. * @param {Number} The month to move to. 0 = January, 11 = December * @param {Number} Forward (+1) or Back (-1). Defaults to +1. [Optional] * @return {Date} this */ $P.moveToMonth = function (month, orient) { var diff = (month - this.getMonth() + 12 * (orient || +1)) % 12; return this.addMonths((diff === 0) ? diff += 12 * (orient || +1) : diff); }; /** * Get the Ordinate of the current day ("th", "st", "rd"). * @return {String} */ $P.getOrdinate = function () { var num = this.getDate(); return ord(num); }; /** * Get the Ordinal day (numeric day number) of the year, adjusted for leap year. * @return {Number} 1 through 365 (366 in leap years) */ $P.getOrdinalNumber = function () { return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1; }; /** * Get the time zone abbreviation of the current date. * @return {String} The abbreviated time zone name (e.g. "EST") */ $P.getTimezone = function () { return $D.getTimezoneAbbreviation(this.getUTCOffset(), this.isDaylightSavingTime()); }; $P.setTimezoneOffset = function (offset) { var here = this.getTimezoneOffset(), there = Number(offset) * -6 / 10; return (there || there === 0) ? this.addMinutes(there - here) : this; }; $P.setTimezone = function (offset) { return this.setTimezoneOffset($D.getTimezoneOffset(offset)); }; /** * Indicates whether Daylight Saving Time is observed in the current time zone. * @return {Boolean} true|false */ $P.hasDaylightSavingTime = function () { return (Date.today().set({month: 0, day: 1}).getTimezoneOffset() !== Date.today().set({month: 6, day: 1}).getTimezoneOffset()); }; /** * Indicates whether this Date instance is within the Daylight Saving Time range for the current time zone. * @return {Boolean} true|false */ $P.isDaylightSavingTime = function () { return Date.today().set({month: 0, day: 1}).getTimezoneOffset() !== this.getTimezoneOffset(); }; /** * Get the offset from UTC of the current date. * @return {String} The 4-character offset string prefixed with + or - (e.g. "-0500") */ $P.getUTCOffset = function (offset) { var n = (offset || this.getTimezoneOffset()) * -10 / 6, r; if (n < 0) { r = (n - 10000).toString(); return r.charAt(0) + r.substr(2); } else { r = (n + 10000).toString(); return "+" + r.substr(1); } }; /** * Returns the number of milliseconds between this date and date. * @param {Date} Defaults to now * @return {Number} The diff in milliseconds */ $P.getElapsed = function (date) { return (date || new Date()) - this; }; /** * Converts the value of the current Date object to its equivalent string representation. * Format Specifiers
    	CUSTOM DATE AND TIME FORMAT STRINGS
    	Format  Description                                                                  Example
    	------  ---------------------------------------------------------------------------  -----------------------
    	 s      The seconds of the minute between 0-59.                                      "0" to "59"
    	 ss     The seconds of the minute with leading zero if required.                     "00" to "59"
    	 
    	 m      The minute of the hour between 0-59.                                         "0"  or "59"
    	 mm     The minute of the hour with leading zero if required.                        "00" or "59"
    	 
    	 h      The hour of the day between 1-12.                                            "1"  to "12"
    	 hh     The hour of the day with leading zero if required.                           "01" to "12"
    	 
    	 H      The hour of the day between 0-23.                                            "0"  to "23"
    	 HH     The hour of the day with leading zero if required.                           "00" to "23"
    	 
    	 d      The day of the month between 1 and 31.                                       "1"  to "31"
    	 dd     The day of the month with leading zero if required.                          "01" to "31"
    	 ddd    Abbreviated day name. Date.CultureInfo.abbreviatedDayNames.                                "Mon" to "Sun" 
    	 dddd   The full day name. Date.CultureInfo.dayNames.                                              "Monday" to "Sunday"
    	 
    	 M      The month of the year between 1-12.                                          "1" to "12"
    	 MM     The month of the year with leading zero if required.                         "01" to "12"
    	 MMM    Abbreviated month name. Date.CultureInfo.abbreviatedMonthNames.                            "Jan" to "Dec"
    	 MMMM   The full month name. Date.CultureInfo.monthNames.                                          "January" to "December"
    
    	 yy     The year as a two-digit number.                                              "99" or "08"
    	 yyyy   The full four digit year.                                                    "1999" or "2008"
    	 
    	 t      Displays the first character of the A.M./P.M. designator.                    "A" or "P"
    			Date.CultureInfo.amDesignator or Date.CultureInfo.pmDesignator
    	 tt     Displays the A.M./P.M. designator.                                           "AM" or "PM"
    			Date.CultureInfo.amDesignator or Date.CultureInfo.pmDesignator
    	 
    	 S      The ordinal suffix ("st, "nd", "rd" or "th") of the current day.            "st, "nd", "rd" or "th"
    
    || *Format* || *Description* || *Example* ||
    || d      || The CultureInfo shortDate Format Pattern                                     || "M/d/yyyy" ||
    || D      || The CultureInfo longDate Format Pattern                                      || "dddd, MMMM dd, yyyy" ||
    || F      || The CultureInfo fullDateTime Format Pattern                                  || "dddd, MMMM dd, yyyy h:mm:ss tt" ||
    || m      || The CultureInfo monthDay Format Pattern                                      || "MMMM dd" ||
    || r      || The CultureInfo rfc1123 Format Pattern                                       || "ddd, dd MMM yyyy HH:mm:ss GMT" ||
    || s      || The CultureInfo sortableDateTime Format Pattern                              || "yyyy-MM-ddTHH:mm:ss" ||
    || t      || The CultureInfo shortTime Format Pattern                                     || "h:mm tt" ||
    || T      || The CultureInfo longTime Format Pattern                                      || "h:mm:ss tt" ||
    || u      || The CultureInfo universalSortableDateTime Format Pattern                     || "yyyy-MM-dd HH:mm:ssZ" ||
    || y      || The CultureInfo yearMonth Format Pattern                                     || "MMMM, yyyy" ||
    	 
    
    	STANDARD DATE AND TIME FORMAT STRINGS
    	Format  Description                                                                  Example ("en-US")
    	------  ---------------------------------------------------------------------------  -----------------------
    	 d      The CultureInfo shortDate Format Pattern                                     "M/d/yyyy"
    	 D      The CultureInfo longDate Format Pattern                                      "dddd, MMMM dd, yyyy"
    	 F      The CultureInfo fullDateTime Format Pattern                                  "dddd, MMMM dd, yyyy h:mm:ss tt"
    	 m      The CultureInfo monthDay Format Pattern                                      "MMMM dd"
    	 r      The CultureInfo rfc1123 Format Pattern                                       "ddd, dd MMM yyyy HH:mm:ss GMT"
    	 s      The CultureInfo sortableDateTime Format Pattern                              "yyyy-MM-ddTHH:mm:ss"
    	 t      The CultureInfo shortTime Format Pattern                                     "h:mm tt"
    	 T      The CultureInfo longTime Format Pattern                                      "h:mm:ss tt"
    	 u      The CultureInfo universalSortableDateTime Format Pattern                     "yyyy-MM-dd HH:mm:ssZ"
    	 y      The CultureInfo yearMonth Format Pattern                                     "MMMM, yyyy"
    	
    * @param {String} A format string consisting of one or more format spcifiers [Optional]. * @return {String} A string representation of the current Date object. */ var ord = function (n) { switch (n * 1) { case 1: case 21: case 31: return "st"; case 2: case 22: return "nd"; case 3: case 23: return "rd"; default: return "th"; } }; $P.toString = function (format, ignoreStandards) { var x = this; // Standard Date and Time Format Strings. Formats pulled from CultureInfo file and // may vary by culture. if (!ignoreStandards && format && format.length === 1) { var y, c = Date.CultureInfo.formatPatterns; x.t = x.toString; switch (format) { case "d": return x.t(c.shortDate); case "D": return x.t(c.longDate); case "F": return x.t(c.fullDateTime); case "m": return x.t(c.monthDay); case "r": case "R": y = x.clone().addMinutes(x.getTimezoneOffset()); return y.toString(c.rfc1123) + " GMT"; case "s": return x.t(c.sortableDateTime); case "t": return x.t(c.shortTime); case "T": return x.t(c.longTime); case "u": y = x.clone().addMinutes(x.getTimezoneOffset()); return y.toString(c.universalSortableDateTime); case "y": return x.t(c.yearMonth); } } return format ? format.replace(/((\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S|q|Q|WW?W?W?)(?![^\[]*\]))/g, function (m) { if (m.charAt(0) === "\\") { return m.replace("\\", ""); } x.h = x.getHours; switch (m) { case "hh": return p(x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12)); case "h": return x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12); case "HH": return p(x.h()); case "H": return x.h(); case "mm": return p(x.getMinutes()); case "m": return x.getMinutes(); case "ss": return p(x.getSeconds()); case "s": return x.getSeconds(); case "yyyy": return p(x.getFullYear(), 4); case "yy": return p(x.getFullYear()); case "dddd": return Date.CultureInfo.dayNames[x.getDay()]; case "ddd": return Date.CultureInfo.abbreviatedDayNames[x.getDay()]; case "dd": return p(x.getDate()); case "d": return x.getDate(); case "MMMM": return Date.CultureInfo.monthNames[x.getMonth()]; case "MMM": return Date.CultureInfo.abbreviatedMonthNames[x.getMonth()]; case "MM": return p((x.getMonth() + 1)); case "M": return x.getMonth() + 1; case "t": return x.h() < 12 ? Date.CultureInfo.amDesignator.substring(0, 1) : Date.CultureInfo.pmDesignator.substring(0, 1); case "tt": return x.h() < 12 ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator; case "S": return ord(x.getDate()); case "W": return x.getWeek(); case "WW": return x.getISOWeek(); case "Q": return "Q" + x.getQuarter(); case "q": return String(x.getQuarter()); default: return m; } }).replace(/\[|\]/g, "") : this._toString(); }; }()); (function () { "use strict"; Date.Parsing = { Exception: function (s) { this.message = "Parse error at '" + s.substring(0, 10) + " ...'"; } }; var $P = Date.Parsing; var dayOffsets = { standard: [0,31,59,90,120,151,181,212,243,273,304,334], leap: [0,31,60,91,121,152,182,213,244,274,305,335] }; $P.isLeapYear = function(year) { return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); }; $P.processTimeObject = function (obj) { var d, jan4, date, offset, dayOffset; d = new Date(); dayOffset = ($P.isLeapYear(obj.year)) ? dayOffsets.leap : dayOffsets.standard; obj.hours = obj.hours ? obj.hours : 0; obj.minutes = obj.minutes ? obj.minutes : 0; obj.seconds = obj.seconds ? obj.seconds : 0; obj.milliseconds = obj.milliseconds ? obj.milliseconds : 0; if (!obj.year) { obj.year = d.getFullYear(); } if (!obj.month && (obj.week || obj.dayOfYear)) { // work out the day of the year... if (!obj.dayOfYear) { obj.weekDay = (!obj.weekDay && obj.weekDay !== 0) ? 1 : obj.weekDay; d = new Date(obj.year, 0, 4); jan4 = d.getDay() === 0 ? 7 : d.getDay(); // JS is 0 indexed on Sunday. offset = jan4+3; obj.dayOfYear = ((obj.week * 7) + (obj.weekDay === 0 ? 7 : obj.weekDay))-offset; } for (var i=0;i <= dayOffset.length;i++) { if (obj.dayOfYear < dayOffset[i] || i === dayOffset.length) { obj.day = obj.day ? obj.day : (obj.dayOfYear - dayOffset[i-1]); break; } else { obj.month = i; } } } else { obj.month = obj.month ? obj.month : 0; obj.day = obj.day ? obj.day : 1; obj.dayOfYear = dayOffset[obj.month] + obj.day; } date = new Date(obj.year, obj.month, obj.day, obj.hours, obj.minutes, obj.seconds, obj.milliseconds); if (obj.zone) { // adjust (and calculate) for timezone here if (obj.zone.toUpperCase() === "Z" || (obj.zone_hours === 0 && obj.zone_minutes === 0)) { // it's UTC/GML so work out the current timeszone offset offset = -date.getTimezoneOffset(); } else { offset = (obj.zone_hours*60) + (obj.zone_minutes ? obj.zone_minutes : 0); if (obj.zone_sign === "+") { offset *= -1; } offset -= date.getTimezoneOffset(); } date.setMinutes(date.getMinutes()+offset); } return date; }; $P.ISO = { regex : /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-4])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?\s?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/, parse : function (s) { var data = s.match(this.regex); if (!data || !data.length) { return null; } var time = { year : data[1] ? Number(data[1]) : data[1], month : data[5] ? (Number(data[5])-1) : data[5], day : data[7] ? Number(data[7]) : data[7], week : data[8] ? Number(data[8]) : data[8], weekDay : data[9] ? (Math.abs(Number(data[9])) === 7 ? 0 : Math.abs(Number(data[9]))) : data[9], // 1-7, starts on Monday. Convert to JS's 0-6 index. dayOfYear : data[10] ? Number(data[10]) : data[10], hours : data[15] ? Number(data[15]) : data[15], minutes : data[16] ? Number(data[16].replace(":","")) : data[16], seconds : data[19] ? Math.floor(Number(data[19].replace(":","").replace(",","."))) : data[19], milliseconds : data[20] ? (Number(data[20].replace(",","."))*1000) : data[20], zone : data[21], zone_sign : data[22], zone_hours : (data[23] && typeof data[23] !== "undefined") ? Number(data[23]) : data[23], zone_minutes : (data[24] && typeof data[23] !== "undefined") ? Number(data[24]) : data[24] }; if (data[18]) { data[18] = 60 * Number(data[18].replace(",", ".")); if (!time.minutes) { time.minutes = data[18]; } else if (!time.seconds) { time.seconds = data[18]; } } if (!time.year || (!time.year && (!time.month && !time.day) && (!time.week && !time.dayOfYear)) ) { return null; } return $P.processTimeObject(time); } }; $P.Numeric = { isNumeric: function (e){return!isNaN(parseFloat(e))&&isFinite(e)}, regex: /\b([0-1]?[0-9])([0-3]?[0-9])([0-2]?[0-9]?[0-9][0-9])\b/i, parse: function (s) { var data, i, time = {}, order = Date.CultureInfo.dateElementOrder.split(""); if (!(this.isNumeric(s)) || // if it's non-numeric OR (s[0] === "+" && s[0] === "-")) { // It's an arithmatic string (eg +/-1000) return null; } if (s.length < 5) { // assume it's just a year. time.year = s; return $P.processTimeObject(time); } data = s.match(this.regex); if (!data || !data.length) { return null; } for (i=0; i < order.length; i++) { switch(order[i]) { case "d": time.day = data[i+1]; break; case "m": time.month = (data[i+1]-1); break; case "y": time.year = data[i+1]; break; } } return $P.processTimeObject(time); } }; $P.Normalizer = { parse: function (s) { var $C = Date.CultureInfo; var $R = Date.CultureInfo.regexPatterns; var __ = Date.i18n.__; s = s.replace($R.jan.source, "January"); s = s.replace($R.feb, "February"); s = s.replace($R.mar, "March"); s = s.replace($R.apr, "April"); s = s.replace($R.may, "May"); s = s.replace($R.jun, "June"); s = s.replace($R.jul, "July"); s = s.replace($R.aug, "August"); s = s.replace($R.sep, "September"); s = s.replace($R.oct, "October"); s = s.replace($R.nov, "November"); s = s.replace($R.dec, "December"); s = s.replace($R.tomorrow, Date.today().addDays(1).toString("d")); s = s.replace($R.yesterday, Date.today().addDays(-1).toString("d")); // s = s.replace(new RegExp($R.today.source + "\\b", "i"), Date.today().toString("d")); s = s.replace(/\bat\b/gi, ""); // replace "at", eg: "tomorrow at 3pm" s = s.replace(/\s{2,}/, " "); // repliace multiple spaces with one. s = s.replace(new RegExp("(\\b\\d\\d?("+__("AM")+"|"+__("PM")+")? )("+$R.tomorrow.source.slice(1)+")", "i"), function(full, m1, m2, m3, m4) { var t = Date.today().addDays(1).toString("d"); var s = t + " " + m1; return s; }); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.mon.source+'))'), Date.today().last().monday().toString("d")); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.tue.source+'))'), Date.today().last().tuesday().toString("d")); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.wed.source+'))'), Date.today().last().wednesday().toString("d")); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.thu.source+'))'), Date.today().last().thursday().toString("d")); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.fri.source+'))'), Date.today().last().friday().toString("d")); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.sat.source+'))'), Date.today().last().saturday().toString("d")); s = s.replace(new RegExp("(("+$R.past.source+')\\s('+$R.sun.source+'))'), Date.today().last().sunday().toString("d")); // s = s.replace($R.thisMorning, "9am")) s = s.replace($R.amThisMorning, function(str, am){return am;}); s = s.replace($R.inTheMorning, "am"); s = s.replace($R.thisMorning, "9am"); s = s.replace($R.amThisEvening, function(str, pm){return pm;}); s = s.replace($R.inTheEvening, "pm"); s = s.replace($R.thisEvening, "7pm"); try { var n = s.split(/([\s\-\.\,\/\x27]+)/); if (n.length === 3) { if ($P.Numeric.isNumeric(n[0]) && $P.Numeric.isNumeric(n[2])) { if (n[2].length >= 4) { // ok, so we're dealing with x/year. But that's not a full date. // This fixes wonky dateElementOrder parsing when set to dmy order. if (Date.CultureInfo.dateElementOrder[0] === 'd') { s = '1/' + n[0] + '/' + n[2]; // set to 1st of month and normalize the seperator } } } } } catch (e) { // continue... } return s; } }; }()); (function () { var $P = Date.Parsing; var _ = $P.Operators = { // // Tokenizers // rtoken: function (r) { // regex token return function (s) { var mx = s.match(r); if (mx) { return ([ mx[0], s.substring(mx[0].length) ]); } else { throw new $P.Exception(s); } }; }, token: function (s) { // whitespace-eating token return function (s) { return _.rtoken(new RegExp("^\s*" + s + "\s*"))(s); // Removed .strip() // return _.rtoken(new RegExp("^\s*" + s + "\s*"))(s).strip(); }; }, stoken: function (s) { // string token return _.rtoken(new RegExp("^" + s)); }, // // Atomic Operators // until: function (p) { return function (s) { var qx = [], rx = null; while (s.length) { try { rx = p.call(this, s); } catch (e) { qx.push(rx[0]); s = rx[1]; continue; } break; } return [ qx, s ]; }; }, many: function (p) { return function (s) { var rx = [], r = null; while (s.length) { try { r = p.call(this, s); } catch (e) { return [ rx, s ]; } rx.push(r[0]); s = r[1]; } return [ rx, s ]; }; }, // generator operators -- see below optional: function (p) { return function (s) { var r = null; try { r = p.call(this, s); } catch (e) { return [ null, s ]; } return [ r[0], r[1] ]; }; }, not: function (p) { return function (s) { try { p.call(this, s); } catch (e) { return [null, s]; } throw new $P.Exception(s); }; }, ignore: function (p) { return p ? function (s) { var r = null; r = p.call(this, s); return [null, r[1]]; } : null; }, product: function () { var px = arguments[0], qx = Array.prototype.slice.call(arguments, 1), rx = []; for (var i = 0 ; i < px.length ; i++) { rx.push(_.each(px[i], qx)); } return rx; }, cache: function (rule) { var cache = {}, r = null; return function (s) { try { r = cache[s] = (cache[s] || rule.call(this, s)); } catch (e) { r = cache[s] = e; } if (r instanceof $P.Exception) { throw r; } else { return r; } }; }, // vector operators -- see below any: function () { var px = arguments; return function (s) { var r = null; for (var i = 0; i < px.length; i++) { if (px[i] == null) { continue; } try { r = (px[i].call(this, s)); } catch (e) { r = null; } if (r) { return r; } } throw new $P.Exception(s); }; }, each: function () { var px = arguments; return function (s) { var rx = [], r = null; for (var i = 0; i < px.length ; i++) { if (px[i] == null) { continue; } try { r = (px[i].call(this, s)); } catch (e) { throw new $P.Exception(s); } rx.push(r[0]); s = r[1]; } return [ rx, s]; }; }, all: function () { var px = arguments, _ = _; return _.each(_.optional(px)); }, // delimited operators sequence: function (px, d, c) { d = d || _.rtoken(/^\s*/); c = c || null; if (px.length == 1) { return px[0]; } return function (s) { var r = null, q = null; var rx = []; for (var i = 0; i < px.length ; i++) { try { r = px[i].call(this, s); } catch (e) { break; } rx.push(r[0]); try { q = d.call(this, r[1]); } catch (ex) { q = null; break; } s = q[1]; } if (!r) { throw new $P.Exception(s); } if (q) { throw new $P.Exception(q[1]); } if (c) { try { r = c.call(this, r[1]); } catch (ey) { throw new $P.Exception(r[1]); } } return [ rx, (r?r[1]:s) ]; }; }, // // Composite Operators // between: function (d1, p, d2) { d2 = d2 || d1; var _fn = _.each(_.ignore(d1), p, _.ignore(d2)); return function (s) { var rx = _fn.call(this, s); return [[rx[0][0], r[0][2]], rx[1]]; }; }, list: function (p, d, c) { d = d || _.rtoken(/^\s*/); c = c || null; return (p instanceof Array ? _.each(_.product(p.slice(0, -1), _.ignore(d)), p.slice(-1), _.ignore(c)) : _.each(_.many(_.each(p, _.ignore(d))), px, _.ignore(c))); }, set: function (px, d, c) { d = d || _.rtoken(/^\s*/); c = c || null; return function (s) { // r is the current match, best the current 'best' match // which means it parsed the most amount of input var r = null, p = null, q = null, rx = null, best = [[], s], last = false; // go through the rules in the given set for (var i = 0; i < px.length ; i++) { // last is a flag indicating whether this must be the last element // if there is only 1 element, then it MUST be the last one q = null; p = null; r = null; last = (px.length == 1); // first, we try simply to match the current pattern // if not, try the next pattern try { r = px[i].call(this, s); } catch (e) { continue; } // since we are matching against a set of elements, the first // thing to do is to add r[0] to matched elements rx = [[r[0]], r[1]]; // if we matched and there is still input to parse and // we don't already know this is the last element, // we're going to next check for the delimiter ... // if there's none, or if there's no input left to parse // than this must be the last element after all ... if (r[1].length > 0 && ! last) { try { q = d.call(this, r[1]); } catch (ex) { last = true; } } else { last = true; } // if we parsed the delimiter and now there's no more input, // that means we shouldn't have parsed the delimiter at all // so don't update r and mark this as the last element ... if (!last && q[1].length === 0) { last = true; } // so, if this isn't the last element, we're going to see if // we can get any more matches from the remaining (unmatched) // elements ... if (!last) { // build a list of the remaining rules we can match against, // i.e., all but the one we just matched against var qx = []; for (var j = 0; j < px.length ; j++) { if (i != j) { qx.push(px[j]); } } // now invoke recursively set with the remaining input // note that we don't include the closing delimiter ... // we'll check for that ourselves at the end p = _.set(qx, d).call(this, q[1]); // if we got a non-empty set as a result ... // (otw rx already contains everything we want to match) if (p[0].length > 0) { // update current result, which is stored in rx ... // basically, pick up the remaining text from p[1] // and concat the result from p[0] so that we don't // get endless nesting ... rx[0] = rx[0].concat(p[0]); rx[1] = p[1]; } } // at this point, rx either contains the last matched element // or the entire matched set that starts with this element. // now we just check to see if this variation is better than // our best so far, in terms of how much of the input is parsed if (rx[1].length < best[1].length) { best = rx; } // if we've parsed all the input, then we're finished if (best[1].length === 0) { break; } } // so now we've either gone through all the patterns trying them // as the initial match; or we found one that parsed the entire // input string ... // if best has no matches, just return empty set ... if (best[0].length === 0) { return best; } // if a closing delimiter is provided, then we have to check it also if (c) { // we try this even if there is no remaining input because the pattern // may well be optional or match empty input ... try { q = c.call(this, best[1]); } catch (ey) { throw new $P.Exception(best[1]); } // it parsed ... be sure to update the best match remaining input best[1] = q[1]; } // if we're here, either there was no closing delimiter or we parsed it // so now we have the best match; just return it! return best; }; }, forward: function (gr, fname) { return function (s) { return gr[fname].call(this, s); }; }, // // Translation Operators // replace: function (rule, repl) { return function (s) { var r = rule.call(this, s); return [repl, r[1]]; }; }, process: function (rule, fn) { return function (s) { var r = rule.call(this, s); return [fn.call(this, r[0]), r[1]]; }; }, min: function (min, rule) { return function (s) { var rx = rule.call(this, s); if (rx[0].length < min) { throw new $P.Exception(s); } return rx; }; } }; // Generator Operators And Vector Operators // Generators are operators that have a signature of F(R) => R, // taking a given rule and returning another rule, such as // ignore, which parses a given rule and throws away the result. // Vector operators are those that have a signature of F(R1,R2,...) => R, // take a list of rules and returning a new rule, such as each. // Generator operators are converted (via the following _generator // function) into functions that can also take a list or array of rules // and return an array of new rules as though the function had been // called on each rule in turn (which is what actually happens). // This allows generators to be used with vector operators more easily. // Example: // each(ignore(foo, bar)) instead of each(ignore(foo), ignore(bar)) // This also turns generators into vector operators, which allows // constructs like: // not(cache(foo, bar)) var _generator = function (op) { function gen() { var args = null, rx = [], px, i; if (arguments.length > 1) { args = Array.prototype.slice.call(arguments); } else if (arguments[0] instanceof Array) { args = arguments[0]; } if (args) { px = args.shift(); if (px.length > 0) { args.unshift(px[i]); rx.push(op.apply(null, args)); args.shift(); return rx; } } else { return op.apply(null, arguments); } } return gen; }; var gx = "optional not ignore cache".split(/\s/); for (var i = 0 ; i < gx.length ; i++) { _[gx[i]] = _generator(_[gx[i]]); } var _vector = function (op) { return function () { if (arguments[0] instanceof Array) { return op.apply(null, arguments[0]); } else { return op.apply(null, arguments); } }; }; var vx = "each any all".split(/\s/); for (var j = 0 ; j < vx.length ; j++) { _[vx[j]] = _vector(_[vx[j]]); } }()); (function () { var $D = Date; var flattenAndCompact = function (ax) { var rx = []; for (var i = 0; i < ax.length; i++) { if (ax[i] instanceof Array) { rx = rx.concat(flattenAndCompact(ax[i])); } else { if (ax[i]) { rx.push(ax[i]); } } } return rx; }; $D.Grammar = {}; $D.Translator = { hour: function (s) { return function () { this.hour = Number(s); }; }, minute: function (s) { return function () { this.minute = Number(s); }; }, second: function (s) { return function () { this.second = Number(s); }; }, /* for ss.s format */ secondAndMillisecond: function (s) { return function () { var mx = s.match(/^([0-5][0-9])\.([0-9]{1,3})/); this.second = Number(mx[1]); this.millisecond = Number(mx[2]); }; }, meridian: function (s) { return function () { this.meridian = s.slice(0, 1).toLowerCase(); }; }, timezone: function (s) { return function () { var n = s.replace(/[^\d\+\-]/g, ""); if (n.length) { this.timezoneOffset = Number(n); } else { this.timezone = s.toLowerCase(); } }; }, day: function (x) { var s = x[0]; return function () { this.day = Number(s.match(/\d+/)[0]); if (this.day < 1) { throw "invalid day"; } }; }, month: function (s) { return function () { this.month = (s.length === 3) ? "jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s)/4 : Number(s) - 1; if (this.month < 0) { throw "invalid month"; } }; }, year: function (s) { return function () { var n = Number(s); this.year = ((s.length > 2) ? n : (n + (((n + 2000) < Date.CultureInfo.twoDigitYearMax) ? 2000 : 1900))); }; }, rday: function (s) { return function () { switch (s) { case "yesterday": this.days = -1; break; case "tomorrow": this.days = 1; break; case "today": this.days = 0; break; case "now": this.days = 0; this.now = true; break; } }; }, finishExact: function (x) { x = (x instanceof Array) ? x : [ x ]; for (var i = 0 ; i < x.length ; i++) { if (x[i]) { x[i].call(this); } } var now = new Date(); if ((this.hour || this.minute) && (!this.month && !this.year && !this.day)) { this.day = now.getDate(); } if (!this.year) { this.year = now.getFullYear(); } if (!this.month && this.month !== 0) { this.month = now.getMonth(); } if (!this.day) { this.day = 1; } if (!this.hour) { this.hour = 0; } if (!this.minute) { this.minute = 0; } if (!this.second) { this.second = 0; } if (!this.millisecond) { this.millisecond = 0; } if (this.meridian && (this.hour || this.hour === 0)) { if (this.meridian == "a" && this.hour > 11 && Date.Config.strict24hr){ throw "Invalid hour and meridian combination"; } else if (this.meridian == "p" && this.hour < 12 && Date.Config.strict24hr){ throw "Invalid hour and meridian combination"; } else if (this.meridian == "p" && this.hour < 12) { this.hour = this.hour + 12; } else if (this.meridian == "a" && this.hour == 12) { this.hour = 0; } } if (this.day > $D.getDaysInMonth(this.year, this.month)) { throw new RangeError(this.day + " is not a valid value for days."); } var r = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond); if (this.year < 100) { r.setFullYear(this.year); // means years less that 100 are process correctly. JS will parse it otherwise as 1900-1999. } if (this.timezone) { r.set({ timezone: this.timezone }); } else if (this.timezoneOffset) { r.set({ timezoneOffset: this.timezoneOffset }); } return r; }, finish: function (x) { x = (x instanceof Array) ? flattenAndCompact(x) : [ x ]; if (x.length === 0) { return null; } for (var i = 0 ; i < x.length ; i++) { if (typeof x[i] == "function") { x[i].call(this); } } var today = $D.today(); if (this.now && !this.unit && !this.operator) { return new Date(); } else if (this.now) { today = new Date(); } var expression = !!(this.days && this.days !== null || this.orient || this.operator); var gap, mod, orient; orient = ((this.orient == "past" || this.operator == "subtract") ? -1 : 1); if(!this.now && "hour minute second".indexOf(this.unit) != -1) { today.setTimeToNow(); } if (this.month && this.unit == "week") { this.value = this.month + 1; delete this.month; delete this.day; } if (this.month || this.month === 0) { if ("year day hour minute second".indexOf(this.unit) != -1) { if (!this.value) { this.value = this.month + 1; } this.month = null; expression = true; } } if (!expression && this.weekday && !this.day && !this.days) { var temp = Date[this.weekday](); this.day = temp.getDate(); if (!this.month) { this.month = temp.getMonth(); } this.year = temp.getFullYear(); } if (expression && this.weekday && this.unit != "month" && this.unit != "week") { this.unit = "day"; gap = ($D.getDayNumberFromName(this.weekday) - today.getDay()); mod = 7; this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod); } if (this.month && this.unit == "day" && this.operator) { if (!this.value) { this.value = (this.month + 1); } this.month = null; } if (this.value != null && this.month != null && this.year != null) { this.day = this.value * 1; } if (this.month && !this.day && this.value) { today.set({ day: this.value * 1 }); if (!expression) { this.day = this.value * 1; } } if (!this.month && this.value && this.unit == "month" && !this.now) { this.month = this.value; expression = true; } if (expression && (this.month || this.month === 0) && this.unit != "year") { this.unit = "month"; gap = (this.month - today.getMonth()); mod = 12; this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod); this.month = null; } if (!this.unit) { this.unit = "day"; } if (!this.value && this.operator && this.operator !== null && this[this.unit + "s"] && this[this.unit + "s"] !== null) { this[this.unit + "s"] = this[this.unit + "s"] + ((this.operator == "add") ? 1 : -1) + (this.value||0) * orient; } else if (this[this.unit + "s"] == null || this.operator != null) { if (!this.value) { this.value = 1; } this[this.unit + "s"] = this.value * orient; } if (this.meridian && (this.hour || this.hour === 0)) { if (this.meridian == "a" && this.hour > 11 && Date.Config.strict24hr){ throw "Invalid hour and meridian combination"; } else if (this.meridian == "p" && this.hour < 12 && Date.Config.strict24hr){ throw "Invalid hour and meridian combination"; } else if (this.meridian == "p" && this.hour < 12) { this.hour = this.hour + 12; } else if (this.meridian == "a" && this.hour == 12) { this.hour = 0; } } if (this.weekday && this.unit !== "week" && !this.day && !this.days) { var temp = Date[this.weekday](); this.day = temp.getDate(); if (temp.getMonth() !== today.getMonth()) { this.month = temp.getMonth(); } } if ((this.month || this.month === 0) && !this.day) { this.day = 1; } if (!this.orient && !this.operator && this.unit == "week" && this.value && !this.day && !this.month) { return Date.today().setWeek(this.value); } if (this.unit == "week" && this.weeks && !this.day && !this.month) { var weekday = (this.weekday) ? this.weekday : "today"; var d = Date[weekday]().addWeeks(this.weeks); if (this.now) { d.setTimeToNow(); } return d; } if (expression && this.timezone && this.day && this.days) { this.day = this.days; } return (expression) ? today.add(this) : today.set(this); } }; var _ = $D.Parsing.Operators, g = $D.Grammar, t = $D.Translator, _fn; g.datePartDelimiter = _.rtoken(/^([\s\-\.\,\/\x27]+)/); g.timePartDelimiter = _.stoken(":"); g.whiteSpace = _.rtoken(/^\s*/); g.generalDelimiter = _.rtoken(/^(([\s\,]|at|@|on)+)/); var _C = {}; g.ctoken = function (keys) { var fn = _C[keys]; if (! fn) { var c = Date.CultureInfo.regexPatterns; var kx = keys.split(/\s+/), px = []; for (var i = 0; i < kx.length ; i++) { px.push(_.replace(_.rtoken(c[kx[i]]), kx[i])); } fn = _C[keys] = _.any.apply(null, px); } return fn; }; g.ctoken2 = function (key) { return _.rtoken(Date.CultureInfo.regexPatterns[key]); }; // hour, minute, second, meridian, timezone g.h = _.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/), t.hour)); g.hh = _.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/), t.hour)); g.H = _.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/), t.hour)); g.HH = _.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/), t.hour)); g.m = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.minute)); g.mm = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.minute)); g.s = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.second)); g.ss = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.second)); g["ss.s"] = _.cache(_.process(_.rtoken(/^[0-5][0-9]\.[0-9]{1,3}/), t.secondAndMillisecond)); g.hms = _.cache(_.sequence([g.H, g.m, g.s], g.timePartDelimiter)); // _.min(1, _.set([ g.H, g.m, g.s ], g._t)); g.t = _.cache(_.process(g.ctoken2("shortMeridian"), t.meridian)); g.tt = _.cache(_.process(g.ctoken2("longMeridian"), t.meridian)); g.z = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone)); g.zz = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone)); g.zzz = _.cache(_.process(g.ctoken2("timezone"), t.timezone)); g.timeSuffix = _.each(_.ignore(g.whiteSpace), _.set([ g.tt, g.zzz ])); g.time = _.each(_.optional(_.ignore(_.stoken("T"))), g.hms, g.timeSuffix); // days, months, years g.d = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/), _.optional(g.ctoken2("ordinalSuffix"))), t.day)); g.dd = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/), _.optional(g.ctoken2("ordinalSuffix"))), t.day)); g.ddd = g.dddd = _.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"), function (s) { return function () { this.weekday = s; }; } )); g.M = _.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/), t.month)); g.MM = _.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/), t.month)); g.MMM = g.MMMM = _.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"), t.month)); // g.MMM = g.MMMM = _.cache(_.process(g.ctoken(Date.CultureInfo.abbreviatedMonthNames.join(" ")), t.month)); g.y = _.cache(_.process(_.rtoken(/^(\d\d?)/), t.year)); g.yy = _.cache(_.process(_.rtoken(/^(\d\d)/), t.year)); g.yyy = _.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/), t.year)); g.yyyy = _.cache(_.process(_.rtoken(/^(\d\d\d\d)/), t.year)); // rolling these up into general purpose rules _fn = function () { return _.each(_.any.apply(null, arguments), _.not(g.ctoken2("timeContext"))); }; g.day = _fn(g.d, g.dd); g.month = _fn(g.M, g.MMM); g.year = _fn(g.yyyy, g.yy); // relative date / time expressions g.orientation = _.process(g.ctoken("past future"), function (s) { return function () { this.orient = s; }; } ); g.operator = _.process(g.ctoken("add subtract"), function (s) { return function () { this.operator = s; }; } ); g.rday = _.process(g.ctoken("yesterday tomorrow today now"), t.rday); g.unit = _.process(g.ctoken("second minute hour day week month year"), function (s) { return function () { this.unit = s; }; } ); g.value = _.process(_.rtoken(/^([-+]?\d+)?(st|nd|rd|th)?/), function (s) { return function () { this.value = s.replace(/\D/g, ""); }; } ); g.expression = _.set([ g.rday, g.operator, g.value, g.unit, g.orientation, g.ddd, g.MMM ]); // pre-loaded rules for different date part order preferences _fn = function () { return _.set(arguments, g.datePartDelimiter); }; g.mdy = _fn(g.ddd, g.month, g.day, g.year); g.ymd = _fn(g.ddd, g.year, g.month, g.day); g.dmy = _fn(g.ddd, g.day, g.month, g.year); g.date = function (s) { return ((g[Date.CultureInfo.dateElementOrder] || g.mdy).call(this, s)); }; // parsing date format specifiers - ex: "h:m:s tt" // this little guy will generate a custom parser based // on the format string, ex: g.format("h:m:s tt") g.format = _.process(_.many( _.any( // translate format specifiers into grammar rules _.process( _.rtoken(/^(dd?d?d?(?!e)|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/), function (fmt) { if (g[fmt]) { return g[fmt]; } else { throw $D.Parsing.Exception(fmt); } } ), // translate separator tokens into token rules _.process(_.rtoken(/^[^dMyhHmstz]+/), // all legal separators function (s) { return _.ignore(_.stoken(s)); } ) )), // construct the parser ... function (rules) { return _.process(_.each.apply(null, rules), t.finishExact); } ); var _F = { //"M/d/yyyy": function (s) { // var m = s.match(/^([0-2]\d|3[0-1]|\d)\/(1[0-2]|0\d|\d)\/(\d\d\d\d)/); // if (m!=null) { // var r = [ t.month.call(this,m[1]), t.day.call(this,m[2]), t.year.call(this,m[3]) ]; // r = t.finishExact.call(this,r); // return [ r, "" ]; // } else { // throw new Date.Parsing.Exception(s); // } //} //"M/d/yyyy": function (s) { return [ new Date(Date._parse(s)), ""]; } }; var _get = function (f) { _F[f] = (_F[f] || g.format(f)[0]); return _F[f]; }; g.allformats = function (fx) { var rx = []; if (fx instanceof Array) { for (var i = 0; i < fx.length; i++) { rx.push(_get(fx[i])); } } else { rx.push(_get(fx)); } return rx; }; g.formats = function (fx) { if (fx instanceof Array) { var rx = []; for (var i = 0 ; i < fx.length ; i++) { rx.push(_get(fx[i])); } return _.any.apply(null, rx); } else { return _get(fx); } }; // check for these formats first g._formats = g.formats([ "\"yyyy-MM-ddTHH:mm:ssZ\"", "yyyy-MM-ddTHH:mm:ss.sz", "yyyy-MM-ddTHH:mm:ssZ", "yyyy-MM-ddTHH:mm:ssz", "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mmZ", "yyyy-MM-ddTHH:mmz", "yyyy-MM-ddTHH:mm", "ddd, MMM dd, yyyy H:mm:ss tt", "ddd MMM d yyyy HH:mm:ss zzz", "MMddyyyy", "ddMMyyyy", "Mddyyyy", "ddMyyyy", "Mdyyyy", "dMyyyy", "yyyy", "Mdyy", "dMyy", "d" ]); // starting rule for general purpose grammar g._start = _.process(_.set([ g.date, g.time, g.expression ], g.generalDelimiter, g.whiteSpace), t.finish); // real starting rule: tries selected formats first, // then general purpose rule g.start = function (s) { try { var r = g._formats.call({}, s); if (r[1].length === 0) { return r; } } catch (e) {} return g._start.call({}, s); }; /** * @desc Converts the specified string value into its JavaScript Date equivalent using CultureInfo specific format information. * * Example
    
    	///////////
    	// Dates //
    	///////////
    
    	// 15-Oct-2004
    	var d1 = Date.parse("10/15/2004");
    
    	// 15-Oct-2004
    	var d1 = Date.parse("15-Oct-2004");
    
    	// 15-Oct-2004
    	var d1 = Date.parse("2004.10.15");
    
    	//Fri Oct 15, 2004
    	var d1 = Date.parse("Fri Oct 15, 2004");
    
    	///////////
    	// Times //
    	///////////
    
    	// Today at 10 PM.
    	var d1 = Date.parse("10 PM");
    
    	// Today at 10:30 PM.
    	var d1 = Date.parse("10:30 P.M.");
    
    	// Today at 6 AM.
    	var d1 = Date.parse("06am");
    
    	/////////////////////
    	// Dates and Times //
    	/////////////////////
    
    	// 8-July-2004 @ 10:30 PM
    	var d1 = Date.parse("July 8th, 2004, 10:30 PM");
    
    	// 1-July-2004 @ 10:30 PM
    	var d1 = Date.parse("2004-07-01T22:30:00");
    
    	////////////////////
    	// Relative Dates //
    	////////////////////
    
    	// Returns today's date. The string "today" is culture specific.
    	var d1 = Date.parse("today");
    
    	// Returns yesterday's date. The string "yesterday" is culture specific.
    	var d1 = Date.parse("yesterday");
    
    	// Returns the date of the next thursday.
    	var d1 = Date.parse("Next thursday");
    
    	// Returns the date of the most previous monday.
    	var d1 = Date.parse("last monday");
    
    	// Returns today's day + one year.
    	var d1 = Date.parse("next year");
    
    	///////////////
    	// Date Math //
    	///////////////
    
    	// Today + 2 days
    	var d1 = Date.parse("t+2");
    
    	// Today + 2 days
    	var d1 = Date.parse("today + 2 days");
    
    	// Today + 3 months
    	var d1 = Date.parse("t+3m");
    
    	// Today - 1 year
    	var d1 = Date.parse("today - 1 year");
    
    	// Today - 1 year
    	var d1 = Date.parse("t-1y"); 
    
    
    	/////////////////////////////
    	// Partial Dates and Times //
    	/////////////////////////////
    
    	// July 15th of this year.
    	var d1 = Date.parse("July 15");
    
    	// 15th day of current day and year.
    	var d1 = Date.parse("15");
    
    	// July 1st of current year at 10pm.
    	var d1 = Date.parse("7/1 10pm");
    	
    * * @param {String} The string value to convert into a Date object [Required] * @return {Date} A Date object or null if the string cannot be converted into a Date. */ function parse (s) { var ords, d, t, r = null; if (!s) { return null; } if (s instanceof Date) { return s.clone(); } if (s.length >= 4 && s.charAt(0) !== "0" && s.charAt(0) !== "+"&& s.charAt(0) !== "-") { // ie: 2004 will pass, 0800 won't. // Start with specific formats d = $D.Parsing.ISO.parse(s) || $D.Parsing.Numeric.parse(s); } if (d instanceof Date && !isNaN(d.getTime())) { return d; } else { // find ordinal dates (1st, 3rd, 8th, etc and remove them as they cause parsing issues) ords = s.match(/\b(\d+)(?:st|nd|rd|th)\b/); // find ordinal matches s = ((ords && ords.length === 2) ? s.replace(ords[0], ords[1]) : s); s = $D.Parsing.Normalizer.parse(s); try { r = $D.Grammar.start.call({}, s.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1")); } catch (e) { return null; } d = ((r[1].length === 0) ? r[0] : null); if (d !== null) { return d; } else { try { // ok we haven't parsed it, last ditch attempt with the built-in parser. t = Date._parse(s); return (t || t === 0) ? new Date(t) : null; } catch (e) { return null; } } } } if (!$D._parse) { $D._parse = $D.parse; } $D.parse = parse; Date.getParseFunction = function (fx) { var fns = Date.Grammar.allformats(fx); return function (s) { var r = null; for (var i = 0; i < fns.length; i++) { try { r = fns[i].call({}, s); } catch (e) { continue; } if (r[1].length === 0) { return r[0]; } } return null; }; }; /** * Converts the specified string value into its JavaScript Date equivalent using the specified format {String} or formats {Array} and the CultureInfo specific format information. * The format of the string value must match one of the supplied formats exactly. * * Example
    
    	// 15-Oct-2004
    	var d1 = Date.parseExact("10/15/2004", "M/d/yyyy");
    
    	// 15-Oct-2004
    	var d1 = Date.parse("15-Oct-2004", "M-ddd-yyyy");
    
    	// 15-Oct-2004
    	var d1 = Date.parse("2004.10.15", "yyyy.MM.dd");
    
    	// Multiple formats
    	var d1 = Date.parseExact("10/15/2004", ["M/d/yyyy", "MMMM d, yyyy"]);
    	
    * * @param {String} The string value to convert into a Date object [Required]. * @param {Object} The expected format {String} or an array of expected formats {Array} of the date string [Required]. * @return {Date} A Date object or null if the string cannot be converted into a Date. */ $D.parseExact = function (s, fx) { return $D.getParseFunction(fx)(s); }; }()); /************************************************************* * SugarPak - Domain Specific Language - Syntactical Sugar * *************************************************************/ (function () { var $D = Date, $P = $D.prototype, $N = Number.prototype; // private $P._orient = +1; // private $P._nth = null; // private $P._is = false; // private $P._same = false; // private $P._isSecond = false; // private $N._dateElement = "days"; /** * Moves the date to the next instance of a date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()). * Example
    
    	Date.today().next().friday();
    	Date.today().next().fri();
    	Date.today().next().march();
    	Date.today().next().mar();
    	Date.today().next().week();
    	
    * * @return {Date} date */ $P.next = function () { this._move = true; this._orient = +1; return this; }; /** * Creates a new Date (Date.today()) and moves the date to the next instance of the date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()). * Example
    
    	Date.next().friday();
    	Date.next().fri();
    	Date.next().march();
    	Date.next().mar();
    	Date.next().week();
    	
    * * @return {Date} date */ $D.next = function () { return $D.today().next(); }; /** * Moves the date to the previous instance of a date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()). * Example
    
    	Date.today().last().friday();
    	Date.today().last().fri();
    	Date.today().last().march();
    	Date.today().last().mar();
    	Date.today().last().week();
    	
    * * @return {Date} date */ $P.last = $P.prev = $P.previous = function () { this._move = true; this._orient = -1; return this; }; /** * Creates a new Date (Date.today()) and moves the date to the previous instance of the date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()). * Example
    
    	Date.last().friday();
    	Date.last().fri();
    	Date.previous().march();
    	Date.prev().mar();
    	Date.last().week();
    	
    * * @return {Date} date */ $D.last = $D.prev = $D.previous = function () { return $D.today().last(); }; /** * Performs a equality check when followed by either a month name, day name or .weekday() function. * Example
    
    	Date.today().is().friday(); // true|false
    	Date.today().is().fri();
    	Date.today().is().march();
    	Date.today().is().mar();
    	
    * * @return {Boolean} true|false */ $P.is = function () { this._is = true; return this; }; /** * Determines if two date objects occur on/in exactly the same instance of the subsequent date part function. * The function .same() must be followed by a date part function (example: .day(), .month(), .year(), etc). * * An optional Date can be passed in the date part function. If now date is passed as a parameter, 'Now' is used. * * The following example demonstrates how to determine if two dates fall on the exact same day. * * Example
    
    	var d1 = Date.today(); // today at 00:00
    	var d2 = new Date();   // exactly now.
    
    	// Do they occur on the same day?
    	d1.same().day(d2); // true
    	
    	 // Do they occur on the same hour?
    	d1.same().hour(d2); // false, unless d2 hour is '00' (midnight).
    	
    	// What if it's the same day, but one year apart?
    	var nextYear = Date.today().add(1).year();
    
    	d1.same().day(nextYear); // false, because the dates must occur on the exact same day. 
    	
    * * Scenario: Determine if a given date occurs during some week period 2 months from now. * * Example
    
    	var future = Date.today().add(2).months();
    	return someDate.same().week(future); // true|false;
    	
    * * @return {Boolean} true|false */ $P.same = function () { this._same = true; this._isSecond = false; return this; }; /** * Determines if the current date/time occurs during Today. Must be preceded by the .is() function. * Example
    
    	someDate.is().today();    // true|false
    	new Date().is().today();  // true
    	Date.today().is().today();// true
    	Date.today().add(-1).day().is().today(); // false
    	
    * * @return {Boolean} true|false */ $P.today = function () { return this.same().day(); }; /** * Determines if the current date is a weekday. This function must be preceded by the .is() function. * Example
    
    	Date.today().is().weekday(); // true|false
    	
    * * @return {Boolean} true|false */ $P.weekday = function () { if (this._nth) { return df("Weekday").call(this); } if (this._move) { return this.addWeekdays(this._orient); } if (this._is) { this._is = false; return (!this.is().sat() && !this.is().sun()); } return false; }; /** * Determines if the current date is on the weekend. This function must be preceded by the .is() function. * Example
    
    	Date.today().is().weekend(); // true|false
    	
    * * @return {Boolean} true|false */ $P.weekend = function () { if (this._is) { this._is = false; return (this.is().sat() || this.is().sun()); } return false; }; /** * Sets the Time of the current Date instance. A string "6:15 pm" or config object {hour:18, minute:15} are accepted. * Example
    
    	// Set time to 6:15pm with a String
    	Date.today().at("6:15pm");
    
    	// Set time to 6:15pm with a config object
    	Date.today().at({hour:18, minute:15});
    	
    * * @return {Date} date */ $P.at = function (time) { return (typeof time === "string") ? $D.parse(this.toString("d") + " " + time) : this.set(time); }; /** * Creates a new Date() and adds this (Number) to the date based on the preceding date element function (eg. second|minute|hour|day|month|year). * Example
    
    	// Undeclared Numbers must be wrapped with parentheses. Requirment of JavaScript.
    	(3).days().fromNow();
    	(6).months().fromNow();
    
    	// Declared Number variables do not require parentheses. 
    	var n = 6;
    	n.months().fromNow();
    	
    * * @return {Date} A new Date instance */ $N.fromNow = $N.after = function (date) { var c = {}; c[this._dateElement] = this; return ((!date) ? new Date() : date.clone()).add(c); }; /** * Creates a new Date() and subtract this (Number) from the date based on the preceding date element function (eg. second|minute|hour|day|month|year). * Example
    
    	// Undeclared Numbers must be wrapped with parentheses. Requirment of JavaScript.
    	(3).days().ago();
    	(6).months().ago();
    
    	// Declared Number variables do not require parentheses. 
    	var n = 6;
    	n.months().ago();
    	
    * * @return {Date} A new Date instance */ $N.ago = $N.before = function (date) { var c = {}, s = (this._dateElement[this._dateElement.length-1] !== "s") ? this._dateElement + "s" : this._dateElement; c[s] = this * -1; return ((!date) ? new Date() : date.clone()).add(c); }; // Do NOT modify the following string tokens. These tokens are used to build dynamic functions. // All culture-specific strings can be found in the CultureInfo files. var dx = ("sunday monday tuesday wednesday thursday friday saturday").split(/\s/), mx = ("january february march april may june july august september october november december").split(/\s/), px = ("Millisecond Second Minute Hour Day Week Month Year Quarter Weekday").split(/\s/), pxf = ("Milliseconds Seconds Minutes Hours Date Week Month FullYear Quarter").split(/\s/), nth = ("final first second third fourth fifth").split(/\s/), de; /** * Returns an object literal of all the date parts. * Example
    
    	var o = new Date().toObject();
    	
    	// { year: 2008, month: 4, week: 20, day: 13, hour: 18, minute: 9, second: 32, millisecond: 812 }
    	
    	// The object properties can be referenced directly from the object.
    	
    	alert(o.day);  // alerts "13"
    	alert(o.year); // alerts "2008"
    	
    * * @return {Date} An object literal representing the original date object. */ $P.toObject = function () { var o = {}; for (var i = 0; i < px.length; i++) { if (this["get" + pxf[i]]) { o[px[i].toLowerCase()] = this["get" + pxf[i]](); } } return o; }; /** * Returns a date created from an object literal. Ignores the .week property if set in the config. * Example
    
    	var o = new Date().toObject();
    	
    	return Date.fromObject(o); // will return the same date. 
    
    	var o2 = {month: 1, day: 20, hour: 18}; // birthday party!
    	Date.fromObject(o2);
    	
    * * @return {Date} An object literal representing the original date object. */ $D.fromObject = function(config) { config.week = null; return Date.today().set(config); }; // Create day name functions and abbreviated day name functions (eg. monday(), friday(), fri()). var df = function (n) { return function () { if (this._is) { this._is = false; return this.getDay() === n; } if (this._move) { this._move = null; } if (this._nth !== null) { // If the .second() function was called earlier, remove the _orient // from the date, and then continue. // This is required because 'second' can be used in two different context. // // Example // // Date.today().add(1).second(); // Date.march().second().monday(); // // Things get crazy with the following... // Date.march().add(1).second().second().monday(); // but it works!! // if (this._isSecond) { this.addSeconds(this._orient * -1); } // make sure we reset _isSecond this._isSecond = false; var ntemp = this._nth; this._nth = null; var temp = this.clone().moveToLastDayOfMonth(); this.moveToNthOccurrence(n, ntemp); if (this > temp) { throw new RangeError($D.getDayName(n) + " does not occur " + ntemp + " times in the month of " + $D.getMonthName(temp.getMonth()) + " " + temp.getFullYear() + "."); } return this; } return this.moveToDayOfWeek(n, this._orient); }; }; var sdf = function (n) { return function () { var t = $D.today(), shift = n - t.getDay(); if (n === 0 && Date.CultureInfo.firstDayOfWeek === 1 && t.getDay() !== 0) { shift = shift + 7; } return t.addDays(shift); }; }; for (var i = 0; i < dx.length; i++) { // Create constant static Day Name variables. Example: Date.MONDAY or Date.MON $D[dx[i].toUpperCase()] = $D[dx[i].toUpperCase().substring(0, 3)] = i; // Create Day Name functions. Example: Date.monday() or Date.mon() $D[dx[i]] = $D[dx[i].substring(0, 3)] = sdf(i); // Create Day Name instance functions. Example: Date.today().next().monday() $P[dx[i]] = $P[dx[i].substring(0, 3)] = df(i); } // Create month name functions and abbreviated month name functions (eg. january(), march(), mar()). var month_instance_functions = function (n) { return function () { if (this._is) { this._is = false; return this.getMonth() === n; } return this.moveToMonth(n, this._orient); }; }; var month_static_functions = function (n) { return function () { return $D.today().set({ month: n, day: 1 }); }; }; for (var j = 0; j < mx.length; j++) { // Create constant static Month Name variables. Example: Date.MARCH or Date.MAR $D[mx[j].toUpperCase()] = $D[mx[j].toUpperCase().substring(0, 3)] = j; // Create Month Name functions. Example: Date.march() or Date.mar() $D[mx[j]] = $D[mx[j].substring(0, 3)] = month_static_functions(j); // Create Month Name instance functions. Example: Date.today().next().march() $P[mx[j]] = $P[mx[j].substring(0, 3)] = month_instance_functions(j); } // Create date element functions and plural date element functions used with Date (eg. day(), days(), months()). var ef = function (j) { return function () { // if the .second() function was called earlier, the _orient // has alread been added. Just return this and reset _isSecond. if (this._isSecond) { this._isSecond = false; return this; } if (this._same) { this._same = this._is = false; var o1 = this.toObject(), o2 = (arguments[0] || new Date()).toObject(), v = "", k = j.toLowerCase(); // the substr trick with -1 doesn't work in IE8 or less k = (k[k.length-1] === "s") ? k.substring(0,k.length-1) : k; for (var m = (px.length - 1); m > -1; m--) { v = px[m].toLowerCase(); if (o1[v] !== o2[v]) { return false; } if (k === v) { break; } } return true; } if (j.substring(j.length - 1) !== "s") { j += "s"; } if (this._move) { this._move = null; } return this["add" + j](this._orient); }; }; var nf = function (n) { return function () { this._dateElement = n; return this; }; }; for (var k = 0; k < px.length; k++) { de = px[k].toLowerCase(); if(de !== "weekday") { // Create date element functions and plural date element functions used with Date (eg. day(), days(), months()). $P[de] = $P[de + "s"] = ef(px[k]); // Create date element functions and plural date element functions used with Number (eg. day(), days(), months()). $N[de] = $N[de + "s"] = nf(de + "s"); } } $P._ss = ef("Second"); var nthfn = function (n) { return function (dayOfWeek) { if (this._same) { return this._ss(arguments[0]); } if (dayOfWeek || dayOfWeek === 0) { return this.moveToNthOccurrence(dayOfWeek, n); } this._nth = n; // if the operator is 'second' add the _orient, then deal with it later... if (n === 2 && (dayOfWeek === undefined || dayOfWeek === null)) { this._isSecond = true; return this.addSeconds(this._orient); } return this; }; }; for (var l = 0; l < nth.length; l++) { $P[nth[l]] = (l === 0) ? nthfn(-1) : nthfn(l); } }()); (function () { var $D = Date, $P = $D.prototype, // $C = $D.CultureInfo, // not used atm $f = [], p = function (s, l) { if (!l) { l = 2; } return ("000" + s).slice(l * -1); }; /** * Converts a PHP format string to Java/.NET format string. * A PHP format string can be used with .$format or .format. * A Java/.NET format string can be used with .toString(). * The .parseExact function will only accept a Java/.NET format string * * Example
    	 var f1 = "%m/%d/%y"
    	 var f2 = Date.normalizeFormat(f1); // "MM/dd/yy"
    
    	 new Date().format(f1);    // "04/13/08"
    	 new Date().$format(f1);   // "04/13/08"
    	 new Date().toString(f2);  // "04/13/08"
    
    	 var date = Date.parseExact("04/13/08", f2); // Sun Apr 13 2008
    	 
    * @param {String} A PHP format string consisting of one or more format spcifiers. * @return {String} The PHP format converted to a Java/.NET format string. */ $D.normalizeFormat = function (format) { // function does nothing atm // $f = []; // var t = new Date().$format(format); // return $f.join(""); return format; }; /** * Format a local Unix timestamp according to locale settings * * Example
    	 Date.strftime("%m/%d/%y", new Date());       // "04/13/08"
    	 Date.strftime("c", "2008-04-13T17:52:03Z");  // "04/13/08"
    	 
    * @param {String} A format string consisting of one or more format spcifiers [Optional]. * @param {Number} The number representing the number of seconds that have elapsed since January 1, 1970 (local time). * @return {String} A string representation of the current Date object. */ $D.strftime = function (format, time) { return new Date(time * 1000).$format(format); }; /** * Parse any textual datetime description into a Unix timestamp. * A Unix timestamp is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT). * * Example
    	 Date.strtotime("04/13/08");              // 1208044800
    	 Date.strtotime("1970-01-01T00:00:00Z");  // 0
    	 
    * @param {String} A format string consisting of one or more format spcifiers [Optional]. * @param {Object} A string or date object. * @return {String} A string representation of the current Date object. */ $D.strtotime = function (time) { var d = $D.parse(time); d.addMinutes(d.getTimezoneOffset() * -1); return Math.round($D.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds()) / 1000); }; /** * Converts the value of the current Date object to its equivalent string representation using a PHP/Unix style of date format specifiers. * * The following descriptions are from http://www.php.net/strftime and http://www.php.net/manual/en/function.date.php. * Copyright � 2001-2008 The PHP Group * * Format Specifiers
    	Format  Description                                                                  Example
    	------  ---------------------------------------------------------------------------  -----------------------
    	 %a     abbreviated weekday name according to the current localed                    "Mon" through "Sun"
    	 %A     full weekday name according to the current locale                            "Sunday" through "Saturday"
    	 %b     abbreviated month name according to the current locale                       "Jan" through "Dec"
    	 %B     full month name according to the current locale                              "January" through "December"
    	 %c     preferred date and time representation for the current locale                "4/13/2008 12:33 PM"
    	 %C     century number (the year divided by 100 and truncated to an integer)         "00" to "99"
    	 %d     day of the month as a decimal number                                         "01" to "31"
    	 %D     same as %m/%d/%y                                                             "04/13/08"
    	 %e     day of the month as a decimal number, a single digit is preceded by a space  "1" to "31"
    	 %g     like %G, but without the century                                             "08"
    	 %G     The 4-digit year corresponding to the ISO week number (see %V).              "2008"
    			This has the same format and value as %Y, except that if the ISO week number 
    			belongs to the previous or next year, that year is used instead.
    	 %h     same as %b                                                                   "Jan" through "Dec"
    	 %H     hour as a decimal number using a 24-hour clock                               "00" to "23"
    	 %I     hour as a decimal number using a 12-hour clock                               "01" to "12"
    	 %j     day of the year as a decimal number                                          "001" to "366"
    	 %m     month as a decimal number                                                    "01" to "12"
    	 %M     minute as a decimal number                                                   "00" to "59"
    	 %n     newline character                                                            "\n"
    	 %p     either "am" or "pm" according to the given time value, or the                "am" or "pm"
    			corresponding strings for the current locale
    	 %r     time in a.m. and p.m. notation                                               "8:44 PM"
    	 %R     time in 24 hour notation                                                     "20:44"
    	 %S     second as a decimal number                                                   "00" to "59"
    	 %t     tab character                                                                "\t"
    	 %T     current time, equal to %H:%M:%S                                              "12:49:11"
    	 %u     weekday as a decimal number ["1", "7"], with "1" representing Monday         "1" to "7"
    	 %U     week number of the current year as a decimal number, starting with the       "0" to ("52" or "53")
    			first Sunday as the first day of the first week
    	 %V     The ISO 8601:1988 week number of the current year as a decimal number,       "00" to ("52" or "53")
    			range 01 to 53, where week 1 is the first week that has at least 4 days 
    			in the current year, and with Monday as the first day of the week. 
    			(Use %G or %g for the year component that corresponds to the week number 
    			for the specified timestamp.)
    	 %W     week number of the current year as a decimal number, starting with the       "00" to ("52" or "53")
    			first Monday as the first day of the first week
    	 %w     day of the week as a decimal, Sunday being "0"                               "0" to "6"
    	 %x     preferred date representation for the current locale without the time        "4/13/2008"
    	 %X     preferred time representation for the current locale without the date        "12:53:05"
    	 %y     year as a decimal number without a century                                   "00" "99"
    	 %Y     year as a decimal number including the century                               "2008"
    	 %Z     time zone or name or abbreviation                                            "UTC", "EST", "PST"
    	 %z     same as %Z 
    	 %%     a literal "%" character                                                      "%"
    	 d      Day of the month, 2 digits with leading zeros                                "01" to "31"
    	 D      A textual representation of a day, three letters                             "Mon" through "Sun"
    	 j      Day of the month without leading zeros                                       "1" to "31"
    	 l      A full textual representation of the day of the week (lowercase "L")         "Sunday" through "Saturday"
    	 N      ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0)  "1" (for Monday) through "7" (for Sunday)
    	 S      English ordinal suffix for the day of the month, 2 characters                "st", "nd", "rd" or "th". Works well with j
    	 w      Numeric representation of the day of the week                                "0" (for Sunday) through "6" (for Saturday)
    	 z      The day of the year (starting from "0")                                      "0" through "365"      
    	 W      ISO-8601 week number of year, weeks starting on Monday                       "00" to ("52" or "53")
    	 F      A full textual representation of a month, such as January or March           "January" through "December"
    	 m      Numeric representation of a month, with leading zeros                        "01" through "12"
    	 M      A short textual representation of a month, three letters                     "Jan" through "Dec"
    	 n      Numeric representation of a month, without leading zeros                     "1" through "12"
    	 t      Number of days in the given month                                            "28" through "31"
    	 L      Whether it's a leap year                                                     "1" if it is a leap year, "0" otherwise
    	 o      ISO-8601 year number. This has the same value as Y, except that if the       "2008"
    			ISO week number (W) belongs to the previous or next year, that year 
    			is used instead.
    	 Y      A full numeric representation of a year, 4 digits                            "2008"
    	 y      A two digit representation of a year                                         "08"
    	 a      Lowercase Ante meridiem and Post meridiem                                    "am" or "pm"
    	 A      Uppercase Ante meridiem and Post meridiem                                    "AM" or "PM"
    	 B      Swatch Internet time                                                         "000" through "999"
    	 g      12-hour format of an hour without leading zeros                              "1" through "12"
    	 G      24-hour format of an hour without leading zeros                              "0" through "23"
    	 h      12-hour format of an hour with leading zeros                                 "01" through "12"
    	 H      24-hour format of an hour with leading zeros                                 "00" through "23"
    	 i      Minutes with leading zeros                                                   "00" to "59"
    	 s      Seconds, with leading zeros                                                  "00" through "59"
    	 u      Milliseconds                                                                 "54321"
    	 e      Timezone identifier                                                          "UTC", "EST", "PST"
    	 I      Whether or not the date is in daylight saving time (uppercase i)             "1" if Daylight Saving Time, "0" otherwise
    	 O      Difference to Greenwich time (GMT) in hours                                  "+0200", "-0600"
    	 P      Difference to Greenwich time (GMT) with colon between hours and minutes      "+02:00", "-06:00"
    	 T      Timezone abbreviation                                                        "UTC", "EST", "PST"
    	 Z      Timezone offset in seconds. The offset for timezones west of UTC is          "-43200" through "50400"
    			always negative, and for those east of UTC is always positive.
    	 c      ISO 8601 date                                                                "2004-02-12T15:19:21+00:00"
    	 r      RFC 2822 formatted date                                                      "Thu, 21 Dec 2000 16:01:07 +0200"
    	 U      Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)                   "0"     
    	 
    * @param {String} A format string consisting of one or more format spcifiers [Optional]. * @return {String} A string representation of the current Date object. */ $P.$format = function (format) { var x = this, y, t = function (v, overrideStandardFormats) { $f.push(v); return x.toString(v, overrideStandardFormats); }; return format ? format.replace(/(%|\\)?.|%%/g, function (m) { if (m.charAt(0) === "\\" || m.substring(0, 2) === "%%") { return m.replace("\\", "").replace("%%", "%"); } switch (m) { case "d": case "%d": return t("dd"); case "D": case "%a": return t("ddd"); case "j": case "%e": return t("d", true); case "l": case "%A": return t("dddd"); case "N": case "%u": return x.getDay() + 1; case "S": return t("S"); case "w": case "%w": return x.getDay(); case "z": return x.getOrdinalNumber(); case "%j": return p(x.getOrdinalNumber(), 3); case "%U": var d1 = x.clone().set({month: 0, day: 1}).addDays(-1).moveToDayOfWeek(0), d2 = x.clone().addDays(1).moveToDayOfWeek(0, -1); return (d2 < d1) ? "00" : p((d2.getOrdinalNumber() - d1.getOrdinalNumber()) / 7 + 1); case "W": case "%V": return x.getISOWeek(); case "%W": return p(x.getWeek()); case "F": case "%B": return t("MMMM"); case "m": case "%m": return t("MM"); case "M": case "%b": case "%h": return t("MMM"); case "n": return t("M"); case "t": return $D.getDaysInMonth(x.getFullYear(), x.getMonth()); case "L": return ($D.isLeapYear(x.getFullYear())) ? 1 : 0; case "o": case "%G": return x.setWeek(x.getISOWeek()).toString("yyyy"); case "%g": return x.$format("%G").slice(-2); case "Y": case "%Y": return t("yyyy"); case "y": case "%y": return t("yy"); case "a": case "%p": return t("tt").toLowerCase(); case "A": return t("tt").toUpperCase(); case "g": case "%I": return t("h"); case "G": return t("H"); case "h": return t("hh"); case "H": case "%H": return t("HH"); case "i": case "%M": return t("mm"); case "s": case "%S": return t("ss"); case "u": return p(x.getMilliseconds(), 3); case "I": return (x.isDaylightSavingTime()) ? 1 : 0; case "O": return x.getUTCOffset(); case "P": y = x.getUTCOffset(); return y.substring(0, y.length - 2) + ":" + y.substring(y.length - 2); case "e": case "T": case "%z": case "%Z": return x.getTimezone(); case "Z": return x.getTimezoneOffset() * -60; case "B": var now = new Date(); return Math.floor(((now.getHours() * 3600) + (now.getMinutes() * 60) + now.getSeconds() + (now.getTimezoneOffset() + 60) * 60) / 86.4); case "c": return x.toISOString().replace(/\"/g, ""); case "U": return $D.strtotime("now"); case "%c": return t("d") + " " + t("t"); case "%C": return Math.floor(x.getFullYear() / 100 + 1); case "%D": return t("MM/dd/yy"); case "%n": return "\\n"; case "%t": return "\\t"; case "%r": return t("hh:mm tt"); case "%R": return t("H:mm"); case "%T": return t("H:mm:ss"); case "%x": return t("d"); case "%X": return t("t"); default: $f.push(m); return m; } }) : this._toString(); }; if (!$P.format) { $P.format = $P.$format; } }()); /* * TimeSpan(milliseconds); * TimeSpan(days, hours, minutes, seconds); * TimeSpan(days, hours, minutes, seconds, milliseconds); */ var TimeSpan = function (days, hours, minutes, seconds, milliseconds) { var attrs = "days hours minutes seconds milliseconds".split(/\s+/); var gFn = function (attr) { return function () { return this[attr]; }; }; var sFn = function (attr) { return function (val) { this[attr] = val; return this; }; }; for (var i = 0; i < attrs.length ; i++) { var $a = attrs[i], $b = $a.slice(0, 1).toUpperCase() + $a.slice(1); TimeSpan.prototype[$a] = 0; TimeSpan.prototype["get" + $b] = gFn($a); TimeSpan.prototype["set" + $b] = sFn($a); } if (arguments.length === 4) { this.setDays(days); this.setHours(hours); this.setMinutes(minutes); this.setSeconds(seconds); } else if (arguments.length === 5) { this.setDays(days); this.setHours(hours); this.setMinutes(minutes); this.setSeconds(seconds); this.setMilliseconds(milliseconds); } else if (arguments.length === 1 && typeof days === "number") { var orient = (days < 0) ? -1 : +1; this.setMilliseconds(Math.abs(days)); this.setDays(Math.floor(this.getMilliseconds() / 86400000) * orient); this.setMilliseconds(this.getMilliseconds() % 86400000); this.setHours(Math.floor(this.getMilliseconds() / 3600000) * orient); this.setMilliseconds(this.getMilliseconds() % 3600000); this.setMinutes(Math.floor(this.getMilliseconds() / 60000) * orient); this.setMilliseconds(this.getMilliseconds() % 60000); this.setSeconds(Math.floor(this.getMilliseconds() / 1000) * orient); this.setMilliseconds(this.getMilliseconds() % 1000); this.setMilliseconds(this.getMilliseconds() * orient); } this.getTotalMilliseconds = function () { return (this.getDays() * 86400000) + (this.getHours() * 3600000) + (this.getMinutes() * 60000) + (this.getSeconds() * 1000); }; this.compareTo = function (time) { var t1 = new Date(1970, 1, 1, this.getHours(), this.getMinutes(), this.getSeconds()), t2; if (time === null) { t2 = new Date(1970, 1, 1, 0, 0, 0); } else { t2 = new Date(1970, 1, 1, time.getHours(), time.getMinutes(), time.getSeconds()); } return (t1 < t2) ? -1 : (t1 > t2) ? 1 : 0; }; this.equals = function (time) { return (this.compareTo(time) === 0); }; this.add = function (time) { return (time === null) ? this : this.addSeconds(time.getTotalMilliseconds() / 1000); }; this.subtract = function (time) { return (time === null) ? this : this.addSeconds(-time.getTotalMilliseconds() / 1000); }; this.addDays = function (n) { return new TimeSpan(this.getTotalMilliseconds() + (n * 86400000)); }; this.addHours = function (n) { return new TimeSpan(this.getTotalMilliseconds() + (n * 3600000)); }; this.addMinutes = function (n) { return new TimeSpan(this.getTotalMilliseconds() + (n * 60000)); }; this.addSeconds = function (n) { return new TimeSpan(this.getTotalMilliseconds() + (n * 1000)); }; this.addMilliseconds = function (n) { return new TimeSpan(this.getTotalMilliseconds() + n); }; this.get12HourHour = function () { return (this.getHours() > 12) ? this.getHours() - 12 : (this.getHours() === 0) ? 12 : this.getHours(); }; this.getDesignator = function () { return (this.getHours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator; }; this.toString = function (format) { this._toString = function () { if (this.getDays() !== null && this.getDays() > 0) { return this.getDays() + "." + this.getHours() + ":" + this.p(this.getMinutes()) + ":" + this.p(this.getSeconds()); } else { return this.getHours() + ":" + this.p(this.getMinutes()) + ":" + this.p(this.getSeconds()); } }; this.p = function (s) { return (s.toString().length < 2) ? "0" + s : s; }; var me = this; return format ? format.replace(/dd?|HH?|hh?|mm?|ss?|tt?/g, function (format) { switch (format) { case "d": return me.getDays(); case "dd": return me.p(me.getDays()); case "H": return me.getHours(); case "HH": return me.p(me.getHours()); case "h": return me.get12HourHour(); case "hh": return me.p(me.get12HourHour()); case "m": return me.getMinutes(); case "mm": return me.p(me.getMinutes()); case "s": return me.getSeconds(); case "ss": return me.p(me.getSeconds()); case "t": return ((me.getHours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator).substring(0, 1); case "tt": return (me.getHours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator; } } ) : this._toString(); }; return this; }; /** * Gets the time of day for this date instances. * @return {TimeSpan} TimeSpan */ Date.prototype.getTimeOfDay = function () { return new TimeSpan(0, this.getHours(), this.getMinutes(), this.getSeconds(), this.getMilliseconds()); }; /* * TimePeriod(startDate, endDate); * TimePeriod(years, months, days, hours, minutes, seconds, milliseconds); */ var TimePeriod = function (years, months, days, hours, minutes, seconds, milliseconds) { var attrs = "years months days hours minutes seconds milliseconds".split(/\s+/); var gFn = function (attr) { return function () { return this[attr]; }; }; var sFn = function (attr) { return function (val) { this[attr] = val; return this; }; }; for (var i = 0; i < attrs.length ; i++) { var $a = attrs[i], $b = $a.slice(0, 1).toUpperCase() + $a.slice(1); TimePeriod.prototype[$a] = 0; TimePeriod.prototype["get" + $b] = gFn($a); TimePeriod.prototype["set" + $b] = sFn($a); } if (arguments.length === 7) { this.years = years; this.months = months; this.setDays(days); this.setHours(hours); this.setMinutes(minutes); this.setSeconds(seconds); this.setMilliseconds(milliseconds); } else if (arguments.length === 2 && arguments[0] instanceof Date && arguments[1] instanceof Date) { // startDate and endDate as arguments var d1 = years.clone(); var d2 = months.clone(); var temp = d1.clone(); var orient = (d1 > d2) ? -1 : +1; this.years = d2.getFullYear() - d1.getFullYear(); temp.addYears(this.years); if (orient === +1) { if (temp > d2) { if (this.years !== 0) { this.years--; } } } else { if (temp < d2) { if (this.years !== 0) { this.years++; } } } d1.addYears(this.years); if (orient === +1) { while (d1 < d2 && d1.clone().addMonths(1) <= d2) { d1.addMonths(1); this.months++; } } else { while (d1 > d2 && d1.clone().addDays(-d1.getDaysInMonth()) > d2) { d1.addMonths(-1); this.months--; } } var diff = d2 - d1; if (diff !== 0) { var ts = new TimeSpan(diff); this.setDays(ts.getDays()); this.setHours(ts.getHours()); this.setMinutes(ts.getMinutes()); this.setSeconds(ts.getSeconds()); this.setMilliseconds(ts.getMilliseconds()); } } return this; };SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/PaxHeaders/knockout.mapping_2.4.1.0000644000000000000000000000007414336451277030256 xustar0030 atime=1717049223.957365375 30 ctime=1717049223.957365375 SABnzbd-4.3.2/interfaces/Glitter/templates/static/javascripts/src/knockout.mapping_2.4.1.js0000644000000000000000000006464514336451277031545 0ustar00rootroot00000000000000/// Knockout Mapping plugin v2.4.1 /// (c) 2013 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/ /// License: MIT (http://www.opensource.org/licenses/mit-license.php) (function (factory) { // Module systems magic dance. if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { // CommonJS or Node: hard-coded dependency on "knockout" factory(require("knockout"), exports); } else if (typeof define === "function" && define["amd"]) { // AMD anonymous module with hard-coded dependency on "knockout" define(["knockout", "exports"], factory); } else { //

    ܨ>Zn|2@!JpXdwd~9 )=lc,~fb)> Oß[zR0#ZzZn %73OsOπ[gctٛų >=/w w2m1Nj hBMS꣰)# &-7 y?n#h,Dt'Egsit䎡Q샢Rq-+_:HER_ٛLR FT9 8(UqE? vWK? {4uF&6 _3I4@J_rk-I9ҺVf"na.tOU+.~7e&P77ItvLvFPӶ]; F T!gA?H?Ft4ba:^#Uƕ7PQU" AX3͔W/!f쭔_oXvQ@ТSp(+wǂȵӓJ<+/BGN52/"o/t5U[{x2(v;yq" ,+vr{ pǚ!hwQPefh> :eAb}:H _ ' gnG39pX.Ijrqn~Dz.B=)>,NoFD ˮ٥ \ L@ 5-7NNPE#8,LXX9b:(Gy7bHyIR!¢*EE /(jc5zSݹ]B,6NE-^s[;;.;]:k'~!hFi3LRF xpR.H(hbR&DYA_;OQ˺'1䃠wza|0X֍DdMBkոW)K>dHZYSlBE6;;Hl6~Gr=;DGp2<=OA^j951~Yү2Gp;-DnLEց1HwкyO&ez^a$,/yfY'?D,3!^:3!wu-P{x^g_ExEV< _9\vb`Jj;ddfB%tv= 5fH<5~^2 ̓=s t>T A^UTuvfg?wL7 bo @P0B_<3 ImD elNyLƧ9d]A/ ŷǫl*SWg~֠'ژv3Tlߚ UGz>8,j#}*oMQ=}m$6,?i. . prʌj!/]_y뺁sU Ȥsw]b^^D3?*&OO(r;ZMpW=tGcQ{ۮݑVۀ}וH{̤R %?{i.U+*EҘ #%12lثԘΨB_˪SqlXa<٤L(N&b:SS|+.V!-G2|Gye#\hyukfoXnx%d&Q 8s"sr( ٛW24qD# hXle~Щpsd#O^L?P*TweҸTaQP秉a36 qI9'k!FAj21OXj92%7H C F tnGn_׺l[8Y4TCmaHnxTY%<,9L<"X̎ii P1jMA E i}ʹT#6[볐 N~m)nTvD>æUhxxYҸd E*`Щ P M?mW@&S k1loc}M=σ/#Y1l !ףFy, FJmGkIfs(+KB\;ps_H(ھe-@S:RET[j)̮_W^ɰ+3Eޯh!1!<BZ0+ /,لo:J9KVБ<'0=],X`g@cx֕ H-U_<\{@H݂*f/u﷠ӓ]|%K>~UqS8cMW=Yk ]0OkHg?1)9D|.;Q471u%@tp[Mɚ+]-ARŬq4haE$FBcfp(]EB"e//9#;{Pcf mU3zLS`DV3d)3Ɩq-x qsrG:>iJ5S>@}-ۅU܊czzC64yZt#v5C+PN (1TyoCOPY}U?c!k7cԊ?zqÜn:9 )A@|tTF|bjtDhni1z*4ut}Aq)P2WMgMiFԲYS\6ьԚ8i/pCW d^TiN;xoZ) PA {?˲́" g/mUӲN gáս؅{fZ+YEgFVUawu$oBj'evȇD+ 7/]S; C …|"k\_g$[Wydvlfgd5ZᓒZfRY1Qa 'mzs7e22}iQ,IrX-=kW"]=Q2 ;;>'lBxxfi5u.H"_^.vt(3aFNVr ѩR@C71q+M3J#Gjj`U۟㧡Fm Q!gCcڇʟAPȏk .q-@%xW[y5jEAI@p.%>5E[ !WMͽT#en|x!ǝ|t=ƓxCS+VЈ;WpXB /f2z$Wƫh;Uz o߽: :P(OQBZ IUtGx!,,pOXt>Բ.J'}x58t nդ5=$Y:~{-k1ȠkܰFBx^T7 l׾6d&*'4pnĄDRl&iUkCgnur_ Aebq+G|#[ޡ{,G%|kA{uޢ`rN#ܿGh)mw2Y"{d+<0آAr}@N)X6إo{zcS;*?m7 i]_+o:KܿD:Iq A?a^ x CVm>?R.YMlAB:/2Ƈ>`xEaf^ anv)&q %@h2WG/{LݰB8;˘w;.8bl ]e%?&`qɖ1?AHRJkkex-HNзυion렲#v'.RnR5N8 5B C5xͬȎ[y? ef=%}=%22警 Ԃ[C> `VT(כixmإ=>aTz[i[6]@ @é'̀m`IOFvX0Jr0nӋL zH;`6UO%׳|NaOX k}h]CixD&e1\+DJwM>ҝM3$W~l?& p;?ލT *QccA$#.;:㩫c 戸CʇzےW15BNNGH1hNUoAI\=DA0*L՜¢O@Dap!=TQeywg@jV´MkrXps4< fb k߭C")or:(yW~Yݷ9nPQ(]3~ׂbxc" [6#:Iw"kƨ$;,55M)>J2U_?M_]R~JCtġ".PSA|yF 7UºbtPM=9FN+} u-[+T@-E2Ж5^ _ Q3uɟvS_(K{BW?R}dP Vt, )ۋv'D~^fg8"1GjɈ#}Bd E %cDοÊRGAۗG(NBr8viklڎqm*uL*=EwzbH~Yo@悜 C)&Lk OMoJf)c?us{ByS D;hA=@ATQk'qh "ٍld37LӛR2>5<7Wv'/[׋r ]AMT!p 倓zőW_qyL';v9Q+U94 =G8<(W$n͵ZwbmBT ȱ4`:3e+d+; (Zjݗs>ռqv?3}i.eLUF= ]ԋ1c&ҢA>BdԴoGH}Z30蓄"I iYeya?_mob~כfnv bf v(V{, gX3BsA_7/i@WpGA "f^0l1^oq˚8mx>%LWs&|`K)=-N[W[ƽqt1`:5pVFX߫sp (W}VLdqˎ680':$m(09|w\, ;>K` -ϐKlyrӂQۼ+5`CgI1JWZޏQejD[ }HD@:>D>% id'H,>%q]-S,oy!ƻ <ō;hҀ} <CwP(q\ BG ɥk9+^ՖHI3 4y?$;xY9mRtƗL 쨳C\8 [ag5ɩ|Ŋ; s*^bi7V! О`rE)ϼUD Dm׷2$}:^yaD V|ypo QM!"c$@hZ/P!ٓaU3&y"h Hb#)tPK!e&7+wݯYPH1}myfd 2f*QVV _R׏jd(|t@R7u#­(7#3ݟjH"nLip2kaдdvJgYi8;N0lʤl.sWԊ+[W%Я?F[_Av1pU$ۯ镢Xc+ wYT&%]F4momm,ƻ[mǑ]]#J>awr!_7uK4c_U𷴍 c *+k˱5^;+cڹ~Q2܄$iA6Dזr(/ DH1S*HR"W dDlSIef%oqL*qm|$Cs-R*t&kL!0%_t7Wj~D>㢯!8@NdcE3)f#q9lL/k`z9=#SGuWGLA&׉xZ#t H8uuKގ#e-@py#Y3įZaòFhG$٫!lE+K2 (HtF0>g'M6̀xX5E|UR  +us?i/~'Sb- 6ɡ~͛=p6I'VS15js+5A@|B&RM?@H@EV-Q8~ㇰ57 G]q(W~kUW^*NcS!O&KsYB=f :@M8ynJ$obh^ ~Vf@u96aUΠm0cPI͊3^51+^7pL2E'L}(3LRo$Ջ&c?&>m⠩P HѮhQ̔1"{mm~CkAt<\#:I964:]&rw:mno!+)y#B8N!C%H(Mܛz sV4/UkTޅ='M$$aٓ3TlzATg"DBxP6#ccYߋI; (_vw32|cۍ꿊c23wfh, 2N=uf*Yʐ^37VۂC}+ wB"@7\WŌ}IhW_nKG:siT.YfN=^8ccl" e}6lߩ&(O҆X@Ƈ>1'SҖ@x>4}A'H 7|ټz #чY#񻂋P|K7g$CLjʮǞ/3A|IU ,WAn2 =cQpišCuD% MWPI-/"?lB=*x}}/@+uHQ\NbM7W: ^Gڏx:1Y׶fOMtX{D>n]T~vf75;;}ONhOkΜ||ϟ2uVd6^unoAywʞ~ ѦNTfq7> q\o&M)2ShU+'ĊE#W0wGY UQX ^C0lʆHelc^ aͩpȚZC2|Ь^{t001_r+0%VDXO%:̫1MtNH^!ʄ @oc{Bab b' S'zoT;ň$422f;yC Ww_ܓ@'ZJB͘ ?Hݒ4ݟ{Z4|QɎ+YRrLmɰZ=6/Atav. vOn 3ODs/,lw? X6lKN=~fߗ=ƬzƐYxo1dREzݤOMK;2 Pu[.3=Su\EkH!! qhbH|WETs VS;WnKak:{Hv/0 ixK*{|H+q <}HȘʰ1W=r@0F3ˮCA /%NjD(?n}JW=^)߸22NExi!aAjx~"d~'-V<q rgonxX#uْ~:,᪛cd]ltR3#ƿ/zq*j[adJp\}:pgc@;Ȣ#X\cePov&Vl4ʘF0M(>(_| Sr᩿%rCġTy Y.y< cw1]Y\BlƘO 5 6: >6'(T9ï(^aGhZ0lnDܢWO&5K`R)yd&5!`T511hXxA_v]]v16~X:x\dC`h$E6< #KSE6z%ZOIf79ٸfadvtTC]+|4rx3p4%`ouy#y{,&b' adhR&xef'Z 1RT)% [?~Ifs.y!8,lHVCЎ`> 0i&]۱z<і9R {Ad>C:x;4+̹qnw V4^bg\i #-QteyV#P,~1|:Z$LX+T~-m<$RRW2鹟?XL@~Վnѐ.m3t2-QZ.o^>s-nAo;O)r'3Ü~;xbH3ḁL_Q-]'5櫑:X@$ j-Ѡ#^ApX8;4"R9lH2A>&XgXlDk@̀u\~s*^pmd̯p̈́&f MtҖ(P\)K+ZˢYȦw8N |!1-uGR]F @X:´V? ^=;9¸m9O1œtjiqAiui:U)BVƃ·8U*rH~jc:&b ƙe;_w.f5C6k0*_/"biKDY*x"?9O im+F^bsOU4̦g: }#"`YX,l9r$!P_մsbq 3ƃ)1b@H12!c1+xEov[L].qUx['+EpXw0&A | JҴA\ Ō h <`L Pe.f@-h*_Y;Y~ uFd9ŗR9f}>pb>@q<5\M&z0) N|xFQf=er4; Zj p8 l=UD-c5+i+(AS/SnS\v/S@;~I] U*I37V8z5STv*RCSzռ_^Fqض M]ܩM1'_:E[ t"^zI҃q5mo;gQ#s01Y :!yHq Ru#w SF~; /} >J;'SY% cd]5kWV:gߊ >95\n׹vӫ*N)ܲ!ˏE3fn;-^@bߨn;E6Դ:8Ne+J<mR@7`sCr^cf7MSzuRIII9Iꅑp$oSS]?0#$Pޣ)P {R'_LK*Phl t4"{y*[d&$s &X5;.@r↾*t~<}@NӮ?&مqB`M<=z D2 Dvu1<L!' vJ(Sl;wfvV P&1?6;St_L@X(gQخ0TIDY|8˩.=DfGW -MF4K')֍7ZɰkAK3;悕Pp>+ɴQ 33'_GRYu7Y~pv|ljt/FY!QQp?}΀`Q FPc;ΥSzCH!ՄcQN@(7 ly ]%#G/]̱ җ3줈` sa U;=$]e;Ňԕ[&v?)F};Vx JE9 ߼8dӥ &kGұi.Ju@X 3k$e3H]BR?/ʘ2Om!WbJTR:ջK}8b1̠-@%‚h!z-~h,+{.(tfa4R8G=DHQB]RdƖOXo<,|k-wta▻5DF%DE *pR{0WYE*.r4HF#ω3 lݗAJMŋżH}j͐xk;< x5@Z?eCUuiP*Y!]y0I|`jYmo,d!K^a𚲓Z@XSkhbO(䶢h3j?KUj+ϴs8+"KYtơMOkR@zF˨z gcJy!])]꘨x<~p+y{NV86rrԉ w#Eĕe gFͪzlrڥ1Cۥ4%MXvXD>*\ihe+sS1֫sGyD=.hG܌9ի&3~(w `̅)g) #c)}Q[< D9"w+HQjiǦ .I{N[ jiԔ-E͖dn! ߠ:Y]DV}vc%`Cfols!*)YD%|HF8 UEǮH vJٷ8 0ymL'с@pVt&7Z\gz$e7}9\YlmV0)3o@g e=a03n)D)B^g)Ho_%)C9y.$0i[fwzErQcC>Wx¥"R(!=[[AF:4c 6%k6]n;t^bZ&),_2h{#PrsjM6ߣBO(%mVӲ M"ި%Th\chb|0|k`g2_}p.ʒ0#ǤӋGABȔH;0<;^8R%8j8Q3f Nf h[pa57\x覸 t349EʱG5^˂~/Wߪ1pLi2pX0Ho6b.Djx_J(GKĵ P&%sOI;c<`JE{oT|jJ_9ekbhʘNLݛ?5\fz<+ihUp%@0R_fZi>\rO1?u֌X xpgtӋfe"zdi- ex񭇬^N45 ~_rU<)ؚp(ge@0\OAfQu*ԍXkFdL$Y9  W/(znB},tŊiclT0&rmMmW~U0QЗj#]_rh0oQ;zX48MˮD=vU8;.^A.N_80f Ʈn_Y~.GIxE ʹ䄜 &)}$ /pZUI%é r(ϷixEmHL?"[Q> E\_x>ثٹ#OnSshqjW ,]Uol# }Hw-&̒sGvP&u"0QɂD%`2N2rVdfHxtgEΣey,VSr{{KQd5%qҎJXa˯"سэ-f.+ާ ̶B}ROQl\1e`#&[_thq>f++DQQ2W5ŕΗj3ȧ2Ͼ_ "^31r3``հ#G2Yؤ='4$-\5 <~4OcWdgF苼'KM؈!"}ko:bC]^>E!ŪXaw#hd0#9Β%}hNL,|Hۿ+MC:^AG)HBQF4k+0_? 9t9<)f)W7w+KȂrNƄK`U.Pcυ' Nf[u:ªg,-#4[ P?d 4~$#U}DA"456>*l}SgBfouw<]angXMUju/4iŬɎΞUΎwa_Xf*fTZ !{@Xk ;š"$G0e8U3RX)%HzT ` ae{ d̔'09 C@(mtL;$6NgA /#-BZV=}j g {? eц Ի_e87ª ^Xq#Q>cq` c8FRANEt8 P߿ kQYA|-k1}=4 \Ic1߬3w8Z0*9['$;0wZx24־sQzΒ5q4[3-NǍз9 ݒ5X$n.Gi#piR)$e*>ZF'!Yɹ#˜y:.ڙ`")tkj1/hf&ݝچ}ekg @}boog&^)qK$wk2k-u;B7[=2u Ae{sv)Mm dg?oM]R_b:v|Zy<<`)yR.՟ԁ((_q#AY.=GJ8/Ͳv<$08}ZOE\t"xLI>a|,!b2ADX ^*>gڰ_Ke>3D*#$kRi  ' ra}{u=ޘ€<dHf KU'yC`@^#pUqd^WހwT%ф4DT9̓6 )&s "b }&gn(H.|a \;Jx|eB8"ʿ:ONe(UĬ*-_[dzH;T~D{:GZ:uB/gOd:HuK\ `tmCCsY^Y f[H%mHdӞ|{s{xB7]+=C-*Y7~WU0؏lWoa*.7 ;N+Ȍt8 n9Ee~L/~Ko*Я4B&3fh}Zk~?Qg A˜]x^t.Rҙ/(}e"#CIsu gn۲ۤ1t*Z,W,߻VO+.;L t8~/ͦP|:%wWvA &?"~[S76 BނX|ڿ2n#[;, pEkrY՘@/Q9pB%5B8xaH1oy|3׿A?Ȇ+#j\Fb##%Iw.B{n* X@5?wY52aq ߠs3*i\m-3S~\re#mэWR"e| صX'M}KazY ;ȔU?gVVNGTm WҮ$TsL7Զnd^eos!I=iKYϩ/_"o!6đDr[TyL~0K'.D](kQ$ pd$$T:!W [ HG?V ѵZMZ +tB٫WS ̟f5vpka`1a.+ u^BHp/~hB bO Ȉ}潪"VkVD9)v9oRj(eE$*D: }psuaRID?}G6x=b?k "f#5 uäf)SIǜs?I6*\eNWlf0/aRRz|`+l:1*ؐߒ.nKƫaX[p޵jV3h#ҒQvl ;:q+1z>n5 4Pb`9lZ;bo]vS * .5C|*x%ۂ5w?c*~@d +}8I5E񼊫'X*~<UFj)M͋IDQωWn0^[uo;\:?ԤQ vK%Jf&}Isgp@X姫r<=H` ?aX(۩ ۺ4G]E &,<:hj% nҬbƿ#U~-xΧ-BtbϮ^6a[H3F[9*v7I: m"Mb?Bߧ)I}{Yɕ6:[Bbg~YC!P#~pknhRiHNV ܽzlcT݈m^7-[x(Fa0IJ2|*2CX:)9Uxb2*z_A$-O{XM5JtT;%t1Z~ ͯγcTS6dž LgՌxdq+<a@G~r,X1/eB9c0K@pwH7aw|⫆ } tSYڳc98uPf^y=Zr3We}DђZ _I]0<kRA(ί'I {g{ vlrA;+Dʞu,:Nh! /l|ޜ!?RGD=az)+9)'C=K|C/K*kMPPzŃ^TDnP}<+IvQO'J;3N&p싫CV66{XT1(QSK6+K'fioj&tr}^ϬJ3<ӡZHXFFݐHY}BqS+zo%M4=GP^ܘfR Jv"&Y3xc6MhCDU{q[T6AQS ?iD?=oOLȒ[hKA*ھ?yv%b_}BdU@ fk`iX[t8B# BHFJ<|S-(ᤴWЄdp8tu nl6% O%'jn02&g3ֱwcT&cSԃ2x!n;y0QQp 4 wrr ]W|:X~Lwxtb#ˋAL 2F]!FuҚLp^0 yv1-jB\+Z%iqQP`%ol]9u`OK5=@1LcdFeIW۵5Y$6 IcȽNePY fxi#P@d:ql.OmxۅG;z!zav6raZ{{4&GNu3ш+o*fgMsBK38雌k`"a_مRh!PN85$;&& |܁zA`9&/Ihu `NmIXK<3r>8Ɔ(U-\1ߩT%dX@-w ${Yq;ejH1 { (GiEޒF__f†ʑ}b`H͒  1C>pMu<+ 8'cxJy3|R9[(j&1hbbf:W>K$pmQ]Oeg}gV-b]ˊ{.ZB؈Z$1?=9/6k*GV^II^JM+̘wț񤬦uwt˴uq On:*rcr̄4'|yL#Kݦ@B%,b B9f7$sjWPɥtt|KFJdws>ndgJ6.#Fxsy`i6tJ=_d<[7iV JvDNX] "c)LV4[u~wKqBSm@ T\ ),$FrYӚe NJD~"s?OsyFM|o`XdB!ޕO)]Uof"-)fKt5pg)Uz^=+/h3P 1,s\E}Jg"=uޭ(HvDS~#? I\G8&|>eN#+#nNasOKj"b#-< ߄3)Ackyѿ:GIpq:Ί@>{VAkS5P6Q>6C8.&.-7.ՈF0{H d+ zs쮑ԫqT5A!4QC{lxP@{,=:1vB+TrE*J}a*ӵkW-뉣K=|Gh883™D 8SϜHaV/i., WG|N 1%nxc%< T&#VTs[,و+$K6pY\Npv_`\k6WA;0)Ȝt_8y</]1>7==UNttױMDA~o&EHp5QGJ?ċePSl Q3ҮvAvc^Iӹ7-OU̥d[z썇3M,"QZO4 Կh$t"cNQXQk5Vzqɦu撒d eշ=,lo߂7v"q Sa:TP0aʌO2N=qd Y/ nma ; S ?Uεs(`J^":pK`')s@ 6vF}٣N@arOS.eV_8hkFMcݖ^|@dP|Lpnx:ˆ]tG+m>p'>~.r Wd[NY bwߦ8vuECKEVaEqP bYdX+]:ce/=BU4.1]בON^%|Q 6a7Ͷ4>P'ǸϖЬ\ Ga}xN+g1epӯ56Xo, d.O~@*k y [<py˼B޻6y%ܙ=<> dHxcT^yVx[3r88}u;8 LGC^t*6fIWM)v EEvYܦ4VRvٻaa$=Sӕ9W_!-9`=͊IR7*iSp*%i~0H(IJwj-=R\֔Kx+7-u&: kZD~r=g"W8i2ɲ_] *:.Sh ^Ђ\j˦P 58TV SNP&,!hZ9ʜq04WO0'9*?XŞɰe4G-2ZI&*VboR0B[zRŘ.V>B.se,)Fh֥nD-t7rD0t% yxEiNv"|ievHPujoж"x5_Xk I)5X !ɾ6i~[UsAE ,?C`V-=wv/sNaB#)=jAɔ}L(esf25 "ŭ( o#kie~>[jSB{kvp٘*G~:$NƘ)} Zz'Qѳ̹C~wES}㺙ɎX!7НTq݌9săciM}gɜԋx&@[j[,zJDe`# uowsu!İB`[Vw_ Z3NF\!yl_3;3tq>?{9Mr]_3&R^Z\~q4!l=㬅{O]o6gO6®6[guzm#;O) <(NS=@PlF>&>Bv?9[LUafKPah6_RS1yX5kwem"͍]C'v8}_7Oi)p1UBl;@/>zIqc2K? kݣ ml6q`#Lh_ʵ?VDžTz U1>sap޺-7O|d}p}mTU,%4Vt>3k'YWZ}l܏lw[WQf˷ue_ giu#? S܏YU'"np#I[+ُ"47N3I$w33+z4lHsO4EiiUoV ?>A}oCޔ8ӥ-[d{9p6(>D5 7]>W jN> &GlQAb(kK6Ěao0IDDͬ5fWHdR+OdtRTV~Ȋ8)i:sC̭qk S:üMz\Y0hZp^+|%CYV :=DtinLD>,= }4"_B=)A}Fl.lJ{`AiV$þ66ۘv0 ͬة{ 6Ox)adrd3|r󞃦ϦÖ$Y!2S0.;BiŐW4__8 HUuM |>ۤW5Z:;]6A6ne 8"MGrhUI(mNJg;[Nl{V$mʝ* RI+~X.STIVΧ7Y`fZ4*)#mJ,~Sgk\~XZ")u +FaHo\8‘DlOYE'D7}Y ?Ջ Rfg6lwe۶@g S G ō l9Ղu"vD|0VA*JR86/v ڸdS؆AOsJL SZ4҂BD:Kn]]Qs~.k\'F$r&P@Z2oGmEʚ0|ѤjRǤ[$pfMS&Rp[1=lc3)Db SQLQD|w07CC+s.tMP!}Km.%>;[ydK9oz& *"sz:;L1b5j&pӋhr:{ Rw,tĉI8 ٖ@~b`?)?&BoORwt}a_BO=SMrQq ]Pt=byV= ט *OJeIAGGK! .{){M-YS=fQͽ@ާ`)=OlIcK4MpzWl-?Vq1zn>g*Ŵ9!Qԇ24·%,B'8xسR/zKk9i> <ݬ3dl V!~QSyjgI! `="4]i)u&)%.S;L~ Sԙ#ppeuЄ'.Dv:0Vn=:=P3^Xϡ}dI>t$r u{G0(=k/jNQ}UVMӀc8xTl"]k\/fXJ"V<9B;xߜnZMC \Tϓ"CyO<ǤZcpOSVj*` ]՚ۍ!^Kbĸ3@@xfJF בKEUp;=͌]Bݢbc[*\.!YG<[b 0}҃3U{kN@G2s{; H9˜/:as޸~'^"gephõ% *FϙݬR瑼q^Zb?Dk ZS4es_n)*2%'6$ZK fXjc{y_]e"yZl>lmF c ?SM2c=+gQN9la͉a""'o3;oSQ$?^h14XCA0Jy{T|V8P[||%j[u By }R٦L7zCs 0 vdEfVձ‚ş9_~N hf\#I<8}3L*Yqem1yej{BEw/㷇-蟌v~7,kByzra^U:avҝlqKFSFE!$EHL#Ub6OJEg% 'y{.DWGuL$y@4a޾vdTr,{}{9S@/h1ϒ@wφM 5Z!s3@78@xñ%†4,"L|y@hѦ-݋(kpb Tp0w$f!?cuNĊ^.tM&A b7N'zhVٴnL^D*)r..{$b#U&kߡ!=R=Rm qćs/!m.]8n,'}H@h +?Q (`N(tX&s&__l׎ `XtJ.,з$LA_CTnC`g K'[2`|Hq*5S AxT8 ;]ρroNX4;oFs_,ĽY^EC4jiLuAMh~I FVshtyQ{B^7|֡BƘ0:c t:}݌yF@aU BLmk,K˝!۹`u)ZËv>~sbx^M=Q,םv"k}R aybL^kaٙ[wQ+Y3v{?=\* Gh1.6=fcINn!GW6>۫o>9Q@:CzLEtFQ0"><" /:uk|*㱶1r2FW †`_c2jEJ .Kf=rxϜ;I.*Kp~3h2b+ot#0WRT[0IDŽ ƉKg }U:iLiQh~/V R3I1Od-EO]if=FխY)KQL;SkIr"x68r4T]MtYOiĻLHWzHrIsY;~w#zk`kH@[A \ekhGdh HaUgmTrjP<祒(0=6ps=ߥ|:PE.%;qlrIҧ|e[lesm"a֝KQD<"AMFX= .~#vaޤcJ͎i;#tyOkHFk4'b9H~/bàE}:/ڷ K'oI]XvE]B҇1=e($"^E1<"f4Mow$4qlE3]ڐ!zkn>"$ IECXN_Dkum_s:vxYq5)%45v0 V s %^Ջ }>-]Ki/`'%cl<žj#("6t/9Hw< Wai̅Βeh\Oz돂OK Fd.$g)arp8댣MNeβwpjmzsQ/ҮЬ$'r sX?fHg0`Y }zf&(ʔlm0~I8QWJׂ9F#ų'Kt8k%XOq;V5Rf:ޫ(9n;\Fl@N3}6 }yܦԚxeZqpM)Fm0-* 2]ߕ}@X: FCOu@=x;(`m .Aݥa“>=}9[r:٣QnS#/7V=oFǯPAB*xٜz@A5/Bg WpVimdJQI?>ڞl6\Od=32!:Cйbw/P fDa\DM"ڂ: bm3UMhr3 3"2r;|ߓY RQfo8i3WM4 >\?bZA Brt. C_ [*746ӵ%l-]d8-1y{' |^wP aEfWQSME-Eܛ cn4ٟ($-]w)sgWm^d?` /ag3{@MYKk_\U rtӆj&VQGޘr0qt sDi+y6L[750Iٖϖ!Sh.5$ݧ{ȑlN̶oSӛMRi)c->+2 i)+rJc2L,7a&: 4LP۹?!q0L_r*RƤAA]d-rJD\G,C4W fzT}~l]-W[\DKқFъ5{lD/9DQu~8}pt3y_@o*-iV#9L`YMҡgz@[-yv-?zy-]1byܞD}ӗw x{<)!(5 %~on 3? .:[Nΐf _XlXSGsI^. $L܀6N| jqUBk Ep/&Z-\ tē]SC.pd!xs< %Sg~.NB>GSk@X j լ2VQ6cƄG{Br<_F S;6 #j]9zsyQtDrllyXºH;CS&S zpteA:q.ֺ^181Բd >GmL見*Lunwi4=89AgM HޛPBb1"EmQ m c3^Z]ANvd1)a,E$$8:ȇmztoFc$9]#4vq i=zyJ[Q`.Űomw}xƼR)rizW㘋'E] %n86Y;teK`͆fUIEw?̉2=[$%j!'՘ѝ&})utH=3̋]~evIl>cLR|. *Nю2p)B#1vJ݅zLX\#NZQ_1Rˈ5.y /EDԥ,':u1Kb&h>#wN/.:hxJ9@8,,clf 6KvoM$0 MEAryt uɵ 1>qZX4XbK(kX3m]Qkԝ@v0AKRP0_Fxhf,E|a'I Ű :W27-TA¹ky"y 0LY|cxs"*JUIRdT*$ ԟ  "dJA@kWv}0|cX%#<2X nN7nݺ:q8KI_$SDN_sFxk=KGskע'TD"Iٜ'g9گ 6^ %P??KgOa8=PoS{T2C@6MgqM:(PfWm Hl(LV A[M䤋1QTeyg/ "! t&s:O~Ra1Xh[@3)Nb锂@oc`@z)ߐ8"Ƴusl{\ǓFcrÉ{Mw (1荋*8!Ns&\PhwϧM:4Ry Lx{ȆCGNv pP bx]V+NgEӾ!Fd0gv=G꾩776Nׯ#7l?br-SMPFʈ" )3iYn58N{g?4h0^TU0~]tc: ԕ=s0t::pe.%?> TI B598c}bE/6kN|{խ7l*h2\۽͂~]aXH@[G.d4RV :WJY{(;}/C ?AMlҤGTxlk,to~P17iqq(sp]=QX? JI%uNgv5vR]zkHST;s )~?%$K3O#ɶT==00cWfa%o!Dg=(SjV%Cs"rAq޿FAn+3)la!v4&s/L_ t==) kWGn;TM`&nEQFCsӃ:Vz AWu{Daa&|dt0T@Χf77d9᜘zM=hȪiRV]kM]<)FƳ'\z魤n^+ok2prW1lGyN0ͳ__|Pz!Qq%Sr.-iB۵Ȃ_SBWYG2$d J]{&5#gi 9LHPQ~l=DJQK3Rj# @9G]"8< %l^\/AeH<0|X >+ٵ&?*s1IӸP"䅱t V"l|ȥF븻3F=Lf B{\!NDhkihG!ծL[2>i!a`)tr*kIz3GvIǯG[Q[\MTZ0ۄQNjg݌ֺ0ŞVs㺵Ft3E&'8Eż)ʰwC<_p-Zr_KL#j촑 V"Ygl ⶝Uk;h& ;lLH?ahF">|i-!%5-W"„`OGU{~~ a"0E<}ivx""n {vkA\?(@{LeIdkv(Al/ wvp#ƃQc LN>3B@)6<);>\I_FQm~aq/B+K+IA%P]A¢ =QɇYl.DŽmyhx]v4ʖV<@V2E^h&62x,@#s f F8}fs_Ql?nP!) h)!tw;>w^Pl<޴3m! P-@ 每9 %N*jVd!Jw*{%aXΞxdcC ruR+I&ttNG '|Sw~ Cؙh牡$ZV xoYIcy^_sO^R\=Xi&ˀBh5-^n4r8/q)9?yT1;E-W%;_d}EVj ю 647~S9 d‚ׄ~Ё  N0f5lU.#u*; liI e\Y5(!dp?VsQvJF7?% ^һ:y'WBK_[mh PK L/Us;דqr3o}miͿNc|/bv..3wגq%aNٝΝkmA:\LA?$Ws spj/{obBUPfp^EN^ۚU.+MzGz16N܋M꓂qK) . N3P;"aŝ~Ejn% 6NHUҨ{Ԝ R3f޼9 '2fѿIj#; (zT?]Ew!Ch5qm̍17Jr1.ɗ5lq37.Iߜ›W,Kv]5u8^n< b]Fmϰ= 07|`î=vD?+/@Co"ԥ~50tˇ{h|I9BzNɇ72% TGQh>$*xM"8@6gC5/e,d?$*3+h TcxX{1[8*qtfL]EQeFj=ff  J7¤屒Uc쵷SqCFiFraE)+Zl.PA,;>?#8Pa6z |$]˸~ʟMw[Kwg[{Wԕ` .O?<-? fΫxj/7$}J 8ggw C{j*k#T/4Oxz=ѦmgjaOX@O K`m{3MmM !LN?ѴR-yalFJabeveLZ"s,"9BJ UHËsTݢ6`C @ |ݿ+AEcេE=ObR^p/AW,~Y06N|ޫg+jo7ȴ?DV.vqℭr#H:*k1][EP0ž-5 @ $TVUGt[ ^/-3hy +\Y9<#h̊0n_nl0w9_EMp_#>":#j Y0E'[׻Y  Tm2m=,%řJ5{46DWNv {k+LRmَ~PAR2PKTF `.ң[`єD~sPAR 2.0FileDesc9ؠ<Ѣ%IEeHE.6@fcF-K,par2test.part1.rarPAR2PKTx P'"paєD~sPAR 2.0IFSC9ؠ<Ѣ%IZ` )6)Mt噷,n˱4f>_PAR2PKTxٵo?|`>єD~sPAR 2.0FileDescn}n'O-/4ta@yOe:ѝYՂD$&\par2test.part2.rarPAR2PKTx^ע?b+.єD~sPAR 2.0IFSCn}n'O-/<7?H73<|_P7#h%2fPAR2PKT"ޑyMyєD~sPAR 2.0FileDesc,=Ǧ*_'IcmPH6!٤~VǤԕpar2test.part3.rarPAR2PKTx>6b'RGєD~sPAR 2.0IFSC,=Ǧ*_'IcnX: [/FͥjH,-hLAL $hPAR2PKT6fiQARrBєD~sPAR 2.0FileDescѿ;ᄭG\7%9`e,Jܟ[Bȹ/par2test.part4.rarPAR2PKTxҮ Id}%єD~sPAR 2.0IFSCѿ;ᄭG\7.c!sK:H ;9]} PAR2PKTɧ5P' ;1:lnєD~sPAR 2.0FileDesc{mzXgF-\Q0Q&'6'\par2test.part5.rarPAR2PKTx?B֋E}єD~sPAR 2.0IFSC{mzXзe Ah( |+x(@sw} 4paOPAR2PKT/sibєD~sPAR 2.0FileDescܱ1`{M!EZ ,/U+EZ ,/U+7par2test.part6.rarPAR2PKTdfRo@Mr1xєD~sPAR 2.0IFSCܱ1`{M!i+ .1N%}PAR2PKT єD~sPAR 2.0RecvSlicG xЗ[!@Jm$N90?h{%բTk*)]GZٌӭ`PR+uYonflqkؾ3-F:O۲B 7VU/:oFjIݜҨt>K޾0@j#[W̊ZuN&^Q;#ؕKʹjjE>b脝 Dj~Y,r ;ݻkܘw)kZ(wu hFΤeKJhӅ:Š\ڤ`5˵ik]_D"m֍ Ph> +:\h>=WC؇{3k}dtן9LHx8/+ 2_J!>z* iYk4`&~7INW+ȹ[}{)AЫK~K˴lk1ԩ< Ԝ?v>Ѹ%H-WUD  䐺/ je&]8s"B#n$`*0sx%\a9$T򤰵-?RU ~e 1?oV GUIIaW\Ifc#(r_Xݘ7)Oh^ pX|.xz6pl_9+2|wm`gR;r-DˢbcZZ55vuI(cu[]S !YjE4e0W6S7D ha'*4g&`K~Y̲ҥZAXwXҌ%EPMAz Kebe>5nP\qu;yxn#Uy31^ދVt BY5gBԔ3ʻK7lqўq@-/a$[?q*? ۓkӽ*{G)z"AY =|z[HGa/7_V/Ky8&*~ҫtpm$z)>OxvvYdX5XQ.yYg6ȴfgӷtP@L4UH&1p.,kbVP#Z:S݁UM[(EOC ; ֦"jbK,(-J>!(LYw\$3:ٱ9|i1-72+ 臧}fUu < M:1諪 s3cƣX+g?8s(|&/3kJq}m xEE+T^|k4ۤH"[HbY[–#+%c]Ʈ ,DʹwtBULCaW+LVp`NSߤәâOj$϶o&PxSbY$2&tzaBGW^,M9p}jCG7-4d 5a'ΥZr<׎.9̎jb}6'p]0scEŵb@3B33>FψDFlWV*L:y4NSB7\X4at7d4۰.4"ln= 0I]RlE/brfl)}gq1Ns/Aw/ı|_oVr4Y ځ` cᲕRe]4O`W:6m'nPԔqsX- J-ۖm" gnן, g]iQ-BQv-[.gA/F$q:8V]m~^XlDΕﻝ7G݅UE% [(-~S?3,UqDՆjemЉ4XVW%WI~Q#nvc}ml e*y>p'ű uqbs r\ҰDl3D9OYKx &Oưmo@.0fnn9$j(8nuG(Ԑ+]pxpR:s{tZM)hk5H,nPҿA%6<4_ʷl| st#`z.FW-bik;.ob?gc:#fΜoBAW*!'Ӷ#lcK|Ė;1ƍ9.'p(g_}^{!C LtO͏K]PXp?*O,'cJe`:#8W ȘD#f3}Pm}tHx`zgi ALnG3*Hvz2:)^-1) %6R{E:݇~'rjUGRF |DO#~iJ2hu#DV`o[<6cVrJ\OQ $-j<kxS돰Bn{+oaܻ,WF!a/! uGNW{k|n5-B%?THYl mZqhĺ*wOWw,5d01e|>]h9MG>zERi rjqXnaʮNڣ~pO>UJۼ1Z3p"[?) yz#j hy2D+{xu?uH+ȠțY0[B1X}ٶc,13 7UgLjա#ؖ jt›&pNckNGd+ߛJ`YLPڱ* oWRB:;7]Zo!@?WPAKP`"<.sSygۚ.U Z2̘{IջqH0Ln-LpASbh'uLLpfxb=] 鼹oaZL?&aɑj%f'mK"L7Qolf8n.=qѾmȲBOeM./V5eT[G݇<}_GMio8dekqD`(*hpW<0w bqdlX/]sc28؞bV 0}>x.0{fM]W-9WQgqT#v'+3aya-cLI RS4cV6Zm.HUe+"&8e wjf_E"M/f}ϰMid=Φ1 6(g<(B’t3/!r`hVP-}$&   )z{drp!~gPM6&Pg&?>!NãI~;r˲1yo,oK].E֋tdˋԓ*ޅj 8+_9<"L.r7 Oֆe"8mBLsşfq?EBX+..V!dHk 6Z k&!blq#Dzb\o =Sޘ贎J7-!{'?O܂}xTߘzlH'q즳 /Xt[g''b!Cұ%̿p$aGp6rhӍAnfQo[Еs6V_DJR¥"j441Q~T:aD=Meѡw[VL<}0 yM$MUi}k>9;\- "uHVbcU@QM^ܚ?. r%4X˽q'f?R6XJ;yxn#[4պ u)a Bړd/˴M Q"$e ػ!7hPtQp@^eZ[4޲^=uE{ z{=A9f,]l?&gZK؅hiL[ITR`yg b$-X@ibo I0-&?L gظ(â(gkT$a]ق0*9DC;2*!lr3!v~VAWAx/6&eLP< DT^EO<-*閻/HBi~X%@~Rq[Ge6l mUHO}jtPyFg8ka]d)@F8fj4ta?44RlW:3E XO&"UIΗ7=Ih{݃k(`*Fx!V| qG86Z[>>5]Q,:,X XåYd+6(b΋ds(;WƣF,=h׹&ZF&{w!ZNh gi4o}'MT+47-^ %Cl' p-:2׬\>5G$/mqu+ RQ];vSI>' {`yY jǩpMb yg[Fc#pop61dZ aĬ]$+v4Cّ0v1TI&P Lx8`%?EHbr+sf| $ȶQߵFTqc D0#Yg1{r w)N=(i/5,ϻ/_TqC')Z+͡8r*UpMPsړYR  W +YQ̆XZglۋd>FÕ0sy҂ϓ[L 6*L9WC+PÎtޢ{m=tJ0t9z7@oct򷘫Xrh2LpbU>}Bjv&@[ԝ6JQH1(X'奈#_r =CfW-燴7{@ںxU`W-Ba7%Ye4~;;mXSPsEkb,ֻ wњ%7Qǂ"7T\7襾h]yުΎ/A\h%-r vƮ&eWNaQį\v3U҄Wvs׫"yw T%P!^\a_Ʉv@P$=+xD,XmS,^x i]k ~y%hYKyXLP[n}D2?":=LvUai4Z`E'\lМ}SlC[/x0]4Ð//8:XD#kRKqiyix @r8?db:&/}йҫd,0’66FItǗo>qa*2wě~#Npy&H])2?xsigK4wdqޤR־认Zf̺8exMF`Ҿ ^Ӆüp5^4 AAA q(wzzòK^cIyVYǂ*F5$8vW㬤酁GcuF]l̆ 9\M~i M[زf"_uڡۺpZ'Ȧň|0ok .2Xirds~Q+wʤ7*Hs[Ľ<1j4ʀ`oGJ$ TOӔ*x_0p`>] p >Ye4C;F-gؔӏ\Hd6BZj>EsOr8x&Ϝx/ZGKE_z1 J(Z iǰb7RYh*I6e{`HY]lD𣅡>BـP9zQX" AnA6܄ HVϟ0ZejA`-awKW$ YTBo.|%LcV3âE~##~WFuW\j\xK`('pcDcK$\~y_ĝDǵҿ4n;\h˘2u1de(QdrCFޥ}1Kϰj]rzS;Y &d`0!YTl4[{]ېQ"dC;cq[1Xi ፺?D_QJku@oL.Wtn9>z szcw}ul:Lė#}#@6t>u\$2-PR ^"9"]Տ ,AOt?l B@U (<~*DдDJ#=f|/`Wha Nt%Oij7Rtլwl!/2hU~v,!2z߸dOv]ߝ߆>1Zas/S۸?#EEnY 2#~C ;0_M맹TxJ+qʆu yK5^,u,21O8HbU^F?h-nW ܢN_srX'fգ6.n7>r8jeZS:Pdz6\ĬmM/`1fb(G'@Pdw "LJʰB®mEPQG6'% >wFIE#1tIBy-v;H'aw U``dws={2rga2 tF+KV>"s~>zbjGkN"cIⓓyS&tc?$nڤW 2 ݱ4|,d ii/9l[G5k {.@ў3,>wkSΌ!98 .XHK$B$Qx°g(*b kbz2; ![v Yؚu6)MZ%ۡ %h\-1LӁiX/[JR述U硟3l~Ӝ-jZǧW)og?q2'[NB'ƀ[-TT=aoL/pQ$ 8UcŝUD\Rt՝/?ctj NbdXkJ'Ѳn"21R^ o# .f&͙gl˩V},9~=ݳy.lt+~f߇HY@#(%NxրS$T(Π"?h) ،?[{E1 $寗$_r#K`*Ϸ]ot@aJ el8Ȱ0411iE` gGA_M[>UHj亃@S a!C7Z^6H/囖ISXdsƨӑ.\%fщ݀ %fmu*YfXHРNFXv\7|n]>ʀ͉iv9jNF!\4 -u*ZKojaH8Dh2ԾN4 D_t<ILfof:@yn!bcs ޳Ē$S"h~xT u)QmM߅ϻk9׼"a7^4ӽԥ E 320M +S3I" vnzB`D".ޢuRKOU°Vr.r EEO/1J50Ȼm+{YQ+VڈƉۧl[0|l!nG}?=oi)$A8i <̠X7 {N+?86:Ne1s);@U}jodBPڛ % pj_H/c0M6<{[=1bx ?hx,|3E,/joK[Y-g6 OmUCOt+C2 3?\#}zKXKk'5GJ A8+֚xh5m%Ը9>( a": pP+ײe.'LmI*cΓ)\%= F<^^Ӳi|j&& pR(D qŒ'm@;%.sYj%C=~tW+\)N/õ#jpNCV9UT}t5HwJ6/O|ˉlת 1*b".-='i3Q/bQ@v8aE('b Qt4~{ 9'mι?}I&O 6/3fVg](l x׿?r-2nX+!_@Ef7~RR? X#Yq2Pp]_lΟ=~*@C0_`n^-tQ,zev^6KB*9Yi&lsz]lW+uRj=Tr#iV1=QLw(cf`BWNtU&1*g4A<<%˻WUGod{5b;$^&AXF &>DNAꚖ -[Bi`nmoFa̘bE}O76l7s_jE h dEu\҃]Yf G^0RtuW$َ87]SE'EEF2HFx*e$NfM?o,+F94KZVf薡oxv!]Ui77)t`6X<[nΥ\US"EUw_>7q|Nk/C^༳[ Iwh)#^{H={aJzH R3w:RM׉o&y"a]mg>f;b'm%>cxb"mפ8U GsbTr\4J&KT(!=ɭ_JfmW86 H<* F]C!_yHho.S`5Iμ14^(٬d`}/h4 S9HM۞4j9a[R%QxWV n[Ŏ)yTbn[tm DzfP.P j^g!z㜩IowU~=@So=b 6{޸l[go<+;splu3a;A+ͤoV'|xңko{2}{ Y/@Yj]t\k8Fk.V.Lň#vj^ˍ\4N$ƱCW!q^VX1>ٟt,9MYOm_⃳`gLax5n+Ďw -! 2f Y( .kY4+~y/)w&fL0B3ƒñJ&b5Gȉ^d6>=V)V?il\Bu,7hHBJ?:(Y]2ZlH_OFOO+*t0Sa.oeއIR?Cc38q1(o,qK8/j`FNJ3c3lyJBNhbL@\.^h%€TFǷ?5WPeIi%{Q1H#n2Ƚ a/ ,ut^%2& 'ıAv$fm@,ñ+sX-md[n̘ ^߇dyCڵsvڛqڿ.#yv Luf$Ce7w{;BWZpsxY , gn6(.Ȫv_2Ŧ:B)gJĤA a'>p7Fv/CI50YS5L:YK8rUJ H!}&;"j\R|B_g_.czu\s0~hC`p2 a߭q,'*WIt/{|d 8t:5;kϱA\Y1lO_:n KS`͌ qʅ^~ ļ"|Mss7BY,RrmC߱,loz)$>ӒbG1o_m0 皿 >Eb,qmM-I!Bh|vc:t_demIEX6{|PSQxX^ܥclPҊ7B-cm^4(1u^N,5xGuˈrO"v–6k l(S4-<['./A;bSs0*Z'VEHO^d85,Y~DTl_0磑e*Qdy*'KIr,Nʠy'N@5B e/N9͗y G%[Pm0|7e 0dH[ ƈY]v e7rBv5M,vS_foZDG,6(sތP4-mB@,m]0M&y4N6@(}F4_.IDʪ)fY +)d:p*NQiÂiJW!9ըwq(s+G5S,ڼ^Kow)2\BeEO9^d6 O=5ةCtB4VD[e RA@. YH7,;r-H0C֡G m8n^{exdSX1zD8mn6"\5]5D%|Y~<e Dp$YˇS\r;DUK}x?Nn4F5򪄧yot%e2p6oאON }N~ȸ)LX &4lfeJoeizyz#W0%ꀽ䴞¼0rLiF[ï 0P̳c%gcn/1o\w, *.Ymni"Fx 4I-ro{3ĖC7"c!47HZ~XfBAxrc9R/ 9,&Ñ0-:?9hXUϭǾg}j#ۈM.::>%ip9 r@}8QABݧuo@+:$~v_hOmmF'oV's+4\>mf,*-}_{h"$kOZ3u=n:oܗ$T%92\֯s&07)M BIc 32.;6^t ]p,7ܑ}qeX$m++}M0{sXIcI*0z.aX[3n<<+{|C"s:l= *Aû_dX2{"z('ں~wчLIm?H aR]ѩkNIyD2^]-'$P2k15r|M;+su@sawE׷8 x&'8OR H5`Z1svNXq=1 T 04;=xԏGXKОHϢgI4l[$kM&GRUȜ*GwQNHR.t_bgLJ Y*+^YfF"d%'hLq2^Ttx.GR\?x,uurk %EiuRmjluBh>[g_tiobeX~_z526c򿚟C~ls'7udeI/H٫#o F#uK/ƦV:\: b +En*=xuwjp@HS;;u޴BbvO/B@(OR*+6y,yk>}l鶽7DdG[H}k98FsˀŜSq ;U+g6r <£|CqVƤ/Mj<{r | =pt\Q HoH6Lyt>^89#h[&4PhGǃ[8q= \+d6 o*aibvԋܳaM3E4y{ObH܍9`,|1"oy滨,s#026,nY!ɳL4z"%7"4vA~gmd} m)8 |wrI6uF_rqV6$ zEՉh2_rV6B6N>,τ(w$-_*jPmG.xTWxvEknO޳6/@'3T2&V7@CuE79}/jubc )tH+&hh5ߦN4]_r3zd7; Ew BDklOG|xa)bK{W!&eć\}>_D#w<čW"zfrR] ڧs\_"Po\`dQgp"9l ;pI&*gcfO;4,}KȸQԵ+`/ax IWRx'ækjS|HIي3QaLmxLpyΜЬ[nW![J(5V焠򽎉U\goČc6VG/GftL^YIy"ѯ؝!Y\ʱ2!-$˴o 6"0GsN꛶pA,`$eҠO7JFGI$giP~QTP ,]f`fbJׯ9MB‚FUW_{Ed/WW?Ӟ"_51g[HCSQ'2۹1ݷQPD6̸Gq4E94)o7D`_4R4Vl2Uh&ngP7xz!GZ5 [ b]<4!3Q?YtE33ǭtyPQuҷeS]c!xlNjTCi34ȚN ެN>t :I&*F 8M*)2HQ;ˉ K3-_QRP5Pȣ=̽^rDDLz jy}C K[oD@h=wVŒ3t̷bd)SBgl%=L;t H3P|%ռ RRTk&E3'ҕ*Nʿ5TrXO̡ l8FnSNG{r|I7vku&OY@#t*:rSi?ڞJ^#Eߐ.n >N#A}2%&kP0u=b;ߡtjw$v-wx~$c%gH&Q)gJ/Lv;N)xjQXryCH]]dIlUuJmYұ.m}mqu`@)[4H(<@ Ε+`<Ƹ6mz^p;T9}KnUG"C*?+!"Vx_@jwLl `{!&Κ>l4->hʥ)s<9XeY*ͪ@:`ߕr^*;a xr+ ~yZyD|n='xf趐0NcslN*2n[Tׅ¢DBsM且-Ug hҡN1{Ɂ,=wu|onoMN5Yuj54pr/QÒ'ux6EpL:y/vB6'\,u;WIPd@R*F2K \eF$j Ԭ| 嚏=l#ۘXlHĸ |nSȰZXnVc!ΜDf2F؎ sS 1CԨ8%1\;UQ&c;q[%$gK謡L]{ %":[-{@/El!/]ji[6gpQ !˾T0#wVP?fwҡ+i'ᨢY4ktؕ'up*qg+g*/#p9 k1Ϥ0؝Y*H\M66:˴^Dhb3׫QWam$4ىI}:L)( ̃Ur!uݟ7ٺ8趌\(4FF.喚o{g=Sel4Z+W+VcӔPZi8^rqkc?9VDhA`d <~ȽcQ w9Nf6Gf',ɏ#uCBjY&AN) %"Ztzo7IwuAGU1īI $UmJFջԀqιusd#9\v ٿDTqy0\U.R*>񣔓h[$C)5pzMhRȮyUwsMI5팻i)7a&^!m|.gwim1;Ѯ aEC[0c\p ѹ)ɛ~HK-ց[ :2{?LchWo0^=YꝃS糩]Ӛ O'Ls2x1c5%l'qwjKI?^bcH(-'L6W7T?hr$&|ьT*n;57߈r lm /tS`/Z~S"G\^"1 m=>9zZZNoYiɩ,492c-: Pcwrz4#EBYWh}c1%^7&wҬbrR݉jntMW捦%s`H/s $6ۿޖX_&!  /*Qo/7JA0 5\mXL:%Ixqz;bO>dGJy>SX6l-s?IqrRjQp!,7#$uŎ[7myc^OyC0(6tu AƏLt(#=7APt%՛^ pMס]pt/&ڈ<ihlX`ʡb<%6p:א9NSpxB*n{R oZr󞖢7}tU8Tb]LsHW>>lTBlsiXS(-V)cHQ=y20Νv]`&z9d/K  y3Qgo -V:a303 5) Kp'/} YfPIamU;׃XVpn7W7'\yaJ7] wh&| {\=Xvy]ڙֻb49~1oQ13sg`ubui|\[ %{[wAe>߷Z9`1PL/"5b>1&߯=tP^ue]] . `nT% |cıR5r1=OST[·٤.'2_R¿#cL-i!G0`:_!'vI$9uo@R׋.4 ]]g\mugPh'~zKI9*wm$2$S5T}dd@/h[!ƣJ*BR5Ǟ)A{)[&pFx8ԏ$C!7繮%qxm\U z"ɏuҼgKk5_i#x4sPdOߢ*1ޅ@Wq3'ey{m\cM .:裶!Xjxa ¨`ge nOl.hdYC?=e|2 ͎ےնYBju8LGBg=DQAf ٓ>Lp֝Hb(B*ņeS;p}Eqͺ~SN}$h;2V1b4d@ԝ p&# 5rP[FlB Gd>`$D)B0:̦ɲʢCV$ݨ~'e)S;h밾72SEXlP)W67qGGmPc (y5:3y*4*?es&VEGWff+;P T5T>S)k/ Kw* rcж(!(F~4BW1tN32.o< Xu>ffcxM{Nl:%5WX#1B0:Rwv}(fBj?ٌT9uI/JNsMUsa \ .}*:7l $y&뗞W-u;K3ryטּ$Oձ˚ e8( $679'(;#2h77eE)*F[z#"Wq[i {h<۶jlT~%= _%[,m^{RX=cFʫCZE8}2.]ZPw#Nk2˪t>q_;S0&mDY$LYJo`k Ry-w`sK=r^'`gaA)H5kJ}6̄($s)d5<=I0[ӭO3vVɚŴcI[ *d]m:y#n 6(A}F$Mm`.zx:H[7s &՛2앧;I?;Oe-o݀uv:]o(E Dm ynv7?C{͒/<2uTJRزpZ=nUhoygU7T_{O|Պ­L-g׎مcBL96 3Qpi'JG _AyYFs֊W pc>mlۇU)L|"Vw'dA? A+KzC- erxXXEgI$!^,x~w=$3Nj7]~8p. M8vwpYcH![w_`&_@# "R)%~lWˤH!vynNwKxQAK?l-Ȭh Ƕw 6c֐p`}P h~; *BV'8u Z:|}ϿJkoee:O6}dWo1hKCK[1h$X6p]eVگ;T&I93bІ>&AURMYUA3tO)m,rlk)*i)x;3怈tC(I&tޕy'0 HY YvaFrl j ?s*˝z8)7P&EfTMS( o؋p) NztO-q]/Yv4zJsƗ]S7~F{Bnj?@Z@^rYC: r gqYU4-5+);5wpD_Z I=!6S{["bKVoчQx}k8Pu\-eW1s,@~֘gVa#0wp\RlERPq *z/5 "T_/9j['ARo.`}ٖ_K/@n]R*ct:ԃGK Yu󌘢H{ov304'GfܬxdzL7NJ+ fI.z35AI*Yiz' fO$/^ ޔ#vȀmD삮W}D% ]|hH.1'S}jftJvW[d l#r@=;8'.QD{- фi ,mEY߃y"5$}H  ͛,ՀO]]vZ:1muNekʴVPnIYKrqGcϋBfa#:vG;׍'Baݤi ?I5(p>wXMSL M+oJ5"Jcid)GMyQ4Ĕ5be@jXb@~(TVJChq Sc7!WSLç|;ftէjP|l4Fi#t Sz^u*l~ yG63I#|"S+Kp̵/l0?eyҴ; %K/C~$VknDU<kʃrZCArn1( Hxvoޫ )SS‚Do؂$!EB 6jus é#aW rO'oA "aQx1{ d;}(4i@ JiuR{.3נ@KI@[ď9; lY,Ec-SGc=^t./9<4>Tr^O ꓷd0tk &K7XsHzT%!Kw%MxGF kr~,qexo3tAK`(iTc̻Rc)÷SU g>4jt[ #p=Sp`$la# Z)c3bAރ:O)`"`¥acm/'Z)]~ۡAqY37uCpe`8wBdѺz[siJ+(RBMsyU+R9N ê{"silp|)a#H>uCmQ/ T%mp)AM m 5cߵ7:`zz_<$9 [@XGlPQuLk'W5nk'25G /D`ZSQ<Erʈfu`Q|=wytz?ɰ{LFb$*j'z|@F?}H:~*;͡h-ⰳ#A3/ "Mc}nTq>LE -y@t<#i!36`<čaA/cF&Pv)pr ] 1bJ5%89l?@l \2ms{?)9PY-qFŵ!"LS* 1pt4Mr-buGښU~Q(BϘz:I[y L-wO^UN_x,C'i4ONOoi$tKOÄ}x|yFiy U(4j*HmA~ fçun4lNyQ;3T,Su?,`(ޟ:0u0 ?V0amPaf/Z:&@Z։9:Eyѹ Ak#\f1"B$>J N5iᱵz8A'rޏdQC<@ Ƞ]/:(#BNhEeGW&gτЙrxR%8WZKMFjZCbT nØ@MTװKy7&O*׮*i{aG ");wHJf哏%ZEd/v\2D DE*ܐ|, KPIGz{vx~UR<#4-hkE0mHy lDP蛣;D)iFp5Ʊ1:`j0]]ŃSsNes"YjGCtx  `3R;@6#ʕ\&9 Sq#?zfm u8\!o^%gӨ h9b-o`?OC-z |*Kϲ <4/jd`*Ed]Q1Nx,v'|Axٓ'j~|Y" A r"z7ioNp };ցe9עMaL*4&Z}Mю<0C(Ʌ/KKZ]{ؐE眱xWsޜxw4)+Hѯkg5b+~@_XB> C_:XER3/un_jHsh<#듨KB\I~p1!k-5;uGl`5dO5煉{ ~䙯>XT|]q֡1Cbp⒈(B.I{x"ҸR^Kkl`VzAaӕg}&mg Cҟ !Db"⮶ *[嘒ƉRTEU^' ^UF,NLΧ#1"hR3Rdq^Xet`TmW-7T|'/?)˴QėP/:oqkb#*u`Y/jhe{GɪV_)ϻFc@佬0"Kƶ l _Y? ~*:i<͔@C3@La m=;:|”/ W 0ޯ t:6B7D蘣_u_" =mjh%h>ǟK.a;֛EYm^@90O+}E:Ag[%^(ϡ}hx<}˃j*f<*B*A!ܡ6APZVSO@t)nMF}oĔ_&t=IאvKoTLT N}qڄlbdlh൶zk e! D^q Z?zLZҩTPOn&}\= ZK'A2*@]s]a0v'KXR$eHTH^䪻̛Q]nL骘Y>IxꟲuPJީ Jߝ0(cc8+1PMN2LXoɃd47.FI繀I@}Laּ\ ]{n^h3ǀu\oDIt8r Q>S8y&<1D;2 ]j".>+VMb*k@NJ}PLJ,D-Ez||pT[DCWa{c*_g4wS LޙU[Րo-'[!c΄\l>zyvBB4P9T!4}/˃ m)+;vCxq*9O]p$AGp־^0|T9ϻ鈹,81&:Y~8Z8ZPOO_BV0;]rq#1O2xJ5X2 ZbJ1>`OΉgm_uƖ;`}>~\9J]'^ ~x PyUan B-?{Kdb+^nT&ReQKXpg[|KyrОC[YњU0L X=R?3,وz )hÉ^}NkV)'H/49¹]U4 8&U 8,n)rB ĥJ&/ņ?<Ͱ)1329tFB=JoZF\G|m-/3Aqp $<ͲHEš &Hy ;k`B=_%rÒ?w#I`bS9d 8؉t7~W͈GKm Lj`e>.ES%,WUh*P3 ^ 'J`^x3P)-t =E^AGsϦ7 {]^sMp@ND@wRQť4}Eckyx|KV@Tŕ}y台"pa6<)pY($1LR>o R\‚ؤzI$*1}gzy,`Yz°{ф0< abFOrߐ_%gM.m-CӒ[ɩ~PHc9 M\D ? eNI:%_N<{jR7j7y*͞SD7,yYL.Ygt[ը@s$Q=`xHz `aY"\sB-VqoLf4.?YH$M؉G>iЉPX 2); Հ1p&h[n;NL[-\*0u+l<y̜i,b0;6I[}N7"v^,ip' 06ܓrH:IL &j $ kӕه'J s :ggתGGAe8ϻ*m~!S{b}7Դ>}-A΅QԤύ8 1~e*GWDlDfFȅXͦF]f_}lb~Ԑ| ӳYw72ٜFGZWʩEyB81DN1hۄ6Rj@W=b:*vi\ /r.S2 su> m%{+K,ޯ)~{PkjDC\єI Ϊx%]pY3XyKj\55_;G34VȉC#v $%:78]ə֌E|{"ZĊX?Tnɳ3TY^ҒC '܎t:2́ '1*Z*2ϋwInd9:v.*="T% "[uB6u*@Éqm's u )>a{Go+}oꨘ<)}D@pdI5MJ<߫\r߽\EggIZ>2UPw]B7,>󘯍oz.ȑ?FDXX>a;q&q޼pőOp)[H=`Aj|}(4m!5{4^(vcm̱@#A6u*ʸ  Nv5](?`}yur~5Fsy'`5c ++Es 퀆Nַ -6.3{@&TEE5F7l9j__w ]c’lT*nUpb]S{. F3|aљ%ڿI?W~aH_wm3 ]7ЀvR_IT}:@q:ˁѥ0~o*L|ӺA❣= \ui?S#7TZz8Sy[ =*c[⤓>Vv)8Fq5'(Q%P]1=@ @86|a)oseӪ 5$6(,;b1Ř*/ RdC|*0….Z}飃eP_P(rq3%_wIk M<.6_kZr5d`eиzPLf""@2EQoM u8qBs*Hfr.>+ha ZL&B\zRa C\9Zܻd~X߶)û7!3bHy/V8AR+[P{"~y끴EsYAIQAPTC[|o'5몼,KW*Y뢒A39ԡ ;Cw7fKxu * #v#fR{ 5RwՎ:MVB(Ƴ7G넸F;9)8  AF#f| *tp5@byFn*HC9 ĹkKԊF'j?\]ފZ6g1{~.X$h=t#]00Q*>&Oywrw̫G;=g㛪@YXmmHo`jcPuz+Q; fDUZd ]}JWlY 3:ɜ#5ȋ oL~_ݼG>f0> 9/{Tw"Li[: wodRp\j [-ulZf,ĵGL8PW\ gq=ytea39a w6=jj=Z 2}**}}x8CxTjZBn Agh(X]/Ꝫѥg,W1&M2!jhg9jү<# @5:5Ksy^x+-Tgd}q%3oKVkILhx|8yoG{ D9ZZf~6'oEB7ˉE`UӁxH U/lOcǏ1iME/R%כm|ؒlh&vd TJJS~ U;'l"bݨ(fs,rʙM^yd毤jv6{8v+ܙP t}b5< y LL [+Lجp{E9KCk_P4\nKܶS2wd;8N;s(J zQJ0z&Gj>R?g\A* ` v>`A bI}SQ'%/GwU'/7nNduxr:ЇG)XYlcdA@x0TWs81 -YKHǁK'%L%L"Tm:0 hP|l} K32PX:C.K Ƿ'fHE;D[}qWT;\(O׌0}uylTJ8+Ժn駖 zQL-LA ^'(ԚWo@$u-ui8CRj =m)g6SY VuH { 8_|2ZvSIvxa&)o1O'}z_$,bGfnc?pcS簧Le*iD>0A'sTȚ/be:mX5"V!H?6 B_6/n3ºOI!i,G%}v/^Da<Y(ЎM1[b=B_)䕈\7G?9@,I (jqLd,)yLv6)CxpM.q ՞kbD_p3kXt45=1dG('y9?!Yh1Bz DJDָ+$x?@sze(2T?">f,?Ɨn8gx=MuOa6Ե2:-J+1KO&pNh]J/{rq!(+dZSʪJq˯ɟ5GGWj%MoN[ X HYypV[9;,i.%'({])vMC3Bc"5O%zkQ.qf7梻0jV@E0^tX;zΨlpuczxӀr'sKx; @:۬M\! ^zhR[:||>7R;V:6;"$$p+5"%Us1H^[Dd "ƅ5 K,疚GR]tWP¦ݛ>ɗ/sP.5 <'#䧿tIR|?/18rߑld!x [pnsU&HGٖb)s=-[nIX!56JY$2f:n0$9[l)xP-4ܷiF-ʼnΝꚯ@us` ({ \w u??2U??3@ Z^J5q v)w [DXv!˕o&SvH`댬ISAMQ[F"|3vUñ"C f4t/Ә n 7lqr0-.춭;XhuM#sa PgOc$wZRk>F( \Gu׀l[<$~a- ~:c \t ~/'+'MG9ڕ48ؙ4Mcrx zDاA:;,jLegEZ isa:py쁰~Z8`ed{Ҍ@)RG/\j.-ۙ#!NUZsݾ[ BΩBY]dKV鍀NH.T;?&R^6u! ɍ^ 7sdhʙDjOu%MSOQuVEo^gd]Z ~&0#WmHᇨB:h@S}c4⫰}RrYA[]i. kS` 9QZ7o[w -xݯ'wZ_E||R7Sh`/*A $$7=edye$tAk|foϲa}8*[\7>v -ea" FZ6>)8{@u:<#.U:*g(tn>b|@/pT4W)Ć~ǜ*'rGI2OuUQeػx;cp I "oq@IU/r߿>,L)GϗW ?#,z!RPao[&-=7R4Xf"Bihb Pۋ'βbv{Р\a?pN!!?(sUvt9`oR>qR৞}j\ UuD)Hվy2,OfJd{'7U[<}.+Kt49{> ]Ҳ.B . 8Rbڈq?UNao 蓦OgmC?F66'N ÍM|F|V%$ab Y>1 ;;&[8pgRo]>ϵO@ݘ@^Elqov{1g] uyGcU1%x MyS"wMYztC~/֔l,SEfׯm(T KFp9]},s ; >U߳'RGPAՀzر) LTe亖N^WwR el4A5,A ꥳ_ǡׂ+F;[TQMՈy!j)x4KMs 4TTLO>2:#t1 'zAݖMٴA ]WF=aV Ҵҕ#~C(-E7N?|Q1o6';+.7^pL1CSKMѭ*5.8O?oplWíMu} #Bx <?W4DRέZQ9'H -Iik^^? ;Դ*Irw8\2=Ne X~),L tфv# q2Cto̤@iW SX9.eP)KP8vm5;T!M2bGE5ۛc|~ӆ$-;۾,j空~؃[ը*5v\J4B Hь`כ;RɼW?`7c2Gw:S@F..IJ`Evm4yx#+d7H9'Կ ݧT+])6F\dc?V3Fb?e)HDX{>U`P_ "a& ϱ8&AR~Sjso_/7r>aW cyiKt3!7{:$QGdsT*IR~\F[D~g &HCPOtH[Tp,ؒc& Z`*%BJ6(΂L)Mq'Il 'VxHj7ޮ%ON*@6WroW$:mgH,$!.L]w=r*/ALd6hOކ" &;es] *iFn^;C;2aXC&V9f ':}[cqBmznQ(.zJ\(c>Hc8(o@n9q-eF:9M0;G_zҐ.)A|u*F2/.L5X\ɧ=F"7=wlWXi<̪)HLLVWgQP3,=9i)f@~עl oRasˁWq Jj'9Il^P4G Vu'(y8:XUB8JڡE"Z{Usnz3 c J\/DWLyYy5*p#BMnuS 4 9ޠ 8|ɑk'6'~͕C'6P8C``(b;aExtcϧyCyj>2pnfT8*4rd]_B^phDP'0S(~kVR\$hPG8/r0g ,]m$ u߆PX2j>.}|:l:wa= z:MhɂMצP˘lp-;j a8Om7W(Lm=!>ç;֛d1C҂۳NwhV_\rmx&q!BAfWy8h@|!.HgXBE 1ߓwXe5m:D}?;Ԥ5/]MI UO8FLSH֮r.nTt]M}t&-x5Aq$qt>7CkYH l7;XpH[󪔛靽 `ENeOPY ҍB3uz2=c1Gcܔp+PZ\(|,IUW>KE[xKe+`6.vz<\թ򲁸 f;.ڸz K`zp8lP9N^0ˠj@z_Cåw|><8:L,̴Z@NV^\Eʫ6wpO3%T8כLpk0y W.w8[ }ʩ*p}Z'ٽFڀpz`&ƺQwf`M# P]V 3:Dɺ;+-x Â%ëޓ9&K\Y^pJ9`"B#y#K:e68bӛ-Tp`Y"!~Ao?{#5/L iWmgk/|,sFCx$`*Z72k漞xNg@j7l쀱{ա2jȺqv*u&eܵ˂CH',Qa}K S=#E 3#o FKu`ЀJi/aKډu\jk1ѭP*+s2-q[2*^ Mb7u!∥ iYۼr_קL}*{[H#;41u:Js*XKf&ڈudiND.E$,r}BMc^I>pd;Azd _}h\*?g  ౸b?wd/_dQՏ񢂼~+Pd%%[ E [0i[:Mp喯tDt*#?a o D +f`w0Q̡޼((\5{lgS ߯>+{|M1{VzBry,,\w23Af/rJ^X3όS/>PAWavX'>mNgC_֒2i $Ga06&ބGpǕY3upχW,~ SR9Nro;BRۨ }CCBI5Ee͸Kn ja}2*h"XS6tU.;s`EnE\LEiI~{K)#SWlƆUA-"o77y;nA_jܵHzAIx`rCŗເw<Rsj%>d1 o1;D>_Rjde@oiS:Ѝ{8%^&١Ku.]o+@vҮ#WnE,D6ߋVmlkz˺ `?] bHZ!IYMY4]3O9d@s]fr>OOj71߇n[#*NZ>lZzD[=5,9@:i%'"Lf1QS}E1d( 3Ka  DC0eng@%[>E o|5- %Ŭ˳ug8,8;95 !)D̬>ryQ4UW vnXp ְfI5] YyaJnY9H`)8ްKM/`@( Jq=n`%]-js gN6/ G#}ջj Ű;WZ>'4O%/)꽉nQ3ia^ [b,?Kz!q}wTih1RdM6\dN?NAw;N}>]jul]ӜՑx٬^WcބÂQiQY;uWwm}S%rkv3U di [8iW{,V= "N0r:7;@N:[)r]q Sҍ7Lr@Qcp*?F]t[(:j$Tv&Bzxt8!`"=d{^%Ψ^_zW@Aٸ0?f.4Y)Qgк} J[Q.`qHE yEZD0J۫ @&LJ7scһ`!ꉑq]gc0f_][ ky>VͯbҦ9g2إ?J٢< җ*+>(t|Dΐ y`&fi\L+P. ^1>̔ fJq mM$\tQS=j<.zA 5HAWɅ/6(QntRmBZ_#ن>?v 76t+ЖqXn(ƢX0nfZ]nnj]Vke?h&kQj*k{)O&"BsW<݋`(qt1 ۖO>>-|[+S̅,͌IT`X u:Aw'Gz'| 83T}%`'O*onc7H`\|R /ݖ@B㯦M<5y13G72{rPAg#ۂ5U.io&Cj{YcM)HeC<_ڧWkbTh$K[L#9j{a@hNH!zrB3+v(rMe"Ăl+oEڱaH>M3/7h/m , UYpPvFk4vI /?ƈZz2YͩNAx9(,@1=S!q} zt2xY0J?D}Lm4 s O(ӫR Йb 8z(&v^ʶl4FC2k6b2;$]P=Wr 6"eo^ER`ObW:ؾ?@8j],_mopѵsߍ|rԦסqʩy965%Ad>xJ M͈G9ޏ־`=EiRǜĪF[a\I፦wI޳co`)/טYK\TNN6NyhŅ%*Ax wa`ר3Lj|=g,WQ B ViCzQw_ךXX.*"lL2&NnŊ'$'=i = h6bL GGxYnsaaYg,v.\XOm;#aKTnY(ũڬrQM17߷b{:\bʍ6~I-%| dQ(Jؾ1:u)I {:GV)x '`P~@3oL롹3mPx҇@OaҖ*?\6'O îD,5C?/馚8=8Aջ=bt^"GT.Z<|yl"^v.X7;W0^VJ\+`g|ocݴWYJ|-vN#1Hp&5?%#8qyŕ4Crc-dԦk&EASV:`mh )ScMcB^FFlָI2'T́BA@0bF'0ÖE-C'<j˄o#qlxhv"۟v˵o#~Z!dxa-Tu#rHcE@m#'ǡOAA1PAG5Ja MN"_Tbr5n )iCif..+WOY*MGCӢd;O\ZU؇[#2eЎ{&^$!%lKtUȎ)g2|&:3P`?jZMf:|t] mY=sl-< U\d7oAm`0>1t˾ PB:8ӗC'㔅 2h2 SPlk#'3!rMhD31,7mB7OdOZMs6>Ѡ_^ mb7: 6 Fq e!"G`,f_ )R!Cʢ Y$ۤz1ݷRD8;@z8ZR;dk9UU Rw:> ]4Դѹ:l V+e?̊[sZW磈~_4prۊN;›fABxmQ(+a`Kg8<< ELIe&RoX 33|gLhUq>3 vO#T|&lj䚘.qt#ig+j!cB%(hmfr% Lyź1־J}<k׸T/@F Ke"Dp2ʱSY]=Kf+W^ (μhCJE)On^>5g'#xn φQK]JIα_~G0sUq(K>xa=q*Iw$#gfS_5Ok\TTXb*geIIb:xFwSmE5iyp5Lc'?#tf'մhr̈`' ;tk4t䯙嫸E >G-}*!^3({YKH2+q1Ӽyw\!#oRcׁ~xnX\ }l3SIA!VTcS~5ɚ,SKr6ʥNda3X%-3],- i5OLOy“O2k'%y*=Yfp`5]W0d}%,K[|Ɲs$ǤGD/msr*KO}cq?jʁ!EѮ4p,Kzl1cC|'iRRBC>o{.K :P|iU4xxcɶ=Ljk\&k{6nm"q'6b!3Al[Phhɽ =.Ĵ2I"[#;cHT]Q) e0v2Tt&6%)#7kaeRR۸F;Q`՝,@C6a)C<{t4 +\!3(90UDHFCΎ79K9i_v^62.+ f2GK'Rx*#$.c X_!SA(U1Iæ0"H6[p,dGe!:EU&l[m05(81" {m *jgHU,Vk]en|6ZƸ&#/Mt/|TSUݸggCne=@d$<( dN㟔[:%( #5E3'y 4ʶOl&we~]o= YX] 7(pHŔc &L]ّ/'NmNx@2C?;hDY,?aix 7io52#Z3B6;f9ʚD҅5~Z,F,#"tu(k̖WsvsεwzH̀쌽Wwė+d (84[j& 9wDGE̟)T[Ʋ8,Q^_)KFN`V"q>ܶ".N 3 +q5iGdW(.v$6~5 M[lqVKAR&(~^|)V2O*x`h?S 8-q[𶝽Z6UL??ebeUWme CY0BQm4e *%=fCYGxգOj%.{txX[^)W\Ej_޿1WYD H(/}HJ\H[LER*tZc/nsTZXpxLhF[3ޒH FUsĀVIb̞6' %Wl]aֿC2eרI)"D Lvδ1Exjۢ9kq_xl,w'cU:B@5yftV!5N*@<J5n,_.ˋTl*RB|7L((L'mæ\ƾݶɱ))K_=$ݟ-ei=T`U:m}v %̥Y^9+8+7 z&= yJU_QKa q3_~*p7;x[5S.G14If%w~0*0Fv*@ا !nn[ Y\6(? V+@0+[ T~++,x{w~gȺ;M%qXP1&<fbxȰ\FDZUSɱ9Xl Aqz.ؓ7 3Z326:^ {ɕK26]۟Gq8)HyI#lѶ9-aw&;P@Pӂm+r57Ab$b]x[$I`0\S|LSqJmZq5GCPoEYf06+7^dGuG$K3`|ulfUѴTUub6?NX:.hcѝEYIP}y%Lvl,sQYwSONn1 ^Rԑ߅Wݺ@W5>q{PY_/ l(Vs% w-\&2Af iā=:πrfagiH0%/]9/ ;]@tN=d|'5S f<1 l }Cv+̶);P9%,[,[i<@?3}.8өbQ3FApj2W1e-f^*7s=*g-u rgɟi뤚A0^Z ^~U&q׮c3=y?>X2$(ei;9P#mI<+J1!Ո64۟ݞMΧ%%z\` xOA,+/n,Sc =>sRvf/^tEDaaУZoV>iz ӎtRf =X]dh!y3P6HG)Hj;&F[_@S[m-yc_7s9VAyJ?DճMףW U&Igt=@dN wfCCWUxlg`aZMˉѼE"aR/.g2; vW:+ bTsh?~PyOT)3RRxh" V2eklIOO3do?* #$FZI+_|@|Jx8Fwq*0o@wp4tTM\oבCS'*~MA^MN|Vqz+fƨ=VsIXw#U oHUY:6_=p]C?Q;bK۽x1t%r刼Ta>,T|IҋDVՅ{&a rog.^|:Ո"yD_YM?ذ@ʝzWX)\=A7>)R4x`=[E3W)39rV ʴ؁G OAYyowDIFѰ{7f'`0$K.HjI0i< fԅD {Qf}D*مD u@#/e n+ȌXH[H0bD}_C[%w[7f@!>jj&3d&M=E R>2"mJN( $Gg")lF&XezVcRD: yy]1Q=eNw~<|>A"=<3_[Z겦8gr{rDy:`@m/q>fRgҐg=i?nv<#Q|G>}/Mҡ@ZKiMCG{7&-`GP[Tjɋv1f,xv5zETH I,b.ivD덱Gx u $.0z}cM/QNCːCr $?_^8>#}DZ,+?f׃rVp(㮏<6alSGgR*鶿no>r#X=$*DEszȐe|G9+:6SbX8`朂HvT 艀AY4$aJ쓸s1#ͥnAǗd22%NPzvM"1&ol \iV xݭn }XA&@ľynon.is:~ZiȑOh&[2ZUsvx6L\ 5,g[%-!1Iu!A2Ts|rg( (s8RO!kNHm_19n zgDfj*:W12,O#^jwMm>dl.8(`Dڶ)q O $6-#AΒٯj@}۹X`Fa4*~92d4/@F&Ƣ77JJy%-D^w&K #8'bPTM?hkuHYMgߞO+g+5,B|2C"TMil>frc˾Il>ſl`f-6vɰv/ S9;"RJ+Waرla8.a,qK>a ?@:m&o(ѵ]qwoiϝɷ閯5H8c;x#Ҿw-`D&N9iRGyfM^:o B"uк/!d9V<P'ރ-?t a^E#K$~qRgMK"7q{?~ET~VP$uqMt]hgC=K]O7B✢{eжmjmgr$tR{khy +ۣʠ&Xۂ5pd%\3Ch\R3&ɦ|+H;,FwçO5xVM0}ǗpxyV?:X&?U?&@Xf|N;i*]]A}ig6or'U]Ɔ$Q[a&цpfLY1Ze(IƖl)P|jKɁT;:q'#=azݭ'$ЧI]8|( :f0 )oHJX`D)8IBz5}H2->t,>g3;j_iQˀ@v<ǜ$Ӊ EY|ߪZm^9Dgt3-ӶIvFxX˕Z4~mnQI}n@608Em3pRxSٟxP̓{۸T9Dy$};O&eo/$IeG\ [\W 6pVE_ Vm3qniG82yLM(qc@o&-Ó1م+L@{d1 BBy_]1v) Mf" ۡ_!cc?ckuz6ܯֶebu+ZÂ|/Upk,ʌxw|+} W/wJ "CZ='>Q\ @jV؝Hilx qVQ=[ EZXA;pA")'VM8g$x2ӥ}zEG< 9-Cr QNW˟Ybb݃1 }٧nr0%ZC/Ao 4x}OERHqVi(UT=A*Sr5 fm# @C]6Bgq}w\AekZ>3C r^UEfFJv{¾P'9;&ܣ۹B&Ֆ_I-eE,gͳAWRY@?_v^ N+Ы?IY{ kWI%%y;=(-ykY< 1F.#@.y[Zĩt؇Brk$P]sFpP%S[cKI[4'+^`/fQfH#ͲVXyHlw/'wTn,@KAf,J<'DY>g*D<u!xn258H.JƟ*tv>5 ܉c3_; 7* -yb~ES| ՏW1mrCxByjrjЖ~0ECHOe[lC~.)A/vY#בu'a d~ ,n1 F2jT+U lHAC1b,0>j;jW c2hMEsSlkBN?,1#FƧÄsrly}樿"%tQY@@29I:ЅSV4[.ced6¦N,됴Z%"}|9PV90M͟XDS`~ p9 t*72&OZ/ND|)zg01^6$E%VF78+}9! GV0EIXz7l.]/LP8R"y